当前位置: 首页 > news >正文

STM32-USART串口实现接收数据三种方法(1.根据\r\n标志符、2.空闲帧中断、3.根据定时器辅助接收)

本章概述思维导图:

USART串口初始化配置

串口初始化配置在(STM32-USART串口初始化章节有详细教程配置),本章不做讲解直接代码示例,本章重点在于串口实现接收数据三种方法;

配置USART1串口接收初始化函数步骤:

1. 开时钟

2. 对串口1模块开启复位时钟,在取消复位;

3. 配置GPIO模式

4. 通过在USART_CR1寄存器上置位UE位来激活USART

5. 编程USART_CR1的M位来定义字长。

6. 在USART_CR2中编程停止位的位数。

7. 利用USART_BRR寄存器选择要求的波特率。

8. 设置USART_CR1中的TE位,发送一个空闲帧作为第一次数据发送。

9. 设置USART_CR1的RE位。激活接收器,使它开始寻找起始位。

10. 设置USART_CR1的IDLEIE位。当USART_SR中的IDLE为’1’时,产生USART中断

11.设置USART_CR1的RXNEIE位。当USART_SR中的ORE或者RXNE为’1’产生USART中断。

12. 调用中断设置优先级函数;

代码示例:

/*USART1串口初始化函数形参bps——>保持通信的波特率PA10设置为输入模式,PA9设置为复用输出模式;
*/
void USART1_Init(u32 bps)
{
//  1. 开时钟RCC->APB2ENR|=1<<2;//开启PA时钟;RCC->APB2ENR|=1<<14;//开启USART1时钟
//  2. 对串口1模块开启复位时钟,在取消复位;RCC->APB2RSTR|=1<<14;//开启USART1复位时钟,复位这一步可以省略配置USART1步骤RCC->APB2RSTR&=~(1<<14);//取消复位时钟,关闭复位
//  3. 配置GPIO模式GPIOA->CRH&=0xfffff00f;//清空PA10、PA9引脚模式GPIOA->CRH|=0x000008b0;//PA10输入PA9输出
//  4.通过在USART_CR1寄存器上置位UE位来激活USARTUSART1->CR1|=1<<13;
//  5.编程USART_CR1的M位来定义字长。USART1->CR1&=~(1<<12);
//  6.在USART_CR2中编程停止位的位数。USART1->CR2&=~(0x3<<12);
//  7.利用USART_BRR寄存器选择要求的波特率。USART1->BRR=72000000/bps;
//  8.设置USART_CR1中的TE位,发送一个空闲帧作为第一次数据发送。USART1->CR1|=1<<3;
//  9.设置USART_CR1的RE位。激活接收器,使它开始寻找起始位。USART1->CR1|=1<<2;
//  10.设置USART_CR1的IDLEIE位。当USART_SR中的IDLE为’1’时,产生USART中断USART1->CR1|=1<<4;
//  11.设置USART_CR1的RXNEIE位。当USART_SR中的ORE或者RXNE为’1’产生USART中断。USART1->CR1|=1<<5;
//  12.调用中断优先级函数STM32_SetNVICPriority(USART1_IRQn ,1,1);
}

USART串口中断服务函数

/*串口1中断服务函数
*/
void USART1_IRQHandler()
{u8 c;if(USART1->SR&1<<5)//判断是否为:接收中断;每接收一个字符就会触发一次中断{c=USART1->DR;//将数据赋值给cUSART1->DR=c;//将数据发生给上位机软件,使得显示界面上显示。}
}

USART1串口1接收实现三种方法

判断串口数据发送完一次数据有三种方法:

1. 是发送数据时以(\r\n)标志为结尾,检测到(\n)时就知道数据完成一次发送

2. 串口初始化函数中开启空闲帧中断

3,定时器辅助串口接收,判断串口1发送一字节和下一字节的间隔时间。超过定时器 初始设定的时间说明字符串数据发送完成

方法1:这里判断一次数据发送完成时根据(\r\n结束标志符)

代码示例:

u8 USART1_buffer[1024];//缓冲区数组,用来接收数据
u16 USART1_cnt=0;//缓冲区数组下标
u8 USART1_flag=0;//联合主函数标志位
/*USART1串口1中断服务函数
*/
void USART1_IRQHandler(void)
{u8 dat;if(USART1->SR&1<<7)//没接收到一个字符触发标志位{dat=USART1->DR;//读取数据if(USART1_cnt<1024){USART1_buffer[USART1_cnt]=dat;//将读取的数据放入到缓冲区数组里if(USART1_buffer[USART1_cnt] == '\n')//判断是否到结束标注位"\r\n"{USART1_buffer[USART1_cnt-1]='\0';//将'\r'写入'\0'结束USART1_flag=1;//数据接收完成}else{USART1_cnt++;}}else{USART1_buffer[USART1_cnt-1]='\0';USART1_cnt=0;}}
}

代码讲解:

创建缓冲区数组用来接收字符,只要字符不为:' \n ';就一直接收;当字符为:' \n '时;将' \r'位置写入' \0 '表示接收完成,同时将标志位置1,联合主函数使用;

主函数代码示例:


#include "USART1.h"
#include "stdio.h"
int main()
{USART1_Init(115200);//USART1串口1初始化函数while(1){if(USART1_flag){printf("buffer=%s\tcnt=%d\n",USART1_buffer,USART1_cnt);USART1_cnt=0;//下标清零USART1_flag=0;//标志位置0;}}
}

代码运行结果图:

数据发送图:

数据成功接收图:

方法2:开启空闲帧中断

