问题:
串口屏与单片机通过串口(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接收数据,接收失败的问题,
如果对您有所帮助,麻烦点赞分享,这对我非常重要,感谢!