第11讲 蓝牙模块与建议数据包解析
本文介绍了蓝牙通信的基本概念,重点讲解了低功耗蓝牙(BLE)的实现方法。通过BT24蓝牙串口透传模块简化开发流程,详细说明了STM32串口3的配置步骤,包括DMA通道设置和中断处理。文章提供了完整的代码示例,实现串口数据接收和解析功能,并演示了如何通过上位机指令控制三色LED灯。最后指出BLE模块不适合OTA升级,建议使用传统蓝牙。该教程为嵌入式开发者提供了实用的蓝牙通信实现方案。
补充
如果想用波特律动 串口助手 - 直接在浏览器使用的串口调试工具此工具调试蓝牙模块的AT模式,需要注意换行的添加;

不是直接在指令的行位添加\r\n,而是在设置里面更改。因为选择ASCII会导致\r\n变成字符一并输出(而是使用左下角齿轮设置)。

概念介绍
蓝牙是我们日常生活中最常用的无线通信协议,类似耳机这种需要持续传输数据的设备一般使用经典蓝牙,像运动手环这类间歇性同步数据的设备使用的是低功耗蓝牙。

蓝牙通信设备有主从之分,在建立蓝牙连接前,从机需要向外广播自己的信息,然后被主机扫描到从机后就会发起连接,连接建立后就可以通过约定好的协议进行通信了。
BLE学习通常包含下面四个主要知识点:

这边咱们直接使用BT24蓝牙串口透传模块,将复杂的蓝牙协议转换成串口传输协议逃一下课。
实操演练
打开串口3选用异步通信模式,修改波特率为9600配合BT24默认波特率。

开启串口中断传输模式。

添加DMA通道,TX RX全部要添加。

生成代码模版开始编辑用户代码。
定义接收数据的buffer:
/* USER CODE BEGIN PV */
uint8_t receiveData[50];
/* USER CODE END PV */
开始串口接收不定长数据并且失能接收过半中断:
/* USER CODE BEGIN 2 */
HAL_UARTEx_ReceiveToIdle_DMA(&huart3,receiveData,sizeof(receiveData));
__HAL_DMA_DISABLE_IT(&hdma_usart3_rx,DMA_IT_HT);
/* USER CODE END 2 */
注意如果和我一样用Keil的话推荐在usart.h里面显式声明串口3的DMA接收句柄:
/* USER CODE BEGIN Private defines */
extern DMA_HandleTypeDef hdma_usart3_rx;
/* USER CODE END Private defines */
在stm32f1xx_hal_uart.c里面找到关于下面这个函数的定义:

复制下来回到usart.c中重定义这个弱定义函数:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart==&huart3)
{
HAL_UART_Transmit_DMA(&huart3,receiveData,Size);
HAL_UARTEx_ReceiveToIdle_DMA(&huart3,receiveData,sizeof(receiveData));
__HAL_DMA_DISABLE_IT(&hdma_usart3_rx,DMA_IT_HT);
}
else
{
}
}
编译下载运行:

拓展功能
下面尝试通过上位机向电脑发送指令来控制三色灯的亮灭,数据组包规则如下:0x01代表红色小灯,0x02代表绿色小灯,0x03代表蓝色小灯;0xFF代表灯亮,0x00代表灯灭;包头为0xAA,包头之后的一帧数据代表总包长度,接下来是数据包内容,最后加上校验和。

代码示例:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart==&huart3)
{
HAL_UART_Transmit_DMA(&huart3,receiveData,Size);
if(receiveData[0]==0xAA)
{
if(receiveData[1]==Size)
{
uint8_t sum=0;
for(int i=0;i<Size-1;i++)
{
sum+=receiveData[i];
}
if(sum ==receiveData[Size-1])
{
//步长为2,找到的都是灯泡控制位
for(int i=2;i<Size-1;i+=2)
{
GPIO_PinState state =GPIO_PIN_SET;
if(receiveData[i+1]==0x00)
{
state=GPIO_PIN_RESET;
}
if(receiveData[i]==0x01)
{
HAL_GPIO_WritePin(LED_RED_GPIO_Port,LED_RED_Pin,state);
}
else if(receiveData[i]==0x02)
{
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port,LED_GREEN_Pin,state);
}
else if(receiveData[i]==0x03)
{
HAL_GPIO_WritePin(LED_BLUE_GPIO_Port,LED_BLUE_Pin,state);
}
}
}
}
}
HAL_UARTEx_ReceiveToIdle_DMA(&huart3,receiveData,sizeof(receiveData));
__HAL_DMA_DISABLE_IT(&hdma_usart3_rx,DMA_IT_HT);
}
else
{
}
}
最后,笔者亲测用BLE模块升级OTA是不可行的,建议还是用传统蓝牙。
更多推荐



所有评论(0)