1733|6

274

帖子

8

TA的资源

纯净的硅(初级)

楼主
 

[ ST NUCLEO-U575ZI-Q 测评] 9-通过UART的"接收超时"功能获取一帧数据 [复制链接]

很多工程师都是通过循环DMA配合UART的IDLE中断实现1帧数据接收的。

但是这种方式也有缺点,比如一个设备在发送同一帧数据时,在发送数据帧的中间去处理中断,造成一个数据帧分成2个部分发出的。这两个部分中间出现了一个空闲帧。那么我们使用上面的方法去接收数据就有问题了。

那么能不能不要一收到空闲帧就断帧,而是有一定的延时呢?有一定的延时就能很好的解决上面的问题。在以前需要使用一个定时器计时。但现在在STM32U5中提供了一个"接收超时"的功能。

通过这个功能,我们可以设置一定的延时时间,如果在收到最后一个字节的停止位后,这个延时时间之后没有收到新的数据,就产生一个中断。

在STM32U5中,通过RTOEN位可以使能这个功能,通过RTOIE可以使能对应的中断。通过RTO可以设置一定的延时时间,注意这个时间是按照波特率的位时间计算的,比如波特率是9600,那么如果想延时100ms,则对应的是发送了960位,那么就要在RTO中写入960,以设置100ms的延时。

在下面的例子中,使用RTOF中断配合DMA实现数据的自动收取和断帧。

一、使能

首先在串口初始化的下面添加使能"接收超时"的功能。

HAL_UART_EnableReceiverTimeout(&huart1); //使能接收超时
HAL_UART_ReceiverTimeout_Config(&huart1,960);   //设置超时时间,这个需要根据波特率算,如果波特率是9600,那么超时按照100ms算的话,就是960,也就是接收960个位的时长为100ms
__HAL_UART_CLEAR_FLAG(&huart1,UART_CLEAR_RTOF); //先清楚RTOF位,这个位指示是否接收超时
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RTO); //使能接收超时的中断

二、中断函数

然后在串口的中断函数中添加处理函数,因RTOF需要软件清除,因此需要在中断中手动清除标志位。因为DMA配置的是循环接收,所以是用的环形数组。进入RTOF中断后,就认为1帧数据结束,从数组中取出数据放到另一个缓存区,并置标志位。有main函数将数据原样发出。

注意自己定义的RTOF中断函数要放在中断函数的前部,不要放在 *HAL_UART_IRQHandler(&huart1);*的后面,因为这个函数里也有RTOF的处理功能,会影响使用的。

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
	static uint16_t last_index;
	uint16_t index;
	if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RTOF) != 0){
		__HAL_UART_CLEAR_FLAG(&huart1,UART_CLEAR_RTOF); //清除标志位
        //以下内容为环形数组的数据读取,写的有点粗糙,仅做参考
		index = 100-( __HAL_DMA_GET_COUNTER(huart1.hdmarx));
		if(index != last_index){
			if(index > last_index){
				for(int i = last_index;i<index;i++){
					send_buf[i-last_index] = recv_buf[i];
				}
				send_buf[100] = index - last_index;
			}else{
				uint16_t s_index = 0;
				for(int i=last_index;i<100;i++){
					send_buf[s_index++] = recv_buf[i];
				}
				for(int i =0;i<index;i++){
					send_buf[s_index++] = recv_buf[i];
				}
				send_buf[100] = s_index;
			}
			last_index = index;
		}
	}
	
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

三、测试IDLE和RTOF中断

最后测试了一下使用IDLE中断和RTOF中断,这两个的时间差。和预期的一样。如果使用115200的波特率,超时值设为1152,则IDLE中断应该比RTOF中断早100ms。通过systick的计数值估算时间,如下图所示。

其中time1是进入IDLE中断的时间,time2是进入RTOF中断的时间。两者相差正好是100,也就是100ms 。

四、总结

IDLE和RTOF两种方式获取1帧数据,各有各的有点。使用IDLE的话有现成的HAL库,但是确实会有判断出错的情况。而使用RTOF的话会更灵活,但是需要自己编写一部分代码。

此帖出自无线连接论坛

最新回复

测评汇总:免费申请|ST NUCLEO-U575ZI-Q https://bbs.eeworld.com.cn/thread-1228653-1-1.html   详情 回复 发表于 2023-1-12 09:23
点赞(1) 关注(1)
 

回复
举报

6998

帖子

11

TA的资源

版主

沙发
 

IDLE和RTOF两种方式获取1帧数据,各有各的有点。使用IDLE的话有现成的HAL库,但是确实会有判断出错的情况。而使用RTOF的话会更灵活,但是需要自己编写一部分代码。

感谢楼主分享这么清晰的串口接收代码。

此帖出自无线连接论坛

点评

谢谢支持  详情 回复 发表于 2023-1-10 10:27
 
 

回复

7205

帖子

2

TA的资源

版主

板凳
 

RTOF是STM32U5特有的功能吗?如果是的话,后续系列感觉也会携带这个功能。

此帖出自无线连接论坛

点评

不是的,STM32G0也有这个功能。估计后续的产品都有这个功能。我看ST的社区说这方面的HAL库也正在设计。  详情 回复 发表于 2023-1-10 10:26
 
 
 

回复

274

帖子

8

TA的资源

纯净的硅(初级)

4
 
wangerxian 发表于 2023-1-10 09:20 RTOF是STM32U5特有的功能吗?如果是的话,后续系列感觉也会携带这个功能。

不是的,STM32G0也有这个功能。估计后续的产品都有这个功能。我看ST的社区说这方面的HAL库也正在设计。

此帖出自无线连接论坛

点评

那不错,以前都是用的空闲中断检测数据是否发送完毕,现在能检测接收超时确实是优化了!  详情 回复 发表于 2023-1-10 11:42
 
 
 

回复

274

帖子

8

TA的资源

纯净的硅(初级)

5
 
lugl4313820 发表于 2023-1-10 07:17 IDLE和RTOF两种方式获取1帧数据,各有各的有点。使用IDLE的话有现成的HAL库,但是确实会有判断出错的情况。 ...

谢谢支持

此帖出自无线连接论坛
 
 
 

回复

7205

帖子

2

TA的资源

版主

6
 
manhuami2007 发表于 2023-1-10 10:26 不是的,STM32G0也有这个功能。估计后续的产品都有这个功能。我看ST的社区说这方面的HAL库也正在设计。

那不错,以前都是用的空闲中断检测数据是否发送完毕,现在能检测接收超时确实是优化了!

此帖出自无线连接论坛
 
 
 

回复

1万

帖子

2853

TA的资源

管理员

7
 

测评汇总:免费申请|ST NUCLEO-U575ZI-Q https://bbs.eeworld.com.cn/thread-1228653-1-1.html

此帖出自无线连接论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
个人签名玩板看这里:
https://bbs.eeworld.com.cn/elecplay.html
EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
快速回复 返回顶部 返回列表