STM32 - nieblokująca obsługa panelu dotykowego z układem XPT2046

STM32 - nieblokująca obsługa panelu dotykowego z układem XPT2046
Pobierz PDF Download icon
Popularne, niedrogie wyświetlacze LCD TFT są zwykle wyposażone w rezystancyjny panel dotykowy współpracujący z układem XPT2046 lub podobnym (ADS7843). Artykuł przedstawia prosty sposób obsługi programowej panelu, z nieblokującym odczytem stanu i pozycji.

nacisku wymaga określenia pozycji obu suwaków, do których nie ma bezpośredniego połączenia elektrycznego. Odbywa się to w dwóch fazach: najpierw podajemy napięcie na jeden potencjometr i odczytujemy napięcie z jednego z końców drugiego potencjometru, a następnie podajemy napięcie na drugi potencjometr i odczytujemy wartość napięcia z jednego z końców pierwszego potencjometru. Rolę potencjometrów w panelu rezystancyjnym pełnią dwie warstwy folii; naciśnięcie panelu powoduje zwarcie obu warstw, a punkt naciśnięcia odpowiada pozycji suwaków potencjometrów.

Układ XPT2046

Używany typowo do współpracy z panelami rezystancyjnymi układ XPT2046 umożliwia łatwe przeprowadzenie wymaganych pomiarów pod kontrolą mikrokontrolera poprzez podawanie i pomiar napięć elektrody panelu. Oprócz podstawowego zastosowania, układ XPT2046 może wykonywać dodatkowe pomiary – temperatury, napięcia zasilania oraz siły nacisku (która wpływa na pole powierzchni styku obu warstw folii).

Układ XPT2046 zawiera klucze napięciowe, multipleksery analogowe oraz 12-bitowy przetwornik analogowo cyfrowy. Jest on wyposażony w interfejs SPI. Krawędzie dwóch warstw folii tworzących panel dotykowy dołącza się do przeznaczonych do tego czterech wejść/wyjść układu. Dodatkowo układ XPT2046 ma wyprowadzone wyjście sygnalizacji naciśnięcia panelu -PENIRQ, aktywne poziomem niskim.

Przetwornik analogowo-cyfrowy XPT2046 jest taktowany zegarem interfejsu SPI. Logika układu została zaprojektowana w taki sposób, że użycie linii wyboru układu -CS jest niezbędne tylko wtedy, gdy z jednym interfejsem SPI mikrokontrolera współpracuje większa liczba układów. W przeciwnym przypadku linia -CS może być stale aktywna – układ reaguje na pierwszy niezerowy bit w ramce danych jako na pierwszy bit ramki, nie ma więc potrzeby sygnalizowania początku ramki przy użyciu linii -CS. Budowę ramek danych przesyłanych do i z układu XPT2046 pokazano na rysunku 1.

Ramka polecenia rozpoczyna się od bitu o wartości 1, po którym następują trzy bity sterujące pomiarem. W naszym zastosowaniu użyjemy tylko dwóch z ośmiu możliwych wartości, odpowiadających pomiarowi pozycji nacisku w osi X i Y. Kolejne 4 bity służą do wyboru trybu pracy układu; w prostych zastosowaniach mają one wartość 0.

Podstawowy tryb akwizycji danych opisany w dokumentacji układu polega na transmisji ramek 24-bitowych. Ramka przesyłana do XPT2046 rozpoczyna się od 8 bitów polecenia, po których następuje 16 bitów o wartości 0. Ramka zwrotna rozpoczyna się od 9 zer, po których następuje 12 bitów wartości odczytanej z przetwornika i 3 zera. Proces konwersji rozpoczyna się po przesłaniu piątego bitu i zajmuje 16 cykli zegarowych. Odczyt pozycji wymaga wykonania dwóch konwersji – dla współrzędnych X i Y, co można uzyskać przesyłając kolejno dwie ramki 24-bitowe.

Dokumentacja układu ukazuje również metodę odczytu serii wyników konwersji co 16 cykli zegara SPI. W takim trybie kolejne polecenia konwersji są przesyłane co 16 cykli zegara – polecenie rozpoczyna się jeszcze w czasie trwania poprzedniej konwersji (rysunek 2). Wadą obu rozwiązań pokazanych w dokumentacji układu jest konieczność wyłuskiwania wyników konwersji ze strumienia danych przy użyciu operacji przesunięć bitowych i maskowań. Należy przy tym zauważyć, że ponieważ dane są w interfejsie SPI transmitowane począwszy od najbardziej znaczącego bitu, składanie wyników 12-bitowych z ramek 8-bitowych wymaga w przypadku mikrokontrolerów używających konwencji adresowania little-endian dodatkowo zmiany kolejności bajtów.

Proponowany sposób współpracy z układem XPT2046

