Renesas Synergy - interfejsy szeregowe (3)

Renesas Synergy - interfejsy szeregowe (3)
Pobierz PDF Download icon
Interfejsy szeregowe są bardzo ważnym elementem budowania systemów mikroprocesorowych. Wiele elementów zewnętrznych takich jak: wyświetlacze, czujniki, moduły komunikacyjne i inne mają wbudowane szeregowe interfejsy komunikacyjne z jednej strony, a mikrokontrolery układy peryferyjne obsługujące transmisję szeregową z drugiej strony. Moduły komunikacyjne mikrokontrolerów są często bardzo rozbudowane. Przychodzące i wysyłane dane mogą być przesyłane kanałami DMA lub są buforowane w FIFO. Bardziej rozbudowane interfejsy na przykład I2C mogą pracować jako master w magistrali z wieloma masterami. Konfigurowanie tego typu peryferii jest prawdziwą udręką programistów. Konieczność zapisania wielu rejestrów konfiguracyjnych i wzajemne czasami skomplikowane zależności pomiędzy bitami konfiguracyjnymi powodują, że łatwo się pomylić i bardzo trudno znaleźć przyczynę pomyłki. Żeby ułatwić i przyspieszyć konfigurację stosuje się dwa wzajemnie się uzupełniające elementy. Pierwszy z nich to najczęściej graficzny konfigurator, a drugi to gotowe biblioteki warstwy HAL.

Programową obsługę termometru rozpoczniemy od procedury otwarcia  i procedury zamknięcia kanału I2C drivera STM75 (listing 13). Funkcja Open został już opisana wyżej. Warto testować w programie wywołującym tę funkcję, czy został zwrócony kod błędu SSP_SUCCES. Jeżeli nie, to kanał nie zostanie otwarty lub zamknięty i użytkownik musi na to zareagować.

Po zainicjowaniu modułu IIC trzeba zainicjować termometr STLM75 przez zapisanie rejestru konfiguracji. Całą procedurę konfiguracji termometru wraz otwarciem kanału I2C pokazano na listingu 14. Zapisanie rejestru konfiguracyjnego polega na wysłaniu dwóch bajtów: adresu rejestru (0x01) i bajtu konfiguracji. Wspominałem już, że do testowania zakończenia transmisji można użyć mechanizmu potwierdzenia callback, jak to zrobiono w wypadku interfejsu SPI. Z opisu funkcji drivera IIC wynika, że callback nie jest niezbędny i jeżeli nie zostanie zdefiniowany (nazwa NULL), to funkcje transferu będą działać jako blokujące. Oznacza to, że funkcja będzie czekać na zakończenie transmisji. W swoim programie postanowiłem użyć callback i testować zakończenie transmisji. Jak w wypadku SPI, moje procedury po wykryciu błędu lub braku potwierdzenia zakończenia transmisji wchodzą w pętle nieskończone. Użytkownik powinien zadbać o obsługę zdarzeń tego typu, aby program nie był trwale blokowany.

Na listingu 15 zamieszczono procedurę callback testującą zdarzenia zakończenia wysyłania danych I2C_EVENT_TX_COMPLETE, zakończenia odbierania danych I2C_EVENT_RX_COMPLETE i niepowodzenia (przerwania) transmisji I2C_EVENT_ABORDED. Do testowania zakończenia transmisji zdefiniowałem dwie zmienne globalne stlm_data_rx, oraz stlm_data_tx. Przed wywołaniem funkcji zapisu, lub odczytu danych przez driver IIC odpowiednia zmienna jest zerowana. Po zakończeniu transferu danych i wystawieniu sekwencji STOP funkcja callback wpisuje do tych zmiennych „1” i program „wie”, że można transferować kolejne dane lub zamknąć kanał komunikacji.

