Posiadam symulator układów elektronicznych, przerysowałem do niego pewien układ z Atmegą16 i wyświetlaczem LCD 2x16 na HD44780. Nie posiadam tego układu w rzeczywistości.
Chciałem napisać procedurę oczekującą na aktywność wyświetlacza LCD (wywoływana bezpośrednio po każdej procedurze wysyłającej rozkaz lub dane na LCD). Zapisanie całego wyświetlacza (32 znaki) z wykorzystaniem trwa pok. 1 sekundę (widać po kolej pojawiające się znaki), a z wykorzystaniem "_delay_us(50)" trwa momentalnie, tak, jak powinno być, a teoretycznie "LcdWait()" powinien trwać krócej niż 50us, bo czeka tylko tyle, ile trzeba, a nie 50us.
Okazało się, że projekt w symulatorze działa dużo wolniej niż jak było sztywne oczekiwanie pewnego okresu czasu (2ms dla rozkazu "0x01" lub 50ns dla pozostałych rozkazów). Nie mam pewności, czy to opóźnienie, to wina symulatora (duża ilość obliczeń), czy błąd w procedurze oczekiwania.
Wyświetlacz jest oparty na HD44780 i podłączony do Atmega16 według następującego porządku
Czy podana poniżej procedura oczekiwania na aktywność wyświetlacza jest poprawna? Nie mam jak sprawdzić na rzeczywistym układzie, bo go nie posiadam.
Chciałem napisać procedurę oczekującą na aktywność wyświetlacza LCD (wywoływana bezpośrednio po każdej procedurze wysyłającej rozkaz lub dane na LCD). Zapisanie całego wyświetlacza (32 znaki) z wykorzystaniem trwa pok. 1 sekundę (widać po kolej pojawiające się znaki), a z wykorzystaniem "_delay_us(50)" trwa momentalnie, tak, jak powinno być, a teoretycznie "LcdWait()" powinien trwać krócej niż 50us, bo czeka tylko tyle, ile trzeba, a nie 50us.
Okazało się, że projekt w symulatorze działa dużo wolniej niż jak było sztywne oczekiwanie pewnego okresu czasu (2ms dla rozkazu "0x01" lub 50ns dla pozostałych rozkazów). Nie mam pewności, czy to opóźnienie, to wina symulatora (duża ilość obliczeń), czy błąd w procedurze oczekiwania.
Wyświetlacz jest oparty na HD44780 i podłączony do Atmega16 według następującego porządku
LCD - Atmega16
RS - PORTC.5
RW - PORTC.4
E - PORTA.3
D4 - PORTC.0
D5 - PORTC.1
D6 - PORTC.2
D7 - PORTC.3Czy podana poniżej procedura oczekiwania na aktywność wyświetlacza jest poprawna? Nie mam jak sprawdzić na rzeczywistym układzie, bo go nie posiadam.
void LcdWait()
{
unsigned char Test = 1; // Zmienna jako liczba z zakresu od 0 do 255, początkowo wartość różna od 0
DDRC = 0xF0; // Linia 0,1,2,3 jako linie wejścia, a linie 4,5,6,7 jako wyjscia
PORTC = 0x10; // Jedynka na RW
while (Test > 0) // Czy liczba Test większa od 0?
// Wartość tej liczby zależy tylko od stanu flagi zajętości
{
PORTA |= 0x08; // Jedynka na linii E
_delay_us(1); // Nie wiem, czy potrzeba, ale chodzi o to, żeby wyświetlacz wystawił odpowiednie dane na piny zanim zostanie dokonany odczyt
Test = PINC; // Odczyt 4 starszych bitów bajtu określający stan wyświetlacza
PORTA &= 0xF7; // Zero na linii E
PORTA |= 0x08; // Jedynka na linii E
_delay_us(1); // Nie wiem, czy potrzeba, ale chodzi o to, żeby wyświetlacz wystawił odpowiednie dane na piny zanim zostanie dokonany odczyt
// Tu nastąpiłby odczyt 4 młodszych bitów bajtu określającego stan wyświetlacza, ale nie następuje, bo te bity nie są potrzebne
PORTA &= 0xF7; // Zero na linii E
Test = Test & 0x08; // Bit flagi zajętości pozostaje niezmieniony, inne bity są zerowane
}
// Tu program wejście dopiero wtedy, gdy wyświetlacz LCD może przyjąć nowy rozkaz
// Poniższe operacje nie są wymagane, ale przywracają stan sprzed wywołania procedury w moim programie
PORTC = 0x00;
DDRC = 0xFF;
}