一、模块大致介绍以及调试

尝试自己做笔记,方便记忆;不足的地方还请大佬指正哈哈,欢迎讨论

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

然后打开手机上的蓝牙调试器、这里只做简单的通信,使用对话模式就可以

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