之前文章写过有关空闲中断+DMA的使用方法,但是本实验使用的是STM32H750VBT6芯片,按照之前的方法配置会出现一下问题,可能原因是此芯片的时钟频率是480M过高影响的原因,所以写一篇针对此系类芯片的配置说明
- 使用CUBE配置串口,默认CUBE配置USART1使用的是PB14和PB15,要是修改成PA9和PA10要手动修改一下。
- 配制DMA
- 配置NVIC,
- main.c 参数定义
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx;
extern UART_HandleTypeDef huart1;
uint8_t rx_len=0;
uint8_t recv_flag=0;
uint8_t rx_buffer[RX_SIZE];
- main.h 参数定义
#define RX_SIZE 200
extern uint8_t rx_len;
extern uint8_t recv_flag;
extern uint8_t rx_buffer[RX_SIZE];
- usart.c MX_USART1_UART_Init函数修改,在末尾添加以下函数
__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_IDLEF);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//开启IDLE中断
while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)==RESET);
HAL_UART_Receive_DMA(&huart1,rx_buffer,RX_SIZE);//开启DMA接收
- 在mian.c 自定义中断函数并添加到stm32h7xx.h USART1_IRQHandler函数里面
void UART1_IRQ(void)
{
static uint16_t i = 0;
if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
HAL_UART_DMAStop(&huart1);
rx_len = RX_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
recv_flag = 1;
}
}
- 主函数,进入循环函数之前再将recv_flag变量清一下零,因为在程序上电时候会进入一次串口中断
recv_flag=0;
while (1)
{
if(recv_flag ==1)
{
printf("接收到的数据长度为%d ",rx_len);
// HAL_UART_Transmit(&huart1,rx_buffer, rx_len, 200);// 正常发送
HAL_UART_Transmit_DMA(&huart1,rx_buffer,rx_len);// DMA发送
rx_len=0;
recv_flag=0;
HAL_UART_Receive_DMA(&huart1,rx_buffer,RX_SIZE);
}
}