为了解决STM32H743 UART DMA接收不到数据的问题,请按照以下步骤排查:
问题原因:STM32H7的缓存(Cache)可能导致DMA写入的数据未被CPU正确读取。
解决方法:在DMA接收缓冲区声明时添加非缓存属性:
// 在board.h或uart初始化文件中定义缓冲区
ALIGN(RT_ALIGN_SIZE)
ATTR_NOCACHE_SECTION // 关键:添加非缓存属性
static rt_uint8_t uart3_rx_buf[BSP_UART3_RX_BUFSIZE];// stm32_uart.c中uart3的配置
struct stm32_uart uart3 = {
.uart_device = {
.config = {
.bufsz = BSP_UART3_RX_BUFSIZE, // 确保大小为256
.rx_buf = uart3_rx_buf, // 指向定义的缓冲区
}
},
.dma_rx = &uart3_dma_rx,
};问题原因:DMA中断未正确触发导致数据未被处理。
解决方法:
stm32h7xx_hal_msp.c中检查DMA中断使能:void HAL_UART_MspInit(UART_HandleTypeDef *huart) {
if (huart->Instance == USART3) {
// 使能DMA流中断
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0); // 根据实际DMA流调整
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
}
}问题原因:DMA不会自动通知数据包结束,需要空闲中断检测帧结束。
解决方法:
__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE); // 使能空闲中断USART3_IRQHandler中处理空闲中断:void USART3_IRQHandler(void) {
if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_IDLE)) {
__HAL_UART_CLEAR_FLAG(&huart3, UART_CLEAR_IDLEF); // 清除标志
rt_hw_serial_isr(&serial3, RT_SERIAL_EVENT_RX_DMADONE); // 通知RT-Thread
}
}问题原因:RT-Thread的串口驱动可能未正确关联DMA。
解决方法:
stm32_uart.c中是否包含以下逻辑:rt_hw_serial_isr()。uart3_dma_rx结构体)。static struct dma_config uart3_dma_rx = {
.dma_instance = DMA1_Stream0, // 根据实际调整
.dma_channel = DMA_CHANNEL_4,
.direction = DMA_PERIPH_TO_MEMORY,
};PD9)连接正确,无短路/断路。DMA_SxCR.EN=1)?DMA_SxNDTR)是否变化?// 步骤1: 定义非缓存缓冲区
ATTR_NOCACHE_SECTION rt_uint8_t uart3_rx_buf[256];
// 步骤2: 初始化时关联缓冲区
struct stm32_uart uart3 = {
.uart_device.config.rx_buf = uart3_rx_buf,
...
};
// 步骤3: 使能空闲中断(在HAL_UART_Init之后)
HAL_UART_Init(&huart3);
__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
// 步骤4: 实现空闲中断处理
void USART3_IRQHandler(void) {
if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_IDLE)) {
__HAL_UART_CLEAR_FLAG(&huart3, UART_CLEAR_IDLEF);
rt_hw_serial_isr(&serial3, RT_SERIAL_EVENT_RX_DMADONE);
}
HAL_UART_IRQHandler(&huart3);
}通过以上步骤,90%以上的类似问题可被解决。重点检查Cache一致性和空闲中断配置。如果问题依旧,请提供更多代码细节(如DMA初始化、中断函数等)进一步分析。
举报
更多回帖