STM32单片机芯片与内部45 UART 不定长度接收 标志位结束 定时器超时 串口空闲中断

目录

一、标志位结束法

1、实现原理

2、代码

3、优缺点

优点:

缺点:

总结:

二、串口空闲中断

1、中断读取

2、DMA接收

3、优缺点

优点:

缺点:

三、定时器空闲超时

1、实现原理

2、代码

3、优缺点

优点:

缺点:


        前文的发送已经很好的实现了发送一个数据,但是接收端仅介绍了每次接收一个字符,如果是双方通信,例如发送端以串口发送如下:

1,125,238,475,359

        其中1表示命令号;125表示传感器1的数据,238表示传感器2的数据,475表示传感器3的数据,359表示传感器4的数据。

2,19,45,37,28

        其中2表示命令号;19表示设定模块1数据,45表示设定模块2数据,37表示设定模块3数据,28表示设定模块4数据。

可以看到两个命令是不等长的(但是每一个相同命令号的应是等长的)

        不等长意味着不能接收到第一个字符进行计数,固定长度后停止。

一、标志位结束法

1、实现原理

        在数据尾部加入特殊字符,一般在工业界采用'\r''\n'来作为帧尾,也就是说串口收到数据后进行数组的存储,当连续收到\r\n,则表示该帧结束。

2、代码

void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	u8 Res;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
		Res =USART_ReceiveData(USART1);	//读取接收到的数据
		
		if((USART_RX_STA&0x8000)==0)//接收未完成
			{
			if(USART_RX_STA&0x4000)//接收到了0x0d
				{
				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
				}
			else //还没收到0X0D
				{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
					{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
					}		 
				}
			}   		 
     } 
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntExit();  											 
#endif
} 
#endif	

        在主函数判断即可实现。

		if(USART_RX_STA&0x8000)
		{					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			printf("\r\n您发送的消息为:\r\n\r\n");
			for(t=0;t<len;t++)
			{
				USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
			}
			USART_RX_STA=0; //一定要清除接收标志
		}

3、优缺点

优点:
  1. 易于解析

    • 固定的结束符:使用固定的字符如\r\n作为帧结束符,可以让接收端程序简单地检测到数据
485通信结合定时器实现4ms超时接收串口空闲中断同场景下各有其可靠性特点。 串口空闲中断STM32F103单片机中可处理通信中长时间无数据传输的情况,释放CPU资源以处理其他任务,适合半双工通信和高效率数据接收。空闲态中断会在串口接收线处于空闲状态一段时间时触发,接收端可基于空闲时间判断帧的结束。在数据传输速率相对稳定、帧间隔相对固定的场景下,串口空闲中断可靠性较高,能准确识别帧的结束,因为它直接依据串口的空闲状态来判定,只要空闲时间达到设定条件就触发中断,对数据帧的完整性判断较为直观。例如在一些工业自动化设备的通信中,数据按照一定的周期和格式进行传输,串口空闲中断可以很好地适应这种规律,准确地识别每帧数据的结束 [^1][^2]。 485通信结合定时器实现4ms超时接收是通过定时器来进行超时判断,若连续4ms未收到新数据,判定为一帧结束。在定时器中断中递减计数器,减至0时标记一帧接收完成。这种方式在数据传输速率稳定、存在干扰导致数据间隔波动较大的场景下具有一定优势。即使数据帧之间的空闲时间固定,只要在4ms内没有新数据到来就认为一帧结束,能在一定程度上避免因干扰等因素导致的误判。例如在一些复杂的电磁环境中,数据传输可能会受到干扰,导致帧间隔稳定,定时器超时接收可以更灵活地应对这种情况,保证数据接收的可靠性 [^3]。 过,485通信结合定时器实现4ms超时接收也存在一些局限性。如果4ms的超时时间设置合理,可能会导致误判。若设置过短,可能会将正常的数据分割成多帧;若设置过长,可能会使接收端等待时间过长,影响系统的实时性。而串口空闲中断则依赖于串口硬件状态的准确判断,如果硬件存在异常,如干扰导致空闲状态误判,也会影响其可靠性。 ### 代码示例 以下是简单示意代码: ```c // 串口空闲中断使能 void enable_uart_idle_interrupt() { USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE); USART_ITConfig(DEBUG_USARTx, USART_IT_IDLE, ENABLE); } // 定时器实现4ms超时接收 #define RX_TIMEOUT_MS 4 volatile uint8_t rx_timeout_counter = RX_TIMEOUT_MS; volatile uint8_t rx_frame_complete = 0; void TIM_Interrupt_Handler() { if (rx_timeout_counter > 0) { rx_timeout_counter--; if (rx_timeout_counter == 0) { rx_frame_complete = 1; } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌夏微秋

希望各位多多支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值