12-bitowe wyniki odczytane z XPT2046 jako liczby bez znaku powinny być reprezentowane w języku C przez dane typu int16_t (16-bitowe liczby całkowite ze znakiem), ze względu na to, że w późniejszym ich przetwarzaniu wyniki pośrednie mogą być liczbami ujemnymi. Konwersja dwóch kanałów z nakładaniem poleceń wymaga łącznie transmisji 40 bitów. W proponowanym rozwiązaniu do i z układu transmitujemy ramkę 48-bitową, złożoną z trzech słów 16-bitowych. Użyteczne dane odbierane są zawarte na 12 najmniej znaczących bitach drugiego i trzeciego odbieranego słowa, dzięki czemu są one poprawnie wyrównane i gotowe do użycia w obliczeniach. W celu uzyskania takiego wyrównanie danych polecenia konwersji muszą zaczynać 5 bitów przed odbieranym słowem danych, co można łatwo uzyskać przesuwając polecenia konwersji tak, by zaczynały się one od 12. i 28. bitu ramki 48-bitowej. Formaty ramek pokazano na rysunku 3.

Realizacja transmisji w STM32

Do akwizycji danych z układu XPT2046 można użyć interfejsu SPI współpracującego z modułem DMA. Maksymalna częstotliwość transmisji SPI wynosi 2 MHz. Interfejs jest inicjowany do transmisji danych 16-bitowych, co eliminuje konieczność programowej zmiany kolejności bajtów odbieranych z układu XPT2046.

Odczyt danych może być inicjowany przy końcu procedury obsługi przerwania timera, zgłaszanego z częstotliwością np. 100 Hz. Po wykryciu nacisku, sygnalizowanym przez układ XPT2046 przy użyciu linii -PENIRQ, procedura obsługi przerwania programuje kanał DMA w celu nadania trzech słów 16-bitowych zawierających polecenia konwersji. Inny kanał DMA jest programowany jednokrotnie na ciągły, powtarzany odbiór trzech słów do bufora cyklicznego. Ponieważ transmisja danych w SPI zachodzi równocześnie w obu kierunkach, odbiór będzie następował wyłącznie w czasie nadawania.

Procedurę inicjującą akwizycję w wersji dla mikrokontrolera STM32L476 pokazano na listingu 1. Przy kolejnym przerwaniu timera, o ile wyjście PENIRQ jest nadal aktywne, odczytane dane są interpretowane. Pierwszą fazą interpretacji danych jest porównanie wartości z dwóch kolejnych odczytów. Wartości odczytane uznaje się za wiarygodne tylko wtedy, gdy wartość bezwzględna różnicy pomiędzy poprzednim i bieżącym wynikiem nie przekracza określonego progu (np. 4); w przeciwnym przypadku dane są odrzucane. Procedurę obsługującą odczyty pokazano na listingu 2.

Kalibracja panelu

Ze względu na znaczne rozrzuty parametrów każdy panel rezystancyjny wymaga kalibracji. W wyniku kalibracji zostają wyznaczone współczynniki macierzy, służącej do przeliczenia odczytów przetwornika analogowo-cyfrowego na współrzędne ekranu wyrażone w pikselach. Zastosowanie macierzy uniezależnia przebieg obliczeń od sposobu podłączenia panela – macierz automatycznie uwzględnia ewentualną zamianę współrzędnych X i Y.

Po wyznaczeniu macierzy kalibracji powinna ona zostać zapisana w pamięci nieulotnej (np. w pamięci Flash mikrokontrolera). Podczas inicjowania oprogramowania następuje sprawdzenie ważności macierzy współczynników i, gdy jest ona nieważna, następuje kalibracja panelu.

Kalibracja polega na kolejnym wyświetleniu na ekranie trzech punktów i naciśnięciu przez użytkownika panelu np. cienkim pisakiem w każdym z wyświetlonym punktów. Punkty powinny być rozmieszczone daleko od siebie i blisko krawędzi wyświetlacza, jednak nie w samych jego rogach. Mogą to być np. dwa punkty w pobliżu rogów wyświetlacza leżących przy wspólnej dłuższej krawędzi i trzeci punkt położony w pobliżu środka przeciwległej dłuższej krawędzi. Procedura kalibracji została pokazana na listingu 3.

Po odczytaniu wartości odpowiadających takim trzem punktom i zapisaniu ich w wektorze xxx następuje wyznaczenie macierzy transformacji. W celu uniknięcia obliczeń zmiennopozycyjnych współczynniki macierzy są zapisywane w postaci liczników ułamków i ich wspólnego mianownika (list. 3). Podczas normalnej pracy urządzenia odczyty przetwornika układu XPT2046 są przeliczane na współrzędne ekranu.

Zmienne xs i ys oznaczają współrzędne ekranu, a xp i yp – odczyty wartości przetwornika XPT2046. Fragment kodu realizujący to zadanie, stanowi część procedury akwizycji z list. 2. Istotnymi zaletami zaprezentowanego rozwiązania są brak oczekiwania programowego na odczyt danych oraz minimalizacja narzutu czasu na obliczenia współrzędnych. Dzięki temu przedstawione fragmenty kodu mogą być użyte w oprogramowaniu bazującym wyłącznie na procedurach obsługi zdarzeń (przerwań) i nie zawierającym pętli zdarzeń.

Grzegorz Mazur

Artykuł ukazał się w
Elektronika Praktyczna
wrzesień 2018
DO POBRANIA
Pobierz PDF Download icon
Materiały dodatkowe

Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik wrzesień 2021

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio wrzesień - październik 2021

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka Podzespoły Aplikacje wrzesień 2021

Automatyka Podzespoły Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna wrzesień 2021

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich wrzesień 2021

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów