Stránka 1 z 3
Problém se znakovým LCD, ATmega32
Napsal: 04 črc 2012, 18:58
od 1N4148
Zkouším ovládat znakový LCD displej 16x2 pomocí ATmegy32, na internetu jsem našel tento tutoriál
http://extremeelectronics.co.in/avr-tutorials/using-lcd-module-with-avrs/ ale bohužel mi nefunguje vše jak by mělo. Zdrojový kód je obsažen v odkazovaném článku (Sample program), připojené knihovny taky (lcdlibv20.zip).
Můj problém je, že v úvodním for-cyklu se mi zobrazuje část textu "Hello world", který by se měl zobrazit až později, a ještě před tím znak "°", který by tam vůbec být neměl, viz foto:
Přijde mi to divné, další text by se neměl vypisovat, dokud for-cyklus neskončí. Přidání prodlevy mezi příkazy ani snížení taktu procesoru nepomohlo. V čem je chyba?
Napsal: 04 črc 2012, 20:32
od gmike
Je to divné, ale zkus příkaz
LCDWriteStringXY(12,1,"%");
nahradit tímhle
LCDWriteStringXY(12,1,"% ");.
Jenom za znak procenta přídáš tři mezery, tím si jednoduše to co nechceš přepíšeš.
edit: nechce mi to vzít tři mezery, ale jsou tam

Napsal: 04 črc 2012, 20:38
od 1N4148
Jasný, to mě taky napadlo. Ale mě jde spíš o to, najít kde je chyba, abych ty knihovny mohl v budoucnu používat a nemusel řešit kolik tam dát mezer.

Napsal: 04 črc 2012, 20:48
od Andrea
V té knihovně je chyba ve funkci void LCDWriteString(const char *msg).
Konkrétně v tomhle
Kód: Vybrat vše
else
{
LCDData('%');
LCDData(*msg);
}
Napsal: 04 črc 2012, 21:19
od 1N4148
Autor knihovny zvolil asi trochu nešťastně znak "%" pro uvozování uživatelsky definovaného symbolu (což by vysvětlovalo, proč se ve výpisu objevil znak "°"), změnil jsem to na "_" a je to ok. Zatím ale nechápu, proč se vypisoval i řetězec "Hello world"

Napsal: 04 črc 2012, 21:21
od Andrea
No kvůli té chybě, tou změnou jsi ji neodstranil.
Napsal: 04 črc 2012, 21:26
od 1N4148
Přiznám se, že se v tom zas tak neorientuju, mohla bys mi prosím sdělit, v čem přesně je ta chyba a jak ji odstranit? Díky.
Napsal: 04 črc 2012, 21:30
od Andrea
Lámej si trochu hlavu, jen opisováním se nic nenaučíš. Řetězce jsou v C zakončené 0, tzv. ASCIIZ, tak se zamysli nad tím, co ta funkce udělá, když poslední znak v řetězci je ten "speciální" a za ním je už jen ta nula.
Napsal: 04 črc 2012, 21:54
od 1N4148
No bude si myslet, že chci vypsat uživatelsky definovaný znak. Podívá se, jaké číslo následuje za %, což je 0. Takže vypíše znak č. 0, což je °. While cyklus skončí a do větve else program nedojde.
Napsal: 04 črc 2012, 22:03
od Andrea
1N4148 píše:No bude si myslet, že chci vypsat uživatelsky definovaný znak. Podívá se, jaké číslo následuje za %, což je 0.
Pleteš si ASCII znak '0' s číslem 0.
1N4148 píše:While cyklus skončí a do větve else program nedojde.
To jseš na omylu, while cyklus neskončí, nemá proč by se ukončil.
Napsal: 04 črc 2012, 22:40
od 1N4148
No dobře, tak funkce narazí na znak %, pokusí se příkazem msg++ přejít na další znak, ale žádný tam není, na tom místě bude nejspíš v paměti uložený ukazatel na string Hello world, program přejde do větve else, vypíše se znak % a string Hello world. Tak a teď zas nevím, kde se vezme znak °

Napsal: 04 črc 2012, 22:41
od Andrea
Tak si to odkrokuj v nějakým simulátoru, když to z toho papíru nedokážeš pochopit.
Napsal: 05 črc 2012, 00:53
od WLAB
Ten kod je zmatlanej, po (287) msg++; se uz nekontroluje konec retezce (chyba je spis tady nez v te else casti), ktery by to vubec chtelo testovat na jednom jedinem miste - a do tela while pak napsat stavovy automat, ktery udela parsing user retezcu (tady by byl hodne jednoduchy). Ten symbol stupen je puvodni zakoncovaci nula, kterou tam nasype (296) LCDData(*msg);
Napsal: 05 črc 2012, 05:32
od AB1
Chyba se projeví, když poslední znak ve stringu je '%'.
Pointer msg se ve smyčce while() dvakrát inkrementuje a tím pádem se přeskočí test koncové nuly.
Pomohlo by třeba
Kód: Vybrat vše
//Custom Char Support
if(*msg=='%')
{
msg++;
if(*msg == '\0') {LCDData('%'); return;} ////// přidáno
int8_t cc = *msg-'0';
if(cc>=0 && cc<=7)
...
...
Napsal: 05 črc 2012, 07:50
od Andrea
Stačí v té else části místo LCDData(*msg); dát msg--;