Skocz do zawartości

[C] obsługa hd44780


PyNone

Pomocna odpowiedź

Mam króciutkie pytanie, na temat obsługi wyświetlacza ze sterownikiem hd44780. W jednym z poradników na ten temat znalazłem fragment kodu do którego mam wątpliwości.

e_1;
_delay_us(1);
flaga=pin_lcd&0x08;
e_0;
e_1;
_delay_us(1);
e_0;

Fragment kodu dotyczy funkcji odczytu flagi zajętości.

Najpierw (1) "mówimy" żeby wyświetlacz przekazał młodszy bajt, (2) czekamy, (3) zapisujemy. A niepokoi mnie 4 i 5 wiersz.

e_0;
e_1;

Kiedy ustawiamy pin "c" na stan niski, a następnie na stan wysoki to wyświetlacz może nie zauważyć tego, ponieważ pomiędzy tymi dwoma komendami nic nie czekamy i czy to nie będzie dla wyświetlacza za szybkie? Jeśli by tego nie zauważył to nie przekazał by starszej części bajtu i... w sumie nie wiem czy coś by się stało, no ale proszę o odpowiedź.

Link do komentarza
Share on other sites

Nie trzeba się domyślać, wszystko jest tutaj:

https://www.sparkfun.com/datasheets/LCD/HD44780.pdf

Podpowiedź: przebiegi czasowe na str. 58 i tabelki z czasami na str. 52. Porównaj to z szybkością procesora na którym wykonujesz ten kod i będziesz miał odpowiedź.

W razie problemów, pytaj o szczegóły.

BTW: Ten kontroler LCD nie ma operacji dwubajtowych. Operacje na magistrali są 8-bitowe i stanowią zamkniętą całość. Po odpowiednim ustawieniu rejestrów możesz pracować w trybie 4-bitowym, ale wtedy jeden cykl przesyła 4 bity a nie bajt.

Link do komentarza
Share on other sites

No może właśnie dlatego, że czas cyklu magistrali tego scalaka (czyli od narastającego zbocza wejścia E do następnego narastającego zbocza E) nie może być krótszy niż 500ns. Przy zegarze 16MHz wykonujesz jedną instrukcję AVR w 62ns. Autor nie umiał wstawiać pojedynczych instrukcji asemblera między operacje I/O żeby cykl zoptymalizować czasowo więc dał od razu z gruba 1us. A skoro działało(?) wystarczająco(?) dobrze(?), to dalej się już nie przejmował. Z resztą najlepiej zapytaj go osobiście. Dlaczego mamy tłumaczyć czyjś kod?

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

Jeszcze a propos pierwszej dopowiedzi: w takim razie dlaczego mówimy "młodsza część bajtu" i "starsza część bajtu"?

I przeprzaszam za niejasność. To nie assembler tylko c.

#define e		(1<<4)
#define set_0		|=
#define set_1		&= ~
#define port_ster	PORTD
#define e_1		port_ster set_1 e
#define e_0		port_ster set_0 e

A tak w ogóle to bajt nie ma ośmiu bitów. Chyba, że nie o to ci chodziło 🙂

Link do komentarza
Share on other sites

Bajt ma prawie zawsze 8 bitów. Teoretycznie może być inaczej, ale kiedyś były i komputery używające systemu dziesiętnego - obecnie standardem są bajty 8 bitowe, innych się po prostu nie używa. Jeśli interesujesz się historią informatyki, to faktycznie warto zwracać uwagę na wielkość bajtu - współczesne komputery używają bajtów 8 bitowych. I nie do końca jest prawdą, że jest to najmniejsza adresowalna jednostka informacji. Operacje bitowe nie są niczym nadzwyczajnym, a dostęp do pamięci często odbywa się w słowach większych niż bajt (np. 16- lub 32- bitowo).

Link do komentarza
Share on other sites

"To nie assembler tylko c"

No własnie, to jest C, więc nie masz - bez użycia specjalnych mechanizmów kompilatora, precyzyjnego strojenia timingu wykonywanych operacji. Jeżeli nawet Twoje operacje I/O tłumaczą się na pojedyncze instrukcje procesora, to jak między nie wstawisz - jeśli akurat potrzebujesz - bardzo krótkie opóźnienie?

Możesz to zrobić tak jak autor kodu:

e_1; 
_delay_us(1); 
flaga=pin_lcd&0x08; 
e_0; 

co generuje zupełnie niepotrzebną tutaj stratę 1us, ale możesz zrobić tak:

e_1; 
asm volatile("nop\n\t"::);
flaga=pin_lcd&0x08; 
e_0; 

i wtedy dostajesz dokładnie 1 cykl rozkazowy opóźnienia. Ponieważ akurat instrukcja NOP wykonuje się jeden cykl, wstawiłeś 1 takt procesora. Znając prędkość swojego procesora możesz powstawiać to w pożądanej liczbie gdzie chesz i tym sposobem zrobić precyzyjnie potrzebny timing.

Nie jest to może piękne, nie jest przenośne i nie spodoba się fanom języków wysokopoziomowych, ale zostało wstawione jako rozszerzenie kompilatora właśnie do takich przypadków.

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.