# stm32_ble_debug **Repository Path**: killerp/stm32_ble_debug ## Basic Information - **Project Name**: stm32_ble_debug - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 7 - **Forks**: 1 - **Created**: 2021-05-19 - **Last Updated**: 2024-06-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## stm32 与 蓝牙调试器 通信例程 ## 前言 串口是我们经常用来输出数据的接口,使用一些蓝牙串口模块,如HC-05能方便的通过蓝牙将串口数据发送到上位机,省去了串口连线到电脑的步骤。 今天分享一个功能强大的APP,蓝牙调试器,它具备以下功能 - 发送/接收蓝牙串口的数据 - 自定义蓝牙串口 发送/接收数据包格式 - 支持多种控件:如按键,文本,滑动窗口,坐标轴显示等。 ![在这里插入图片描述](/picture/20210517205508381.png) **尤其是自定义数据包格式 和 多种可选的控件 是数据处理强大工具!** 本次实验基于stm32及HC-05蓝牙串口模块,上位机为安卓手机,蓝牙调试器下载: ## 一,设置数据包格式 APP界面如图所示,设备连接 与 对话模式 都是基操 ,我们直奔主题:**专业调试** ![在这里插入图片描述](picture/2021051720591697.jpg) **首先新建一个工程,暂时取名为demo,我们需要关注 编辑控件 和 通信设置 功能;先进入通信设置,设置我们的数据包格式:** 根据自己的数据需求,设置数据包内传输的数据。数据包的格式设置规则如下: - 起始字节:0xA5 - 原始数据 - 校验和 - 结束字节:0x5A 数据格式支持 bool,char,short,int,float四种c语言常用的数据类型,在本次例程中,我将传输char,short,int,float类型的数据。假定我们要发送和接收的数据包格式如下: ![在这里插入图片描述](picture/2021051721251260-1621391325468.png) **根据上面的数据包格式,到APP中的发送和接收数据包界面,分别添加一个char,short,int,float的变量;如图:到此我们就完成了数据包格式的设置了。** ![在这里插入图片描述](picture/20210517213030362-1621391329413.jpg) ## 二,编辑控件 **这里以Y-T一维波形图为例子**,简单介绍控件的设置流程: 点击+,选择Y-T一维波形图,随后弹出下面窗口: **该波形图能同时显示6个通道的数据,Receive表示数据来自接收的数据包,随后是数据类型,最后是链接到上一步中我们创建的变量。** ![在这里插入图片描述](picture/20210517213724203-1621391337712.jpg) 补充:右上角的黄色的齿轮可设置数据接收周期,这个取决于逆串口发送的周期,暂时设置为100ms。同时还能支持控件的移动和缩放等。 ## 三,stm32 串口发送 蓝牙调试器的设置基本完成了,接下来就是单片机的串口程序设计了,这里以stm32为例子: 简单介绍一下串口的配置: - 串口波特率:9600 - 使能DMA发送 - 使能接收中断 这一段代码显示如何组装我们的数据 ```c #define USART_TX_LEN 14 //数据包大小 extern uint8_t USART_TX_BUF[USART_TX_LEN]; //数据包缓存区 ``` ```c char x = 0x01; short y = 0x02; int z = 0x03; float f = 4.5; USART_TX_BUF[0] = 0xA5; USART_TX_BUF[1] = (uint8_t)x; Short_to_Byte(y,&USART_TX_BUF[2]); Int_to_Byte(z,&USART_TX_BUF[4]); Float_to_Byte(f,&USART_TX_BUF[8]); //计算校验和 USART_TX_BUF[12] =(uint8_t) ((USART_TX_BUF[1]+USART_TX_BUF[2]+USART_TX_BUF[3]+USART_TX_BUF[4]+USART_TX_BUF[5]+USART_TX_BUF[6]+USART_TX_BUF[7]+USART_TX_BUF[8]+USART_TX_BUF[9]+USART_TX_BUF[10]+USART_TX_BUF[11])&0xff); USART_TX_BUF[13] = 0x5A; //通过串口1发送 ble_send(USART_TX_BUF,14); //延时100ms delay_ms(100); ``` 串口发送函数: ```c //send data to hc-05 int ble_send(uint8_t *data,int len) { while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET); //wait until tx complete if(!data)return -1; HAL_UART_Transmit_DMA(&huart1,data,len); //ʹÓÃDMAģʽ·¢ËÍ while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET); return 0; } ``` **还有short,int,float转换为uint8_t类型的函数:** ```c void Int_to_Byte(int i,uint8_t *byte) { unsigned long longdata = 0; longdata = *(unsigned long*)&i; byte[3] = (longdata & 0xFF000000) >> 24; byte[2] = (longdata & 0x00FF0000) >> 16; byte[1] = (longdata & 0x0000FF00) >> 8; byte[0] = (longdata & 0x000000FF); } void Float_to_Byte(float f,uint8_t *byte) { unsigned long longdata = 0; longdata = *(unsigned long*)&f; byte[3] = (longdata & 0xFF000000) >> 24; byte[2] = (longdata & 0x00FF0000) >> 16; byte[1] = (longdata & 0x0000FF00) >> 8; byte[0] = (longdata & 0x000000FF); } void Short_to_Byte(short s,uint8_t *byte) { byte[1] = (s & 0xFF00) >> 8; byte[0] = (s & 0xFF); } ``` 蓝牙调试器接收界面显示: ![在这里插入图片描述](picture/20210517231732731-1621391367953.jpg) ## 四,stm32 串口接收 首先,我们在 蓝牙调试器 中添加 可编辑文本 控件 来输入我们要发送的数据; 本实验中,我们发送一帧数据包给stm32,stm32解析出数据后,对数据进行加法运算并返回到蓝牙调试器。 实现效果如图: 黑色框中显示接收到的数据,绿色框中显示发送的数据; > 对于char 类型+1,short+2,int+3,float+1.1; > ![在这里插入图片描述](picture/20210519101144674-1621391351936.jpg) > > > > stm32使能串口接收中断,并在中断中处理数据: ```c #define USART_RX_LEN 14 uint8_t USART_RX_BUF[USART_RX_LEN]; typedef struct { uint8_t option; //bit0 indecate weather the msg is recved char x; short y; int z; float f; }Ble_Data; Ble_Data rec_data; //蓝牙接收结构体 void USART1_IRQ_Cb(void) { uint8_t err = 0; if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE)!=RESET)) //接收中断(接收到的数据必须是0x5a结尾0xa5开头) { HAL_UART_Receive(&huart1,USART_RX_BUF,USART_RX_LEN,100); //读取串口接收的一字节数据到Res //检查包头,包尾 if(USART_RX_BUF[0]==0xa5 && USART_RX_BUF[USART_RX_LEN-1]==0x5a) { //检查校验和 err = (uint8_t) ((USART_RX_BUF[1]+USART_RX_BUF[2]+USART_RX_BUF[3]+USART_RX_BUF[4]+USART_RX_BUF[5]+USART_RX_BUF[6]+USART_RX_BUF[7]+USART_RX_BUF[8]+USART_RX_BUF[9]+USART_RX_BUF[10]+USART_RX_BUF[11])&0xff); if(err!=USART_RX_BUF[12]) { //返回错误 数据无效 rec_data.option |=0x00; return ; } //数据有效 rec_data.option |=0x01; //将buff中的字节数据转换成指定类型 rec_data.x = (char)USART_RX_BUF[1]; rec_data.y = *((short *) (&USART_RX_BUF[2])); rec_data.z = *((int *) (&USART_RX_BUF[4])); rec_data.f = *((float *) (&USART_RX_BUF[8])); } } } ``` ![在这里插入图片描述](picture/20210519102124328-1621391360562.png)