Przykład użycia modułu wyświetlacza do budowy zegarka

Przykład użycia modułu wyświetlacza do budowy zegarka

Zegar i termometr są jednymi z najchętniej wykonywanych aplikacji. Jednak tę aplikację wykonałem kierując się nie tyle potrzebą budowy kolejnego czasomierza, ile chęcią wykonania programu demonstrującego sposób, w jaki należy używać opisywanego na tej stronie (>>>kliknij<<<) modułu wyświetlacza alfanumerycznego sterowanego przez doskonałe, bo eliminujące konieczność używania rezystorów ograniczających prąd segmentów, układy scalone typu PR4010 firmy Prema Semiconductor a dostępne np. w ofercie TME. Wyświetlacz jest sterowany przez płytkę ewaluacyjną ZL5MCS51 z mikrokontrolerem AT89C51RD2 (rdzeń 8051) taktowanym zegarem 11,0592MHz. Płytka jest wyposażona w układ scalony zegara czasu rzeczywistego M41T00, który również jest używany w tej aplikacji.

Moduły zostały opracowane w taki sposób, aby można je było łączyć ze sobą bokami zwiększając liczbę wyświetlanych znaków. Dla potrzeb tego przykładu zdecydowałem się na zastosowanie dwóch modułów, co umożliwia wyświetlenie 8 znaków alfanumerycznych. Sposób ich połączenia pokazano na fotografii 1. Do pierwszego modułu z lewej należy przylutować przewody połączeniowe (fotografia 2) i za ich pomocą doprowadzić sygnały sterujące. W urządzeniu modelowym wszystkie sygnały, zarówno sterujące wyświetlaczem jak i programowego interfejsu TWI, były wyprowadzone z portu P2: BLANK (wygaszanie LED) P2.0, DIN (wyjście danych LED) P2.1, CLK (sygnał zegarowy danych LED) P2.2, LOAD (sygnał zegarowy ładowania danych LED) P2.3, SDA (linia danych TWI), przycisk P2.4, P2.6, SCL (linia zegarowa TWI) P2.7. Wspomniane definicje są umieszczone na początku modułów led-8x5x7.c oraz TWI.c i co oczywiste, można je zmienić.

Fotografia 1. Sposób połączenia płytek modułów wyświetlacza

W programie obsługi zdefiniowałem wzorce cyfr 0…9, dwukropek, apostrof, znak zapytania (dla potrzeb funkcji nastaw), myślnik oraz znak pusty (oznaczony gwiazdką). Wzorce znaków są zawarte w tablicy digits[]. Punkt zaświecony to logiczne 0, punkt zgaszony to logiczna 1. Definicje znaków wykonano jako pogrubione, ponieważ tak moim zdaniem lepiej wyglądają na wyświetlaczu, ale każdy może je sobie przerobić według własnego uznania.

Fotografia 2. Połączone moduły z przylutowanymi przewodami

