LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
Artykuły

Digilent Pmod i STM32 (cz. 7) – PmodBT2, PmodTC1 i PmodCLP

W siódmej odsłonie cyklu poświęconego modułom peryferyjnym Pmod firmy Digilent omówimy kolejne trzy moduły. Będą to: PmodBT2 – umożliwiający komunikację Bluetooth w standardzie 2.1, 2.0, 1.2, lub 1.0, PmodTC1 – zawierający termoparę do pomiaru temperatury i PmodCLP z wyświetlaczem znakowym z interfejsem równoległym. Przykłady dla wymienionych modułów zostały przygotowane dla środowiska Atollic TrueSTUDIO, a także zestawu uruchomieniowego KAmeleon (www.kameleonboard.org) z wykorzystaniem biblioteki STM32Cube_FW_L4.

PmodBT2

Moduł PmodBT2 z układem RN42 z oferty firmy Microchip pozwala na komunikację za pośrednictwem interfejsu bezprzewodowego Bluetooth. Układ obsługuje wersje 2.1, 2.0, 1.2 i 1.0 standardu i jest urządzeniem klasy drugiej o mocy wyjściowej 2,5 mW zapewniającym zasięg komunikacji do 10 m. Układy RN42 mają wbudowany stos Bluetooth, zależnie od modelu urządzenia implementujący różne profile. Znajdujący się w module PmodBT2 układ RN42-I/RM implementuje profil SPP (Serial Port Profile) emulujący port szeregowy podczas połączenia dwóch urządzeń.

Pozostałe artykuły z cyklu dostępne są w zasobach portalu Mikrokontroler.pl

Komunikacja z modułem Bluetooth

Komunikacja z modułem odbywa się za pośrednictwem interfejsu UART z dodatkowymi sygnałami RTS i CTS odpowiedzialnymi za kontrolę przepływu danych. Za pośrednictwem tego interfejsu można przesyłać dane, które trafiają bezpośrednio na łącze radiowe i następnie do urządzenia połączonego z układem. Moduł jest domyślnie skonfigurowany do połączenia zgodnie z następującą konfiguracją:

  • Prędkość transmisji 115200,
  • 8 bitów danych,
  • Brak parzystości,
  • 1 bit stopu,
  • Sprzętowa kontrola przepływu (RTS/CTS).

Fotografia 1. Moduł PmodBT2

Tryb komend

RN42 może także zostać wprowadzony w tryb komend, w którym można odczytać, a także zmienić jego konfigurację. Aby wejść do tego trybu należy wysłać sekwencję znaków: „$$$”, na którą układ RN42 powinien odpowiedzieć przez wysłanie ”CMD\r\n”. Każda komenda składa się z jednego lub dwóch znaków, a także opcjonalnych argumentów oddzielonych przecinkiem. Na końcu komendy należy wysłać znak ‘\r’, po którym można spodziewać się odpowiedzi od modułu. W przykładzie została użyta tylko jedna z komend, służąca do odczytu wersji firmware’u: „V\r”, na którą moduł odpowiada, wysyłając odpowiedni napis z wersją oprogramowania: „Ver 6.15 04/26/2013\n\r(c) Roving Networks\r\n”. Wszystkie wspierane komendy można znaleźć w dokumentacji: http://ww1.microchip.com/downloads/en/DeviceDoc/bluetooth_cr_UG-v1.0r.pdf. Aby zakończyć tryb wprowadzania komend należy wysłać „—\r” (trzy minusy i powrót karetki), na co układ powinien odpowiedzieć przesyłając „END\n\r” i przechodząc z powrotem do trybu transmisji danych.

Linie GPIO do sterowania modułem

Oprócz sygnałów odpowiedzialnych za komunikację za pośrednictwem interfejsu UART, PmodBT2 udostępnia także kilka linii GPIO do kontrolowania, a także monitorowania pracy układu RN42. Sygnały te przedstawiono w tabeli 1.

Tabela 1. Sygnały PIO dostępne w module PmodBT2

