LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

Digilent Pmod i STM32 (cz. 9) – PmodNAV, PmodPMON1 i PmodTMP2

W dziewiątym i jednocześnie przedostatnim odcinku cyklu poświęconego modułom Pmod firmy Digilent przedstawione zostaną: PmodNAV z akcelerometrem, magnetometrem, żyroskopem i barometrem, PmodPMON1 służący do monitorowania mocy, a także PmodTMP2 z czujnikiem temperatury. Przykłady przedstawione w niniejszym artykule przygotowano dla środowiska Atollic TrueSTUDIO i zestawu uruchomieniowego KAmeleon (www.kameleonboard.org) z wykorzystaniem biblioteki STM32Cube_FW_L4.

PmodNAV

Moduł PmodNAV umożliwia wykonywanie pomiarów ruchu w dziewięciu osiach (3-osiowy akcelerometr, 3-osiowy żyroskop oraz 3-osiowy magnetometr), a także ciśnienia atmosferycznego. Jego sercem są dwa układy firmy ST: LSM9DS1 i LPS25HB. Zakresy pomiarowe poszczególnych wielkości są konfigurowalne i wynoszą:

  • akcelerometr: ±2/±4/±8/±16 g,
  • żyroskop: ±245/±500/±2000 dps,
  • magnetometr: ±4/±8/±12/±16 gauss,
  • barometr: 260-1260 hPa.
Pozostałe artykuły z cyklu dostępne są w zasobach portalu Mikrokontroler.pl

Rozdzielczość pomiaru ciśnienia wynosi 4096 LSB/hPa, natomiast dla pozostałych wielkości jest zależna od wybranego zakresu, a jej maksymalna wartość (dla najmniejszego zakresu) wynosi odpowiednio: 0,061 mg/LSB, 8,75 mdps/LSB i 0,14 mgauss/LSB.

Fotografia 1. Moduł PmodNAV

Możliwości czujników wbudowanych w moduł PmodNAV

Układ LSM9DS1 umożliwia generację przerwań po przekroczeniu ustawionych progów mierzonych wielkości na każdej z osi, po wykryciu aktywności, a także wówczas, gdy dostępne są nowe dane pomiarowe. Dodatkowo akcelerometr i żyroskop można skonfigurować w trybie FIFO, w którym dane pomiarowe obu czujników są buforowane w wewnętrznej kolejce. Do jej obsługi można użyć przerwań informujących o przekroczeniu zadanej liczby elementów. Czujnik ciśnienia LPS25HB charakteryzuje się podobną funkcjonalnością, pozwalającą na konfigurację progów do generacji przerwań. Posiada on także wewnętrzną kolejkę FIFO do buforowania danych pomiarowych.

Połączenie z zestawem KAmeleon

Oba układy mogą być obsługiwane za pośrednictwem interfejsów SPI oraz I2C, jednak w module PmodNAV udostępniony jest tylko pierwszy z nich. Znajduje się on na złączu Pmod typu 2A (J1), w którym oprócz linii danych oraz zegara znajdują są także trzy sygnały wybierające urządzenie (akcelerometr/żyroskop, magnetometr, barometr), wspólna linia przerwań i sygnał gotowości danych z magnetometru. Dwa ostatnie sygnały nie są używane w przykładzie, jednak ze względu na rozmieszczenie pozostałych sygnałów na złączu nie jest możliwe podłączenie modułu PmodNAV do złącza Pmod-SPI na płytce KAmeleon. Z tego względu moduł został podłączony do złącza ARDUINO według tabeli 1 i fotografii 2.

Tabela 1. Sygnały PmodNAV oraz odpowiadające im piny złącza ARDUINO i mikrokontrolera; w tabeli pominięto sygnały nieużywane w przykładzie (INT i DRDY) i linie zasilania występujące na złączu Pmod

