【HC—05蓝牙模块与stm32F103C8T6通信基于HAL库】
DMA通信,HC-05、STM32
一、模块大致介绍以及调试
尝试自己做笔记,方便记忆;不足的地方还请大佬指正哈哈,欢迎讨论
1、将HC—05蓝牙模块与串口模块连接好,将串口助手的参数配置好

HC—05蓝牙模块命令模式下默认波特率为38400,无奇偶校验位,一个停止位

要进入模块命令模式,在给模块上电前按住模块上的按钮,上电后模块状态指示灯慢闪即进入了命令模式

2、常用的HC—05蓝牙模块命令
命令后面要回车,否则模块不识别

图上缺少模块状态的命令:AT+ROLE(AT+ROLE=0或1或2,前提是购买的模块支持三种模式,市面上有的模块仅支持从机模式)
0:从机模式:模块为被其他模块所连接模式
1:主机模式:模块为主动链接其他蓝牙模块的模式
2:回环模式:模块将接受到的数据返还给连接的主蓝牙设备
配置模块波特率AT+UART=115200,0,0
查询模块蓝牙名称AT+NAME(设置蓝牙名称AT+NAME=hahah)有的模块会失败
配置模块为从机AT+ROLE=0;
这里主要注意停止位0:1位,1:2位
3、打开串口助手测试

二、stm32cubemax的配置
1、使用DMA加中断的方式接收数据
首先按照我们配置的蓝牙波特率以及校验位和停止位配置;我这里使用的是USART2;

打开USART2的中断以及添加DMA接收

2、 DMA模式选择
DMA有循环模式和正常模式2种模式。
DMA接收要用循环模式,只需调用一次接收函数即可,重复调用也只有第一次调用有效,若是正常模式,需要在每次接收完成后重复调用
DMA发送要用正常模式,需在每次发送时重复调用 还要打开UART中断,否则即使重复调用DMA发送函数也只有第一次发送有效,其余不会执行(UART发送状态一直处于 BUSY) 若是 循环模式,则会连续不断地发送,不会停止。
串口发送不配置为DMA,串口配置DMA后, 会有连续两次发送会出现数据丢失的情况,因此不使用。
将DMA接收模式更改为循环模式

为接收引脚配置上拉电阻

三、代码实现
1、 main.c
#define DMA_BUF_SIZE 256
//这个DMA大小放在main.h里
/*定义接受数据的数组,容量为设置的DMA接收字节大小*/
uint8_t rx_buf[DMA_BUF_SIZE] = {0} ;
/*定义偏移量,用来记录已读取到数据位置 */
uint8_t rx_offset = 0;
int main(void)
{
/*使能串口空闲中断 */
__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);
/*需要先连接蓝牙之后再按一次复位才能发送
这里主要是蓝牙连接速度赶不上初始化速度
*/
HAL_UART_Transmit(&huart2,Connectchar,sizeof(Connectchar),1000);
/*设置DMA传输和使能DMA,将uart2接收到的数据传输到rx_buf */
HAL_UART_Receive_DMA(&huart2,rx_buf,DMA_BUF_SIZE);
while(1)
{
}
}
main.h中声明全局变量
extern uint8_t rx_buf[DMA_BUF_SIZE] ;
extern uint8_t rx_offset;
2、stm32f1xx_it.c
这里主要是处理串口通信内容,将接收到的数据再发送回去
声明我们自定义的函数
/* USER CODE BEGIN PFP */
void USER_UART_IRQHandler(UART_HandleTypeDef *huart);
/* USER CODE END PFP */
将我们自定义的处理函数添加到USART2中断函数中,否则不会调用自定义函数
//将我们自定义的处理函数添加到USART2中断函数中,否则无法调用自定义函数
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
USER_UART_IRQHandler(&huart2);
/* USER CODE END USART2_IRQn 1 */
}
3、数据处理
自定义我们的中断处理函数
//自定义我们的中断处理函数
void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
{
if(huart->Instance ==USART2)
{
if(__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE)!=RESET)
{
/*把空闲中断标志位清除,否则一直进入中断*/
__HAL_UART_CLEAR_IDLEFLAG(huart);
/*
计算接收到的数据长度
__HAL_DMA_GET_COUNTER获取DMA剩余缓冲区大小
*/
uint8_t Length =DMA_BUF_SIZE-__HAL_DMA_GET_COUNTER(&hdma_usart2_rx)-rx_offset;
/*将接收到的数据发送出去*/
HAL_UART_Transmit(huart,rx_buf+rx_offset,Length,HAL_MAX_DELAY);
rx_offset += Length;
}
}
}
rx_buf+rx_offset用来指向最新传过来的数据的首地址,length则是用来计算最新传过来数据的长度
四、硬件连接以及测试
ok把程序烧录进去,
将蓝牙模块连接到对应串口引脚上,注意Rx接Tx;Tx接RX
然后打开手机上的蓝牙调试器、这里只做简单的通信,使用对话模式就可以




更多推荐



所有评论(0)