gd32F303串口接收的几种方式

一、串口接受到换行符停止

#include "usart.h"UCHAR arr_rxData[1024]={0};//存储串口接收的数据
UINT arr_len=0;//串口已经接收数据的字节数个数
USART_RX_FLAG rxFlg=FLASE;//默认串口未接收到数据void USART2_Init(void)
{rcu_periph_clock_enable(RCU_GPIOB); //enable GPIO clock rcu_periph_clock_enable(RCU_USART2);// enable USART clockgpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10); // USARTx_Tx gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);//USARTx_Rxusart_deinit(USART2); //USART configure usart_baudrate_set(USART2, 115200);                //设置波特率usart_word_length_set(USART2, USART_WL_8BIT);      //设置数据位usart_parity_config(Uusart_hardware_flow_rts_config(USART2, USART_RTS_DISABLE); usart_hardware_flow_cts_config(USART2, USART_CTS_DISABLE); //无硬件数据流控制usart_receive_config(USART2, USART_RECEIVE_ENABLE);        //使能接收器usart_transmit_config(USART2, USART_TRANSMIT_ENABLE);      //使能发送器nvic_irq_enable(USART2_IRQn, 1, 0);//配置NVIC分组,初始化NVIC分组4usart_interrupt_enable(USART2, USART_INT_RBNE);//使能接收中断usart_enable(USART2);//使能串口
}int fputc(int ch, FILE *f) 
{while(RESET == usart_flag_get(USART2, USART_FLAG_TBE));usart_data_transmit(USART2, (uint8_t)ch);return ch;
}/****************************************************************************
1、如果使能接收中断但是还是没有进入中断处理函数,可能是硬件接线比较松,导致出现问题
2、接收数据代码书写if(rxFlg==TRUE)//表示接受一次数据完成{printf("receive data:%s\r\n",arr_rxData);//将接收数据的标志位,数据长度,存储数据数组都清0rxFlg=FLASE;arr_len=0;memset(arr_rxData,0,sizeof(arr_rxData));}
******************************************************************************/
void USART2_IRQHandler(void) 
{if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_RBNE)){arr_rxData[arr_len++]=usart_data_receive(USART2);if(arr_rxData[arr_len-1]==0x0a){rxFlg=TRUE;arr_len--;arr_rxData[arr_len]='\0';}}//usart_interrupt_flag_clear(USART2, USART_INT_FLAG_RBNE);/*清除中断标志位,不用手动清除中断标志位,因为不管是直接读寄存器还是通过DMA,只要是对USART_DATA寄存器的一个读操作都可以硬件自动清除RBNE位*/
}

 

二、使用空闲中断实现串口接收 

    对于串口接收到的数据,还有很重要的一点就是不确定长度,这样就不知道何时该停止接收,这个时候,串口的空闲中断就体现出他的重要性了,那么什么是空闲中断呢?

        空闲中断是在检测到有数据接收后,总线上在一个字节的时间内没有再接收到数据时,从而产生中断。即串口的RXNE位被置位之后才开始检测,检测到空闲之后,串口的CR1寄存器的IDLE位被硬件置1。

#include "usart.h"UCHAR arr_rxData[1024]={0};//存储串口接收的数据
UINT arr_len=0;//串口已经接收数据的字节数个数
USART_RX_FLAG rxFlg=FLASE;//默认串口未接收到数据void USART2_Init(void)
{rcu_periph_clock_enable(RCU_GPIOB); //enable GPIO clock rcu_periph_clock_enable(RCU_USART2);// enable USART clockgpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10); // USARTx_Tx gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);//USARTx_Rxusart_deinit(USART2); //USART configure usart_baudrate_set(USART2, 115200);                //设置波特率usart_word_length_set(USART2, USART_WL_8BIT);      //设置数据位usart_parity_config(Uusart_hardware_flow_rts_config(USART2, USART_RTS_DISABLE); usart_hardware_flow_cts_config(USART2, USART_CTS_DISABLE); //无硬件数据流控制usart_receive_config(USART2, USART_RECEIVE_ENABLE);        //使能接收器usart_transmit_config(USART2, USART_TRANSMIT_ENABLE);      //使能发送器nvic_irq_enable(USART2_IRQn, 1, 0);//配置NVIC分组,初始化NVIC分组4usart_interrupt_enable(USART2, USART_INT_RBNE);//使能接收中断usart_enable(USART2);//使能串口
}int fputc(int ch, FILE *f) 
{while(RESET == usart_flag_get(USART2, USART_FLAG_TBE));usart_data_transmit(USART2, (uint8_t)ch);return ch;
}void USART2_IRQHandler(void) 
{if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_RBNE)){arr_rxData[arr_len++]=usart_data_receive(USART2);}if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_IDLE)){usart_interrupt_flag_clear(USART2,USART_INT_FLAG_IDLE);	/* 清除空闲中断标志位 */usart_data_receive(USART2);		rxFlg=TRUE;arr_len--;arr_rxData[arr_len]='\0';}
}

