单片机
返回首页

STM32 HAL库使用中断实现串口接收不定长数据

2025-02-18 来源:cnblogs

以前用DMA实现接收不定长数据,DMA的方法接收串口助手的数据,全部没问题,不过如果接收模块返回的数据,而这些数据如果包含回车换行的话就会停止接收,例如接收:ATrnOKrn,就只能接收到ATr,导致没有接收完成,具体原因还没搞懂,有了解的,希望可以告知一下,DMA不定长接收方法传输门:https://www.cnblogs.com/xingboy/p/9714907.html。


好了,不多说了,现在进入正文。首先建立一个STM32Cumebx的工程,打开串口中断,完成配置,具体的配置流程就不细说了,没什么难度就只是打开串口跟中断而已。


生成工程代码后,先定义好一些变量:


//串口4中断接收定义

#define MAX_RECV_LEN 1024         //设定可以接收的最大字节

uint8_t msg_buff[MAX_RECV_LEN] = {0}; //接收缓存区

uint8_t * msg = msg_buff;    //定义一个指针指向接收缓存区

int flag = 0;        //接收完成标志

int len_u4=0;  //数据长度记录


接着重写串口接收回调函数


/*重写串口接收回调函数*/

void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)

{

     uint8_t ret = HAL_OK;

    msg++;

        len_u4++;//数据长度计数

    if( msg == msg_buff + MAX_RECV_LEN)

    {

        msg = msg_buff;

    }

         do  

    {  

        ret = HAL_UART_Receive_IT(UartHandle,(uint8_t *)msg,1);            

    }while(ret != HAL_OK);

        if(*(msg-1) == 'n')   //接收以n为结尾字符,则表示接收完成

    {

        flag  = 1;

    }

}


最后在main函数里面编写接收后的逻辑,注意要在while(1){ }前打开串口接收中断


int main(void)

{

  /* USER CODE BEGIN 1 */


  /* USER CODE END 1 */


  /* MCU Configuration----------------------------------------------------------*/


  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  HAL_Init();


  /* USER CODE BEGIN Init */


  /* USER CODE END Init */


  /* Configure the system clock */

  SystemClock_Config();


  /* USER CODE BEGIN SysInit */


  /* USER CODE END SysInit */


  /* Initialize all configured peripherals */

  MX_GPIO_Init();


 MX_DMA_Init();

  MX_USART3_UART_Init();


  MX_UART4_Init();

  /* USER CODE BEGIN 2 */


  /* USER CODE END 2 */


  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

    //自己添加代码部分:while前打开串口中断接收

    HAL_UART_Receive_IT(&huart4, (uint8_t *)msg, 1); //开启第一次中断

  while (1)

  {

  /* USER CODE END WHILE *//* USER CODE BEGIN 3 */

//======自己添加代码部分=========        

            if (flag == 1)

    {

            printf('msg_buff = %s ;len = %drn',msg_buff,len_u4);

       HAL_Delay(100); //加延时,保证接收到数据过长的时候,等待数据存入缓存区发送

            HAL_UART_Transmit(&huart3,msg_buff, len_u4,100);     //将串口4接收到的数据通过串口3传出    

            memset(msg_buff, 0, sizeof(msg_buff));   //清空缓存区

           // 指向接收缓存的头部

            msg = msg_buff;

            (&huart4)->pRxBuffPtr = msg;

            flag = 0;

                        len_u4=0;//每次数据长度清0

    }

        HAL_Delay(10);

  }

//==============================

  /* USER CODE END 3 */


}


运行结果如下,效果正确

谈谈串口RS232跟RS485:这两个串口除了逻辑电平不同外,还有传输距离也不同,如果对速度要求不高,传输距离要比较远的就用RS485比较好,虽然RS485是个半双工,但是抑制共模干扰能力比较强,不过这些只是对于硬件层面的,对于软件层面来说他们的本质都是串口,在STM32Cubemx中,都是只是配置为串口,按照串口的编程来处理即可。

进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦线性调频增强器

  • 家用电器遥控器

  • 12V 转 28V DC-DC 变换器(基于 LM2585)

  • 红外开关

  • DS1669数字电位器

  • HA1377 桥式放大器 BCL 电容 17W(汽车音频)

    相关电子头条文章