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

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

文章目录

  • 前言
  • 一、串口接收定长数据
      • 1. 函数介绍
      • 2.代码实现
  • 二、串口接收不定长数据
      • 1.函数介绍
      • 2. 代码实现
  • 三,两者回调函数的区别比较
  • 四,空闲中断的介绍
  • 总结


前言

一、串口接收定长数据

1. 函数介绍

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

参数:

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

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

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

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

参数:

  • 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.函数介绍

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

参数:

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

参数:

  • 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));
}

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

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 协议.。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/812053.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot3 + Vue3 + Uniapp + uView + Elenment 实现动态二级分类以及二级分类的管理

SpringBoot3 Vue3 Uniapp uView Elenment 实现动态二级分类以及二级分类的管理 1. 效果展示1.1 前端显示效果1.2 后台管理一级分类1.3 后台管理二级分类 2. 后端代码2.1 GoodsCategoryController.java2.2.1 GoodsCategoryMapper.java2.2.2 GoodsCategorySonMapper.java2.3.…

Zookeeper的集群搭建和ZAB协议详解

Zookeeper的集群搭建 1)zk集群中的角色 Zookeeper集群中的节点有三个角色: Leader:处理集群的所有事务请求,集群中只有一个LeaderFollwoer:只能处理读请求,参与Leader选举Observer:只能处理读…

数仓维度建模

维度建模 数仓建模方法1. 范式建模法(Third Normal Form,3NF)2. 维度建模法(Dimensional Modeling)3. 实体建模法(Entity Modeling) 维度建模1. 事实表事实表种类事务事实表周期快照事实表累计快…

强大的数据分析计算软件:Stata 15 for Mac 激活版

Stata 15 for Mac是一款高级统计分析软件,具有强大的数据管理和数据提取工具。以下是其功能和特点的详细介绍: 软件下载:Stata 15 for Mac 激活版版下载 数据管理:Stata 15 for Mac支持多种数据库、数据格式和计算机语言&#xff…

如何在淘~宝接单和解决别人问题-java开发

如下这是一个连接:https://s.tb.cn/c.0vDtL3https://s.tb.cn/c.0vDtL3 解决各种问题。可付费咨询

【JAVA基础篇教学】第四篇:Java条件语句

博主打算从0-1讲解下java基础教学,今天教学第四篇: Java条件语句。 在Java中,条件语句用于根据不同的条件执行不同的代码块。Java提供了if、else if和else等关键字来实现条件判断。 一、if语句 if语句用于执行一个代码块,如果给…

TripoSR: Fast 3D Object Reconstruction from a Single Image 论文阅读

1 Abstract TripoSR的核心是一个基于变换器的架构,专为单图像3D重建设计。它接受单张RGB图像作为输入,并输出图像中物体的3D表示。TripoSR的核心包括:图像编码器、图像到三平面解码器和基于三平面的神经辐射场(NeRF)。…

【网络】服务器间FTP传输文件被限速问题的排查(未达最优解)

服务器间FTP传输文件被限速问题的排查 问题描述具体问题软硬件环境文件传输方式的2种策略FTP相关信息问题表现问题解决结论 发散探讨——基于此问题进行发散研究相关知识从FileZilla软件入手从Windows入手从Linux入手从协议入手Windows和Linux的文件共享,分别是使用…

状态模式:管理对象状态转换的动态策略

在软件开发中,状态模式是一种行为型设计模式,它允许一个对象在其内部状态改变时改变它的行为。这种模式把与特定状态相关的行为局部化,并且将不同状态的行为分散到对应的状态类中,使得状态和行为可以独立变化。本文将详细介绍状态…

ORA-00600: internal error code, arguments: [krbcbp_9]

解决方案 1、清理过期 2、control_file_record_keep_time 修改 恢复时间窗口 RMAN (Recovery Manager) 是 Oracle 数据库的备份和恢复工具。在 RMAN 中,可以使用“恢复窗口”的概念来指定数据库可以恢复到的时间点。这个时间点是基于最近的完整备份或增量备份。 …

[Linux][进程控制][进程程序替换]详细解读

目录 1.进程创建1.fork函数初识2.fork函数返回值3.写时拷贝4.fork之后,父子进程代码共享5.fork常规用法6.fork调用失败的原因 2.进程终止0.进程终止时,操作系统做了什么?1.进程退出场景2.进程常见退出方法4 _exit函数(系统接口)4.exit函数(库…

html 引入vue Element ui 的方式

第一种&#xff1a;使用CDN的方式引入 <!--引入 element-ui 的样式&#xff0c;--> <link rel"stylesheet" href"https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <!-- 必须先引入vue&#xff0c; 后使用element-ui --> <…

【单片机毕业设计8-基于stm32c8t6的RFID校园门禁系统】

【单片机毕业设计8-基于stm32c8t6的RFID校园门禁系统】 前言一、功能介绍二、硬件部分三、软件部分总结 前言 &#x1f525;这里是小殷学长&#xff0c;单片机毕业设计篇8基于stm32的RFID校园门禁系统 &#x1f9ff;创作不易&#xff0c;拒绝白嫖可私 一、功能介绍 -----------…

银行司库系统应用架构介绍

继国务院国资委印发了《关于推动中央企业加快司库体系建设进一步加强资金管理的意见》以及《关于中央企业加快建设世界一流财务管理体系的指导意见》&#xff0c;司库体系建设开始得到了更多重视。其中&#xff0c;作为改革风向标&#xff0c;央企数字化转型及司库建设对整个行…

Django Rest Framework的序列化和反序列化

DRF的序列化和反序列化 目录 DRF的序列化和反序列化Django传统序列化Django传统反序列化安装DRF序列化器serializers序列化反序列化反序列化保存instance和data CBV和APIView执行流程源码解析CBV源码分析APIView源码分析 DRF的Request解析魔法方法__getattr__ 什么是序列化&…

抽象工厂模式:深入探索面向对象设计的多样性

在软件开发中&#xff0c;正确地应用设计模式对于构建可扩展、可维护和高效的系统至关重要。抽象工厂模式作为创建型设计模式之一&#xff0c;提供了一个高层接口&#xff0c;用于创建一系列相关或依赖对象&#xff0c;而无需指定它们具体的类。本文将详细介绍抽象工厂模式的概…

数学建模-最优包衣厚度终点判别法-三(Bayes判别分析法和梯度下降算法)

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是viperrrrrrr~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff…

Linux内核之自旋锁:自旋锁初始化之spin_lock_init用法实例(四十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

数字IC/FPGA——锁存器/触发器/寄存器

本文主要介绍以下几点&#xff1a; 什么是触发器和锁存器门电路和触发器的区别什么是电平钟控触发器电平钟控触发器触发器和锁存器的区别触发器的分类方式&#xff1a;逻辑功能、触发方式、电路结构、存储数据原理、构成触发器的基本器件寄存器利用移位寄存器实现串并转换或并…

Android Studio 使用Flutter开发第一个Web页面(进行中)

附上Flutter官方文档 1、新建Flutter项目&#xff08;需要勾选web选项&#xff09; 新建项目构成为&#xff1a; 2、配置 Flutter 使用 path 策略 官方文档 在main.dart中&#xff0c;需要导入flutter_web_plugins/url_strategy.dart包&#xff0c;并在main(){}函数中usePath…