三、使用DMA转运数据实现串口接收 

 对于串口的数据接收来说,和发送一样,如果采用传统的接收中断模式接收数据,同样的会因为频繁中断而导致消耗大量CPU资源,所以也使用DMA进行串口数据的接收。

#define USART2_ADDR (uint32_t)&USART_DATA(USART2)
UCHAR UART2_RX_BUF[UART2_RX_LEN*2]; 		/* 双接收缓冲区 */
USART_RX_FLAG UART2_RX_STAT = FLASE;	
UINT UART2_RX_NUM = 0;					/* 接收到的数据个数 */void USART2_DMA_Init(void)
{dma_parameter_struct dma_init_struct;	/* DMA配置参数结构体 */rcu_periph_clock_enable(RCU_GPIOB); //enable GPIO clock rcu_periph_clock_enable(RCU_USART2);// enable USART clockrcu_periph_clock_enable(RCU_DMA0);		/* 使能 DMA0 时钟 */gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10); gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);usart_deinit(USART2); //USART configure usart_baudrate_set(USART2, 115200);                //设置波特率usart_word_length_set(USART2, USART_WL_8BIT);      //设置数据位usart_parity_config(USART2, USART_PM_NONE);        //设置奇偶校验位usart_stop_bit_set(USART2, USART_STB_1BIT);        //设置停止位usart_hardware_flow_rts_config(USART2, USART_RTS_DISABLE); //禁用rtsusart_hardware_flow_cts_config(USART2, USART_CTS_DISABLE); //无硬件数据流控制usart_receive_config(USART2, USART_RECEIVE_ENABLE);        //使能接收器usart_transmit_config(USART2, USART_TRANSMIT_ENABLE);      //使能发送器/* USART0 DMA 接收配置*/dma_deinit(DMA0, DMA_CH2);/*USART2_RX:CH2 USART0_RX:CH4*/dma_struct_para_init(&dma_init_struct);dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;		/* 外设到存储器方向 */dma_init_struct.memory_addr = (uint32_t)UART2_RX_BUF;		/* 存储器基地址 */dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;	/* 存储器地址自增 */dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;		/* 存储器位宽为8位 */dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;			/* 软件优先级为极高*/dma_init(DMA0, DMA_CH2, &dma_init_struct);dma_circulation_disable(DMA0, DMA_CH2);/* DMA循环模式配置,不使用循环模式 */usart_dma_transmit_config(USART2, USART_DENT_ENABLE);usart_dma_receive_config(USART2, USART_DENR_ENABLE);nvic_irq_enable(DMA0_Channel2_IRQn, 0, 0);/* DMA0 通道2 中断优先级设置并使能 */dma_channel_enable(DMA0, DMA_CH2);/* 使能 DMA0 通道2 */nvic_irq_enable(USART2_IRQn, 1, 0);//配置NVIC分组,初始化NVIC分组4usart_interrupt_enable(USART2, USART_INT_IDLE);/* 使能USART0空闲中断 */usart_enable(USART2);//使能串口
}/*
如果接收完毕,那么将数据打印出来
if(UART2_RX_STAT == TRUE)
{UART2_RX_STAT = FLASE;printf("RECEIVE %d data:%s \r\n", UART2_RX_NUM, UART2_RX_BUF);
}
*/
void USART2_IRQHandler(void)	
{if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_IDLE)) //空闲中断{usart_interrupt_flag_clear(USART2,USART_INT_FLAG_IDLE);	/* 清除空闲中断标志位 */usart_data_receive(USART2);								/* 清除接收完成标志位 */dma_channel_disable(DMA0, DMA_CH2);						/* 关闭DMA传输 */UART2_RX_NUM = sizeof(UART2_RX_BUF) - dma_transfer_number_get(DMA0,DMA_CH2);UART2_RX_BUF[UART2_RX_NUM] = '\0';	/* 添加字符串结束符 */UART2_RX_STAT = TRUE;/* 接收完成 */				/* 重新设置DMA传输 */dma_memory_address_config(DMA0,DMA_CH2,(uint32_t)UART2_RX_BUF);dma_transfer_number_config(DMA0,DMA_CH2,sizeof(UART2_RX_BUF));dma_channel_enable(DMA0, DMA_CH2);		/* 开启DMA传输 */}
}

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

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