在串口初始化函数中配置USART1_CR1的IDLEIE:IDLE中断使能位

中断服务函数配置示例代码:

/*USART1串口1中断服务函数
*/
void USART1_IRQHandler(void)
{u8 dat;if(USART1->SR&1<<5)//每接收到一个字符触发标志位{dat=USART1->DR;//读取数据if(USART1_cnt<1024){USART1_buffer[USART1_cnt]=dat;//将读取的数据放入到缓冲区数组里USART1_cnt++;}else{USART1_cnt=0;} }if(USART1->SR&1<<4)//空闲帧标志,这是全部发送完触发一次{dat=USART1->DR;USART1_flag=1;//数据接收完成}USART1->SR=0;
}

主函数示例代码:

#include "USART1.h"
#include "stdio.h"
int main()
{USART1_Init(115200);//USART1串口1初始化函数while(1){if(USART1_flag){USART1_buffer[USART1_cnt]='\0';//写入结束标志符printf("buffer=%s\tcnt=%d\n",USART1_buffer,USART1_cnt);USART1_cnt=0;//下标清零USART1_flag=0;//标志位置0;}}
}

代码运行结果图:

数据发送图:

数据成功接收图:

方法3:定时器辅助串口接收

定时器辅助串口接收,判断串口1发送一字节和下一字节的间隔时间。超过定时器 初始设定的时间说明字符串数据发送完成

配置步骤:

第一步:算出发送一个字节数据要多少时间:

1m=1000ms=1000000us;

1000000/(115200/10)=86.80555555us;发送一字节数据需要86.8055微秒;

判断第一个字节数据和第二字节数据的间隔时间有没有超过10ms

第二步:在串口1初始化函数中关闭空闲帧中断并且串口中断服务函数里关闭空闲帧中断; 在定时器2初始化函数里关闭使能计数器,并且关闭定时器。设定定时时间10毫 秒

第三步:在串口第一次接收一字节数数时,在串口1中断服务函数里清空计数器并且开启定 时器。

第四步:如果数据全部返送完成,在定时器2中断服务函数里将标志位置一并且关闭定时器 等待下一次数据发送玩出触发定时器2中断

第三步示例代码:

/*USART1串口1中断服务函数
*/
void USART1_IRQHandler(void)
{u8 dat;if(USART1->SR&1<<5)//每接收到一个字符触发标志位{dat=USART1->DR;//读取数据if(USART1_cnt<1024){TIM2->CNT=0;//清空计数器TIM2->CR1|=1<<0;//开启定时器USART1_buffer[USART1_cnt]=dat;//将读取的数据放入到缓冲区数组里USART1_cnt++;}else{USART1_flag=1;} }USART1->SR=0;
}

第四步示例代码:

/*定时器2中断服务函数
*/
void  TIM2_IRQHandler(void)
{if(TIM2->SR&1<<0){USART1_flag=1;//定时时间到标志位置1TIM2->SR&=~(1<<0);TIM2->CR1&=~(1<<0);//关闭定时器}
}

主函数示例代码:


#include "USART1.h"
#include "stdio.h"
#include "TIM.h"
int main()
{USART1_Init(115200);//USART1串口1初始化函数TIM2_Init(7200,10000);//定时器2设置定时时间为10毫秒while(1){if(USART1_flag){USART1_buffer[USART1_cnt]='\0';//给缓冲区数组写入结束标识符;printf("buffer=%s cnt=%d\n",USART1_buffer,USART1_cnt);USART1_cnt=0;//下标清零USART1_flag=0;//标志位置0;}}
}

代码运行结果图:

数据发送图:

数据成功接收图:


制作不易!喜欢的小伙伴给个小赞赞!喜欢我的小伙伴点个关注!有不懂的地方和需要的资源随时问我哟!

http://www.xdnf.cn/news/1197145.html

相关文章:

  • 将远程 main 分支同步到 develop 分支的完整指南
  • 深入理解指针(三)
  • 用 Flask 打造宠物店线上平台:从 0 到 1 的全栈开发实践
  • 2024-2025华为ICT大赛中国区 实践赛网络赛道(高教组)全国总决赛 理论部分真题+解析
  • KNN算法实现图片的识别
  • 实战演练1:实战演练之命名实体识别
  • JavaScript数组去重性能优化:Set与Object哈希表为何效率最高
  • 俄罗斯方块游戏开发(面向对象编程)
  • 通过v4l2,采集视频,FFmpeg编码压缩封装视频(三)
  • Python-初学openCV——图像预处理(三)
  • 01人工智能中优雅草商业实战项目视频字幕翻译以及声音转译之底层处理逻辑阐述-卓伊凡|莉莉
  • Python 数据分析(四):Pandas 进阶
  • macOS配置 GO语言环境
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博舆情分析实现
  • Linux 系统网络配置及 IP 地址相关知识汇总
  • 八股文Kafka学习
  • 哈希表应用(map,set共同作用)
  • 基于 KNN 算法的手写数字识别项目实践
  • DAY21-二叉树的遍历方式
  • vuhub jangow-01-1.0.1靶场攻略
  • 简易 BMI 身体质量指数计算器
  • C++算法竞赛篇(六)一维数组题型讲解
  • 用哈希表封装Myunordered_map和Myunordered_set
  • mac neo4j install verifcation
  • mac配置多版本jdk
  • Python 列表推导式与生成器表达式
  • 【成功经验分享】Github Education (Github学生认证)认证
  • 数据江湖的“三国演义”:数据仓库、数据湖与湖仓一体的全景对比
  • RAG vs 微调
  • 使用uni-app开发一个点餐收银台系统前端静态项目练习