STM32 DMA使用

1.使能对应DMA时钟&中断

void MX_DMA_Init(void) 
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Stream1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);

}//注意,DMA优先级要高于串口中断

2.初始化DMA&串口

void USART3_UART_Init(u32 bound)
{

    UART3_Handler.Instance = USART3;                        //UART3
    UART3_Handler.Init.BaudRate = bound;                    //波特率
    UART3_Handler.Init.WordLength = UART_WORDLENGTH_8B;    //长度
    UART3_Handler.Init.StopBits = UART_STOPBITS_1;        //停止位1位
    UART3_Handler.Init.Parity = UART_PARITY_NONE;            //无奇偶校验
    UART3_Handler.Init.Mode = UART_MODE_TX_RX;            //收发模式
    UART3_Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;    //无硬件流控制
    UART3_Handler.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&UART3_Handler) != HAL_OK)
    {

    }
//    HAL_UART_Receive_IT(&UART3_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量(使用回调函数处理中断需要调用该函数)
//    UART3_Handler.State=HAL_UART_STATE_READY;
    __HAL_UART_ENABLE_IT(&UART3_Handler, UART_IT_IDLE);//使能idle中断
    HAL_UART_Receive_DMA(&UART3_Handler,rx3_buffer,BUFFER_SIZE);//打开DMA接收,数据存入rx_buffer数组中。
}

 

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_Initure;
   if(huart->Instance==USART3)//如果是串口3,进行串口3 MSP初始化
    {
        __HAL_RCC_GPIOB_CLK_ENABLE();            //使能GPIOB时钟
        __HAL_RCC_USART3_CLK_ENABLE();            //使能USART3时钟
    
        GPIO_Initure.Pin=GPIO_PIN_10;            //PB10
        GPIO_Initure.Mode=GPIO_MODE_AF_PP;        //复用推挽输出
        GPIO_Initure.Pull=GPIO_PULLUP;            //上拉
        GPIO_Initure.Speed=GPIO_SPEED_FAST;        //高速
        GPIO_Initure.Alternate=GPIO_AF7_USART3;    //复用为USART1
        HAL_GPIO_Init(GPIOB,&GPIO_Initure);           //初始化PB10

        GPIO_Initure.Pin=GPIO_PIN_11;            //PB11
        HAL_GPIO_Init(GPIOB,&GPIO_Initure);           //初始化PB11
//        __HAL_UART_DISABLE_IT(huart,UART_IT_TC);

        
            /* USART3 DMA Init */
    /* USART3_RX Init */
    hdma_usart3_rx.Instance = DMA1_Stream1;
    hdma_usart3_rx.Init.Channel = DMA_CHANNEL_4;
    hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart3_rx.Init.Mode = DMA_NORMAL;
    hdma_usart3_rx.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_usart3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK)
    {
      ;//_Error_Handler(__FILE__, __LINE__);
    } 
        __HAL_LINKDMA(huart,hdmarx,hdma_usart3_rx);

    /* USART3 interrupt Init */
    HAL_NVIC_SetPriority(USART3_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(USART3_IRQn);
//        __HAL_UART_ENABLE_IT(huart,UART_IT_RXNE);        //开启接收中断
//        HAL_NVIC_SetPriority(USART3_IRQn,2,0);            //抢占优先级3,子优先级3
//        HAL_NVIC_EnableIRQ(USART3_IRQn);                //使能USART1中断通道
    }
    

}

 

3.修改中断函数

void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
    uint32_t tmp_flag = 0;
    uint32_t temp;
    tmp_flag =__HAL_UART_GET_FLAG(&UART3_Handler,UART_FLAG_IDLE); //获取IDLE标志位
    if((tmp_flag != RESET))//idle标志被置位
    { 
        __HAL_UART_CLEAR_IDLEFLAG(&UART3_Handler);//清除标志位
        temp = UART3_Handler.Instance->SR;  //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能
        temp = UART3_Handler.Instance->DR; //读取数据寄存器中的数据
        HAL_UART_DMAStop(&UART3_Handler); //
        if(rx3_buffer[0]!=0 && strlen((char *)rx3_buffer) > 2)
    {
            temp  = hdma_usart3_rx.Instance->NDTR;// 获取DMA中未传输的数据个数,NDTR寄存器分析见下面
            rx3_len =  BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
            recv3_end_flag = 1;  // 接受完成标志位置1
            if( rx3_len < BUFFER_SIZE)
            {
                rx3_buffer[rx3_len]= 0;                    /*此次数据最后一个*/
            }
            else
                rx3_buffer[BUFFER_SIZE-1]= 0;        /*接收BUF最后一个*/
        }
        if(BUFFER_SIZE == rx3_len)
        {
                __HAL_USART_ENABLE_IT( &UART3_Handler,USART_IT_RXNE);
        }
        else
        {
                HAL_UART_Receive_DMA(&UART3_Handler,rx3_buffer,BUFFER_SIZE);//重新打开DMA接收 
        }        
    }
    
    if(__HAL_USART_GET_FLAG( &UART3_Handler, USART_IT_RXNE) != RESET)
  {
                __HAL_USART_CLEAR_FLAG( &UART3_Handler, USART_IT_RXNE);
                __HAL_USART_DISABLE_IT( &UART3_Handler, USART_IT_RXNE);
                HAL_UART_Receive_DMA(&UART3_Handler,rx3_buffer,BUFFER_SIZE);//重新打开DMA接收 
  }
  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&UART3_Handler);
  /* USER CODE BEGIN USART3_IRQn 1 */

  /* USER CODE END USART3_IRQn 1 */
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值