相关文章

Google为什么它还没有开发出ChatGPT,如何反超,小公司创新的产品如何反超巨头 行业巨头如何防止被小公司或创新型公司的产品超越

Google虽然收购了Geoffrey Hinton及其在多伦多大学的两名研究生组成的公司DNNresearch Inc.,但为什么它还没有开发出类似ChatGPT的产品,可能有以下几个原因: 不同的研发方向:Google在人工智能领域的研发方向可能与OpenAI&#xff…

大创项目推荐 深度学习 opencv python 公式识别(图像识别 机器视觉)

文章目录 0 前言1 课题说明2 效果展示3 具体实现4 关键代码实现5 算法综合效果6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 基于深度学习的数学公式识别算法实现 该项目较为新颖,适合作为竞赛课题方向,学…

基于Spring Boot+Vue.js的停车场收费管理系统 需求分析

1 用户(收费员) 1.1 主页 1.1.1 摄像头实时捕捉画面,如果有车牌号则识别出车牌(如:京A11111),通过车牌底色识别出小型车(蓝色)、大型车(黄色)。…

java面试题-Redis缓存穿透、雪崩、击穿

远离八股文,面试大白话,通俗且易懂 看完后试着用自己的话复述出来。有问题请指出,有需要帮助理解的或者遇到的真实面试题不知道怎么总结的也请评论中写出来,大家一起解决。 java面试题汇总-目录-持续更新中 这个问的挺多的&#x…

《对话品牌》——科技与时尚的融合

本期节目《对话品牌》栏目组邀请到了江西先禾服饰有限公司董事长吁火兰女士参加栏目录制,分享其企业故事,树立品牌形象,提升品牌价值! 节目嘉宾:吁火兰 节目主持人:杨楠 节目播出平台:中央新…

【已解决】java 无法将类 XX类中的构造器 X应用到给定类型

原因: 实际参数列表和形式参数列表长度不同 解决方法: 给类添加AllArgsConstructor注解即可。

Xcode编写基于C++的动态连接库(dylib)且用node-ffi-napi测试

创建一个dylib工程示例 在 Xcode 中创建一个动态链接库(.dylib 文件)的步骤如下: 打开 Xcode: 打开 Xcode 应用程序。 创建新的工程: 选择 "Create a new Xcode project",或者使用菜单 File &g…

MagicAnimate:Temporally consistent human image animation using diffusion model

1.Introduction 本文研究了任务形象动画人物,旨在根据特定的运动序列生成一个具有特定参考身份的视频。现有的人物图像动画的数据驱动方法可以基于所使用的生成主干模型分为两类,1.基于GAN,通常使用变形函数将参考图变形为目标姿态&#xff0…

JVM虚拟机系统性学习-JVM调优之通过gceasy分析GC日志对堆、元空间、线程堆栈和垃圾回收器进行调优

通过 gceasy工具对生成的 GC 日志进行分析 这里使用的 JDK 版本为 JDK8! 在分析 GC 日志时,可以同时采用多种工具(Arthas、gceasy、JVM 连接 Graphana 监控)进行分析,避免某种工具分析不准确 gceasy 每个月只可以免费…

广州旅游攻略(略说一二)