Sygnał Numer pinu PmodNAV Numer pinu KAmeleon ARDUINO CONNECTOR Pin mikrokontrolera
CS_A/G 1 D10 PB12
MOSI 2 D11 PB15
MISO 3 D12 PB14
SCLK 4 D13 PB10
CS_M 9 D9 PB13
CS_ALT 10 D8 PD11

 

Fotografia 2. Moduł PmodNAV przyłączony do zestawu KAmeleon

Kod przykładu

Przykładowy kod do obsługi modułu PmodNAV został umieszczony w plikach PmodNAV.c i PmodNAV.h. Pierwsza z funkcji – PmodNAV_Config, znajdująca się na listingu 1, jest odpowiedzialna za konfigurację interfejsu SPI w trybie 3 (CPOL=1, CPHA=1) z programową kontrolą sygnału CS. Dodatkowo, uruchamia ciągłe pomiary we wszystkich czujnikach:

  • akcelerometr: 10 Hz,
  • żyroskop: 14,9 Hz,
  • magnetometr: 10 Hz (wartość domyślna),
  • barometr: 12,5 Hz.

Linie GPIO są ustawiane w funkcji HAL_SPI_MspInit wywoływanej przez bibliotekę STM32Cube wewnątrz funkcji HAL_SPI_Init. Piny podłączone do linii danych (MISO oraz MOSI) i zegara (SCLK) są konfigurowane jako funkcja alternatywna dla SPI2, natomiast wszystkie linie CS są ustawiane jako zwykłe wyjścia i będą kontrolowane programowo. Funkcję tę przedstawiono na listingu 2.

Kod programu z plikami projektowymi środowiska Atollic można pobrać w sekcji „Do pobrania”

Listing 1. Konfiguracja interfejsu SPI2 i konfiguracja modułu PmodNAV

void PmodNAV_Config(void)
{
  // Configure the SPI connected to the Pmod module.
  pmodNavSpi.Instance = SPI2;
  pmodNavSpi.Init.Mode = SPI_MODE_MASTER;
  pmodNavSpi.Init.Direction = SPI_DIRECTION_2LINES;
  pmodNavSpi.Init.DataSize = SPI_DATASIZE_8BIT;
  pmodNavSpi.Init.CLKPolarity = SPI_POLARITY_HIGH;
  pmodNavSpi.Init.CLKPhase = SPI_PHASE_2EDGE;
  pmodNavSpi.Init.NSS = SPI_NSS_SOFT;
  pmodNavSpi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
  pmodNavSpi.Init.FirstBit = SPI_FIRSTBIT_MSB;
  pmodNavSpi.Init.TIMode = SPI_TIMODE_DISABLE;
  pmodNavSpi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  pmodNavSpi.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;

  HAL_SPI_Init(&pmodNavSpi);

  writeRegisterM(0x22, 0x00); // Enable the continuous conversion mode for the magnetometer.
  writeRegisterAG(0x10, 0x20); // Enable the gyroscope measurements with the  14.9Hz data rate.
  writeRegisterAG(0x20, 0x20); // Enable the accelerometer measurements with the  10Hz data rate.
  writeRegisterALT(0x20, 0xB0); // Enable the pressure measurements with 12.5 Hz data rate.
}

Listing 2. Konfiguracja linii GPIO dla modułu PmodNAV

void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
  // Initialize GPIO used by the SPI2 peripheral. All CS signals are controlled by the software.
  __HAL_RCC_SPI2_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  GPIO_InitTypeDef GPIO_InitStruct;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
  GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;

  // CS_A/G - PB12
  GPIO_InitStruct.Pin = GPIO_PIN_12;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);

  // CS_M - PB13
  GPIO_InitStruct.Pin = GPIO_PIN_13;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);

  // CS_ALT - PD11
  GPIO_InitStruct.Pin = GPIO_PIN_11;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11, GPIO_PIN_SET);
}

Komunikacja z czujnikami

