Skocz do zawartości

[C] Wyświetlacz LCD alfanumeryczny


mopsiok

Pomocna odpowiedź

Witam wszystkich.

Temat zapewne wielokrotnie wałkowany i strasznie oklepany, jednak niestety jestem kolejną osobą mającą problem z obsługą wyświetlacza 16x2. Niedawno przerzuciłem się z Bascoma na C, bo ten pierwszy mnie strasznie ograniczał, no i już na początku napotykam problemy. Po przerobieniu kilku pierwszych tematów z książki pana Borkowskiego ("AVR i ARM7, programowanie mikrokontrolerów dla każdego") postanowiłem przeskoczyć do działu o obsłudze tegoż właśnie wyświetlacza. Zastosowałem nieco inne podłączenie niż zalecane w książce, jednak dokonałem zmian w przedstawionym w niej programie. Po odpaleniu niestety nic się nie dzieje (dodam, że z obsłużeniem go w Bascomie nie było żadnych problemów).

Wyświetlacz jest podłączony następująco:

- linia RS - PortD.1

- linia E - PortD.2

- linie danych DB4..7 - PortD.4 .. PortD.7

A oto kod mojego programu (choć nie wiem czy można go nazwać moim, skoro został praktycznie przepisany z książki - oczywiście po dokładnej analizie 🙂 ):

#include <avr/io.h>
#define F_CPU 7372800
#include <util/delay.h>

#define DDR_LCD DDRD
#define PORT_LCD PORTD
#define RS_LCD 1
#define E_LCD 2
#define DB4_LCD 4
#define DB5_LCD 5
#define DB6_LCD 6
#define DB7_LCD 7

void wyslij(int8_t);
void wlacz(void);
void czysc(void);
void wyswietl(char*, int8_t);

/*
PD1: RS
PD2: E
PD4-7: DATA 4-7
*/


int main(void)
{
char napis[15] = "Witaj, kotlecie";
wlacz();
wyswietl(napis, 15);
for(;;);

return 0;
}


//=====================================================================

void wyslij(int8_t bajt)
{
PORT_LCD |= _BV(EN_LCD); //ustaw bit EN
PORT_LCD = (bajt & 0xF0) | (PORT_LCD & 0x0F); //pozostaw 4 najmlodsze bity PORT_LCD, a do najstarszych przypisz 4 najstarsze bity bajtu
PORT_LCD &= ~(_BV(EN_LCD)); //wyzeruj EN (przeslij pierwsza czesc bajtu)
asm volatile("nop"); //odczekaj jeden cykl

PORT_LCD |= _BV(EN_LCD); //ustaw bit EN
PORT_LCD = ((bajt & 0x0F) << 4) | (PORT_LCD & 0x0F); //pozostaw 4 najmlodsze bity PORT_LCD, a do najstarszych przypisz 4 najmlodsze bity bajtu
PORT_LCD &= ~(_BC(EN_LCD)); //wyzeruj EN (przeslij druga czesc bajtu)

_delay_us(40); //dychnij sobie chwilke.
}

void wlacz()
{
DDR_LCD = (0xF0) | (1<<RS_LCD) | (1<<EN_LCD); //ustaw kierunek wyjsciowy na linii danych, pinie RS i EN
PORT_LCD = 0;
_delay_ms(45);

//1 - wyslij sekwencje 0011
PORT_LCD |= (1<<EN_LCD);
PORT_LCD |= (1<<DB4_LCD) | (1<<DB5_LCD);
PORT_LCD &= ~(_BV(EN_LCD));
_delay_ms(4.1);

//2 - to samo, tylko ze krotsza przerwa
PORT_LCD |= (1<<EN_LCD);
asm volatile("nop");
PORT_LCD &= ~(_BV(EN_LCD));
_delay_us(100);

//3 - to samo
PORT_LCD |= (1<<EN_LCD);
asm volatile("nop");
PORT_LCD &= ~(_BV(EN_LCD));
_delay_us(100);

//4 - ustaw interfejs 4-bitowy
PORT_LCD |= (1<<EN_LCD);
PORT_LCD &= ~(_BV(DB4_LCD));
PORT_LCD &= ~(_BV(EN_LCD));

/*ustaw parametry wyswietlacza
bit 4 = 0 (slowo danych ma 4 bity)
bit 3 = 1 (2 wiersze znakow)
bit 2 = 0 (matryca 5x8 pikseli)*/
PORT_LCD &= ~(_BV(RS_LCD));
wyslij(0b00101000);
PORT_LCD |= _BV(RS_LCD);

/*ustaw tryb pracy wyswietlacza
bit 2 = 1 (inkrementowanie adresu zapisu danych)
bit 1 = 1 (wylaczenie przesuwania w prawo)*/
PORT_LCD &= ~(_BV(RS_LCD));
wyslij(0b00000110);
PORT_LCD |= _BV(RS_LCD);

/*wlacz wyswietlacz
bit 2 = 1 (wlaczenie wyswietlania)
bit 1 = 1 (kursor aktywny)
bit 0 = 0 (kursor nie miga)*/
PORT_LCD &= ~(_BV(RS_LCD));
wyslij(0b00001110);
PORT_LCD |= _BV(RS_LCD);

czysc();
}

