LCD w AVT3505 - problem z zadziałaniem.

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
gadula88
-
Posty: 4
Rejestracja: 15 kwie 2006, 22:15

LCD w AVT3505 - problem z zadziałaniem.

Post autor: gadula88 » 15 kwie 2006, 22:38

No wiec tak jak w temacie, złożyłem płytkę testową do kursu AVR-GCC. I wszystko było by OK, gdyby nie to że nie mogę nic wyświetlić na LCD (4x20znaków). Próbowałem również BASCOMa, ale też nie chce zadziałać. Wyświetlacz nie chce się nawet zainicjalizować, po włączeniu zapalają się dwie linie i ciągle się świecą. Próbowałem różnych bibliotek i procedur, ustawiania różnych częstotliwości kwarca, i tylko jedna wersja działa i to tylko jeśli połączę płytki bez tej małej z kluczami 4066 (przewody między płytkami mają ok 5cm):

Kod: Zaznacz cały

#include <avr/io.h>

//
#define LCD  PORTB
#define E  4
#define RS  2
//
#define SET_E   PORTD |= _BV(E)
#define CLR_E   PORTD &= ~_BV(E)
//
#define SET_RS  PORTD |= _BV(RS)
#define CLR_RS  PORTD &= ~_BV(RS)


// funkcja opóźniająca o x*1ms
void waitms(char x)
{
unsigned char a, b; // zmnienne licznikowe
for( ; x > 0; --x) // ta pętla zostanie wykonana x-razy
  for(b = 10; b > 0; --b) // a ta 10 razy
for(a = 100; a > 0; --a) // natomiast ta 100 razy
__asm("nop"); // dodatkowa instrukcja opóźniająca o 1 cykl
// razem to da opóźnienie ok. x * 1ms
// x od 0 do 255
}

// pcodedura zapisu bajtu do wyświetlacza LCD
// bez rozróżnienia instrukcja/dana
void write_to_lcd(char x)
{
SET_E; // ustaw na E stan wysoki
LCD = ((LCD & 0x0F) | (x & 0xF0)); // zapis pierwszej połówki bajtu
CLR_E; // opadające zbocze na E -> zapis do wyświetlacza
SET_E; // ustaw na E stan wysoki
LCD = ((LCD & 0x0F) | ((x & 0x0F) << 4)); // zapis drugiej połowki bajtu
CLR_E; // opadające zbocze na E -> zapis do wyświetlacza
waitms(1); // czekaj 1ms
}

