STM32Butterfly2 i akcelerometr LIS35D
Funkcja inicjalizująca akcelerometr w pierwszej kolejności definiuje dwuelementową tablicę. Pierwszy element tablicy służy do ustawienia adresu, do którego zostanie zapisany drugi element tablicy. Zaś drugi element, poprzez ustawienie odpowiednich bitów, włącza wszystkie detektory wszystkich trzech osi oraz włącza wykonywanie pomiarów. Tak stworzona tablica jest wysyłana przy użyciu funkcji i2cm_transfer_7bit. Funkcja ta wymaga podania pięciu parametrów. Pierwszy z nich określa adres układu, z którym odbywać się będzie transmisja, drugi parametr wskazuje bufor danych do wysłania, trzeci jest liczbą ilości danych do wysłania, czwarty parametr wskazuje bufor dla odbieranych danych, a ostatni parametr określa ilość danych do odebrania. W przypadku braku danych do wysłania lub odebrania w miejsce tych parametrów wpisuje się NULL (dla bufora) i 0 (dla ilości danych).
W ramach działania funkcja wysyłająca i odbierająca dane zwraca rezultat działania. Zwrócona wartość równa 0 informuje o udanym przeprowadzeniu działania, zaś wartość poniżej zera oznacza wystąpienie błędu. W przypadku wystąpienia błędu na wyświetlaczu pojawi się odpowiedni komunikat wraz z kodem błędu, a program zostanie wprowadzony do nieskończonej pętli blokując dalsze działanie. Jeśli inicjalizacja została przeprowadzona bez błędu na wyświetlaczu pojawia się komunikat powitalny a program przechodzi do nieskończonej pętli.
W ramach nieskończonej pętli aktualizuje wartości wychylenia akcelerometru w każdej z trzech osi oraz przedstawia je na wyświetlaczu. Wartości są zapisywane do zmiennych utworzonych w ramach deklaracji nieskończonej pętli. Sam proces aktualizacji wychylenia realizowany jest przez funkcję lis35_get(&x,&y,&z), której listing przedstawiono poniżej.
static int lis35_get(pos_t *x, pos_t *y, pos_t *z) { static const uint8_t outx_reg = LIS35_REG_OUTX | LIS35_AUTOINC; signed char r_regs[5]; int res = i2cm_transfer_7bit( LIS35_I2CADDR, &outx_reg , sizeof(outx_reg), r_regs, sizeof(r_regs) ); if(!res) { *x = r_regs[0]; *y = r_regs[2]; *z = r_regs[4]; } return res; }
W pierwszym kroku definiowany jest zmienna przechowująca adres rejestru, od którego będzie odbywał się odczyt. Dodatkowo ustawiany jest bit wymuszający automatyczną inkrementację po każdym odczycie rejestru. Drugą zdefiniowaną zmienną jest pięcioelementowa tablica służąca jako bufor odczytywanych danych. Tablica jest pięciowymiarowa ze względu na dodatkowe rejestry pomiędzy tymi, które przechowują informacje o wychyleniu. Odczyt wartości odbywa się przy użyciu wcześniej opisanej funkcji do transmisji z wykorzystaniem magistrali I2C – i2cm_transfer_7bit. Jeśli transmisja odbyła się bezbłędnie otrzymane dane są przetwarzane poprzez zapis uzyskanych wartości do zmiennych prezentujących wychylenie osi w odpowiednim kierunku.
Natomiast sama prezentacja wychylenia prezentowana jest przez funkcję print_value(x,y,z). Jej listing przedstawiono poniżej.
static void print_value(pos_t x,pos_t y, pos_t z) { char buf[24]; tiny_snprintf( buf,sizeof(buf),"X=%d ",x); nlcd_put_string(buf,0,1); tiny_snprintf( buf,sizeof(buf),"Y=%d ",y); nlcd_put_string(buf,0,2); tiny_snprintf( buf,sizeof(buf),"Z=%d ",z); nlcd_put_string(buf,0,3); }
Jak można zauważyć w pierwszym kroku tworzony jest bufor danych, a następnie wywoływana jest funkcja tiny_snprintf, która odpowiada za odpowiednie sformatowanie wartości liczbowej do postaci ciągu znaków. Tak uzyskany ciąg znaków wyświetlany jest na wyświetlaczu przy użyciu funkcji nlcd_put_string. Operacja ta jest wykonywana trzykrotnie, dla każdej z osi oddzielnie.
Należy zauważyć, iż w programie głównym nie ma kodu odpowiedzialnego za konfigurację między innymi układu RCC. Proces ten jest realizowany w ramach przerwania reset_handler, wywoływanego w momencie uruchomienia mikrokontrolera. W ramach działania powyższego przerwania realizowane jest między innymi kopiowanie danych z pamięci Flash do SRAM, wyzerowanie segmentu bss, konfiguracja wspomnianego układu RCC oraz wywołanie programu głównego main().