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

本文介绍了如何在STM32中设置硬件UART接收超时检测,适用于双工通信中需要超时判断的场景,如Modbus协议。通过CubeMx配置串口并参考数据手册启用超时检测功能,实现无需软件定时器的超时判断。文中提供了一段使能超时检测的代码并在测试中得到验证。

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!)给单片机,单片机能返回数据(后面的***是因为打印了空字节,忽略),则证明有效。
### STM32硬件UART配置、使用教程及原理 #### 配置方法 对于STM32微控制器而言,其内部集成了多个通用异步收发传输器(UART),这些外设能够通过简单的配置实现全双工通信功能。为了使能并初始化一个UART接口,在程序启动阶段需调用`MX_USARTx_UART_Init()`函数来设置波特率、数据长度、停止位以及校验方式等参数[^3]。 ```c static void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 9600; // 设置波特率为9600bps huart1.Init.WordLength = UART_WORDLENGTH_8B; // 数据帧为8位宽 huart1.Init.StopBits = UART_STOPBITS_1; // 单个停止位 huart1.Init.Parity = UART_PARITY_NONE; // 不启用奇偶校验 huart1.Init.Mode = UART_MODE_TX_RX; // 启用发送接收模式 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 关闭硬件流控 huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } } ``` 此段代码展示了如何利用CubeMX工具自动生成的基础框架下进一步定制化USART1的具体属性。值得注意的是,这里选择了不带任何特殊控制机制的标准二进制编码格式作为默认选项。 #### 使用教程 一旦完成了上述基本设定之后,就可以借助于HAL库提供的API来进行实际的数据交换操作了。例如要向外部设备发出一串字符,则可通过`HAL_UART_Transmit()`传递指向待传送缓冲区指针及其大小给指定实例对象完成该动作[^2]: ```c char message[] = "Hello World!"; if(HAL_UART_Transmit(&huart1, (uint8_t*)message,strlen(message), HAL_MAX_DELAY)!= HAL_OK){ /* 发送失败处理 */ } ``` 这段示例中定义了一条字符串常量,并将其转换成适合底层驱动识别的形式后交给UART模块负责物理层面上的信息流通工作。同时设置超时等待条件以确保整个过程顺利完成。 至于从外界获取输入信号同样简单明了——只需调用对应的接受版本命令即可[`HAL_UART_Receive`](https://www.st.com/resource/en/user_manual/dm00574831-description-of-stm32-hal-drivers-stmicroelectronics.pdf)。 #### 工作原理 在更深层次上理解UART的工作机理有助于更好地掌握编程技巧。每当应用程序准备好了新的字节供输出时,它会被存储在一个名为TDR(Transmit Data Register)的地方;与此同时,另一个称为Tx Shift Reg的移位寄存器会逐步将这个数值按照预设规则逐位向外发射出去直至结束为止[^5]。而当接收到新到来的消息片段时,它们先进入Rx Shift Reg里暂存起来然后再转移到RDR(Received Data register),最后才被提取出来供给高层应用逻辑解析使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值