// procedura zapisu instrukcji do wyświetlacza LCD
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)
{
waitms(15); // czekaj 15ms na ustabilizowanie się napięcia zasilającego
CLR_E; // E = 0
CLR_RS; // RS = 0
char i; // zmianna licznikowa
for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji
  {
  SET_E; // E = 1
  LCD &= 0x3F; //
  CLR_E; // E = 0
  waitms(5); // czekaj 5ms
  }
SET_E; // E = 1
LCD &= 0x2E; //
CLR_E; // E = 0
waitms(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)
{
// konfiguracja portów we/wy
DDRB = 0xFF;
DDRD = 0xFC;
PORTB = 0xFF;
PORTD = 0xF7;
// inicjalizacja LCD
lcd_init();
// zapisz na LCD przykładowy tekst
write_text("Ala ma kota :D");
// petla nieskończona
while(1);
return 0;
}
Czy mógłby ktoś napisać procedurę działającą z tą płytką testową? Bo ja już nie mam pomysłów na uruchomienie tego LCD :cry:

PS. LCD dobry, podłączałem go do komputera na 2 metrowej taśmie i ładnie śmigało.

Awatar użytkownika
radzio
Użytkownik
Posty: 573
Rejestracja: 07 gru 2004, 23:06
Lokalizacja: Sosnowiec
Kontakt:

Post autor: radzio » 16 kwie 2006, 9:40

Możliwe że jest to spowodowane błędami na płytce, przeczytaj to : https://elportal.pl/n0017/c_materialy/a ... aw3505.pdf

gadula88
-
Posty: 4
Rejestracja: 15 kwie 2006, 22:15

Post autor: gadula88 » 16 kwie 2006, 10:09

Płytki zamawiałem w AVT, i odrazu razem dostałem tą małą. Przeróbek według tego opisu, dokonywałem już przy składaniu zestawu. Siedzę nad tym problemem już prawie tydzień :/ Niewiedziałem że zabawa z uC będzie taka ciężka :(

Awatar użytkownika
radzio
Użytkownik
Posty: 573
Rejestracja: 07 gru 2004, 23:06
Lokalizacja: Sosnowiec
Kontakt:

Post autor: radzio » 16 kwie 2006, 10:38

NIe posiadam tej płytki, ale zmontowałem na szybko te same połaczenia między uP a LCD i to mi działa :

Kod: Zaznacz cały

int main(void) 
{ 
// konfiguracja portów we/wy 
DDRB = 0xFF; 
DDRD = 0xFF; 

PORTB = 0xFF; 
PORTD = 0xFF; 
// inicjalizacja LCD 
PORTD &= ~(1 << PD3);
lcd_init(); 
// zapisz na LCD przykładowy tekst 
write_text("Ala ma kota :D"); 
// petla nieskończona 
while(1); 
return 0; 
}

Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 16 kwie 2006, 10:56

gadula88 pisze:No wiec tak jak w temacie, złożyłem płytkę testową do kursu AVR-GCC. I wszystko było by OK, gdyby nie to że nie mogę nic wyświetlić na LCD (4x20znaków)...
Jeśli możesz - podeślij mi napisane kody (kompletne programy) na prywatną skrzynkę: radoslaw.koppel_at_elportal.pl
(_at_ = @)
Zobaczę co się da zrobić - posiadam oczywiście odpowiednią płytkę.

Pozdrawiam

gadula88
-
Posty: 4
Rejestracja: 15 kwie 2006, 22:15

Post autor: gadula88 » 17 kwie 2006, 12:28

Złośliwość rzeczy martwych :lol: Problem polegał na zimnym lucie w goldpinach LCD, i nie do końca działającym jednym kluczu w 4066. Ściągnałem gotową bibliotekę ze strony http://jump.to/fleury , i wszystko działa aż miło:
Obrazek

PS. Dziękuję za pomoc i abym nie musiał wam już więcej głowy zawracać głupotami :wink:

Awatar użytkownika
gwozdex
Użytkownik
Posty: 879
Rejestracja: 24 lut 2006, 10:04
Lokalizacja: Czechowice-Dziedzice
Kontakt:

Post autor: gwozdex » 27 paź 2011, 11:57

Witam!
Nie chciałem rozpoczynać nowego tematu więc napisze tutaj.

Mam problem z uruchomieniem wyświetlacza od nokii 3310. Nie wiem co może być przyczyną.
- połączenia pomiędzy wyświetlaczem a płytką są ok.
- wyświetlacz jest nowy
- napięcia na pinach sterujących złącza LV-OUT są ok ( w stanie niskim 0.3V w stanie wysokim 3.26V bo takie napięcie ustawiłem jako zasilające display)
- używam kodów ze strony autora jedynie kompiluje je najnowsza wersją WinAVR, ale nie sądzę, że to ma znaczenie ponieważ kompilacja przebiega bez najmniejszego ostrzeżenia.
- mój zestaw AVT3505 złożyłem z 3 małą płytką na której zamontowany jest bufor ale nie sądzę, że on psuje wszystko bo np. wyświetlacz LCd 16x2 ruszył bez problemu a wykorzystywane są te same piny ( no chyba, że SPI ma za duża prędkość)
- program wgrywam przy użyciu bootloadera AVR109 wprost z WinAVR ale to przecież tez nie jest istotne.

Generalnie objaw jest taki, że brak jakichkolwiek objawów życia :). Kompletnie nic się nie dzieje z wyświetlaczem.

Może są jakieś różne typy tych wyświetlaczy...

Podłączyłem drugi wyświetlacz i nic...

dodam tylko że napięcie na kondensatorze pomiędzy 6 i 7 pinem wyświetlacza wynosi 2.7V.

Awatar użytkownika
dondu
Użytkownik
Posty: 211
Rejestracja: 24 maja 2005, 9:47
Lokalizacja: Śląskie
Kontakt:

Post autor: dondu » 28 paź 2011, 2:53

Pokaż schemat.

Awatar użytkownika
gwozdex
Użytkownik
Posty: 879
Rejestracja: 24 lut 2006, 10:04
Lokalizacja: Czechowice-Dziedzice
Kontakt:

Post autor: gwozdex » 28 paź 2011, 10:17

Schemat załączam poniżej.
Tak jak napisałem korzystam z płytki AVT3505 oraz listingów Kolegi Radosława Koppel.

Najprawdopodobniej posiadam wyświetlacze z innym kontrolerem niż PCD8544.
Pozwolę sobie zacytować część listingu Radka dotyczącą inicjacji oryginalnego wyświetlacza:

Kod: Zaznacz cały

// Inicjacja LCD
void lcd_Init(void)
{
	// Zerowanie. Według dokumentacji wystarczy 100ns. Na wszelki wypadek wprowadzam niewielkie opóźnienie. 
	PORT(LCD_PORT) &= ~(1<<LCD_RES); 
	asm volatile("nop\n\t nop\n\t"::);
	PORT(LCD_PORT) |= 1<<LCD_RES; 
	// Wysyłanie sekwencji startowej
	lcd_Command(LCDC_FS|LCDC_FS_EXTENDED); // 0x21 Komendy rozszerzone
	lcd_Command(LCDC_VOP|72); // 0x48 Kontrast
	lcd_Command(LCDC_TEMP|2); // 0x6 Korekcja temperaturowa
	lcd_Command(LCDC_BIAS|3); // 0x13 Tryb multipleksowania
	lcd_Command(LCDC_FS|LCDC_FS_BASIC|LCDC_FS_HORADDR); //  Komendy standardowe, tryb adresowania
	lcd_Command(LCDC_DC|LCDC_DC_NORMAL); // Włączenie trybu normalnego
	lcd_GoTo(0,0);
Natomiast wyczytałem w tym artykule:
http://ep.com.pl/files/2844.pdf ,
że inicjacja "chińskich" wyświetlaczy musi przebiegać nieco inaczej:

Kod: Zaznacz cały

//inicjalizacja sterownika LCD
void InitDisNok(void)
{
int i;
WriteCmd(0x21);//komendy rosrzerzone
WriteCmd(0x05);//komenda
WriteCmd(0xc8);//Ustawienie Vop
WriteCmd(0x06);//korekcja temperatury dla PCD8544
WriteCmd(0x14);//wspólczynnik multipleksowania
WriteCmd(0x20);//komendy standardowe - adresowanie poziome
WriteCmd(0x01);
WriteCmd(0x0c);// tyb wyświetlania stndard mode
WriteCmd(0x40);//zerowanie licznika wierszy
WriteCmd(0x80);//zerowanie licznika kolumn
ClrDisp();//zerowanie pamięci
//for(i=0;i<612;i++)//612
//WriteData(0x00);//zerowanie pamieci RAM wyswietlacza
}
Spróbuje w ten sposób i zobaczymy jakie efekty to da.
Pozdrawiam.
gwozdex.

PS. Jaki zbieg okoliczności... Również na innym forum użytkownik dondu odpisał mi jako pierwszy :)
Załączniki
schemat.JPG

Awatar użytkownika
dondu
Użytkownik
Posty: 211
Rejestracja: 24 maja 2005, 9:47
Lokalizacja: Śląskie
Kontakt:

Post autor: dondu » 28 paź 2011, 17:40

gwozdex pisze:PS. Jaki zbieg okoliczności... Również na innym forum użytkownik dondu odpisał mi jako pierwszy :)
Tak już mam, że lubię rozwiązywać problemy :)
Ale tam tematu nie dokończyłeś ... no to spróbujmy tutaj.