Sygnał Złącze Opis
~RST J1(8) Reset; aktywny w stanie niskim
PIO2 (STATUS) J1(7) Stan połączenia; stan wysoki oznacza aktywne połączenie
PIO3 JP2 Automatyczne wykrywanie i parowanie; w stanie wysokim oznacza automatyczne poszukiwanie drugiego urządzenia o klasie 0x55AA (CoD, Class of Device) i zapisanie jego adresu. W stanie niskim moduł oczekuje na wykrycie przez inne urządzenie.
PIO4 JP1 Przywrócenie ustawień fabrycznych – pin powinien mieć stan wysoki przy włączeniu zasilania i dwukrotnie zmienić stan z sekundową przerwą.
PIO6 JP3 Automatyczne łączenie; w stanie wysokim moduł łączy się automatycznie z wcześniej znalezionym i sparowanym urządzeniem.
PIO7 JP4 Prędkość transmisji interfejsu UART; w stanie wysokim 9600, w stanie niskim według konfiguracji (domyślnie 115200).

Stan sygnałów podłączonych do złączy JP1, JP2, JP3, a także JP4 można ustawić w stan wysoki za pomocą zworek – domyślnie wszystkie one są w stanie niskim. PmodBT2 dysponuje także złączem J2, na którym znajdują się sygnały interfejsu SPI, przez który można aktualizować oprogramowanie układu RN42.

Połączenie z płytką KAmeleon

Moduł PmodBT2 posiada złącze Pmod dla interfejsu UART typu 4A. W miejsce sygnału INT podłączono sygnał STATUS (PIO2), informujący o stanie połączenia. W przykładzie moduł podłączono do złącza oznaczonego jako ARDUINO CONNECTOR na płytce KAmeleon według tabeli 2.

Tabela 2. Sposób podłączenia modułu PmodBT2 do płytki KAmeleon

Sygnał Numer pinu PmodBT2 Numer pinu KAmeleon ARDUINO CONNECTOR Pin mikrokontrolera
RTS 1 D9 PB13
RX 2 D13 PB10
TX 3 D7 PB11
CTS 4 D12 PB14
GND 5 GND
VCC 6 +3,3
STATUS 7 D10 PB12
~RST 8 D11 PB15
NC 9
NC 10
GND 11
VCC 12

Kod przykładu

Kod do obsługi opisywanego modułu został umieszczony w plikach: źródłowym src/PmodBT2.c, a także nagłówkowym inc/PmodBT2.h. Funkcja PmodBT2_Config konfiguruje piny dla sygnałów ~RST i STATUS. Pin PB12 ustawiono jako źródło przerwania na obu zboczach tak, aby można było zaobserwować zmiany stanu połączenia. Następnie układ RN42 jest resetowany pinem PB15 i konfigurowany jest interfejs UART3 zgodnie z domyślną konfiguracją modułu. Procedurę konfiguracji przedstawiono na listingu 1.

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

Listing 1. Konfiguracja GPIO i UART dla modułu PmodBT2

void PmodBT2_Config(void)
{
  __HAL_RCC_GPIOB_CLK_ENABLE();
  GPIO_InitTypeDef GPIO_InitStruct;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Pin = GPIO_PIN_12;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
  GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull  = GPIO_PULLUP;
  GPIO_InitStruct.Pin = GPIO_PIN_15;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET);
  HAL_Delay(500);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET);
  HAL_Delay(500);
  pmodBt2Uart.Instance = USART3;
  pmodBt2Uart.Init.BaudRate = 115200;
  pmodBt2Uart.Init.WordLength = UART_WORDLENGTH_8B;
  pmodBt2Uart.Init.StopBits = UART_STOPBITS_1;
  pmodBt2Uart.Init.Parity = UART_PARITY_NONE;
  pmodBt2Uart.Init.Mode = UART_MODE_TX_RX;
  pmodBt2Uart.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
  pmodBt2Uart.Init.OverSampling = UART_OVERSAMPLING_16;
  pmodBt2Uart.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  HAL_UART_Init(&pmodBt2Uart);
}

Wszystkie cztery piny podłączone do interfejsu USART3 są konfigurowane w funkcji PmodBT2_HAL_UART_MspInit, która podobnie jak w przypadku innych modułów wykorzystujących ten interfejs, jest wywoływana w funkcji HAL_UART_MspInit w pliku main.c. Decyduje ona o tym, który interfejs powinien zostać skonfigurowany i wywołuje konfigurację USART3 dla PmodBT2, lub LPUART1 dla modułu Serial. Wspomniane funkcje znajdują się na listingach 2 i 3.

Listing 2. Konfiguracja pinów dla interfejsu USART3

