Связь по Bluetooth между STM32 и Android

В данной статье показан один из рабочих вариантов связи по Bluetooth соединению между микроконтроллером STM32 (используется плата STM32 Value Discovery) и любым Android-устройством (смартфон, планшет и т.п.). В качестве примера показано управление светодиодом с планшета, а также обратная отправка сообщений в Android.

В качестве Bluetooth модуля используется дешевый китайский модуль HC-06, который был рассмотрен в этой статье.

Bluetooth модули

В качестве Android устройства используется дешевый китайский планшет Ainol Aurora с внешним USB-Bluetooth модулем (т.к. своего нет), подключенным через USB Host.

Схема подключения платы STM32 Discovery к модулю HC-06 проста:

Схема подключения Bluetooth к STM32

Для тех, кто не работал с STM32 лучше сначала прочитать 3 вводные статьи для начинающих по STM32.

Программа для STM32 писалась в среде CooCox CoIDE, на основе стандартного примера STMicroelectronics. ПО для Android писалось в среде Eclipse и основано на коде из этой статьи, за исключением того, что настройки MAC-адреса Bluetooth модуля из тела программы вынесены в меню.

Исходный код программы для STM32:

 #include "stm32f10x_usart.h" #include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include "misc.h"  int i;  //ErrorStatus HSEStartUpStatus;  void NVIC_Configuration(void); void GPIO_Configuration(void); void USART_Configuration(void); void USART1_IRQHandler(void); void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount);  int main(void) { 	usart_rxtx();     while(1)     {      } }  /******************************************************************************/ /*            STM32F10x Peripherals Interrupt Handlers                        */ /******************************************************************************/  /**   * @brief  Функция обработчик прерывания USARTx.   * @param  None   * @retval None   */ void USART1_IRQHandler(void) {     if ((USART1->SR & USART_FLAG_RXNE) != (u16)RESET) 	{ 		i = USART_ReceiveData(USART1); 		if(i == '1'){ 			GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_SET);		// Устанавливаем '1' на 8 ноге 			UARTSend("LED ONrn",sizeof("LED ONrn"));	// Выводим надпись в UART 		} 		else if(i == '0'){ 			GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_RESET);		// Устанавливаем '0' на 8 ноге 			UARTSend("LED OFFrn",sizeof("LED OFFrn")); 		} 	} }  void usart_rxtx(void) {     const unsigned char welcome_str[] = " Welcome to Bluetooth!rn";      /* Enable USART1 and GPIOA clock */     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);      /* NVIC Configuration */     NVIC_Configuration();      /* Configure the GPIOs */     GPIO_Configuration();      /* Configure the USART1 */     USART_Configuration();      /* Enable the USART1 Receive interrupt: this interrupt is generated when the          USART1 receive data register is not empty */     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);      /* print welcome information */     UARTSend(welcome_str, sizeof(welcome_str)); }  /******************************************************************************* * Function Name  : GPIO_Configuration * Description    : Конфигурирование GPIO. *******************************************************************************/ void GPIO_Configuration(void) {   GPIO_InitTypeDef GPIO_InitStructure;    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;   GPIO_Init(GPIOA, &GPIO_InitStructure); //Сохраняем    /* Конфигурируем USART1 Tx (нога PA.09) как симметричный (push-pull) пин */   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   GPIO_Init(GPIOA, &GPIO_InitStructure);    /* Конфигурируем USART1 Rx (PA.10) как вход без подтяжки */   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   GPIO_Init(GPIOA, &GPIO_InitStructure); }  /******************************************************************************* * Function Name  : USART_Configuration * Description    : Настройка USART1. *******************************************************************************/ void USART_Configuration(void) {   USART_InitTypeDef USART_InitStructure;  /* USART1 configuration ------------------------------------------------------*/   /* USART1 configured as follow:         - BaudRate = 9600 baud         - Word Length = 8 Bits         - One Stop Bit         - No parity         - Hardware flow control disabled (RTS and CTS signals)         - Receive and transmit enabled         - USART Clock disabled         - USART CPOL: Clock is active low         - USART CPHA: Data is captured on the middle         - USART LastBit: The clock pulse of the last data bit is not output to                          the SCLK pin   */   USART_InitStructure.USART_BaudRate = 9600;		// Скорость передачи   USART_InitStructure.USART_WordLength = USART_WordLength_8b;   USART_InitStructure.USART_StopBits = USART_StopBits_1;   USART_InitStructure.USART_Parity = USART_Parity_No;   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    USART_Init(USART1, &USART_InitStructure);    /* Включаем USART1 */   USART_Cmd(USART1, ENABLE); }  /**   * @brief  Настройка прерывания.   * @param  None   * @retval None   */ void NVIC_Configuration(void) {   NVIC_InitTypeDef NVIC_InitStructure;    /* Включаем прерывание от USARTx */   NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   NVIC_Init(&NVIC_InitStructure); }  /******************************************************************************* * Function Name  : UARTSend * Description    : Отсылает строку данных по UART. * Input          : - pucBuffer: buffers to be printed. *                : - ulCount  : buffer's length *******************************************************************************/ void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount) {     //     // Loop while there are more characters to send.     //     while(ulCount--)     {         USART_SendData(USART1, (uint16_t) *pucBuffer++);         /* Loop until the end of transmission */         while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)         {         }     } } 

Код достаточно простой, в функции GPIO_Configuration() происходит конфигурирование ног контроллера, в USART_Configuration() настраивается UART, а в функции NVIC_Configuration () происходит настройка прерывания.

Для передачи строки по UART служит функция UARTSend(), а при приеме данных происходит прерывание и срабатывает функция USART1_IRQHandler(). В данной функции, в зависимости от принятой цифры 1 или 0, подается команда на 8-ногу платы для включения или выключения подключенного к ней светодиода. А также, происходит передача строки «LED ON» или «LED OFF» обратно в UART. Как видите ничего сложного нет.

Вид главного активити в Android планшете

Исходный код приложения для Android я приводить не буду, т.к. он большой и основан на этой статье. Расскажу лишь про отличия. Каждое Bluetooth устройство содержит свой уникальный MAC-адрес. В вышеупомянутой статье он задавался в коде программы в виде константы, и чтобы его изменить нужно было ставить среду Eclipse, загружать проект, редактировать эту строчку, компилировать и устанавливать его в устройство. Поэтому я решил вынести установку MAC-адреса в настройки. Для этого я использовал android.preference. Я прилагаю проект в Eclipse и готовый APK файл, если возникнут какие-то вопросы по статье, то спрашивайте ниже в комментариях, либо на форуме по STM32.

Данный проект может быть взят за основу для более серьезного проекта, к примеру построение робота, с управлением от Android (собственно о чем мы и расскажем в следующих статьях), прием данных от уличной метеостанции на ваш телефон и т.п.

Прикрепленные файлы:

  • STM32_Android.rar (850 Кб)

Теги: