AVR LCD - Szia Levi!

2013-01-03

 

Telik az idő, a cikkek alapján azt is hihetné a kedves látogatóm, hogy itt nem történik semmi. Pedig történik. De nem elég, hogy a dolgok történnek, az embernek meg is kell írnia. Az egyik ilyen dolog, hogy beszereztem egy dugdosós panelt, és megpróbálok elszakadni attól, hogy mindenhez NYÁK-ot készítek. Készítettem hozzá kiegészítő dolgokat is. Most a tetejénél látszik egy szimpla csupalyuk panel csík, amibe tüskesot forrasztottam, és onnan tekeregnek a programozó és a soros csatlakozás vezetékei a mikrovezérlőhöz. Éppen a legutolsó APH2-es fejem van rádugva. Az LCD panelba szintén tüskesor van forrasztva, igy van a panelba dugva. A panel árát még csak-csak kiköhögtem, de nem voltam hajlandó horror áron néhány dirib-darab vezetéket venni hozzá. A számítógépek UTP ábelében lévő vezetékek kiválóak erre a célra. Csak ne a lágy patch kábelt, hanem a merevebb fali kábelt keressük. Ahol húznak be ilyen vezetéket, mindig akad némi maradék. A dugdosós panelről annyit kell tudni, hogy a két szélén hosszában vannak összekötve a lyukak, piros és kék csíkkal jelezve, nyilván a tápnak. A közepén pedig lefelé és fölfelé vannak a lyukak összekötve. Így azután elég szabadon garázdálkodhatunk, dugdoshatjuk az alkatrészeket és a vezetékeket. A panel ráragasztottam egy darab deszkára, hogy a később csatlakozó dolgokat majd ehhez csavarozhassam.

Vagy 10 éve foglalkoztam ezzel a Hitachi (ma Renesanse) HD44780 vezérlőjű LCD kijelzővel. Akkor még ADuC és h8 mikrovezérlőkkel. C kompatibilitás ide vagy oda, mégis át kellett írni a kódot. A HD44780 egy olyan célvezérlő, amely képes meghajtani az LCD szegmenseket. Ennek azért van jelentősége, mert az egyes szegmenseket pontosan 50%-os kitöltésű tényezőjű jellel kell meghajtani, különben az igen vékony, átlátszó, ónoxid réteg legalvanizálódik egy idő múlva az üvegről. Nomeg kismillió láb kell, ha nem is Full HD a kijelzés. A Z80-asok idején (80-as évek), a párhuzamos, 8 bit-es inteface-ek voltak divatban. Azután, hogy miért ez maradt a túlélő? A mai világban egy AVR lábra 3-4 funkció is jut, így minden egyes láb nagyon értékes amit nem kell az LCD kijelző vezérléséhez elhasználnunk. A vezérlő annyi engedményt tesz, hogy lehetséges 4 adat vonalon, fél byte-onként beletölteni a mondanivalónkat. Van három vezérlő lába. Az R/S láb 0 állapotában parancsot, 1 állapotában adatot vár a vezérlő. Az R/W láb 0 álapotában írni lehet a vezérlőt, 1 állapotánál pedig olvasni. Az E láb tulajdonképpen órajel, a jel a lefutó élére történik meg az adatok olvasása. Kell még neki föld, meg táp, és egy trimmer poti, amivel ac LCD kontrasztját be kell állítanunk. Ez tréfás dolog, ha nincs beállítva, nem látszik semmi, azt is hihetjük nem működik a kapcsolásunk, pedig a proc már régen kiírta amit kellett. A HD44780 fut vagy 2-300 kHz-en. Tehát nem olyan gyors, mint a modernebb áramkörök. Eredetileg az R/W láb segítségével ki lehet olvasni a vezérlőből az állapotát, és várakozni mindaddig, amig el nem készül a feladatával. De itt is meg lehet egy lábat takarítani. A R/W lábat leföldelve dönthetünk úgy, hogy nem kérdezünk semmit, csak parancsokat osztogatunk neki. A vezérlő katalógus lapja közli, hogy milyen művelethez mennyi időre vanszüksége, és azt kivárjuk. Itt látható a nem túl bonyolult kapcsolás. És még maradt láb egy ilyen kis 300 Ft-os vezérlőn is, hogy más áramköröket illesszünk hozzá.

Azért szerzett néhány álmatlan éjszakát ez a kis áramkör. Az egyik hiba amit vétettem, hogy nem volt jól beállítva a CKSEL bitek, és 8MHz-en ketyegett az áramkör 4 helyett. Persze az időzítések nem stimmeltek, a LCD nem bírta a tempót :-). A másik hiba az inicializálás körül volt. Még nem írtam, de a HD44780, annak ellenére, hogy nem egy külön áramkör, de valójában nem tudja milyen LCD kijelző van rákötve. Tehát meg kell mondanunk neki, hogy 1, vagy több soros a kijelző, egy karakter 5x7 pontból, vagy többől áll, 8 vagy 4 vonalon szeretnénk vele beszélgetni. Szóval bekapcsolás után 8 soros az alapértelmezett interface. Alapból az ember a nem használt lábakat leföldeli. De a konfigurációnak megfelelő D3 bitet igazából 1-be kell kötni, hogy rögtön, amíg 8 bites módban van az interface megkapja a 2 soros kijelzésre váltó kódot. Végül ez csak 3 éjszakámba került, mire rájöttem. A legbosszantóbb, hogy 5 perc múlva, mikor alaposabban megnéztem a doksit, kiderült, hogy van egy másik módszer is, mégpedig, hogy a vezérlő kódot kétszer kell a vezérlőnek betáplálni. Nem logikus, de működik. Még egy gondolat. Találkoztam már olyan (utángyártott) LCD modullal, ami még lassabb volt, ilyen esetben még hosszabb várakozásokra lehet szükség.

Itt látható a program.



/*******************************************************************************
*   Author       -  Kiraly Tibor                                               *
*                   http://www.tkiraaly.hu                                     *
*   Date         -  2012.12.09.                                                *
*   Chip         -  Atmel ATtiny2313 & HD77480                                 *
*   Compiler     -  avr-gcc (WinAVR )                                          *
*                                                                              *
*   Bekapcsolas bekapcsolja a LED-et,majd az LCD-re kiirja: Szia Levi!         *
*                                                                              *
********************************************************************************
*   PonyProg Configuration and Security Bits (bepipalva):                      *
*   Belso 4MHz-es osszc.:     SUT0, CKSEL3, CKSEL2, CKSEL0                     *
*                                                                              *
*******************************************************************************/
//
//
//    LCD bekotese:
//
//    14   LCD_D7       - PB3 - 15
//    13   LCD_D6       - PB2 - 14
//    12   LCD_D5       - PB1 - 13
//    11   LCD_D4       - PB0 - 12
//    10   LCD_D3       - GND
//     9   LCD_D2       - GND
//     8   LCD_D1       - GND
//     7   LCD_D0       - GND
//     6   LCD_E        - PD6 - 11   (1 - change data - 0)
//     5   LCD_RW       - GND        (0- write, 1- read)
//     4   LCD_RS       - PD5        (0- istruction, 1- data)
//     3   LCD_KONTR    - 10 kOhm trim.
//     2   LCD_VDD      - +5V
//     1   LCD_VSS      - GND


#ifndef F_CPU
#define F_CPU                4000000             //MHz
#endif



#include "tkiraaly_attiny2313.h"
#include 




void lcd_init4( void);
void lcd_putc( UC);




#define LCD_E                6
#define LCD_E_0              BC( PORTD, LCD_E)
#define LCD_E_1              BS( PORTD, LCD_E)

#define LCD_RS               5
#define LCD_RS_UTASITAS      BC( PORTD, LCD_RS)
#define LCD_RS_ADAT          BS( PORTD, LCD_RS)

#define LED                  4
#define LED_BE               BC( PORTD, LED)
#define LED_KI               BS( PORTD, LED)

#define LCD_PORT             PORTB               // also 4 bit
#define LCD_PORT_ENABLE      DDRB= 0B00001111    // also 4 bit kimenet




int main( void)
{
   DDRD= 0B01110000;                             // kimenetek beallitasa (1)
   LCD_PORT_ENABLE;
   lcd_init4();
   LED_BE;
   lcd_putc( 'S');
   lcd_putc( 'z');
   lcd_putc( 'i');
   lcd_putc( 'a');
   lcd_putc( ' ');
   lcd_putc( 'L');
   lcd_putc( 'e');
   lcd_putc( 'v');
   lcd_putc( 'i');
   lcd_putc( '!');
   return 0;
}




void lcd_init4( void)                            // LCD init - 4 bit interface
{
   _delay_ms( 50);                               // 50 msec varakozas
   LCD_PORT= 0x00000010;
   LCD_E_1;
   LCD_E_0;
   _delay_ms( 5);
   LCD_E_1;
   LCD_E_0;
   _delay_ms( 1);
   lcd_putc( 0B00101000);                        // 4 bit interface, 2 sor, 5x8 pontos betu
   lcd_putc( 0B00101000);                        // megegszer, az LCD miatt
   lcd_putc( 0B00001100);                        // kijelzes be, cursor ki
   lcd_putc( 0B00000110);                        // set entry mode
   lcd_putc( 0B00000010);                        // bal felso sarokba
   _delay_ms( 2);
   LCD_RS_ADAT;
}




void lcd_putc( UC c)                             // LCD 1 betu kiiras
{
   LCD_E_1;                                      // felso 4 bit
   LCD_PORT= ( LCD_PORT & 0B11110000) | ( 0B00001111 & c >> 4);
   LCD_E_0;
   LCD_E_1;                                      // also 4 bit
   LCD_PORT= ( LCD_PORT & 0B11110000) | ( 0B00001111 & c);
   LCD_E_0;
   _delay_us( 37);
}

Reménykedem, hogy talán sikerült jól bekommenteznem, és mindenkinek érthető a kód. Egyrészt az általam jegyzett "tkiraaly_attiny2313.h" header file-ra van szükség hozzá, másrészt -ra. Ez szükséges az WinAVR-hez mellékelt késleltető (delay) rutinok használatához. Ebben az egyszerű programban csupán két függvénnyel operálok, az egyik az LCD modult inicializálja, a másik pedig fél byte-onként kikír egy adatot.

Itt a vége, fuss el véle, legytek az én vendégeim, innen letölthetitek a hozzávalókat összecsomagolva.