Ten schemat to za mało. Musisz pokazać pełny schemat i naprawdę warto na jego przygotowanie poświęcić czas, by zyskać czas na szukaniu problemu. Tym bardziej, że używasz innego napięcia zasilania uC, a innego do LCD. No i oczywiście podawać na schemacie oznaczenia i wartości elementów, bo to strasznie istotne.

No chyba, że piekiełko na stopniu 1 chcesz odwiedzać :)

Awatar użytkownika
gwozdex
Użytkownik
Posty: 879
Rejestracja: 24 lut 2006, 10:04
Lokalizacja: Czechowice-Dziedzice
Kontakt:

Post autor: gwozdex » 28 paź 2011, 19:32

Tak już mam, że lubię rozwiązywać problemy :)
Ale tam tematu nie dokończyłeś ... no to spróbujmy tutaj.
I za tą pomoc serdecznie dziękuję...

Problem po części rozwiązany. Tak jak przypuszczałem problem był natury programowej. Mianowicie wyświetlacz którym dysponuje nie jest sterowany przez PCD8544, ale przez jakiś inny sterownik. Po zainicjowaniu wyświetlacza wg "receptury" podanej przeze mnie w poprzednim poście (2 listing) moim oczom ukazała się piękna bitmapa.
Niestety jeszcze coś nie jest tak jak powinno ponieważ przy próbie wypisania tekstu całość jest przesunięta o jeden znak w lewo.

