STM32 硬件UART接收超时检测设置

STM32 硬件UART接收超时检测设置

-----------------本文作者“智御电子”,期待与电子爱好者交流学习。----------------

应用场景

在uart应用中有时候需要进行双工通信,主机需要对从机的数据进行接收超时检测,例如modbus协议,主机在接收从机数据在3.5个字节时间后认为数据包接收完毕。那在这种情况下,一般的做法是设置一个定时器,在每接收到一个字节时清零定时器重新计数,直到定时器超过3.5个字节时间后触发中断即默认数据包接收完毕。

以上的定时器设置的超时判断是需要软件介入的。这里STM32的有些串口是提供硬件超时检测功能。这样就省去如上的步骤。

设置步骤

本实验是利用CubeMx生成的工程进行验证的。

  • 首先,利用cubemx配置usart1(注意:并不是每个STM32芯片的串口都具有硬件超时检测功能的)。值得注意的是在cubeMX中并没有设置硬件超时的选项,所以这里只是生产可用的usart工程。
  • 生成工程后,我们去数据手册,其中有这样的描述。

    所以本文添加一个使能超时检测的函数,如下所示

void Uart_RxOvertimeEnable(void)
{
    /*使能接收超时功能*/
    SET_BIT(huart1.Instance->CR2,USART_CR2_RTOEN);
    /*使能超时接收中断*/
    //SET_BIT(huart1.Instance->CR1,USART_CR1_RTOIE);
    /*向RTOR寄存器填入需要超时的长度,单位为一个波特时长,3.5个字节*11波特长度 = 39  */
    WRITE_REG(huart1.Instance->RTOR,39);
}
  • 接着在main函数中添加这个函数,并且写了一个小小的测试实例。

int main(void)
{

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();

  /*使能超时检测*/
  Uart_RxOvertimeEnable();
  /* Infinite loop */
  /*采用中断接收数据,模拟接收*/
  HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 100);
  while (1)
  {
    //数据接收后,一直等待超时
   while(READ_BIT(huart1.Instance->ISR,USART_ISR_RTOF))
    {
        /*清除rtof标志*/
         SET_BIT(huart1.Instance->ICR,USART_ICR_RTOCF);
        /*将接收的数据发送出去测试一下*/
       HAL_UART_Transmit_IT(&huart1, (uint8_t *)aRxBuffer, 100);
       HAL_Delay(1000);
    }
  }
}
  • 最后通过串口调试助手通过上位机发送数据(this is test!)给单片机,单片机能返回数据(后面的***是因为打印了空字节,忽略),则证明有效。

原文地址:https://www.cnblogs.com/SC-Electronic/p/9747438.html

时间: 2024-10-13 15:03:50

STM32 硬件UART接收超时检测设置的相关文章

【c#】设置Socket连接、接收超时(转)

用到Socket,发现如果连接错误,比如Connect的端口不对,会造成很长时间的延时,程序就僵在那里,效果很不好: 在网上找到很方便的设置办法,分享如下: Socket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,1000); 设置Socket接收超时,时长为1000毫秒,这样1秒之后就会收到反馈,比之前强多了:

perl Socket接收超时设置

一般来说, IO::Socket::INET里的Timeout设置是对于conncet的 如果你想设置recv接收超时, 可以这样设置: 1 usr Socket: 2 ...... 3 setsockopt($socket, SOL_SOCKET, SO_RCVTIMEO, pack('l!l!', 1, 0)); 4 #注意这里pack有三个参数, 后面的1表示超时1秒, 最后的0你可以默认 5 #而前面的'l!l!', !表示64位平台 6 #如果你是用IO::Socket::INET他的

网络编程中的超时检测

我们在网络编程中常见的一种做法是:创建好套接字后以阻塞的方式读写,如果没有数据可读的话,程序会一直等待.事实上,网络状况一直不断变化,很有可能在通讯过程中出现网络连接断开.我们在程序中有必要对这种情况进行检测,从而及时做出响应.下面介绍几种常用的超时检测方法(假设我们要求通过套接字等待数据的最大时间为8秒): 一. 设置套接字接收超时 setsockopt可以设置套接字的属性,其中包括接收超时时间.参考代码如下        struct timeval tv; // 描述时间的结构体变量   

VC socket Connect 超时时间设置

设置connect超时很简单,CSDN上也有人提到过使用select,但却没有一个令人满意与完整的答案.偶所讲的也正是select函数,此函数集成在winsock1.1中,简单点讲,"作用使那些想避免在套接字调用过程中被锁定的应用程序,采取一种有序的方式,同时对多个套接字进行管理"(<Windows网络编程技术>原话).使用方法与解释请见<Windows网络编程技术>. 在使用此函数前,需先将socket设置为非阻塞模式,这样,在connect时,才会立马跳过,

网络超时检测的三种方法

作者:于老师,华清远见嵌入式学院讲师. 网络通信中,很多操作会使得进程阻塞,这时我们要设定时间,到时间后强制返回,避免进程在没有数据的情况下无限阻塞 这里我们总结一下网络超时检测的三种方法: 通过setsockopt设置套接字属性SO_RCVTIMEO struct timeval t = {5, 0}           if  (setsockopt(listenfd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t)) == -1) {             

网络超时检测方法

超时检测的必要性:避免进程在没有数据时无限制地阻塞,当设定的时间到时,进程从原操作返回继续运行. 方法(1):使用setsockopt函数 时间结构体 struct timeval  tv; 可设定 tv.tv_sec = 5; // 设置5秒时间 tv.tv_usec = 0; 然后设置超时选项 setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); 注意:将进程中和sockfd相关的阻塞,变为非阻塞. 实例代码: serve

python故障查找:超时未设置

最近一台基于python的应用服务总是出现问题.需求是用户可以在页面上提交批量处理任务,后台把这些任务入到一个Queue里排队处理,然后通过一个线程专门处理.现在总是偶尔出现假死状态,任务处理中断执行.开始总是以为是哪里出错了,导致程序中断.可以检查程序,任务处理过程全部try了,并打印日志.但是查找日志没有任何出错.首先要排查的线程到底有没有活着,如果活着,是在哪里阻塞了,所以想对任务处理线程执行dump,然后分析.本以为是python中有像jvm中的jstack的工具,但是上网查找没有结果,

golang net http库相关超时的设置

net.http 包中的超时设置 app.Server.ReadTimeout app.Server.WriteTimeout 是针对所有请求设置的选项 默认 net.http keepalived 开启,超时时间为 3 分钟,如下 1942    type tcpKeepAliveListener struct { 1943          *net.TCPListener 1944    } 1945 1946    func (ln tcpKeepAliveListener) Accep

MYSQL的数据连接超时时间设置

大规模多线程操作事务的时候,有时候打开一个链接,会进行等待,这时候如果数据库的超时时间设置的过短,就可能会出现,数据链接自动被释放,当然设置过大也不好,慢SQL或其他因素引起的链接过长,导致整个系统被拖慢,甚至挂掉. SO,适当的设置超时时间. 网上查了很多资料,大多数解决方案都写的太复杂,其实只要设置一下等待超时时间就OK了 设置方法: SHOW GLOBAL VARIABLES LIKE '%timeout%'SET GLOBAL wait_timeout=10000