WebElektronika

LCD kijelző használata az ATmega32-es mikrovezérlőnél

person access_time 2016.03.31.
Megnézzük most az LCD kijelző használatát. A program úgy készült el, hogy univerzális legyen, tehát könnyen tudjuk módosítani a portokat.


Elkészítünk most egy LCD vezérlést, egy ATmega32-es mikrovezérlőt használunk fel erre a célra. Az LCD-nk kétsoros, és 20 karakter széles. Látni lehet majd a kódból, hogy könnyedén módosítható, ha más LCD-t alkalmazunk, illetve, ha az adat- és vezérlőjelek nem a "B" porton vannak.

Az LCD vezérlő a HD44780, amelynek az adatlapja például itt érhető el. 

A vezérlőjelek (RS, RW, EN) a "B" porton találhatók (PB0, PB1, PB2), illetve az LCD adatbemenetei a PB4-PB7 portbiteken helyezkednek el. A PB3 bittel kapcsoljuk be az LCD-t.
Ha meg kell változtatni a portot, például PORTB-ről PORTD-re, akkor csak a makróknál kell ezt a változtatást megtenni.

Az lcdInit() függvény segítségével állítjuk be a Hitachi vezérlőt úgy, hogy csak 4 adatbit segítségével küldjük ki a megjelenítendő karaktereket az LCD-re. Ez a függvény egy egyszerű állapotgépet valósít meg.

Az lcdCmd() függvénnyel parancsot tudunk kiküldeni a vezérlő felé, a prints() segítségével pedig karaktereket, sztring-eket tudunk megjeleníteni az LCD-n. Ehhez pozícionálni kell a kurzort, ahol a kiírást elkezdjük. Ezt oldja meg a gotoXY() függvény.

Az lcdCmd() és a prints() függvények főleg egyforma műveleteket tartalmaznak, ezek az lcdOperate() függvényben kaptak helyet. A különbség LCDPort és az RS közötti logikai operátor.

#include <avr/io.h>
#include <util/delay.h>

#define RS  0x01
#define RW  0x02
#define EN  0x04

#define LCDPort    PORTB
#define LCDTap    PORTB3

void lcdInit(void);
void lcdCmd(unsigned char ch);
void prints(const char *ch);
void gotoXY(unsigned char x, unsigned char y);
void lcdOperate(unsigned char ch);

int main(void)
{
    DDRB = 0xFF;

    lcdInit();
    LCDPort |= 1 << LCDTap;
    
    gotoXY(0,0);
    prints("WebElektronika");
    gotoXY(0,1);
    prints("Online ujsag");
    
    while(1);
}

void lcdInit(void)
{
    LCDPort &= ~RS;
    LCDPort &= ~EN;
    LCDPort &= ~RW;
    LCDPort |= 0x30;
    _delay_ms(30);
    
    LCDPort |= EN;
    LCDPort &= ~EN;
    _delay_ms(5);
    
    LCDPort |= EN;
    LCDPort &= ~EN;
    _delay_ms(5);
    
    LCDPort |= EN;
    LCDPort &= ~EN;
    _delay_ms(5);
    
    LCDPort &= 0x20;
    LCDPort |= EN;
    LCDPort &= ~EN;
    lcdCmd(0x28);
    _delay_ms(30);

    lcdCmd(0x0E);
    _delay_ms(30);
    
    lcdCmd(0x01);
    _delay_ms(30);
    
    lcdCmd(0x06);
    _delay_ms(30);
    
    lcdCmd(0x80);
    _delay_ms(30);
}

void lcdCmd(unsigned char ch)
{
    LCDPort &= ~RS;
    lcdOperate(ch);
}

void lcdOperate(unsigned char ch)
{
    LCDPort &= ~EN;
    LCDPort &= ~RW;
    LCDPort &= 0x0f;
    LCDPort |= ((ch ) & 0xf0);
    LCDPort &= ~RW;
    LCDPort |= EN;
    _delay_ms(2);

    LCDPort &= ~EN;
    LCDPort &= 0x0f;
    LCDPort |= ((ch << 4) &  0xf0);
    LCDPort |= EN;
    _delay_ms(2);

    LCDPort &= ~EN;
}

void prints(const char *ch)
{
    while (*ch)
    {
        LCDPort |= RS;
        lcdOperate(*ch);
        ch++;
    }
}

void gotoXY(unsigned char x, unsigned char y)
{
    if(x<40)
    {
        if(y)
            x |= 0x40;
        x |= 0x80;
        lcdCmd(x);
    }
}