Obiecuje, że jak tylko uporam się z tematem do końca poinformuję o wynikach i zamieszczę konkretne informacje co i jak... (na obu forach :))

Póki co dziękuję i pozdrawiam.
gwozdex.

PS. wartości rezystorów na moim schemacie to 4,7k.

Awatar użytkownika
gwozdex
Użytkownik
Posty: 879
Rejestracja: 24 lut 2006, 10:04
Lokalizacja: Czechowice-Dziedzice
Kontakt:

Post autor: gwozdex » 10 lis 2011, 12:46

Witam po przerwie!

Zatem jak już wspomniałem problem był w nieoryginalnym wyświetlaczu.
Oprócz tego ciekawe jest to, że jeśli wartość kontrastu ustawię na wartość mniejszą niż 0xc0 to na wyświetlaczu nic nie widać. Ostatecznie procedura inicjacji wygląda u mnie następująco:

Kod: Zaznacz cały

void lcd_Init(void)
{
	// Zerowanie. Według dokumentacji wystarczy 100ns. Na wszelki wypadek wprowadzam niewielkie opóźnienie. 
	PORT(LCD_PORT) &= ~(1<<LCD_RES); 
	asm volatile("nop\n\t nop\n\t"::);
	PORT(LCD_PORT) |= 1<<LCD_RES; 
	// Wysyłanie sekwencji startowej
	lcd_Command(LCDC_FS|LCDC_FS_EXTENDED); // Komendy rozszerzone
	lcd_Command(LCDC_VOP|0xc6); // Kontrast
	lcd_Command(LCDC_TEMP|2); // Korekcja temperaturowa
	lcd_Command(LCDC_BIAS|3); // Tryb multipleksowania
	lcd_Command(LCDC_FS|LCDC_FS_BASIC|LCDC_FS_HORADDR); // Komendy standardowe, tryb adresowania
	lcd_Command(LCDC_DC|LCDC_DC_NORMAL); // Włączenie trybu normalnego
	// Czyszczenie wyświetlacza
	lcd_Fill(0);
	lcd_Update();
}
Pozdrawiam i dziękuję za pomoc.

ODPOWIEDZ