STM32串口接收策略

  • 最近不做嵌入式,这是一个以前做过产品的技术备忘。因为之前请教大神得到一些很好的思路。

如果我们需要接收一个序列协议,怎么做呢?
先放到缓冲区然后再检查标志位是一种思路。道理简单,关键要看怎么设计。这里介绍的方法是巧妙利用定时器,与串口中断进行耦合,得到一种鲁棒的接收方法。

具体:

  1. 打开定时器与串口中断
  2. 首先用示波器查看完整帧所需要的时间,并且设置为timMax。
  3. 定时器以适当的中断频率开启(例如1ms),每次中断都把表示时间的变量+1。
  4. 如果定时器中断时间超过timMax,则令接收数组的指针为0。
  5. 每次进来串口中断之后,定时器时间变量为0,接收数组的指针+1。

给出代码:

定时器端:

/**
  * @brief This function handles TIM4 global interrupt.
  */
void TIM4_IRQHandler(void)
{
  /* USER CODE BEGIN TIM4_IRQn 0 */
	
  /* USER CODE END TIM4_IRQn 0 */
  HAL_TIM_IRQHandler(&htim4);
  /* USER CODE BEGIN TIM4_IRQn 1 */
	
	div_freq_flag_temp_laser_1 += 1;
	
	// Èç¹ûһֱûÓб»ÇåÁã ÄÇôºÜ¿ì»áÇ¿ÖÆÇåÁã   Ò»¶¨Òª×¢Òâ ֮ǰµÄ»ù´¡ÖÜÆÚ²»ÊÇ1ms£¡£¡ÏÖÔڸĹýÀ´¾Í¿ÉÒÔÁË£¡
	if(div_freq_flag_temp_laser_1 > div_freq_laser_flag){
		laser_1_ptr = 0;
	}
	
	// ToggleIO
	// HAL_GPIO_TogglePin(GPIOH, GPIO_PIN_9);
	
  /* USER CODE END TIM4_IRQn 1 */
}

串口端:

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
	
	div_freq_flag_temp_laser_1 = 0;  // ½ÓÊս׶α£Ö¤temp²»»á³¬¹ý10ms
	
	lazer_data1[laser_1_ptr] = recvyoadata1[0];
	laser_1_ptr += 1;
	
	// ²½½øµç»ú ºáÏò  X 
//	if(lazer_data1[0]==0x55 && lazer_data1[1]==0x51 && lazer_data1[10]==0xFF)
	if(lazer_data1[0] == 0x55)

	{
		// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
		lazer_op1= (uint16_t)(lazer_data1[6] << 8 | lazer_data1[7]);  // 2 3  //  
		
		// YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
		lazer_op2=(uint16_t)(lazer_data1[8] << 8 | lazer_data1[9]); 
		
	//	HAL_GPIO_TogglePin(GPIOH, GPIO_PIN_9);	
	}

	HAL_UART_Receive_IT(&huart1, recvyoadata1,1);
  /* USER CODE END USART1_IRQn 1 */
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值