Po prawidłowym otwarciu kanału i skonfigurowaniu termometru można wysyłać sekwencję odczytu rejestrów temperatury. Jak pokazano na rysunku 27, składa się ona z dwóch części. Pierwsza to wysłanie sekwencji START, adresu Slave z bitem R/W=0 oraz bajtu adresu rejestru 0x00 bez bitu STOP W drugiej części trzeba ponownie wysłać sekwencję START, adres slave z bitem R/W=1, oraz odczytać z magistrali 2 bajty rejestru temperatury. Całość kończy się sekwencją STOP. Na listingu 16 pokazano fragment programu wykonujący te czynności.

Mamy już wszystkie elementy składowe do napisania funkcji, która:

- Otwiera kanał transmisyjny I2C.
- Konfiguruje termometr STLM75.
- Odczytuje rejestr temperatury.
- Wykonuje konwersję zgodnie z zasadą pokazaną na rys. 23.
- Wyświetla temperaturę na ekranie wyświetlacza OLED.
- Zamyka kanał I2C.

Listing 17 prezentuje kompletną procedurę odczytującą i wyświetlającą temperaturą otoczenia mierzoną przez STLM75. Każde wywołanie STLMTempRead() otwiera i zamyka kanał I2C drivera STM75. Używając tylko tego drivera można by było raz otworzyć kanał i go nie zamykać, jednak przy planowanej obsłudze innych układów dołączonych do magistrali niezamknięty kanał nie pozwoli na otworzenie kanału kolejnego drivera i zostanie przy próbie otwarcia zostanie zgłoszony kod błędu SSP_ERR_IN_USE.

W czasie testu  procedura STLMTempRead() była wywoływana w niekończonej pętli. Dotkniecie czujnika palcem powodowało zwiększanie odczytywanej temperatury. Wynik działania programu z listingu 18 pokazano na rysunku 28.

Zobaczymy teraz jak wykonać obsługę kolejnego układu – czujnika wilgotności HTS221 dołączonego do tej samej magistrali I2C. Pomiar wilgotność względnej powietrza jest wykorzystywany w stacjach meteorologicznych, urządzeniach AGD (np. lodówkach) czujnikach wentylatorów łazienkowych, sterownikach klimatyzacji, układów automatyki domowej itp. Umieszczony na płytce czujnik HTS221 mierzy wilgotność w zakresie od 20% do 80% rH z dokładnością ±4,5%. Pomiar może być wykonywany z częstotliwością od 1 pomiaru na sekundę do 25 pomiarów na 2 sekundy. Oprócz pomiaru wilgotności czujnik mierzy temperaturę w zakresie -40…+120°C z dokładnością ±0,5°C w zakresie +15…+40°C oraz ±1°C w zakresie 0…+60°C. Schemat blokowy układu pokazano na rysunku 29.

Podobnie jak dla innych czujników, konfiguracja parametrów pracy i odczytywanie mierzonych wartości odbywa się przez zapisywanie i odczytywanie rejestrów wewnętrznych. W tym celu będziemy potrzebowali dwóch funkcji: odczytania zawartości rejestru o podanym adresie i zapisania rejestru o podanym adresie.

Zapisanie rejestru rozpoczyna się od wysłania przez mikrokontroler sekwencji START, a po niej adresu Slave 0x5F. Potwierdzenia adresu przez HTS221 pozwala na wysłanie przez mikrokontroler adresu rejestru, a po nim zapisywanej danej (rysunek 30). Odczytanie rejestru rozpoczyna się od wysłania sekwencji START i adresu Slave z bitem R/W=0 (zapis) i bajt adresu rejestru. Potem jest wysyłana powtórna sekwencja START, adres Slave z bitem R/W=1, a po nim odczytywany jest jeden bajt zawartości zaadresowanego rejestru (rysunek 31). Podobnie jak w przypadku termometru STML75 będziemy potrzebowali dodania i konfiguracji funkcji drivera IIC.

