uart - 发送完成回调未在 UART DMA 中被调用
问题描述
我想做的很简单。通过 DMA 传输并等待它被传输。然后接收并等待接收。
当我注释掉接收部分(包括回调)时,它将进入传输完成回调函数。但是当我取消注释接收部分时,它不会进入 tx cplt 回调,而是直接进入接收 cplt 回调。当我检查接收缓冲区时,我没有得到我所期望的(显然)。可能出了什么问题?
我正在使用 Atollic True Studio V 9.0、CubeMx v5.1.0、STM32F407VG-DISC1 板并为 UART2 启用了 DMA。
我尝试通过 UART DMA 发送字符缓冲区并接收它。它似乎根本没有传输,因为它没有进入 txCplt 回调。它直接进入 Rxcplt 回调。
uint8_t tx_arr[10], rx_arr[10];
__IO ITStatus UartReady = RESET;
int main(void)
{
int i = 0;
for(i = 0; i<10; i++)
rx_arr[i] = 0;
for(i = 0; i<10; i++)
tx_arr[i] = i*2;
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART6_UART_Init();
MX_USART2_UART_Init();
while (1)
{
if( HAL_UART_Transmit_DMA(&huart2, (uint8_t*)tx_arr, 10)!= HAL_OK )
{
Error_Handler();
}
while(UartReady != SET)
{
}
UartReady = RESET;
if( HAL_UART_Receive_DMA(&huart2, (uint8_t*)rx_arr, 10)!= HAL_OK )
{
Error_Handler();
}
while(UartReady != SET)
{
}
UartReady = RESET;
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
UartReady = SET;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UartReady = SET;
}
我希望 rx_arr 会被 0,2,4,6,...18 填满,但它会被垃圾填满
解决方案
在我看来,原因是您在两个 ISR 中使用相同的标志变量,两次都在您的主循环中忙于等待。
如果您取消注释这两个处理程序操作,您迟早会遇到一个竞争条件,两个处理程序将它们的“SET”值一个接一个地快速放置 - 在主循环等待它之前。然后,主循环通过将变量设置回“RESET”来“使用”这个标志。几行之后,另一个等待循环来了,但没有提供服务(因为两个 ISR 都运行得更早,只留下一个“SET”值,一个覆盖另一个)。然后,您的主循环被卡住了。
为了验证我的假设,您可以在进入主循环之前激活一个单向看门狗,并在每个主循环周期触发它。如果主循环像我假设的那样卡住,您将检测到复位原因随后指向看门狗。
推荐阅读
- python - 为本地模块配置 Python 日志记录与主文件不同
- gnuplot - 有没有办法在 GNUPLOT 上“返回”、“中断”、“循环”或“停止”?
- pycharm - 取消注释代码块不起作用
- javascript - 如何在选择选择引导程序中包含输入文本作为选项
- javascript - 如果单击超链接,使浏览器提交额外的 HTTP-Header
- python - 如何使用 matplotlib 绘制烛台跳过空日期?
- node.js - NPM 安装显示错误
- python - 使用 Bokeh Python 未显示烛台
- sql - 带有连接和外键约束的 SQL 删除
- angular - 如何在 Angular 6 库中创建延迟加载的功能模块?