【STM32】USART接收不定长数据、防止数据溢出

给大家分享一种usart接收不定长数据,并且防止数据溢出卡死等情况;

在这里需要引用到两个中断,接收数据非空中断(RXNE)&接收总线空闲中断(IDLE),废话不多说,直接上代码。

中断服务函数中数据处理:

u8 RxBuffer[30];					//接收缓冲区,长度自己定义
/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
	static uint8_t USART_REC_LEN=0;	//usart接收数据长度
	uint8_t clr;					//清除usart数据寄存器用
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
	if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE))//当接收数据非空标志位置一,开始将数据放于缓冲区中
	{
		RxBuffer[ USART_REC_LEN++ ] = USART1->DR;	//读数据
		if( USART_REC_LEN >= 48)					//防止缓冲区数据溢出使用
		{
			USART_REC_LEN = 0;						//将缓冲区地址清零
		}
	}
	if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
	{
		clr = USART1->SR;		
		clr = USART1->DR;			//清除数据寄存器
		USART1_REC_OK = 1;			//接收完成标志置1
		USART_REC_LEN = 0;			//将缓冲区地址清零
	}
  /* USER CODE END USART1_IRQn 1 */
}

usart初始化完毕后:

	__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);				//使能usart1接收非空中断
	__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);				//使能usart1接收总线空闲中断

切记一定要打开这两个中断哟~
while循环中数据处理:

if( 1 == USART1_REC_OK )				//如果接收总线空闲中断来了,说明暂时无数据接收
{
	USART1_REC_OK= 0;				//清除标志位
	data_process(RxBuffer);			//处理缓冲区数据
	memset(RxBuffer, 0, 30);		//清空缓冲区
}

实测结果:
使用sscom将0~100多个字节数据按照1ms-nms定时发送,测试时长10min
,程序未出现卡死情况,缓冲区数据完整性正常。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
STM32 中,USART 接收不定数据的实现可以通过以下步骤完成: 1. 配置 USART 的外设时钟和 GPIO 引脚。在初始化 USART 之前,需要先初始化外设时钟和相关的 GPIO 引脚,以便正确连接 USART 和外部设备。 2. 配置 USART 的通信参数。将 USART 设置为异步模式,选择波特率,数据位数,停止位数和校验方式等通信参数。 3. 使用中断或 DMA 实现 USART 接收数据。在接收数据时,可以使用中断或 DMA 机制。其中,中断机制是最常见的方式,可以在接收数据时触发中断,并且可以在中断处理函数中读取接收缓冲区中的数据。 4. 处理接收到的数据。由于 USART 接收数据不定的,因此需要在处理接收到的数据时进行一些特殊处理。例如,可以在接收数据时检查数据结束符,或者在接收数据度达到预定度时停止接收。 下面是一个简单的示例代码,演示了如何使用中断机制接收 USART 数据: ``` #include "stm32f4xx.h" #define BUFFER_SIZE 1024 uint8_t rx_buffer[BUFFER_SIZE]; uint16_t rx_index = 0; void USART2_IRQHandler(void) { if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { rx_buffer[rx_index++] = USART_ReceiveData(USART2); if (rx_index >= BUFFER_SIZE) { // 数据接收完成,进行处理 // ... rx_index = 0; } } } int main(void) { // 初始化外设时钟和 GPIO 引脚 // ... // 初始化 USART USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; 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_Init(USART2, &USART_InitStructure); // 使能 USART 接收中断 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 启动 USART USART_Cmd(USART2, ENABLE); while (1) { // 主循环代码 // ... } } ``` 在上面的代码中,当接收USART 数据时,会触发中断处理函数 USART2_IRQHandler。在该函数中,通过 USART_GetITStatus 函数判断是否接收数据,并通过 USART_ReceiveData 函数读取接收缓冲区中的数据,并将数据存储到 rx_buffer 缓冲区中。同时,通过检查 rx_index 变量的值,判断是否接收到了足够的数据,如果接收到了足够的数据,则进行数据处理,并将 rx_index 变量清零,以便下一次接收

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值