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

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.