Tym razem chciałbym opisać sposób dokonania komunikacji z modułem bluetooth HC-05. Połączenie odbywa się poprzez interfejs UART, który można wykonać bezpośrednio poprzez STM32, lub z wykorzystaniem komend AT. Pierwszy sposób ma większe zastosowanie ponieważ umożliwia dołączania dodatkowych modułów z których można przesyłać dane komputer lub tablet z wykorzystaniem bezprzewodowej komunikacji.
Na początku zaprezentują podstawową wersję programu na układ STM32 po czym przejdę do komend AT.
Program dla STM32:
W zasadzie nie ma tutaj żadnych cudów. Do wykonania komunikacji pomiędzy układem a STM-em należy skonfigurować interfejs UART, przerwania do niego oraz ustawić porty TX i RX.Poniżej funkcja ustawiająca piny dla TX oraz RX:
- void GPIO_INIT()
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; // PB10 (TX) PB11 (RX)
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(GPIOB, &GPIO_InitStruct);
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);
- }
Włączenie i konfiguracja UART-u:
- void USART_INIT(uint32_t set_baudrate)
- {
- USART_InitTypeDef USART_InitStruct;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
- USART_InitStruct.USART_BaudRate = set_baudrate;
- USART_InitStruct.USART_WordLength = USART_WordLength_8b;
- USART_InitStruct.USART_StopBits = USART_StopBits_1;
- USART_InitStruct.USART_Parity = USART_Parity_No;
- USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
- USART_Init(USART3, &USART_InitStruct);
- USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
- USART_Cmd(USART1, ENABLE);
- }
Konfiguracja przerwań NVIC:
- void NVIC_INIT()
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
Funkcje pozwalające na komunikację:
Wysyłanie danych:
- int8_t USART_Buffer[8][32];
- uint16_t usart_buf_in[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- uint16_t usart_buf_out[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- uint16_t usart_buf_num[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- int __io_putchar(int c)
- {
- send_char(c);
- return c;
- }
- void USARTSend(volatile char *c)
- {
- //Pętla działa do puki będzie jakiś znak do wysłania
- while(*c)
- {
- while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
- USART_SendData(USART3, *c++);
- }
- }
- void USART_InsertToBuffer(uint8_t usart_num, uint8_t c)
- {
- usart_num = 0;
- //Sprawdza dostepne miejsce w buforze
- if (usart_buf_num[usart_num] < 32)
- {
- if (usart_buf_in[usart_num] > (32 - 1))
- {
- usart_buf_in[usart_num] = 0;
- }
- USART_Buffer[usart_num][usart_buf_in[usart_num]] = c;
- usart_buf_in[usart_num]++;
- usart_buf_num[usart_num]++;
- }
- }
- uint8_t USART_Getc(USART_TypeDef* USARTx)
- {
- uint8_t usart_num = 0;
- uint8_t c = 0;
- //Sprawdza czy sa dane w buforze
- if (usart_buf_num[usart_num] > 0)
- {
- if (usart_buf_out[usart_num] > (32 - 1))
- {
- usart_buf_out[usart_num] = 0;
- }
- c = USART_Buffer[usart_num][usart_buf_out[usart_num]];
- USART_Buffer[usart_num][usart_buf_out[usart_num]] = 0;
- usart_buf_out[usart_num]++;
- usart_buf_num[usart_num]--;
- }
- return c;
- }
- #ifdef USART3
- void USART3_IRQHandler(void)
- {
- //Sprawdzenie czy wystapilo przerwanie z powodu odebrania danych
- if (USART_GetITStatus(USART3, USART_IT_RXNE))
- {
- #ifdef USART3_USE_CUSTOM_IRQ
- //Wywołaj funckje przerwania
- USART3_ReceiveHandler(USART3->DR);
- #else
- //Podaj dane do Buffera
- USART_InsertToBuffer(0, USART3->DR);
- #endif
- }
- }
- #endif
Program przygotowany w taki sposób pozwoli na wysyłanie odbieranie danych przez moduł. Oczywiście przewody TX i RX należy podłączyć na krzyż. Układ zasilany jest napięciem 3.3V. Do 5V mogą być podłączone tylko odpowiednio przygotowane płytki.
HC-05 podłączony do STM-a ,z komputerem lub telefonem może się komunikować poprzez interfejs bluetooth.
Komenty AT
Teraz chciałbym przejść do opisania komend AT, jakie można wysłać do układu.
Należy pamiętać, że zgodnie z dokumentacją układu PIN34 musi być podciągnięty do zasilania. Jeżeli został podłączony do zasilania po włączeniu zasilania to parametry transmisji będą następujące:
prędkość transmisji 9600bps, 8 bitów, 1 bit stopu brak kontroli parzystości. Natomiast gdy zasilanie zostało włączone razem z podciągnięciem pinu do stanu wysokiego to parametry będą się nieco różniły: prędkość transmisji 38400, 8 bitów, 1 bit stopu oraz brak kontroli parzystości.
Aby wszystkie komendy działały należy wspomniany wcześniej pin pozostawić w stanie wysokim.
Poniżej przedstawię kilka podstawowych komend których można użyć do połączenia się z modułem. Wspomnę tylko, że te komendy w większości modułów, zwłaszcza tych starszych wersjach, akceptują tylko te wprowadzone dużymi literami. Poniżej kilka podstawowych komend:
- AT - odpowiedź OK - sprawdzenie komunikacji
- AT+RESET - odpowiedź OK - wyjście z trybu komend AT
- AT+NAME - wyświetl nazwę modułu
- AT+ADDR - wyświetli adres
- AT+VERSION<param> - wersja oprogramowania
- AT+UART - wyświetlenie prędkości transmisji, od 4800 do 1328400
- AT+ROLE - tryb pracy modułu, 1 dla master, 0 dla slave
- AT+ORGL - przywrócenie ustawień fabrycznych
- AT+PSWD - wyświetla hasło
- AT+CLASS - sprawdzenie typu urzadzenia
- AT+STATE - zwraca status układu
W przypadku chęci zmiany niektórych parametrów podaje się je po "=" razem z komendą:
- AT+NAME=PRZYKLADOWA NAZWA - zmiana nazwy
- AT+UART=9600 - zmiana prędkości transmisji
- AT+UART=9600,1,0,\r\n - prędkość transmisji, bit stopu, bit parzystości
- AT+PSWD=8888 - zmiana hasła