HAL库中使用空闲中断+DMA接收数据,接收失败的问题

发布于:2025-03-20 ⋅ 阅读:(15) ⋅ 点赞:(0)

问题:

串口屏与单片机通过串口(USART1)进行通信,调试时发现问题,现象如下:
手动页面的几个文本,输入的数字不会显示出来,比如初始值为0,输入200,200会一闪而过,又恢复到0。 检查了页面ID和文本ID,单片机解析的函数都没有问题。

①连接上调试器时,文本输入、显示非常正常。
②不接调试器时,文本输入、显示时而正常,时而有问题。

解决:

1,不知道哪里的原因,接上调试器时又运行正常,没法调试。所以只能在代码中给变量赋值,看程序是否运行到某一行

如下所示:
串口接收到数据时,会在串口空闲中断中调用接收函数plcd_device->Receive,所以在plcd_device->Receive中给modbus_data.manual_target_speed赋上不同的值(66、77、88),来判断串口到底有没有接收到正确格式的数据。

uint8_t g_RecvTmpBuf1[256];

void Start_USART1_Recv(void)	//lcd
{
	//使用DMA+idle来接收
	HAL_UARTEx_ReceiveToIdle_DMA(&huart1, g_RecvTmpBuf1, 128);
}


//空闲中断被调用
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if (huart->Instance == USART1) 	//lcd
    {
		/* 把数据写入rx_buf */
		plcd_device->Receive(g_RecvTmpBuf1, Size);
		
		// 重新启动DMA接收
		Start_USART1_Recv();
    }	
}


static void LcdDevice_Receive(uint8_t* data, uint16_t length) 
{
	modbus_data.manual_target_speed = 66;

	// 判断数据帧的头部和尾部是否符合预期
	if(data[0] == 0xee && data[length-1] == 0xff && data[length-2] == 0xff && data[length-3] == 0xfc && data[length-4] == 0xff)
	{
		// 将接收到的有效数据复制到接收缓冲区中
		for (uint16_t i = 0; i < length; i++) 
		{
			plcd_device->rx_buffer[plcd_device->rindex] = data[i];
			plcd_device->rindex++;
			if (plcd_device->rindex >= RSIZE_LCD) // 超过接收缓冲区大小,循环使用
			{
				plcd_device->rindex = 0;
			}
		}

		// 设置接收标志位,表示接收到了一帧数据
		plcd_device->rcv_flag = 1;		


		modbus_data.manual_target_speed = 77;
	} else if(data[0] == 0xA5)
	{
		// 将接收到的有效数据复制到接收缓冲区中
		for (uint16_t i = 0; i < length; i++) 
		{
			plcd_device->rx_buffer[plcd_device->rindex] = data[i];
			plcd_device->rindex++;
			if (plcd_device->rindex >= RSIZE_LCD) // 超过接收缓冲区大小,循环使用
			{
				plcd_device->rindex = 0;
			}
		}

		// 设置接收标志位,表示接收到了一帧数据
		plcd_device->rcv_flag = 1;	
		plcd_device->lcd_step_flag = 1;
	}
	else 
	{
		// 如果数据帧不符合预期,重置索引
		plcd_device->rindex = 0;
		modbus_data.manual_target_speed = 88;
	}

}

结果发现,有时候根本就不会进入接收函数,说明根本就没有接收到串口屏发来的数据。

2,继续研究,
如图,我的启动DMA接收是在任务一开始执行一次,然后在空闲中断中重新使能。
有没有可能是,不知道什么原因,第一次启动之后,后续没有重新启动?
在这里插入图片描述
在这里插入图片描述

所以尝试解决方法:持续使能串口屏的DMA接收。
在这里插入图片描述

果然,接收正常啦!
又掌握了一种调试方法!真不错

关于HAL库中使用空闲中断+DMA接收数据,接收失败的问题,
如果对您有所帮助,麻烦点赞分享,这对我非常重要,感谢!