void PmodBT2_HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
  __HAL_RCC_USART3_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  GPIO_InitTypeDef GPIO_InitStruct;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
  GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  HAL_NVIC_SetPriority(USART3_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(USART3_IRQn);
}

Listing 3. Wybór konfiguracji jednego z dwóch interfejsów

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
  if(huart->Instance == USART3)
    PmodBT2_HAL_UART_MspInit(huart);
  else if(huart->Instance == LPUART1)
    Serial_HAL_UART_MspInit(huart);
}

Użycie trybu komend

Kolejna z funkcji znajdujących się w pliku PmodBT2.cPmodBT2_ReadVersion, stanowi przykład użycia trybu komend układu RN42. Funkcja przełącza tryb, odczytuje wersję oprogramowania i przywraca tryb danych. Po każdym kroku sprawdzana jest poprawność otrzymanej odpowiedzi. Dane o wersji wpisywane są do przekazanego w argumencie bufora, a długość pierwszej linii odpowiedzi układu wpisywana jest do odpowiedniego wskaźnika. Cała funkcja znajduje się na listingu 4.

Listing 4. Odczyt wersji oprogramowania układu RN42 w trybie komend

bool PmodBT2_ReadVersion(char* data, int* len)
{
  char cmdResponse[5];
  HAL_UART_Transmit(&pmodBt2Uart, (uint8_t*)"$$$", 3, 100);
  HAL_UART_Receive(&pmodBt2Uart, (uint8_t*)cmdResponse, 5, 100);
  if(strncmp(cmdResponse, "CMD\r\n", 5) != 0)
    return false;
  HAL_UART_Transmit(&pmodBt2Uart, (uint8_t*)"V\r", 2, 100);
  HAL_UART_Receive(&pmodBt2Uart, (uint8_t*)data, 100, 100);
  HAL_UART_Transmit(&pmodBt2Uart, (uint8_t*)"---\r", 4, 100);
  HAL_UART_Receive(&pmodBt2Uart, (uint8_t*)cmdResponse, 5, 100);
  if(strncmp(cmdResponse, "END\r\n", 5) != 0)
      return false;
  *len = 0;
  while(data[(*len)++] != '\n');
  return true;
}

Ostatnie dwie funkcje: PmodBT2_Write i PmodBT2_Read są jedynie wrapperami na funkcje biblioteczne inicjalizujące odpowiednio zapis i odczyt z wykorzystaniem przerwań.

Obsługa przerwań od interfejsu UART

W przykładzie zaimplementowano dwie funkcje obsługujące przerwania od interfejsu UART, wykonywane po zakończeniu odbioru znaku i wysłaniu bufora. Pierwsza z nich zapisuje dane do bufora i jeżeli odebrany znak jest nową linią (‘\n’), to inicjalizuje transmisję odebranych danych poprzedzonych napisem „PmodBT2 ECHO: ”. Kod obsługujący koniec transmisji sprawdza, czy w buforze znajdują się dane do wysłania. Jeżeli tak, to rozpoczynany jest kolejny zapis. W przeciwnym razie następuje odczyt kolejnej porcji danych. Opisane funkcje obsługi przerwań przedstawiono na listingu 5.

Listing 5. Obsługa przerwań interfejsu UART

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if(textBuffer[bufferIndex] == '\n')
    PmodBT2_Write(echoText, echoTextLen);
  else {
    bufferIndex++;
    PmodBT2_Read(&textBuffer[bufferIndex], 1);
  }
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
  if(bufferIndex == 0)
  {
	PmodBT2_Read(textBuffer, 1);
    return;
  }
  PmodBT2_Write(textBuffer, bufferIndex + 1);
  bufferIndex = 0;
}

Główna funkcja programu – main, zajmuje się konfiguracją systemu, a także modułu PmodBT2. Następnie odczytywana jest wersja oprogramowania, a odpowiedź układu wysyłana jest na interfejs LPUART1 dostępny jako wirtualny port szeregowy po podłączeniu KAmeleona do komputera. Na koniec program przechodzi do nasłuchu nadchodzących danych, które automatycznie odsyłane są do nadawcy. Dodatkowo stan połączenia sygnalizowany jest za pomocą diody LED1 podłączonej do pinu PC7. Efekt działania programu zaprezentowano na fotografii 2. Do celów demonstracji użyto aplikację Serial Bluetooth Terminal dla systemu Android.

Fotografia 2. Komunikacja pomiędzy PmodBT2 a telefonem

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