Mimo iż pojedynczy znak składa się z matrycy 5×7 punktów LED, to jednak każda definicja zawiera 8 bajtów. I tu należy się kilka słów wyjaśnienia. Każdy wzorzec znaku w tablicy digits[] kończy się bajtem 0xFF działającym w „magiczny” sposób, którego pomimo prób nie udało mi się odkryć. Uznałem, że nie warto dla odkrycia roli 16 bajtów zajętych w pamięci Flash poświęcać aż tyle czasu i po prostu pogodziłem się z tymi „czarami”. Jeśli ktoś wykona układ i uda mi się odkryć dlaczego funkcja wyświetlająca zachowuje się w taki dziwny sposób, to proszę o wpis na stronie lub informację na e-mail. Ale do rzeczy. Funkcja wysyłająca dane do wyświetlacza jest wywoływana przez przerwanie Timera 1. Procedurę jego obsługi pokazano na listingu 1. Dla lepszego zrozumienia opisu warto kliknąć na link >>>SCHEMAT<<< i rzucić okiem na schemat. Układ Premy mają 10 wyjść. Na każdej płytce są 3 układy, co umożliwia wykorzystanie 30 bitów. Każdy wyświetlacz składa się z 35 diod LED. Ma 5 doprowadzeń kolumn i 7 doprowadzeń wierszy. Wiersze są ze sobą połączone równolegle, natomiast kolumny są zasilane przez odrębne wyjścia układów. Łatwo policzyć, że do sterowania wszystkim wyświetlaczami jest wymagane 7+4×5=27 sygnałów wejść/wyjść i że 3 bity pozostają wolne. Układ drivera jest szeregowym rejestrem przesuwnym, więc bit przesłany jako pierwszy staje się najstarszym, 10-tym. Jak można zauważyć na schemacie, ostatnie 3 bity układu U3 są niepodłączone, więc pierwsze bity słowa danych nie mają znaczenia.
Dane są doprowadzane do wejścia DIN i wpisywane przy każdym narastającym zboczu na wejściu CLK. Narastające zbocze sygnału na wejściu LOAD powoduje przepisanie stanów z wewnętrznych rejestrów przesuwnych na wyjścia układu. W związku z taką budową wewnętrzną układu, pierwsze przesłane do modułu bity (numer 21...27) odpowiadają za załączenie poszczególnych wierszy. Wyświetlacz musi być multipleksowany. Oznacza to, że w danym momencie może być załączony tylko jeden wiersz, a przełączanie pomiędzy nimi powinno być na tyle szybkie, aby ludzkie oko go nie zauważyło. Zaleca się częstotliwość multipleksowania równą co najmniej 300 Hz (w układzie modelowym ok. 310Hz). Oznacza to konieczność wysłania do rejestrów kompletu danych (4 bajty na moduł) co 1/300 sekundy. Częstotliwość wywoływania przerwania ustalają stałe tauh i taul zdefiniowane na początku programu głównego.

Listing 1. Obsługa przerwania Timera 1
//funkcja wysylajaca dane do wyswietlacza; 60 bitów = dwa moduly
void TMR0_int() interrupt 1
{
  TH0 = tauh;
  TL0 = taul;
  line++;
  if (line > 7) line = 0;
  //na poczatku trzy puste bity
  for (i = 0; i < 3;)
  {
    CLK = 1;
    CLK = 0;
    i++;
  }
//jako pierwszy jest wysylany kod zalaczenia
  zzz = pos[line];
  for (i = 0; i < 7;)
  {
    zzz <<= 1;
    DIN = CY;
    CLK = 1;
    CLK = 0;
    i++;
  }
  for (j = 0; j < 4;)
  {
//cztery znaki z bufora (beda wyswietlane na koncu)

    offset = (display[7 - j] * 8) + line;
    zzz = digits[offset];
    for (i = 0; i < 5;)

    {
      zzz <<= 1;
      DIN = CY;
      CLK = 1;
      CLK = 0;
      i++;
    }
    j++;
  }
//-------------- drugi wyswietlacz ---------
//na poczatku trzy puste bity
  for (i = 0; i < 3;)
  {
    CLK = 1;
    CLK = 0;
    i++;
  }
//kod zalaczenia dla drugiego wyswietlacza
  zzz = pos[line];
  for (i = 0; i < 7;)
  {
    zzz <<= 1;
    DIN = CY;
    CLK = 1;
    CLK = 0;
    i++;
  }
  for (j = 0; j < 4;)
  {
//cztery znaki z bufora
    offset = (display[3 - j] * 8) + line;
    zzz = digits[offset];
    for (i = 0; i < 5;)
    {
      zzz <<= 1;
      DIN = CY;
      CLK = 1;
      CLK = 0;
      i++;
    }
    j++;
  }
  LOAD = 1;
  LOAD = 0;
}

Funkcja obsługi zegara TWI_odczyt(adrMT40,8,0); pobiera z jego rejestrów znaki w kodzie BCD. Są one odpowiednio umieszczane w buforze display[] przez program główny (listing 2). Konwersja BCD na wyświetlana cyfrę odbywa się przez proste wyliczenie zmiennej offset=display[7-j]*8+line; (lub – zależnie od wyświetlacza – display[3-j]*8+line) pełniącej rolę indeksu tablicy digits[] i pobranie bajtu z tej tablicy. W związku z tym, że każda definicja znaku zawiera 8 bajtów, to pobrana z tablicy liczba jest mnożona przez 8. I właśnie w tym momencie odbywały się „czary”. Ponieważ jeśli definicja znaku miała 7 bajtów i wyliczony indeks był uzyskiwany dzięki mnożeniu przez 7, to na wyświetlaczu pojawiały się jakieś prześwity powodujące zmniejszenie kontrastu.

