• STM32 串口接收定长,不定长数据


    本文为大家介绍如何使用 串口 接收定长 和 不定长 的数据。


    前言

    一、串口接收定长数据

    1. 函数介绍

    1. 开启串口的接收中断:
    HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
    
    • 1

    参数:

    • huart:这是一个指向 UART_HandleTypeDef 结构体的指针,用于标识特定的 UART 外设实例。该结构体包含了该 UART 实例的各种配置和状态信息。

    • pData:这是一个指向存储接收数据的缓冲区的指针。当接收到数据时,数据将被存储在该缓冲区中。

    • Size:这是要接收的数据的字节数。函数将尝试从 UART 接收指定数量的字节到 pData 缓冲区中。

    1. 串口接收完成回调函数:
    // 当串口接收到数据就调用该回调函数
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    参数:

    • huart:这是一个指向 UART_HandleTypeDef 结构体的指针,用于标识特定的 UART 外设实例。该结构体包含了该 UART 实例的各种配置和状态信息。

    2.代码实现

    // 接收数据的缓冲区
    uint8_t recv_buff = 0;
    
    // 1. 开启串口接收中断(每次只接收1位数据)
    HAL_UART_Receive_IT(&huart1, &recv_buff, 1);
    
    
    /* 2.中断的方式接收定长的数据 */
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
    	if(huart->Instance == USART1)
    	{			
    		if(recv_buff == 'A')
    		{
    			printf("recv : A \r\n");
    		}
    		else if(recv_buff == 'B')
    		{
    			printf("recv : B \r\n");
    		}
    
    		
    	// 再次开启串口接收中断(每次只接收1位数据)
    	HAL_UART_Receive_IT(&huart1, &recv_buff, 1);
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    二、串口接收不定长数据

    这里会引入空闲中断,至于什么是空闲中断 在第四大点中会介绍。

    1.函数介绍

    1. 开启串口空闲接收中断
    HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
    
    • 1

    参数:

    • huart:UART 句柄,指向正在使用的串口设备。
    • pData:存储接收数据的缓冲区的指针。
    • Size:期望接收的数据字节数。
    1. 串口接收事件回调函数
    void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
    {
    
    }
    
    • 1
    • 2
    • 3
    • 4

    参数:

    • huart:UART 句柄,指向正在使用的串口设备。
    • Size:接收到的数据字节数。

    2. 代码实现

    uint8_t recv_buff[20] = {0}; // 定义一个长度为 20 的接收缓冲区
    
    // 1.打开空闲接收中断
    HAL_UARTEx_ReceiveToIdle_IT(&huart1, recv_buff, sizeof(recv_buff));
    
    // 2. 空闲中断时调用的回调函数
    void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
    {
        if(huart->Instance == USART1) // 检查是否为 USART1 串口
        {
            recv_buff[Size] = '\0'; // 在接收到的数据末尾添加字符串结束符
    
           
            if(strcmp((char*)recv_buff, "LED ON") == 0)
            {
                printf("led on is ok\r\n");
            }
          
            else if(strcmp((char*)recv_buff, "LED OFF") == 0)
            {
                printf("led off is ok\r\n"); 
            }
        }
        
        // 重新开启空闲接收中断,继续监听串口数据
        HAL_UARTEx_ReceiveToIdle_IT(&huart1, recv_buff, sizeof(recv_buff));
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    三,两者回调函数的区别比较

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
    void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size);

    这两个函数都是串口接收的回调函数,但是它们在触发时机上有所不同:

    • HAL_UART_RxCpltCallback 函数是标准的 HAL 库提供的串口接收完成回调函数。它在每次成功接收到指定数量的数据后被调用,即每当接收完成一个数据包时触发一次。

    • HAL_UARTEx_RxEventCallback 函数是 HAL 扩展库提供的串口接收事件回调函数。它可以在串口接收到特定事件时被调用,比如接收到空闲状态时触发。这个函数可以用于处理更多的接收事件,而不仅仅是每次接收完成一个数据包时触发。

    因此,区别在于 HAL_UARTEx_RxEventCallback 函数可以处理更多类型的接收事件,而 HAL_UART_RxCpltCallback 函数仅在每次接收完成一个数据包时触发

    四,空闲中断的介绍

    在这里插入图片描述

    一帧数据传输结束后,通信线路将会维持高电平,这个状态称为空闲状态。当 CPU 检测到通信线路处于空闲状态时,且空闲状态持续时间大于一个字节传输时间时将会触发空闲中断 。空闲中断的触发通常表示一次完整的数据传输已经结束。

    当 产生空闲中断后,会调用 空闲中断的接收事件回调函数,将接收到的数据全部打印出来,这样就可以实现不定长数据的接收。

    应用场景:

    1. 串口通信中的数据帧解析: 在串口通信中,空闲中断常用于解析数据帧。一旦检测到空闲中断,就可以确定一帧数据已经接收完整,并开始解析其中的数据。

    2. 数据接收超时处理: 空闲中断可以用于实现数据接收的超时处理。如果一定时间内未触发空闲中断,可以认为数据接收超时,并进行相应的处理,例如丢弃接收缓冲区中的数据或发出超时警告。

    3. 多任务环境下的数据同步: 在多任务系统中,空闲中断可以用于实现任务之间的数据同步。当一个任务接收到完整的数据帧后,可以通过触发空闲中断来通知其他任务进行相关操作或处理。

    总之,空闲中断在串口通信中具有重要的作用,用于检测数据传输的完成和触发相应的处理操作,适用于各种数据接收和处理场景。


    总结

    下一篇文章为大家介绍 串口 UART 协议.。

  • 相关阅读:
    蓝牙协议之配对和绑定学习笔记
    假脸检测:Exploring Decision-based Black-box Attacks on Face Forgery Detection
    Java版本下的鸿鹄企业电子招投标系统二次开发实践:源代码支持与定制开发
    score_inverse_problems运行环境,pycharm重新安装,jax,jaxlib的GPU版本安装-230831
    Python各方法读取ES性能比较
    为什么在vue2中改变数据视图不会更新,带你阅读源码
    对拍系列 v1.0
    Day07--wxs的概念以及其基本的用法
    [Unity]GPU Instance 如何将人形Animator动画保存到图片里
    代码随想录算法训练营第五九天 | 下一个更大元素II、接雨水
  • 原文地址:https://blog.csdn.net/wuyiyu_/article/details/137636438