Do komunikacji z czujnikami modułu PmodNAV przygotowano dwie funkcje pomocnicze: writeRegister i readRegister, pokazane na listingu 3. Realizują one zapis i odczyt rejestru o podanym adresie. Wszystkie czujniki wymagają podania kierunku transmisji na najstarszym bicie adresu (1– odczyt, 0 – zapis), a każda transakcja musi składać się z co najmniej dwóch bajtów. Opisywane funkcje operują na pojedynczych rejestrach, dlatego zawsze wykorzystują dwa bajty – adres oraz wartość rejestru.

Listing 3. Zapis i odczyt rejestru układów LSM9DS1 i LPS25HB

#define SPI_READ_FLAG   0x80
#define SPI_WRITE_FLAG  0x00

static void writeRegister(uint8_t address, uint8_t data)
{
  // The first byte contains the address with the write flag.
  uint8_t txbuf[2] = {address | SPI_WRITE_FLAG, data};
  HAL_SPI_Transmit(&pmodNavSpi, txbuf, 2, 100);
}

static uint8_t readRegister(uint8_t address)
{
  // Reading a byte requires the address at the beginning, so the whole SPI transaction
  // has to be 2 bytes long.
  uint8_t txbuf[2] = {address | SPI_READ_FLAG, 0x00};
  uint8_t rxbuf[2] = {0x00};

  HAL_SPI_TransmitReceive(&pmodNavSpi, txbuf, rxbuf, 2, 100);
  return rxbuf[1];
}

Z powyższych funkcji korzystają inne funkcje, realizujące zapis i odczyt rejestrów. Obsługują one dodatkowo odpowiednie sygnały CS, co przedstawiono na listingu 4. Pozostałe zestawy funkcji obsługujące magnetometr i barometr wyglądają analogicznie.

Listing 4. Zapis i odczyt rejestru akcelerometru i żyroskopu

static void writeRegisterAG(uint8_t address, uint8_t data)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
  writeRegister(address, data);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
}

// Read the Accelerometer/Gyroscope register.
static uint8_t readRegisterAG(uint8_t address)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
  uint8_t data = readRegister(address);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
  return data;
}

Konwersja danych

Pozostałe funkcje zaimplementowane w pliku PmodNAV.c odpowiadają za konwersję odczytanych wartości z czujników na wartości wyrażone w odpowiednich jednostkach:

  • akcelerometr [mg],
  • żyroskop [mdps],
  • magnetometr [mG],
  • barometr [hPa].

Jako przykład, na listingu 5 przedstawiono funkcję konwertującą dane pomiarowe z akcelerometru, w której konwersja jest przeprowadzana dla zakresu ±2 g i rozdzielczości 0.061 mg/LSB. Funkcje obsługujące pozostałe czujniki zaimplementowano w analogiczny sposób.

Listing 5. Konwersja wyników pomiaru z akcelerometru

void PmodNAV_ReadAcc(int32_t* x, int32_t* y, int32_t* z)
{
  // Read the measured values from all three axes.
  *x = (int16_t)((readRegisterAG(0x29) << 8) | readRegisterAG(0x28));
  *y = (int16_t)((readRegisterAG(0x2B) << 8) | readRegisterAG(0x2A));
  *z = (int16_t)((readRegisterAG(0x2D) << 8) | readRegisterAG(0x2C));

  // Configured range is +/- 2g (default value) with 0.061 mg/LSB resolution.
  *x = (*x * 1.0) * 0.061;
  *y = (*y * 1.0) * 0.061;
  *z = (*z * 1.0) * 0.061;
}

Główna funkcja przykładu – main, wykonuje konfigurację modułu PmodNAV, a następnie cyklicznie odczytuje wskazania wszystkich dostępnych czujników. Wyniki są wysyłane na port szeregowy LPUART1, dostępny jako wirtualny port szeregowy po podłączeniu KAmeleona do komputera. Obsługa portu znajduje się w plikach serial.c i serial.h.

Moduły PmodNAV, PmodPMON1 i PmodTMP2 a także zestaw KAmeleon oraz wiele innych płytek ewaluacyjnych i modułów rozszerzających można znaleźć w ofercie Kamami.pl