STM32Butterfly2: obsługa LCD z telefonu Nokia 6100/6610

Ze względu na fakt, iż transmisja z wyświetlaczem nie jest zgodna z żadnym standardem, komunikacja z nim odbywa się programowo. Ramka wysyłana do wyświetlacza składa się z 9 bitów, pierwszy bit określa czy aktualnie wysyłana jest komenda czy wysyłane są dane. W związku z tym w programie zostały zdefiniowane dwie funkcje: wysyłająca dane transfer_spi_data, wysyłająca komendę transfer_spi_command. Jako parametr obie funkcje przyjmują wysyłany komunikat. Poniżej przedstawiono listing obu funkcji.

 

Jak można zauważyć różnica w obu funkcjach sprowadza się do stanu pierwszego bitu, który jest wysyłany (ustawienie wartości linii MOSI). W obu funkcja w pierwszej kolejności następuje ustawienie odpowiednich stanów na liniach SCE oraz SCK, po ustawienie linii MOSI, określającej czy wysyłana jest komenda, czy dane następuje wywołanie funkcji transfer_spi, która wysyła podaną jako parametr wartość.

Po zainicjalizowaniu wyświetlacza, w programie głównym, przeprowadzany jest proces jego czyszczenia. Realizuje to funkcja nlcd_clear_screen(), której działanie sprowadza się do ustawienia aktualnego adresu na pierwszą komórkę i zapisaniu do wszystkich komórek wartości 0.

W następnym kroku realizowane jest rysowanie dwóch linii: poziomej oraz pionowej. Działanie to realizowane jest przez funkcje: draw_hline (linia pozioma), draw_vline (linia pionowa).  Obie funkcje wymagają podania dwóch parametrów: pierwszy określa pozycję linii, drugi parametr definiuje kolor. Działanie obu funkcji sprowadza się do wielokrotnego wywołania funkcji nlcd_set_pixel, rysującej pojedynczy piksel w określonej pozycji (pierwsze dwa parametry funkcji) o określonym kolorze (trzeci parametr). W wyniku inkrementacji zmiennej określającej położenie w pozycji poziomej lub pionowej punktu otrzymujemy rysowanie linii na wyświetlaczu. Poniżej przedstawiono listing funkcji nlcd_set_pixel.

 

W pierwszym kroku działania funkcji mamy ustawianą pozycję X, następnie ustawiana jest pozycja Y. Po określeniu adresu komórki następuje zapisanie jej wartością określającą kolor piksela. Po narysowaniu obu linii program przechodzi do nieskończonej pętli for, w deklaracji tej pętli mamy jednoczesną definicję czterech zmiennych: x, y, px, py. Zmienne xy określają aktualną pozycję linii, natomiast zmienne px i py są poprzednią pozycją linii. Pierwszym działaniem w pętli jest dwukrotny odczyt stanu położenia joysticka, drugi odczyt wykonywany jest z pewnym opóźnieniem w celu eliminacji drgań styków. Uzyskanie stanu linii joysticka realizowane jest przy użyciu funkcji joy_keys. Zwraca ona zmodyfikowaną wartość funkcji io_get_mask, która jako pierwszy parametr przyjmuje nazwę portu, jako drugi parametr przyjmuje maskę ograniczającą odczyt do wskazanych linii. Listing poniżej przedstawia funkcję joy_keys.

 

W przypadku gdy oba odczyty są różne program powraca do pierwszego odczytu stanu joysticka i ponawia cały proces. Natomiast gdy oba odczyty są identyczne następuje przejście do programu, który przesuwa jedną z linii. Operacja przemieszczania linii realizowana jest w ramach instrukcji case, wykorzystanie jej umożliwia określić działanie w zależności od pozycji joysticka. W ramach działania na określoną pozycję joysticka następuje sprawdzenie czy pozycja linii nie wychodzi poza zakres, w przypadku spełnienia tego warunku następuje inkrementacja lub dekrementacja położenia linii.

Na samo zakończenie pętli realizowane jest rysowanie linii na podstawie zmiennych x i y. W przypadku gdy wartość zmiennej x jest różna od px następuje narysowanie linii w położeniu px o kolorze tła. Identyczna sytuacja jest z linią pionową i zmiennymi y i py. Po narysowaniu linii poziomej i pionowej następuje aktualizacja zmiennych px i py.

W programie głównym brak jest operacji inicjalizujących zegary oraz część peryferii, są one realizowane w obsłudze przerwania wywoływanego przez reset. Właśnie w ramach obsługi przerwania reset_handler następuje skopiowanie danych z pamięci Flash do pamięci SRAM, ich inicjalizacja wyzerowanie sekcji .bss, inicjalizacja peryferii oraz  wywołanie programu głównego – main().

Do pobrania

O autorze