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

Atmega16 i LCD 4x20 - 8 bitów - nie działa [C]

kliwer19 09 Lut 2010 21:06 1965 5
REKLAMA
  • #1 7669900
    kliwer19
    Poziom 10  
    Witam. Chce zainicjować wyświetlacz 4x20 podłączony do atmega16. Zapis do LCD jest 8 bitowy i dane są na porcie D a port C steruje wyświetlaczem. Nie wiem już gdzie szukać błędu bo dalej mam objawy, że wyświetla mi się 1 i 3 linia. Oto kod programu. Za pomoc byłbym bardzo wdzięczny.

    #define 	LCD_MODE           0x07
    #define 	LCD_8BIT_2LINE   00111000
    #define 	LCD_CLR_SCR      00000001
    #define 	LCD_DISP_OFF     00001000   
    #define 	LCD_DISP_ON      00001110 
    
    
    void lcd_write8(char data)
    {
    LCD_E_PORT |=_BV(LCD_E_PIN) ;    // ustaw na E stan wysoki
    LCD_PORT = data;                        //zapis i bajtu do lcd
    LCD_E_PORT &= ~_BV(LCD_E_PIN); // opadające zbocze na E -> zapis do wyświetlacza
    _delay_ms(1);
    				
    } 
    
    void lcd_putc(const uint8_t chr)
    {
    	LCD_RW_PORT &=~_BV(LCD_RW_PIN);
    	LCD_RS_PORT |= _BV(LCD_RS_PIN);
    	lcd_write8(chr);
    }
    
    void lcd_command(const uint8_t com)
    {
    	LCD_RW_PORT &=~_BV(LCD_RW_PIN) ;
    	LCD_RS_PORT &= ~_BV(LCD_RS_PIN);
    	lcd_write8(com);
    }
    
    void lcd_init(void)
    {
    	uint8_t i;
    	 _delay_ms(35);
    	LCD_RS_PORT &= ~_BV(LCD_RS_PIN);
    	i=3;
    	do 
    {
    	lcd_write8(LCD_8BIT_2LINE);
    	_delay_ms(10);
    }
    	while (--i);
    	lcd_write8(LCD_8BIT_2LINE);
    	_delay_ms(1);
    	lcd_command(LCD_DISP_OFF);
    	_delay_ms(1);
    	lcd_command(LCD_CLR_SCR);
    	_delay_ms(5);
    	lcd_command(LCD_MODE);
    	lcd_command(LCD_DISP_ON);
    }


    inventco.eu - post edytowałem - znaczniki CODE, zmieniłem tytuł regulamin p.11.1
  • REKLAMA
  • #2 7672013
    chudybyk
    Poziom 31  
    Witam!
    Kolejne linie nie są w obszarze pamięci wyświetlacza po kolei. Druga i czwarta linia zaczynają się od adresu 40h (czyli 64 dziesiętnie). Druga możliwość to zbyt słabo podkręcony kontrast. Te wyświetlacze, nie wiadomo czemu, dziwnie traktują te linie.
  • REKLAMA
  • #3 7672038
    kliwer19
    Poziom 10  
    tzn o co chodzi z tymi liniami? bo nie mam pojęcia jak to zmienić?
  • REKLAMA
  • #4 7672148
    chudybyk
    Poziom 31  
    To znaczy, że wypisując tekst 20-znakowy w pierwszej linii ustawiasz kursor na adres 0. Kiedy masz więcej niż 20 znaków i chcesz pisać w drugiej linii, to musisz wypisać pierwsze 20 znaków, a potem przestawić kursor pod adres 64 (czyli szesnastkowo 0x40), kiedy chcesz pisać w trzeciej linii znowu przestawiasz kursor na adres 20 (czyli 0x14), bo fizycznie ta linia znajduje się zaraz za pierwszą w pamięci. (Wiem, że to niewygodne i głupie, ale tak jest) Czwarta linia znajduje się znowu od adresu 0x54 czyli 84. Najlepiej napisz sobie procedurkę podobną do tej:
    
    // *** ustawia kursor na pozycji x,y liczone od zera 
    // *** (x - numer kolumny, y - numer wiersza
    void lcd_setAt(const byte x, const byte y){
    	byte adres;
    	switch (y){
    		case	0: adres = 0x00; break;
    		case	1: adres = 0x40; break;
    		case	2: adres = 0x14; break;
    		case	3: adres = 0x54; break;
    		default:	adres = 0x00;
    	}
    	lcd_instr(LCD_CODE_SET_AT | (adres+x));
    }
    
  • REKLAMA
  • #5 7672226
    kliwer19
    Poziom 10  
    hm... no rozumiem to ustawienie kursora ale nie mam pojęcia jak to połączyć z zapisem do LCD i innymi funkcjami:/

    Dodano po 13 [minuty]:

    oraz z zainicjowaniem lcd:(
  • #6 7672273
    chudybyk
    Poziom 31  
    Reszta komend jest bez zmian. Ustawiasz kursor np. na adres0x40 i wysyłasz kolejne znaki do wydrukowania. Będą się pokazywać począwszy od drugiej linii. To jest jak z kursorem ekranowym na komputerze. Przesuwa się razem z pisanymi znakami.
    Dla przykładu możesz zerknąć na moje procedurki obsługi lcd.:
REKLAMA