Bootstrap

STM32F429IGT6使用CubeMX配置串口通信配置DMA

1、硬件电路

 

2、设置RCC,选择高速外部时钟HSE,时钟设置为180MHz

3、配置USART1引脚 

 

 

4、生成工程配置

 

5、部分代码

/* USER CODE BEGIN 0 */
volatile uint8_t rx_len = 0;  //接收一帧数据的长度
volatile uint8_t recv_end_flag = 0; //一帧数据接收完成标志
uint8_t rx_buffer[20]={0};  //接收数据缓存数组
uint8_t rx_buffer2[20]={0};  //接收数据缓存数组2
/* USER CODE END 0 */
void MX_USART1_UART_Init(void)
{

    /* USER CODE BEGIN USART1_Init 0 */

    /* USER CODE END USART1_Init 0 */

    /* USER CODE BEGIN USART1_Init 1 */

    /* USER CODE END USART1_Init 1 */
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
        Error_Handler();
    }
    /* USER CODE BEGIN USART1_Init 2 */
    __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能串口空闲中断
    HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);    //设置DMA传输,将串口1的数据搬运到rx_buffer中,每次BUFFER_SIZE个字节
    /* USER CODE END USART1_Init 2 */
}
void USART1_IRQHandler(void)
{
    /* USER CODE BEGIN USART1_IRQn 0 */
    uint8_t temp_flag = 0; // 数据传输完成标志位
    uint8_t temp;          // DMA未传输的数据个数
    temp_flag = __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE);   //获取串口1是否处于空闲状态
    if (RESET != temp_flag)
    {
        memset(rx_buffer2, 0, BUFFER_SIZE);
        __HAL_UART_CLEAR_IDLEFLAG(&huart1); // 清除空闲中断标志位
        HAL_UART_DMAStop(&huart1);          // 停止DMA传输
        memcpy(rx_buffer2, rx_buffer, BUFFER_SIZE);
        temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);  //获取DMA传输期间剩余的数据量
        rx_len = BUFFER_SIZE - temp; // 接收到的字节数
        recv_end_flag = 1;           // 置位接收完成标志位
    }
    /* USER CODE END USART1_IRQn 0 */
    HAL_UART_IRQHandler(&huart1);
    /* USER CODE BEGIN USART1_IRQn 1 */

    /* USER CODE END USART1_IRQn 1 */
}
    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        if (1 == recv_end_flag)
        {
            HAL_UART_Transmit(&huart1, rx_buffer2, rx_len, 0xffff);
            printf("\r\n");
            HAL_UART_Transmit_DMA(&huart1, rx_buffer2, rx_len); // 之前此函数(DMA模式)在执行时还没有发送完数据数据就被下面的memset函数清零了(CPU清零),所以增加一个二级缓存数组rx_buffer2用来打印数据
                                                              // 当DMA再次接收到数据触发中断进入中断服务函数时,把rx_buffer2数组清空,这样就能保证代码正常运行。
            printf("\r\n");
            rx_len = 0;
            recv_end_flag = 0;
            memset(rx_buffer, 0, BUFFER_SIZE);
        }
        HAL_UART_Receive_DMA(&huart1, rx_buffer, BUFFER_SIZE); // 设置DMA传输,将串口1的数据搬运到rx_buffer中,每次BUFFER_SIZE个字节
        LED_TIME();
    }
    /* USER CODE END 3 */

6、实验现象

 

;