广州是中国南方的一个重要城市,也是广东省的省会,拥有着悠久的历史和丰富的文化遗产。作为中国最繁华的城市之一,广州吸引了大量的游客前来探索其独特的魅力。今天我将为大家介绍一份广州旅游攻略,希望能帮助各位游客更好地了解这…

实验六 指针程序设计 要求设三个指针变量p1,p2,p3, 使p1指向三个数中最大者,p2指向次大者,p3指向最小者

1. 从键盘输入任意三个数,要求设三个指针变量p1,p2,p3, 使p1指向三个数中最大者,p2指向次大者,p3指向最小者, 然后从大到小输出三个数。 运行时分别输入3,7,5和6,-4,2&a…

华为实训课笔记

华为实训 12/1312/14 12/13 ping 基于ICMP协议&#xff0c;用来进行可达性测试 ping 目的IP地址/设备域名&#xff08;主机名&#xff09; 如果能收到 reply 回复&#xff0c;则表示双方可以正常通信 <Huawei> 用户视图&#xff0c;只能做查询和一些简单的资源调用&…

【Android开发-30】Android中获取全局Context和使用Intent传递对象的讲解

1&#xff0c;获取全局Context的技巧 在Android编程中&#xff0c;Context对象常常扮演着重要的角色&#xff0c;例如在弹出Toast、启动活动、发送广播、操作数据库和使用通知等场景下都需要它的支持。然而&#xff0c;在某些情况下&#xff0c;直接获取Context对象并不那么容…

【C++】策略模式

目录 一、简介1. 含义2. 特点 二、实现1. 策略接口&#xff08;Strategy Interface&#xff09;2. 具体策略类&#xff08;Concrete Strategies&#xff09;3. 上下文类&#xff08;Context&#xff09;4. 使用策略模式 三、总结如果这篇文章对你有所帮助&#xff0c;渴望获得你…

使用qemu在arm上模拟x86并运行docker

背景 有一个x86的docker镜像&#xff0c;但是需要运行在aarch64(arm64)上&#xff0c;无奈只能用qemu模拟x86的架构&#xff0c;但是最终没有实现。 原因分析&#xff1a;可能是使用的server版本的ubuntu镜像&#xff0c;建议之后换用desktop版本的ubuntu18镜像&#xff08;猜…

mjpg-streamer配置其它端口访问视频

环境 树莓派4B ubuntu 20.04 U口摄像头 确认摄像头可访问 lsusb查看 在dev下可查看到video* sudo mplayer tv://可打开摄像头并访问到视频 下载mjpg-streamer并编译安装 在github下载zip包&#xff0c;下载的源码&#xff0c;需要编译安装 unzip解压 cd mjpg-streamer/mjp…

亚信科技AntDB数据库——深入了解AntDB-M元数据锁的相关概念

AntDB-M在架构上分为两层&#xff0c;服务层和存储引擎层。元数据的并发管理集中在服务层&#xff0c;数据的存储访问在存储引擎层。为了保证DDL操作与DML操作之间的一致性&#xff0c;引入了元数据锁&#xff08;MDL&#xff09;。 AntDB-M提供了丰富的元数据锁功能&#xff…

电脑重启代码hhh

备份 自动运行 模型 图表 无标题-查询 成绩表 liushaoje(1) -表 读者表liushaojie(1).表 借阅表liushaojie(1) -表 借阅表liushaojie 查询创建工具美化 SQL 代码段 liushaojie 运行停止解释 11、列出员工表中比1号部门的某一个员工…

java写个爬虫抓取汽车之家车型配置参数

前几天有个搞工程的表弟找我&#xff0c;问我什么车好&#xff0c;可以经常跑工地的&#xff0c;看上去又有面子。于是我挥动发财的小手&#xff0c;写一个爬虫程序&#xff0c;筛选并整理了一些数据&#xff0c;并附上下载的图片提供参考&#xff0c;看中了果断第二天提车到手…

SQL区间

SQL区间 1、区间概述2、SQL区间2.1、区间分割2.2、区间交叉3、SQL区间的应用3.1、区间分割问题3.2、区间交叉问题1、区间概述 区间相较数列具有不同的数据特征,不过在实际应用中,数列与区间的处理具有较多相通性。常见的区间操作有区间分割、区间交叉等 SQL如何实现区间分割…