Konfiguracja jest podobna do drivera dla STLM75. Co oczywiste, inny jest adres Slave (0x5f) i inne nazwy kanału oraz funkcji callback. Do komunikacji z układem będziemy potrzebowali funkcji: otwarcia i zamknięcia kanału IIC, konfiguracji układu, funkcji zapisania i odczytywania rejestrów (rysunek 32). Funkcje otwarcia i zamknięcia kanału IIC pokazano na listingu 19. Sterowanie układem, oraz wyniki pomiaru i zawartości rejestrów kalibracyjnych są umieszczone w adresowanych rejestrach. Wykaz tych rejestrów pokazano na rysunku 33. Pomiary wilgotności i temperatury mogą być wykonywane na żądanie, po wysłaniu polecenia (one shot) lub w sposób ciągły z określoną częstotliwością. Do programowania częstotliwości pomiarów jest przeznaczony rejestr CTRL_REG1 o adresie 0x20, pokazany na rysunku 34. Bit PD trego rejestru jest przeznaczony do wprowadzania układu w stan obniżonego poboru mocy, a bit BDU określa czy rejestr z danymi wyjściowymi wilgotności i temperatury ma być odświeżany automatycznie po wykonaniu pomiarów, czy tez po odczytaniu przez mikrokontroler 8 starszych bitów wynikupoprzedniego  pomiaru. Po właczeniu zasilania bit PD jest wyzerowany i żeby można było wykonywac pomiary trzeba do PD wpisać „1”.

Wyzerowanie bitów ODR1 i ODR2 wprowadza układ w tryb pomiaru na żądanie. Żeby wyzwolić taki pomiar trzeba ustawić bit ONE_SHOT w rejestrze CTRL_REG2, jak pokazano na rysunku 35. Po wyzwoleniu pomiaru (również w trybie pomiaru ciągłego) trzeba testować czy wynik pomiaru został zapisany do rejestrów wyjściowych. Żeby to zrobić trzeba odczytać zawartość rejestru statusowego STATUS_REG. Ustawienie bitu H_DA (bit b1 STATUS_REG) oznacza, że wynik pomiaru wilgotności został zapisany do rejestrów wyjściowych HUMIDITY_OUT_L i HUMIDITY_OUT_H, a ustawienie bitu T_DA (bit b0 STATUS_REG) oznacza, że wynik pomiaru temperatury został wpisany do rejestrów pomiaru temperatury. Operacje zapisywania i odczytywania rejestrów są pokazane na listingach 20 i 21.

W czasie testów czujnika skonfigurowałem układ do pracy z wyzwalaniem na żądanie i z ustawionym bitem BDU. Procedura inicjalizacyjną pokazano na listingu 22. W wielu czujnikach wartości odczytywane z wyjściowych rejestrów pomiarów trzeba  przekonwertować z formatu U2, ewentualnie przeskalować lub dodać offset. W czujniku HTS221 jest inaczej. Pierwszą zasadniczą różnicą jest umieszczenie w pamięci układu szeregu dodatkowych rejestrów kalibracyjnych. Każdy układ w procesie produkcyjnym jest kalibrowany, a w jego nieulotnej pamięci Flash są zapisywane dane do kalibracji. W czasie sekwencji włączania zasilania układu dane kalibracyjne są przepisywane z pamięci Flash do rejestrów kalibracyjnych pokazanych na rysunku 36.  W trakcie inicjalizacji układu mikrokontroler musi odczytać dane kalibracyjne, po to by je potem wykorzystać przy każdorazowym odczycie wilgotności i temperatury. Procedurę odczytu rejestrów kalibracyjnych pokazano na listingu 23. W wyniku działania tej funkcji są zapisane zmienne globalne pokazane na listingu 24. Te zmienne w połączeniu z 16-bitowymi danymi wyjściowymi będą służyły do wyliczenia mierzonej wartości. W wypadku temperatury wartości T0_cal, T1_cal, T0_degC i T1degC są współrzędnymi wyznaczającymi prostą kalibracji –pokazano to na rysunku 37.

Aby zmierzyć temperaturę należy:

- Wyzwolić pomiar.
- Poczekać na zakończenie pomiaru (odczytywanie rejestru statusu).
- Odczytać rejestry temperatury.
- Wyliczyć na podstawie odczytanych rejestrów i danych kalibracji mierzona temperaturę.
- Wyświetlić wynik na ekranie wyświetlacza.

Na listingu 25 pokazano procedurę odczytywania rejestrów temperatury. Kompletna procedura inicjowania, odczytywania, konwersji wyświetlania wyniku jest pokazana na listingu 26. Do konwersji zmiennej typu float na znaki ASCII potrzebnej do wyświetlenia wyniku użyłem standardowej funkcji sprintf. W trakcie testów okazało się, że konwersja nie działa poprawnie. Zatrzymanie programu na pułapce programowej za wywołaniem sprintf oraz podejrzenie zawartości bufora str[] i zmiennej float Temperature wykazało, że znaki w buforze str zupełnie nie odpowiadają wartości zmiennej Temperature. Okazało się, że standardowe funkcje potrzebują do działania sterty. Projekt domyślnie ustawia rozmiar sterty na zero, zapewne po to, aby minimalizować użycie pamięci RAM.

Rozmiar sterty jest ustawiany w zakładce BSP konfiguratora projektu (rysunek 38). W okienku jest również umieszczona informacja o tym, ze funkcje standardowe wymagają sterty o minimalnym rozmiarze 4 kB. Po zmianie ustawień funkcja sprintf zaczęła działać poprawnie.

Podobnie działają funkcje odczytywania, przeliczania i wyświetlania wilgotności. Wilgotność jest wyliczana z wyrażenia H_rh = (((H_T - H0_cal))/(H1_cal - H0_cal) * (H1_rh - H0_rh) + H0_rh (rysunek 39). Na listingu 26 i 27 pokazano procedury odczytu rejestru wilgotności oraz kompletną procedurę inicjowania pomiaru, odczytania rejestru wilgotności, konwersji na podstawie danych kalibracyjnych i prezentacji wyniku. W końcowym teście, po zainicjowaniu układów STLM75 i HTS221, funkcje pobierania i wyświetlania danych z obu czujników są umieszczone w pętli (listing 28). Wynik działania tego programu pokazano na rysunku 40.

Podsumowanie

Przedstawione tu informacje mogą być przydatne przy konstruowaniu urządzeń w tym urządzeń IoT wykorzystujących interfejsy szeregowe mikrokontrolerów Renesas Synergy. Zastosowałem konfigurator środowiska e2studio oraz funkcje drivera warstwy HAL firmowej biblioteki SSP. Zakończenie transmisji było testowane przez mechanizm powiadamiania callback, również konfigurowanym z poziomu e2studio.

Konfigurowanie i programowanie interfejsów jest stosunkowo łatwe, ale w trakcie pracy nad programem okazało się, że wsparcie społeczności użytkowników jest znikome w porównaniu z bardziej znanymi rodzinami mikrokontrolerów innych producentów. Brak tego wsparcia oznacza, ze jest bardzo trudno znaleźć chociażby najprostsze przykłady pomagające w zrozumieniu działania nawet mniej skomplikowanych elementów programowania mikrokontrolerów Synergy. Najprawdopodobniej wynika to z tego, ze Synergy jest nowością na rynku i pewnie za jakiś czas to się zmieni. Mam nadzieję, że artykuł będzie pomocą w zrozumieniu idei konfigurowania i użycia najniższej warstwy HAL w programowaniu interfejsów szeregowych mikrokontrolerów Renesas Synergy.

Tomasz Jabłoński, EP

 

(Uwaga! Kompletny artykuł zawierający wszystkie listingi i ilustracje jest dostępny w pliku PDF).

Artykuł ukazał się w
Elektronika Praktyczna
październik 2017
DO POBRANIA
Pobierz PDF Download icon
Materiały dodatkowe

Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik kwiecień 2024

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio marzec - kwiecień 2024

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje marzec 2024

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna kwiecień 2024

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich kwiecień 2024

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów