基于stm32的HAL库的串口实现不定长数据收发(三)(接收中断)

news2024/11/26 11:43:58

串口实现不定长数据收发(接收中断)


1头文件

#include "uart1.h"
#include "string.h"
#include "stdio.h"
#include "sys.h"

#define UART1_RX_BUF_SIZE 128  //接收
#define UART1_TX_BUF_SIZE 64	 //发送 发送可以小一些看使用的场景

//宏定义错误代码

#define UART_EOK       0 
#define UART_ERROR     1
#define UART_ETIMEOUT  2 //数据超时
#define UART_EINVAL    3 //非法字符
void uart1_init(uint32_t baudrate);
void uart1_receiv_test(void);


//接收来的数据保存到数组里面

uint8_t uart1_rx_buf[UART1_RX_BUF_SIZE];
uint16_t uart1_rx_len = 0;//数组长度
uint16_t uart1_cnt    = 0,uart1_cntPre = 0;//会正常一些 需要判断计数器有无变化

2初始化函数

UART_HandleTypeDef uart1_handle = {0};
//初始化
void uart1_init(uint32_t baudrate)
{
        
        uart1_handle.Instance = USART1;                  //选择通用异步收发器
        uart1_handle.Init.BaudRate =  baudrate;          //波特率
        uart1_handle.Init.WordLength= UART_WORDLENGTH_8B;//字长参数列表用的8位
        uart1_handle.Init.StopBits  = UART_STOPBITS_1;   //停止位的数量
        uart1_handle.Init.Parity    = UART_PARITY_NONE   //奇偶校验,不准确一般不用,故不设置
        uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;//流控制?
        uart1_handle.Init.Mode      = UART_MODE_TX_RX;    //我们的需要时既要收又要发
        HAL_UART_Init(&uart1_handle);

}

3msp公用的一个函数这里有三个串口,都会调用msp先进行一个判断

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
   判断是否为USART1
    if(huart->Instance == USART1)
    {
    //使能USART1,GPIO时钟
    __HAL_RCC_USART1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef gpio_initstruct;
    //配置TX
    gpio_initstruct.Pin  = GPIO_PIN_9;//数据手册
    gpio_initstruct.Mode = GPIO_MODE_AF_PP;//数据手册要求
    gpio_initstruct.Pull = GPIO_PULLUP;//随意
    gpio_initstruct.Speed= GPIO_SPEED_FREQ_HIGH;//随意
    HAL_GPIO_Init(GPIOA,&gpio_initstruct);
    
    //配置RX
    gpio_initstruct.Pin  = GPIO_PIN_10;
    gpio_initstruct.Mode = GPIO_MODE_AF_INPUT;//复用推完输入和输入模式一样

    //NVIC
    HAL_NVIC_EnableIRQ(USART1_IRQn);      //使能NVIC中断
    HAL_NVIC_SetPriority(USART1_IRQn,2,2);//设置中断优先级
    //确定RXNE被置为1 __HAL_UART_ENABLE_IT()

    __HAL_UART_ENABLE_IT(huart,UART_IT_RXNE);
    
}
}


4中断服务函数--数据收发

void UASRT1_IRQHandler(void)
{
    uint8_t receive data = 0;
    //判断什么时候数据的收发 如何判断是否收到数据  看RXNE  RDR接收数据寄存器内不为空 就会触发一个        
    //中断就可以进行一个操作
	//判断是否为RXNE触发的中断
    if(__HAL_UART_GET_FLAG(&uart1_handle,UART_FLAG_RXNE) != RESER)//被置1不为RESET
    {
    		//需要判断数组是否接收完,防止缓冲区被刷爆
            if(uart1_cnt >= sizeof(uart1_rx_buf))
            uart1_cnt = 0;
            //进行接收
		    //接收的位置,接收的数据,接受的长度,超时时间
            HAL_UART_Receive(&uart1_handle,&receive_data,1,1,1000);
            //接收到的数据保存到数组中
            uart1_rx_buf[uart1_cnt++] = receive_data;
            
}
}

5重定向到串口1中SR ? DR? ch  将fputc 定向到printf中

int fputc(int ch,FILE *f)??
{
    while((USART1->SR & 0x40) == 0);//一直卡住  判断是否为1
    
    USART1->DR = (uint8_t)ch;//将dr的值赋到ch中,要勾选魔术棒中的Micro
    return ch;   
}

6需要判断数组是否接收完

uint8_t uart1_wait_receive(void)
{
    if(uart1_cnt == 0)
    return UART_ERROR;
    if(uart_cnt == uart1_cntPre)//数据接收完毕 计数器无变化
    return UART_EOK;
    
    //以上条件都不满足
    uart1_cntPre = uart1_cnt;
    return UART_ERROR;
    
}

7将BUF清空以便于下一次的接收,如果上一次的数据在里面会造成不必要的问题

void uart1_rx_clear(void)
{
    //对接收寄存器进行清空
    memset(&uart1_rx_buf,0,sizeof(uart1_rx_buf));
    uart1_rx_len = 0;
}

8测试函数

void uart1_receiv_test(void)
{
    //在while中一直调用该函数
	//数据接收完整就打印出来
	//重定向fputc
    if(uart1_wait_receive() == UART_EOK)
    {
    printf("recv: %s\r\n", uart1_rx_buf);
    uart1_rx_clear();    
}
}

9 main函数

int main(void)
{
    HAL_Init();                     /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9);/* 设置时钟, 72Mhz */
    uart1_init(115200);            /* LED初始化 */
    
    while(1)
    {
    uart1_receiv_test();

    delay_ms(10)
}
}

10 运行结果

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

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

相关文章

量化选股:原理与实战指南(一)

