近期移植GD32F1到GD32F4,测试DMA串口空闲中断,F1可以运行但F4发现存在BUG。
问题:第一次串口助手发送数据,助手能正常显示接收长度和回显发送的字符;但是第二次发送数据的时候,助手异常显示长度为0,且回显不了字符。
现象如下:
附上中断代码:
// USART0 中断处理函数
void USART0_IRQHandler(void) {
if (usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE) != 0) { // 读空闲中断标志
usart_flag_get(USART0, USART_FLAG_IDLE); // 先读STAT0
usart_data_receive(USART0); // 再读DATA寄存器-这两个操作目的是:清除空闲标志位
//当前接收长度: 总的长度 - dma剩余的长度
U0CB.URxCounter += (U0_RX_MAX+1) - dma_transfer_number_get(DMA1,DMA_CH5);
//IN指针的end 指向 当前缓冲区的已有值末尾的位置
U0CB.URxDataIN->end = &U0_RXBuff[U0CB.URxCounter - 1];
if(U0CB.URxDataIN == U0CB.URxDataEND){ //如果IN指针指向了END 代表缓冲区已满
U0CB.URxDataIN = &U0CB.URxDataPtr[0]; //回到缓冲区开头
}else{
//IN指针指向下一组
U0CB.URxDataIN++;
}
if(U0_RX_SIZE - U0CB.URxCounter >= U0_RX_MAX){ //如果当前缓存区的位置还能存下一次数据的最大长度
U0CB.URxDataIN->start = &U0_RXBuff[U0CB.URxCounter]; //start指向当前缓冲区的下一次数据首
}else{
U0CB.URxDataIN->start = U0_RXBuff; //如果不够,就回卷到缓冲区开头
U0CB.URxCounter = 0; //计数值也跟着回卷
}
//重新配置DMA
dma_channel_disable(DMA1, DMA_CH5); // 禁用 DMA 通道
dma_transfer_number_config(DMA1, DMA_CH5,U0_RX_MAX+1);
dma_memory_address_config(DMA1, DMA_CH5, DMA_MEMORY_0, (uint32_t)U0CB.URxDataIN->start);//地址是下一次数据位置
dma_channel_enable(DMA1, DMA_CH5); // 重新启用 DMA 通道
}
}
解决方案:
添加“清除DMA完成标志”
dma_flag_clear(DMA1, DMA_CH5, DMA_FLAG_FTF); // 清除DMA完成标志
dma_channel_disable(DMA1, DMA_CH5); // 禁用 DMA 通道
dma_flag_clear(DMA1, DMA_CH5, DMA_FLAG_FTF); // 清除DMA完成标志
dma_transfer_number_config(DMA1, DMA_CH5,U0_RX_MAX+1); // 重配置dma大小
dma_memory_address_config(DMA1, DMA_CH5, DMA_MEMORY_0, (uint32_t)U0CB.URxDataIN->start);//地址是下一次数据位置
dma_channel_enable(DMA1, DMA_CH5); // 重新启用 DMA 通道
附上效果图
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/cccmjjj/article/details/144154911
|