首页 > 其他 > 详细

HAL库配置UART

时间:2020-10-02 09:51:36      阅读:95      评论:0      收藏:0      [点我收藏+]

1、查询(基本不用)

2、中断

3、中断+DMA

操作分3个步骤

1、设置STM32cubeMX,初始化代码在stm32f4xx_hal_msp.c,执行代码在main.C

技术分享图片

 

2、打开中断和接收相关函数

//开启空闲中断
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);  

//UART_IT_IDLE  空闲中断
//UART_IT_RXNE
//UART_IT_TXE
//UART_IT_PE
//UART_IT_TC
//UART_IT_LBD
//UART_IT_CTS
//UART_IT_ERR
                
//开启DMA接收,                                     
  HAL_UART_Receive_DMA(&huart1, (uint8_t*)uart1_rx_buf, USART1_RX_BUF_SIZE); 
  
//@file    stm32f4xx_hal_uart.c    
/*
阻塞模式Blocking mode:通信以轮询模式执行。
        (+) HAL_UART_Transmit()
        (+) HAL_UART_Receive()
非阻塞模式Non-Blocking:使用中断执行通信,这些API会返回HAL状态
        (+) HAL_UART_Transmit_IT()
        (+) HAL_UART_Receive_IT()
        (+) HAL_UART_IRQHandler()

非阻塞模式Non-Blocking:使用DMA执行通信或,这些API会返回HAL状态
        (+) HAL_UART_Transmit_DMA()
        (+) HAL_UART_Receive_DMA()
        (+) HAL_UART_DMAPause()
        (+) HAL_UART_DMAResume()
        (+) HAL_UART_DMAStop()

非阻塞模式Non-Blocking回调函数:
        (+) HAL_UART_TxHalfCpltCallback()
        (+) HAL_UART_TxCpltCallback()
        (+) HAL_UART_RxHalfCpltCallback()
        (+) HAL_UART_RxCpltCallback()
        (+) HAL_UART_ErrorCallback()

非阻塞模式Non-Blocking中止执行函数:
        (+) HAL_UART_Abort()
        (+) HAL_UART_AbortTransmit()
        (+) HAL_UART_AbortReceive()
        (+) HAL_UART_Abort_IT()
        (+) HAL_UART_AbortTransmit_IT()
        (+) HAL_UART_AbortReceive_IT()

        (+) HAL_UART_AbortCpltCallback()
        (+) HAL_UART_AbortTransmitCpltCallback()
        (+) HAL_UART_AbortReceiveCpltCallback()

*/

 

3、处理相关函数

      处理相关函数一般放在中断函数,或者回调函数内。先判断中断串口号,中断类型,清除中断类型。 

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  USER_UART_IRQHandler(&huart1);  //加入自己的中断处理函数
  /* USER CODE END USART1_IRQn 1 */
}

 

//下面是自己的空闲中断处理函数
void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
{
    if(USART1 == huart->Instance)                                   //判断是否是串口1
    {
        if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))   //判断是否是空闲中断
        {
            __HAL_UART_CLEAR_IDLEFLAG(&huart1);                     //清楚空闲中断标志(否则会一直不断进入中断)
            USAR_UART_IDLECallback(huart);                          //调用中断处理函数
        }
    }
}

 

//空闲中断回调函数
void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
{
   if(USART1 == huart->Instance){
        uint8_t data_len1;                                                          //停止本次DMA传输
        data_len1  = USART1_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);   //计算接收到的数据长度
        fifo_uart1_rx.tail =  data_len1; 
 
        if(fifo_uart1_rx.head <= fifo_uart1_rx.tail)
        {
            fifo_uart1_rx.DMAsize = fifo_uart1_rx.tail - fifo_uart1_rx.head;
        }
        else if(fifo_uart1_rx.head > fifo_uart1_rx.tail)
        {
            fifo_uart1_rx.DMAsize = USART1_RX_BUF_SIZE - fifo_uart1_rx.head + fifo_uart1_rx.tail;
        }
            fifo_uart1_rx.flag = 1;//置位标志,表示接收到数据
                
                
                
                
                __HAL_DMA_DISABLE(huart->hdmarx);
                //__HAL_DMA_SET_COUNTER(huart->hdmarx, USART1_RX_BUF_SIZE);        
            __HAL_DMA_ENABLE(huart->hdmarx);
                
        /*用户实现的回调函数*/
                memcpy(uart1_tx_dma_buf,uart1_rx_buf,data_len1);
              HAL_UART_Transmit_DMA(&huart1, uart1_tx_dma_buf, data_len1);         
               memset(uart1_rx_buf,0,sizeof(uart1_rx_buf));
    // HAL_UART_Transmit_DMA(&huart1, uart1_rx_buf, sizeof(uart1_rx_buf) - 1); 
    
        // 采用DMA发送 str,按照str实际大小发送,不发送字符串末尾的‘0‘
                
//        if(p_uart1_rx_complete_callback != NULL)
//            (*p_uart1_rx_complete_callback)(); 
//                //这里是定义的回调函数指针,
//                //用户可以自己定义这个回调函数,
//                //因为我做的这个模块是要打包给别人使用的,
//                //这种用户实现的函数都是通过函数指针定义的,
//                //这样用户可以自己定义回调函数的函数名,如果不需要回调,可以将这里注释掉;
 
    }

}

 

//串口接收环形缓冲区取出函数
//参数1:串口接收环形缓冲区对象指针
//参数2:串口接收环形缓冲区最大长度
//参数3:取出的数据缓冲区地址
//参数4:取出的数据长度
//返回数据:取出的数据长度
uint16_t uart1_get_data(uint8_t *data_rsv,uint16_t len)
{
    uint16_t i=0;
    if(fifo_uart1_rx.flag &&(fifo_uart1_rx.DMAsize > 0))//接收到数据
    {
        for(;i<len;i++)//取出环形缓冲区的数据
        {
            data_rsv[i] = fifo_uart1_rx.buf[fifo_uart1_rx.head];
            fifo_uart1_rx.head ++;
            fifo_uart1_rx.head %= USART1_RX_BUF_SIZE;
            if(fifo_uart1_rx.head == fifo_uart1_rx.tail) 
            {
                fifo_uart1_rx.flag = 0;//清空接收数据标志
                i++;
                break;
            }
        }
    }
    return (i);
}

 

HAL库配置UART

原文:https://www.cnblogs.com/icaowu/p/13760112.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!