void czysc()
{
PORT_LCD &= ~(_BV(RS_LCD));
wyslij(1);
PORT_LCD |= _BV(RS_LCD);
_delay_ms(1.64);
}

void wyswietl(char *napis, int8_t ile)
{
int8_t k = 0;
while(k<ile)
{
	wyslij(napis[k]);
	k++;
}
}

Czy ktoś wie gdzie jest błąd? Przeanalizowałem kod wielokrotnie i niestety nie potrafię go znaleźć 🙁. Wszystko wydaje mi się być takie, jak powinno (po zapoznaniu się ze sposobem komunikacji z wyświetlaczem).

Proszę o wyrozumiałość, bowiem mimo że w Bascomie robiłem już całkiem wiele, to w C jestem zupełnie nowy (jakoś nigdy nie trawiłem tego języka, stąd właśnie wybór padł na Bascoma - przepraszam i proszę o wybaczenie 🤣 ).

Z góry dzięki i pozdrawiam

mopsiok

Link do komentarza
Share on other sites

Ojej, ale walnąłem błąd! Aż wstyd się przyznać, ale... Wszędzie używałem EN_LCD, a w include mam E_LCD 😅. Nie mam pojęcia dlaczego wcześniej nie wywaliło mi przy tym żadnego błędu i kompilowało się tak jak powinno, ale teraz już to poprawiłem i kod działa jak natura chciała 🙂. Dzięki Dondu za linka, skorzystałem z biblioteki, która również działa, leci pomógł za chęci.

//Edit

Widzę że Kling mnie wyprzedził, przepraszam, nie zauważyłem tego. Dałbym pomógł, ale już nie mogę o_O.

Zatem temat do zamknięcia i dziękuję Wam za pomoc.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Dziwne, że kompilator nie wyrzucił warninga.

wyrzucił, tylko autor je (bo jest ich więcej) kompletnie zignorował:

rm -rf PROBY.o PROBY.elf dep/* PROBY.hex PROBY.eep PROBY.lss PROBY.map

Build succeeded with 0 Warnings...

avr-gcc -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT PROBY.o -MF dep/PROBY.o.d -c ../PROBY.c

../PROBY.c: In function 'wyslij':

../PROBY.c:41: error: 'EN_LCD' undeclared (first use in this function)

../PROBY.c:41: error: (Each undeclared identifier is reported only once

../PROBY.c:41: error: for each function it appears in.)

../PROBY.c:48: warning: implicit declaration of function '_BC'

../PROBY.c: In function 'wlacz':

../PROBY.c:55: error: 'EN_LCD' undeclared (first use in this function)

make: *** [PROBY.o] Error 1

Build failed with 4 errors and 1 warnings...

EDIT:

Tym razem Ty mnie wyprzedziłeś gdy pisałem powyższe 🙂

Link do komentarza
Share on other sites

To może teraz będzie miał nauczkę na przyszłość, że jednak czytanie komunikatów kompilatora jest celowe, a ignorowanie ostrzeżeń może mieć miejsce tylko wtedy, gdy jesteśmy pewni swojego rozwiązania.

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.