logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

LCD 2x16 (1602ZFA) z ATmega8 - wyświetla kwadraty, problem z kompatybilnością?

hondatrx700xx 05 Wrz 2014 15:24 1362 0
REKLAMA
  • #1 13936320
    hondatrx700xx
    Poziom 1  
    Witam.

    Mam problem z wyświetlaczem LCD 2x16 (1602FZA).
    LCD cały czas wyświetla tylko kwadraty. Programuje na atmega8 i skorzystałem z kodu który mam w kursie. Gdzieś na elektrodzie wyczytałem że może być to problem z kompatybilnością.

    "Co się tyczy wyświetlacza, to nie wiem czy ten 1602ZFA V1.0, oparty o sterownik ST7066U i ST7065C, jest w pełni kompatybilny ze sterownikiem HD44780 (a taki zastosował autor SKALARa), szczególnie jeżeli chodzi o sterowanie 4 bitowe (wiem, że z tym są problemy). "

    Jak sobie poradzić z tym fantem.


    KOD:
    #include <avr/io.h>
    #define F_CPU 1000000
    #include <util/delay.h>

    //w programie zak³ada siê, ¿e:
    //a) wszystkie linie obs³uguj¹ce wyœwietlacz LCD
    // s¹ pod³¹czone do jednego portu,
    //b) linie DB4..7 s¹ pod³¹czone do linii 4..7 portu.
    #define DDR_LCD DDRB
    #define PORT_LCD PORTB
    #define RS_LCD 2
    #define EN_LCD 3
    #define DB4_LCD 4
    #define DB5_LCD 5
    #define DB6_LCD 6
    #define DB7_LCD 7

    //deklaracje funkcji
    void Wyslij_do_LCD(int8_t);
    void WlaczLCD(void);
    void CzyscLCD(void);
    void WyswietlLCD(char*, int8_t);

    //funkcja g³ówna
    int main(void)
    {
    char napis[15] = "Witaj, kotlecie";

    WlaczLCD();

    WyswietlLCD(napis, 15);

    for(; ; );

    return 0;
    }


    //////////////////////////////////////////////
    void Wyslij_do_LCD(int8_t bajt)
    {
    //ustawienie EN
    PORT_LCD |= _BV(EN_LCD);

    //wys³anie 4 najstarszych bitów danych
    PORT_LCD = (bajt & 0xF0)|(PORT_LCD & 0x0F);

    //potwierdzenie wys³ania danych (opadaj¹cym zboczem EN)
    PORT_LCD &= ~(_BV(EN_LCD));

    //zaczekaj cykl
    asm volatile("nop");

    //ustawienie EN
    PORT_LCD |= _BV(EN_LCD);

    //wys³anie 4 najm³odszych bitów danych
    PORT_LCD = ((bajt & 0x0F)<<4)|(PORT_LCD & 0x0F);

    //potwierdzenie wys³ania danych (opadaj¹cym zboczem EN)
    PORT_LCD &= ~(_BV(EN_LCD));

    //zaczekaj 40 us
    _delay_us(40);
    }


    void WlaczLCD()
    {
    //ustawienie kierunku wyjœciowego linii pod³¹czonych do LCD
    DDR_LCD = (0xF0)|(1<<RS_LCD)|(1<<EN_LCD);
    //stan niski na liniach
    PORT_LCD = 0;

    //zaczekaj co najmniej 45 ms na ustabilizowanie siê napiêcia
    _delay_ms(45);

    //1
    //ustaw liniê EN
    PORT_LCD |= (1<<EN_LCD);
    //za³aduj sekwencjê 0011
    PORT_LCD |= (1<<DB4_LCD)|(1<<DB5_LCD);

    //potwierdŸ opadaj¹cym zboczem EN
    PORT_LCD &= ~(_BV(EN_LCD));

    //zaczekaj co najmniej 4.1 ms
    _delay_ms(4.1);

    //2
    //ustaw liniê EN
    PORT_LCD |= (1<<EN_LCD);
    //potwierdŸ opadaj¹cym zboczem EN sekwencjê 0011
    PORT_LCD &= ~(_BV(EN_LCD));

    //zaczekaj co najmniej 100 us
    _delay_us(100);

    //3
    //ustaw liniê EN
    PORT_LCD |= (1<<EN_LCD);
    //potwierdŸ opadaj¹cym zboczem EN sekwencjê 0011
    PORT_LCD &= ~(_BV(EN_LCD));

    //zaczekaj co najmniej 100 us
    _delay_us(100);

    //4
    //ustaw liniê EN
    PORT_LCD |= (1<<EN_LCD);
    //ustawienie interfejsu 4-bitowego
    PORT_LCD &= ~(_BV(DB4_LCD));

    //potwierdŸ opadaj¹cym zboczem EN
    PORT_LCD &= ~(_BV(EN_LCD));

    //ustaw parametry wyœwietlacza
    //bit 4 = 0 (s³owo danych ma 4 bity)
    //bit 3 = 1 (2 wiersze znaków)
    //bit 2 = 0 (matryca 5x8 pikseli)
    PORT_LCD &= ~(_BV(RS_LCD));
    Wyslij_do_LCD(0b00101000);
    PORT_LCD |= _BV(RS_LCD);

    //ustaw tryb pracy wyœwietlacza
    //bit 2 = 1 (inkrementowanie adresu zapisu danych)
    //bit 1 = 1 (wy³¹czenie przesuwania w prawo)
    PORT_LCD &= ~(_BV(RS_LCD));
    Wyslij_do_LCD(0b00000110);
    PORT_LCD |= _BV(RS_LCD);

    //w³¹cz wyœwietlacz
    //bit 2 = 1 (w³¹czenie wyœwietlania)
    //bit 1 = 1 (kursor aktywny)
    //bit 0 = 0 (kursor nie miga)
    PORT_LCD &= ~(_BV(RS_LCD));
    Wyslij_do_LCD(0b00001110);
    PORT_LCD |= _BV(RS_LCD);

    CzyscLCD();
    }

    void CzyscLCD()
    {
    PORT_LCD &= ~(_BV(RS_LCD));
    Wyslij_do_LCD(1);
    PORT_LCD |= _BV(RS_LCD);

    //czekaj 1.64 ms
    _delay_ms(1.64);
    }

    void WyswietlLCD(char *napis, int8_t ile)
    {
    int8_t k = 0;
    while(k<ile)
    {
    Wyslij_do_LCD(napis[k]);
    k++;
    }
    }
  • REKLAMA
REKLAMA