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ć.
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.
- 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.
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.
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.
- 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.
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.
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).