Problém se znakovým LCD, ATmega32

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
1N4148
Příspěvky: 185
Registrován: 15 led 2012, 00:00

Problém se znakovým LCD, ATmega32

#1 Příspěvek 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:
Obrázek
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?
Uživatelský avatar
gmike
Příspěvky: 95
Registrován: 26 zář 2009, 00:00

#2 Příspěvek 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 :)
Uživatelský avatar
1N4148
Příspěvky: 185
Registrován: 15 led 2012, 00:00

#3 Příspěvek 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. :D
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#4 Příspěvek 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);
      }
Uživatelský avatar
1N4148
Příspěvky: 185
Registrován: 15 led 2012, 00:00

#5 Příspěvek 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" :?
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#6 Příspěvek od Andrea »

No kvůli té chybě, tou změnou jsi ji neodstranil.
Uživatelský avatar
1N4148
Příspěvky: 185
Registrován: 15 led 2012, 00:00

#7 Příspěvek 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.
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#8 Příspěvek 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.
Uživatelský avatar
1N4148
Příspěvky: 185
Registrován: 15 led 2012, 00:00

#9 Příspěvek 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.
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#10 Příspěvek 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.
Uživatelský avatar
1N4148
Příspěvky: 185
Registrován: 15 led 2012, 00:00

#11 Příspěvek 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 ° :twisted:
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#12 Příspěvek od Andrea »

:roll:
Tak si to odkrokuj v nějakým simulátoru, když to z toho papíru nedokážeš pochopit.
Uživatelský avatar
WLAB
Příspěvky: 867
Registrován: 13 zář 2005, 00:00
Bydliště: Praha

#13 Příspěvek 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);
de omnibus dubitandum est
Uživatelský avatar
AB1
Příspěvky: 312
Registrován: 23 lis 2009, 00:00

#14 Příspěvek 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)
...
...       
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#15 Příspěvek od Andrea »

Stačí v té else části místo LCDData(*msg); dát msg--;
Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“