Atmega8 + LCD = Problem.

Feb 04, 2008 1 Replies

Witam! Mam problem z podłączeniem wyświetlacza lcd do w/w procka. Jest to problem z dwoma wyświetlaczami jeden na hd44780A00 drugi KS066F00 2x16 znaków. Niby inicjalizacja przebiega poprawnie, oba rzędy równomiernie "podświetlone", ale nic nie wyświetla albo jakieś bzdety.



0to rozpis pinologii: Port Port Wyśw. Proca D4 PD0 D5 PD1 D6 PD2 D7 PD3 RS PD4 RW PD5 E PD6

A oto kod programu: Program z mikrokontrolery.net z moimi przeróbkami.


#define F_CPU 1000000L



#include <avr/io.h>



#include <util/delay.h> /* Kiedyś <avr/delay.h> */



// #define LCD PORTD #define E 6 #define RS 5 #define RW 4



// #define SET_E LCD |= _BV(E) #define CLR_E LCD &= ~_BV(E) #define CLR_RW LCD &= ~_BV(RW)



// #define SET_RS LCD |= _BV(RS) #define CLR_RS LCD &= ~_BV(RS)



// funkcja opóźniająca o x*1ms ----- Wymieniłem pętle na util/delay.h // procedura zapisu bajtu do wyświetlacza LCD // bez rozróżnienia instrukcja/dana



void write_to_lcd(char x) { char b, c; CLR_RW; SET_E; b = ( x & 0x0F ); c = (( x & 0xF0 ) >> 4); LCD=c; CLR_E; _delay_ms(1); SET_E; LCD=b; CLR_E; _delay_ms(1); // czekaj 1ms }



// procedura zapisu instrukcji do wyświetlacza void write_command(char x) { CLR_RS; // niski stan na RS -> zapis instrukcji write_to_lcd(x); // zapis do LCD }



// procedura zapisu danej do wyświetlacza LCD void write_char(char x) { SET_RS; // wysoki stan na RS -> zapis danej write_to_lcd(x); // zapis do LCD }



// procedura zapisu tekstu do wyświetlacza LCD void write_text(char * s) { while(*s) // do napotkania 0 { write_char(*s); // zapisz znak wskazywany przez s na LCD s++; // zwiększ s (przygotuj nastepny znak) } }


// procedura inicjalizacji wyświetlacza LCD void lcd_init(void) { _delay_ms(15); // czekaj 15ms na ustabilizowanie się napięcia zasilającego CLR_RW; _delay_ms(1); CLR_E; // E = 0 CLR_RS; // RS = 0 char i; // zmianna licznikowa for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji { LCD =0x3F;//&= 0x3F; // SET_E; // E = 1 _delay_ms(5); CLR_E; // E = 0 _delay_ms(5); // czekaj 5ms } LCD = 0x2E; // SET_E; // E = 1



_delay_ms(5); CLR_E; // E = 0 _delay_ms(1); // czekaj 1ms write_command(0x28); // interfejs 4-bity, 2-linie, znak 5x7 write_command(0x08); // wyłącz LCD, kursor i miganie write_command(0x01); // czyść LCD write_command(0x06); // bez przesuwania w prawo write_command(0x0C); // włącz LCD, bez kursora i mrugania }



// program główny int main(void) { DDRD = 0xFF; PORTD = 0x0F; lcd_init(); write_text("01234"); CLR_RW; SET_E; CLR_E; SET_E; CLR_E; while(1); return 0; }


Jakby Ktoś z Was mógłby mi cos podpowiedzieć, byłbym wdzięczny.



Pozdrawiam bo(o)t_manager


Bo(o)t_manager pisze:

[...]
[...]
[...]

Nie ma prawa działać, bo wykonując linię: LCD=c; zapisujesz cały rejestr PORTD, zmieniając przy tym także stany bitów E, RW i RS. Powinno być raczej coś w rodzaju: LCD = (LCD & 0xF0) | c; albo optymalniej od razu wyznaczać cały bajt do wysłania na port. Pamiętaj poza tym o aktywnym zboczu sygnału E (czy nie należy przypadkiem najpierw wystawić danych na linie D4-D7 a potem dopiero "machać" linią E). No i sprawdź w dokumentacji, jaką długość min. musi mieć sygnał E.

Poza tym po co jest to trzykrotne machanie bitami na początku? Zobacz w PDFie kontrolera LCD jak ma wyglądać jego inicjalizacja w tryb 4-bitowy.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required