这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » STM32G070RB探测9-串口不定长接收(中断方式接收中断空闲中断)

共17条 1/2 1 2 跳转至

STM32G070RB探测9-串口不定长接收(中断方式接收中断空闲中断)

高工
2020-12-27 00:24:24     打赏
上篇实现了串口点灯,但是用的是固定长度数据,那么如何实现不定长的接收呢?STM32有用串口接收中断+空闲中断.也有用DMA+空闲中断的,今天我先用串口接收中断+空闲中断原理就是每接收到一个字节产生一次接收中断,将接收的数据放进缓存区,当一包数据接收完会产生空闲中断,这是我们判断接收完成续上篇,这次不用点点点了,因为跟上篇配置一样,简单写个结构体
#define RX_BUF_MAX_LEN     512        // 最大接收缓存字节数
typedef struct
{
	uint8_t rx_buff[RX_BUF_MAX_LEN];//缓存区
	uint8_t len;	  //接收长度
	uint8_t flag;  //用于判断是否接收完 1为接收完
}USRAT_RX;
再写个初始化(清空)结构体
void Clear_Usart(USRAT_RX *usart_rx)//初始化(清空)串口结构体
{
	memset((uint8_t *)usart_rx, 0, sizeof(USRAT_RX));//全写0
}
把之前的回调函数注释了,感觉HAL库的回调函数并不好用,直接在中断里写吧
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
	if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_RXNE) != RESET)//产生接收中断
	{
		HAL_UART_IRQHandler(&huart2); // 该函数会清空中断标志,取消中断使能,并间接调用回调函数,清除接收标志
		// 收到数据,将其放入缓冲区
		usart1_rx.rx_buff[usart1_rx.len++] = recv_buf;
		if(usart1_rx.len>RX_BUF_MAX_LEN){//防止刷爆串口缓存
			usart1_rx.flag = 1;  // 标记接收完成
		}

	}
	if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) != RESET)//产生空闲中断(说明接收完)
	{
		__HAL_UART_CLEAR_IDLEFLAG(&huart2);     //清楚空闲中断标志(否则会一直不断进入中断)
		usart1_rx.flag = 1;  // 标记接收完成
		if(usart1_rx.len==0){//防止误入
			usart1_rx.flag = 0;
		}
	}
	HAL_UART_Receive_IT(&huart2,&recv_buf,1);   // 重新使能接收中断
  /* USER CODE END USART2_IRQn 0 */
}


注释已经很清楚了,我就不解释了,我们还要初始化串口结构体,打开接收中断和空闲中断
Clear_Usart(&usart1_rx);//初始化串口结构体
HAL_UART_Receive_IT(&huart2,&recv_buf,1);//使能串口接收中断
__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE); // 使能空闲中断
在while(1)里添加判断函数
if(usart1_rx.flag){//判断接收完成
  printf("%s\r\n",usart1_rx.rx_buff);//打印出数据
  if(strstr((const char *)usart1_rx.rx_buff, "LED_ON") != NULL){//如果匹配到数据LED_ON
  	HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET);
  	printf("Turn on the LED");
	}
  else if(strstr((const char *)usart1_rx.rx_buff, "LED_OFF") != NULL){//如果匹配到数据LED_OFF
  	HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);
  	printf("Turn off the LED");
	}
  else {//不匹配打印error
  	printf("error\r\n");
	}
  Clear_Usart(&usart1_rx);//清空串口结构体
}


看效果



院士
2020-12-27 07:22:36     打赏
2楼

空闲中断的应用还是挺好用的。不知道G070系列的串口其它几个是否也支持


高工
2020-12-27 09:24:40     打赏
3楼

谢谢分享


高工
2020-12-27 23:05:55     打赏
4楼

代码写的还是非常不错的


工程师
2020-12-27 23:44:27     打赏
5楼

可以的


工程师
2020-12-30 22:13:47     打赏
6楼

感谢您的分享


菜鸟
2022-04-26 10:55:04     打赏
7楼
此帖仅楼主可见

菜鸟
2022-04-26 15:03:59     打赏
8楼
此帖仅楼主可见

工程师
2022-09-30 10:24:12     打赏
9楼

感谢分享


助工
2022-10-24 09:14:32     打赏
10楼
再次学习

共17条 1/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]