串口dma接收,加消息缓存机制

主要应对异步通讯
比如单片机间串口通讯

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 */
	if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)==SET)
	{
		u16 temp=0;
		last_len=data_len+last_len;
		if(last_len>rx_len)
			last_len=0;
		__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除串口空闲中断
		/*当检测到空闲总线时,该位被硬件置位。如果USART_CR1中的IDLEIE为1,产生中断。由
		软件序列清除该位(先读USART_SR,然后读USART_DR)上下两两方式都可以,使用一个*/
//		temp=huart1.Instance->SR;//读取后清除
//		temp=huart1.Instance->DR;//读取后清除
		HAL_UART_DMAStop(&huart1);//暂停接收数据
		temp=hdma_usart1_rx.Instance->NDTR;//得到当前还剩多少字节
		data_len=rx_len-temp;//总自己减去剩余的得到已经接收的字节数
		for(u16 num=0;num<data_len;num++)
		{
			receive_buf_now[last_len+num]=receive_buf[num];
		}
	
			USAR_UART_IDLECallback(&huart1);
	}
  /* USER CODE END USART1_IRQn 1 */
}

要加入全局变量

__IO u8 receive_buf[rx_len]={0};    //DMA接收的缓存
__IO u8 receive_buf_now[rx_len]={0};//由DMA接收的缓存得到的数据,可以手动清空
__IO u16 data_len=0;//接收到数据的字节数
__IO u16 last_len=0;//指定receive_buf_now[]数据上次接收的地位,可以实现多次空闲中断数据的接收处理
//u8 rec_log=0;

其中

#define rx_len          512//缓存大小

在中断处理函数前要加入

void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
{
	printf("\r\n------------------------\r\n");
	HAL_UART_Transmit(&huart1,receive_buf_now,data_len+last_len,0x200);//打印接收数据,用于调试
	//printf("%x",receive_buf_now[0]);
	rec_log=0;
	printf("\r\n========================\r\n");
	HAL_UART_Receive_DMA(huart, (uint8_t*)receive_buf, rx_len);//重新使能DMA中断
}

在主函数串口处理函数中,要进行的操作

	memset(receive_buf_now,0,last_len+data_len);//清空receive_buf_now[]数组
	last_len=0;//清空,因为receive_buf_now开始接收新的数据
	data_len=0;//清空,因为receive_buf_now开始接收新的数据

完成,至此一个串口接收流程完成,多用于at指令类的模块,测试ok

别人工程下串口接收函数

void UART0_IRQHandler(void)
{
	uint32_t intsrc, tmp;
	uint8_t dat;
	intsrc = UART_GetIntId(UART_0);
	tmp = intsrc & UART_IIR_INTID_MASK;
	if (tmp == UART_IIR_INTID_RDA)
	{	
		dat= UART_ReceiveByte(UART_0);
		if(!recvFinish)
		{
			if(recvBegin)
			{
				recvBuf[recvCnt++] = dat;
				if(recvCnt==64)
				{
					recvBegin = 0;
					recvFinish = 1;
				}
			}
			else if(dat==0XAA)
			{
				recvCnt = 0;
				recvBuf[recvCnt++] = dat;
			}
			else if(dat==0X55&&recvCnt==1)
			{
				recvBuf[recvCnt++] = dat;
				recvBegin = 1;
			}
		}
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值