IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 关于单片机串口通信只能读取上位机传输的第一个字节 -> 正文阅读

[嵌入式]关于单片机串口通信只能读取上位机传输的第一个字节

一.问题提出

最近在学习STM32串口通信的时候,对照正点原子的代码,自己写了一个简易的串口通信的协议来练练手,代码长这样:

主程序

#include "HeadFile.h"
int main(void)
{		

	HardwareInit();
	while(1)
	{
		if(USART1_state==2)
		{
			u8 i;
			printf("get: ");
			for(i=0;i<counter;i++)
			{
				printf("%c",USART_RX_BUF[i]);
			}
			printf("\n");
			counter=0;
			USART1_state=0;
		}
	}
}

串口配置(正点原子的代码,没有改动)

void ConfigureUART1(u32 bound)
{
	
//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟

	//USART1_TX   GPIOA.9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);			//初始化GPIOA.9

	//USART1_RX	  GPIOA.10初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;			  //PA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);				  //初始化GPIOA.10

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		  //子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			  //IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);							  //根据指定的参数初始化VIC寄存器

	//USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;										//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;						//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;							//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;								//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;					//收发模式

	USART_Init(USART1, &USART_InitStructure);	   //初始化串口1
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启串口接受中断
	USART_Cmd(USART1, ENABLE);					   //使能串口1
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
}

串口中断函数

void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	u8 Res;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断
	{
		printf("Interrupt entered\n\n");
		Res =USART_ReceiveData(USART1);	//读取接收到的数据
		if(Res==0xAA)
		{
			USART1_state=1;
			printf("STATE1 ENTERED\n\n");
		}
		else
		{
			if(USART1_state==1&&Res!=0xFC)
			{
				USART_RX_BUF[counter++]=Res;
				printf("READING char:%c\n",Res);
			}
			if(Res==0xFC)
			{
				USART1_state=2;
				printf("STATE2 ENTERED\n\n");
			}
		}
	}
}

原因分析:

按照我的预期,这个简单的串口协议解析程序应该是这样工作的:

  • 电脑通过串口助手使用CH340连接单片机发送一串数据,比如: 0xAA 0xBB 0xCC 0xDD 0xFC
  • 单片机收到数据并处理,将处理过程通过串口打印出来
  • 如果解析成功,会向上位机把数据串echo出来

然而,它是这样工作的(发送的是0xAA 0xB5 0xC3 0xFC):
请添加图片描述
正常状态下,应该会返回:“get:得”

这意味着程序顺利的进入了串口中断,收到了帧头,却没有解析后面的数据,确切来说,根本没有进入else部分.程序只解析到了0xAA,其后的数据被丢失.

利用串口助手多字符串发送工具一个字符一个字符的发送数据,每个字符之间间隔1ms,如下图:请添加图片描述
发现程序正常,解析成功.请添加图片描述
请添加图片描述
思考人生…看来不是协议本身的问题…

查阅了资料,有建议说串口中断接收并存储数据之后就不要干其他事情,否则中断函数耗时过多,容易使数据丢失,导致解析失败.意识到debug用的printf会占用大量的处理时间,可能是导致程序只能读取识别帧头的原因.
将所有串口中断内printf删掉,编译烧录,发送数据,解析成功…


解决方案:

串口中断里,不要加入任何数据解析之外的逻辑
比如:延时,串行输出,浮点数计算…如果硬是要debug,建议用keil或者在中断里点个不同颜色的灯表示运行状态
另外,用printf函数debug是一个坏习惯…今天我又给我这个喜欢在代码里面加一堆printf来debug的人上了一课.

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-23 16:51:02  更:2021-08-23 16:51:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:18:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码