Listing 2. Pętla główna programu zegara
//program glowny
void main()
{
  ctrlport = 0x10;
//inicjowanie TWI
  TWI_ini();
//wstawienie dwukropka (13) i apostrofu (14)
  display[2] = 13;
  display[5] = 14;
//ustawienie timerow i przerwan
  TMOD = 0x11;
  TH0 = tauh;
  TL0 = taul;
  TR0 = ET0 = 1;
  EA = 1;
  se0 = se1 = 0;

while (1)
{
  TWI_odczyt(adrMT40,8,0);
//godziny
  display[0] = (TWIbufor[2] >> 4) & 0x03;
  display[1] = TWIbufor[2] & 0x0F;
//minuty
  display[3] = (TWIbufor[1] >> 4) & 0x07;
  display[4] = TWIbufor[1] & 0x0F;
//sekundy
  display[6] = (TWIbufor[0] >> 4) & 0x07;
  display[7] = TWIbufor[0] & 0x0F;
//reakcja na klawisz
  if (SW3 == 0)
  {
    if (se1 != (TWIbufor[0] & 0x0F))
    {
      se0++;
      se1 = (TWIbufor[0] & 0x0F);
    }
    if (se0 == 3) nastawy();
    }
  }
}

Interfejs użytkownika

Zegar jest obsługiwany za pomocą pojedynczego przycisku dołączonego do P2.4. Jego dłuższe przytrzymanie (przez ponad 3 sekundy) wywołuje procedurę nastaw. Układ zegara RTC nadal działa, więc jeśli nie chcemy zmienić ustawień zegara, to należy po prostu przez chwilę poczekać. Po wejściu do nastaw, wyświetlacz sekund jest czyszczony, a na ostatniej pozycji pojawia się cyfra „1”. Oznacza ona, że użytkownik ma możliwość zmiany ustawień dziesiątek wskazań godziny. Kolejne naciśnięcia przycisku powodują zmianę pomiędzy 0 a 2. Po ustawieniu żądanej wartości należy poczekać 3 sekundy. Wówczas na wyświetlaczu pojawi się cyfra „2” i będzie można wykonać nastawy jednostek wskazań godziny. Zależnie od pierwszej cyfry, można kolejne naciśnięcia przycisku powodują zmiany w zakresie 0…3 (pierwsza cyfra 2) lub 0…0 (pierwsza cyfra 0 lub 1). Po zakończeniu nastaw jednostek godzin należy poczekać 3 sekundy na wyświetlenie „3”. Następnie, analogicznie jak godziny, lecz z innymi zakresami cyfr, ustawia się dziesiątki i jednostki minut. Po zakończeniu ustawiania jednostek minut zostanie wyświetlony znak „?” i zegar będzie czekał na naciśnięcie klawisza powodującego start zliczania czasu. Wówczas ustawiona godzina jest wpisywana do rejestrów zegara, licznik sekund zostaje wyzerowany i czas jest zliczany od ustawionej godziny. Uwaga: nie ma możliwości cofnięcia się i powtórnego wykonania nastaw w inny sposób, niż przez uruchomienie zliczania czasu i ponowne wejście do procedury nastaw. Zegar czeka na przyciśnięcie klawisza uruchamiającego zliczanie czasu przez 30 sekund. Jeśli nie zostanie on naciśnięty, to program wraca do wskazań czasu bieżącego zliczanego przez układ zegarka RTC.
Program skompilowano za pomocą wersji demonstracyjnej kompilatora Ride7 firmy Raisonance. Po skompilowaniu zajmuje on nieco ponad 1,2kB w pamięci Flash. Moduł TWI jest autorstwa Jarka Dolińskiego.

Jacek Bogusz
j.bogusz@easy-soft.net.pl

 

http://www.tomaszbogusz.blox.pl/

ZałącznikWielkość
źródło programu sterującego38.24 KB

Dodaj nowy komentarz

Zawartość pola nie będzie udostępniana publicznie.