Bo(o)t_manager
Guest
Mon Feb 04, 2008 10:42 pm
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
Adam Dybkowski
Guest
Mon Feb 04, 2008 11:31 pm
Bo(o)t_manager pisze:
[quote:5751e6ad6f]Mam problem z podłączeniem wyświetlacza lcd do w/w procka.
[...]
D4 PD0
D5 PD1
D6 PD2
D7 PD3
RS PD4
RW PD5
E PD6
[...]
#define LCD PORTD
#define E 6
#define RS 5
#define RW 4
[...]
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
}
[/quote:5751e6ad6f]
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.
--
Adam Dybkowski
http://www.amwaw.edu.pl/~adybkows/
Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.