ZL30ARM (STM32F103) + LabView: obsługa akcelerometru MMA7455
Aplikacja
Choć czujnik posiada małą 14- pniową obudowę LGA 1977-01 o wymiarach 3mm na 5mm to istnieje możliwość ręcznego przylutowania go, np. za pomocą pasty lutowniczej lub łącząc pad ze ścieżką cienkim drutem przy odwróconym układzie pinami do góry.
Rys. 3. Schemat połączenia układu z zestawem ewaluacyjnym ZL30ARM
Płytka ZL30ARM jest połączona z czujnikiem MMA7455 tak jak przedstawiono to na Rys. 3. Dla uproszczenia zasilanie analogowe i cyfrowe można połączyć razem do jednego pinu zasilającego 3,3V – może to być dowolny pin dostępny na wyprowadzonych złączach szpilkowym. Należy zwrócić uwagę, że interfejsu I2C nie można podłączyć bezpośrednio do 4-sytkowego złącza na płytce ZL30ARM o nazwie I2C, ponieważ to złącze jest w standardzie 5V, a dla układu MMA7455 wymagane jest zasilanie 3,3V. Dlatego do tego złącza na płytce ZL30ARM należy podpiąć piny SCL i SDA, przy konfiguracji zworek JP1 i JP2 odłączającej podciągnięcie do +5V. Opcjonalnie linie SCL i SDA można podłączyć odpowiednio do linii PB6 i PB7 na złączach kołkowych (przy zdjętych zworach JP1 i JP2). W związku z powyższym rezystory podciągające muszą być podłączone na płytce z czujnikiem i podpięte do zasilania 3,3V. Dodatkowo należy podpiąć także masę w dowolnym miejscu. Piny INT1/DDRY oraz INT2 nie są wykorzystywane w przedstawionej aplikacji, jednak użytkownik ,który chce rozwijać dalej projekt może je także podpiąć. Szczegółowe zasady działania tych linii można znaleźć w nocie aplikacyjnej czujnika. Dodatkowo producent zaleca użycie kondensatorów filtrujących 10µF i 0,1µF między każde zasilanie a masę, co nie zostało przedstawione.
Program w swoim działaniu wykorzystuje trzy funkcje odpowiedzialne za komunikację z układem MMA7455. Pierwsza funkcja – SingleWrite(u8 RegisterAdress, u8 RegisterData) – służy do konfiguracji czujnika, jako parametry przyjmuje 8-bitowy adres rejestru oraz 8-bitową wartość, która zostanie zapisana do wskazanego rejestru. Na Listingu 1 przedstawiony został kod funkcji SingleWrite, natomiast na Rys. 4 zobrazowana kolejne kroki działania, które są następujące:
- wysłanie bit startu,
- wysłanie adres czujnika – 0x1C (jest to adres wbudowany przez producenta), wraz z bitem R/W (odczyt/zapis) ustawionym w tryb zapisu,
- oczekiwanie na potwierdzenie od czujnika (AK – acknowledgement),
- wysyłanie adresu rejestru, który będzie edytowany – 0x16 (rejestr MCTL),
- oczekiwanie na potwierdzenie od czujnika,
- wysłanie danej jaka zostanie wpisane do rejestru, którego adres został przesłany wcześniej. W naszym przypadku czujnik jest wprowadzany w tryb Measurement Mode z czułością 4g czyli przesyłana jest wartość 0x05,
- oczekiwanie na potwierdzenie,
- przesłanie bitu stopu.
Rys. 4. Zapis bajta danych do jednego rejestru
Listing 1. Funkcja zapisująca wskazany rejestr określonymi danymi
void SingleWrite(u8 RegisterAdress, u8 RegisterData) { //wysłanie bitu startu I2C_GenerateSTART(I2C1, ENABLE); GPIO_SetBits(LED_PORT, LED_PIN); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); //wysłanie adresu urządzenia GPIO_ResetBits(LED_PORT, LED_PIN); I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS7, I2C_Direction_Transmitter); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //wysłanie adresu rejestru I2C_SendData(I2C1, RegisterAdress); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //wysłanie danych do zapisu w rejestrze I2C_SendData(I2C1, RegisterData); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //wysłanie bitu stopu I2C_GenerateSTOP(I2C1, ENABLE); }
Kolejną funkcją jest SingleRead(u8 RegisterAddr, uint8_t I2C1_Bufferx[]), która służy do odczytu ??? Czytanie danych z sensora przedstawia rysunek 4 – jest to tryb odczytu jednego bajta. Kolejno:
- wysłanie bit startu,
- wysłanie adres czujnika – 0x1C,
- oczekiwanie na potwierdzenie od czujnika (AK – acknowledgement),
- wysyłanie adresu rejestru, którego wartość będzie odczytywana,
- oczekiwanie na potwierdzenie od czujnika,
- powtórne wysłanie bitu startu,
- powtórne wysłanie adresu czujnika 0x1C,
- odebranie danych,
- wysłanie znaku stopu (be oczekiwania na znak potwierdzenia).
Rys. 5. Odczyt bajta danych
Listing 2. Funkcja odczytująca bajt danych spod wskazanego adresu
void SingleRead(u8 RegisterAddr, uint8_t I2C1_Bufferx[]) { //wysłanie bitu startu I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); //wysłanie adresy czujnika I2C_AcknowledgeConfig(I2C1, DISABLE); I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS7, I2C_Direction_Transmitter); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //wysłanie adresu rejestru do odczytu I2C_SendData(I2C1, RegisterAddr); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //wysłanie bitu startu I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); //odbiór danych od układu I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS7, I2C_Direction_Receiver); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); //wysłanie bitu stopu I2C_GenerateSTOP(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); //zapis odebranych danych do bufora I2C1_Bufferx[0] = I2C_ReceiveData(I2C1); }