🌟作者简介:热爱数据分析,学习Python、Stata、SPSS等统计语言的小高同学~🍊个人主页:小高要坚强的博客🍓当前专栏:《Python之量化交易》🍎本文内容:量化选股:原理与实战指南(一)🌸作者“三要”格言:要坚强、要努力、要学习 目录 引言 一、量化选股的基本概…

docker入门(二)之容器命令及私有仓库的部署(本地和harbor)

容器命令: 1.启动容器 接下来演示在docker下运行一个ubuntu系统,从中学习各容器命令。 --name"容器新名字" 为容器指定一个名称(不指定的话会随机分配一个名字)。 -d: 后台运行容器并返回容器ID,也就启动守护式容器(后台运行) -…

【Golang】关于Go语言中的定时器原理与实战应用

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

【计算机网络 - 基础问题】每日 3 题(三十八)

✍个人博客:https://blog.csdn.net/Newin2020?typeblog 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞…

ROS2 “通信方式” 参数服务器

为什么加“通信方式”引号,因为我觉得他就不算通信,最多最多就是一个动态加载参数方式 所以ros通信方式就三种,topic service action 别犟,犟就是你对! 常用的 param参数方法如下: # declare_parameter…

基于Java的旅游网站管理系统—计算机毕业设计源码39235

摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对旅游网站等问题,对旅游网站进行…

项目计划书,项目经理日常文档,项目管理计划,项目总体实施计划,总体测试计划,总体运维计划,总体开发计划(word原件获取)

项目开发计划包括项目描述、项目组织、成本预算、人力资源估算、设备资源计划、沟通计划、采购计划、风险计划、项目过程定义及项目的进度安排和里程碑、质量计划、数据管理计划、度量和分析计划、监控计划和培训计划等。 软件资料清单列表部分文档: 工作安排任务书…

Shuffle Net系列详解 (4) Shuffle Net V2实践部分讲解 for pytorch版本

Shuffle Net 系列 实践部分1.文件划分2.Block(差异文件)3.Network(差异文件)3.总结 实践部分 在看代码之前先叠加一个甲,本文并未跑出来这个实验结果。实验条件有限,论文中采用的ImageNet dataset 数据集有些太大了。后续会出一个简化版本的代码进行实践…

探索Spring Cloud Config:构建高可用的配置中心

目录 认识Spring Cloud ConfigConfig Server读取配置文件步骤1:(1)创建config-server项目(2)在config-server中开启Config Server功能(3)在config-server配置文件进行相关配置(4&…

深入理解 Transformer:构建先进 NLP 模型的关键技术

目录 一、Transformer 为何如此重要?二、Transformer 的核心组成部分1. 注意力机制2. 位置编码3. 前馈神经网络 三、Transformer 的训练方法1. 无监督预训练2. 有监督微调 四、Transformer 的应用场景五、总结与展望 在自然语言处理(NLP)的领…

【JAVA-数据结构】二叉树

这篇是二叉树相关内容。 1. 树型结构 1.1 概念 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。朝把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶下的。它具有以…

外卖点餐系统小程序的设计

管理员账户功能包括:系统首页,个人中心,外卖员管理,餐厅管理,用户管理,菜品分类管理,菜品信息管理,外卖订单管理,订单配送管理 微信端账号功能包括:系统首页…

Java项目实战II基于Java+Spring Boot+MySQL的智能物流管理系统 (源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着电子商…

人、机不同的学习机理

在人机协同的过程中,断点(或称为障碍点)是指可能导致人机合作效率下降、决策失误或任务失败的关键环节。以下是一些常见的断点及其影响:人类和机器之间的信息传递不畅,可能导致误解或遗漏关键信息,技术术语…

YOLO11改进|注意力机制篇|引入三重注意力机制Triplet Attention

目录 一、【Triplet Attention】注意力机制1.1【Triplet Attention】注意力介绍1.2【Triplet Attention】核心代码 二、添加【Triplet Attention】注意力机制2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【Triplet Attention】注意力机…

ARM嵌入式学习--第二天

-指令流水线 -基础知识 1.流水线技术通过多个功能部件并行工作来缩短程序执行时间,提高处理器的效率和吞吐率 2.增加流水线级数,可以简化流水线的各级逻辑,进一步提高了处理器的性能 3.以三级流水线分析: pc代表程序计数器&#x…

Graph Contrastive Learning 图对比学习GCL

Preamble GCL主要任务:学习一个编码器,可以编码出结构和结点特征信息,得到一个低维的表达 早期大部分GNN模型都是有监督的训练 自监督学习主要分成两种:生成式(用已有信息去预测自己的其他信息) and 对…

C++学习笔记----9、发现继承的技巧(一)---- 使用继承构建类(1)

在前面的章节中,你学到了继承关系是一种真实世界对象以层次存在的模式。在编程世界中,当需要写一个类基于其构建,或进行细微的修改的另一个类时,那种模式就有了关系。完成这个目标的一个方式是拷贝一个类的代码粘贴到另一个类中。…

一个月学会Java 第14天 内部类

Day14 内部类 类有外边的public class,然后还有一个文件多个的class,但是有没有想过,class可以作为成员也就是类内部的类,甚至作为方法内部的属性也就是类内部的方法的内部出现。除了这两个, 还有直接对着上节课讲的抽…

GeoScene Pro教程(008):GeoScenePro数据查询和检索

文章目录 1、工具分类2、数据常用工具2.1 加载数据2.2 查询需求2.2.1 按照属性查询查询1:人口大于300万的城市有哪些查询2:自治州有哪些查询3:城市名字中带有“荆”的有哪些补充2.2.2 按照位置查询需求2:导出湖北省境内的铁路数据需求3:武汉市共有多少条铁路2.2.3 空间连接…