首页 > 其他分享 > 基于LL库函数实现UART

基于LL库函数实现UART

时间:2022-08-23 21:59:04浏览次数:55  
标签:DMA STREAM USART UART LL DMA2 USART1 库函数

5. 基于LL库函数实现UART

5.1 Cube 配置

5.2 Cube 生成代码

void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  LL_USART_InitTypeDef USART_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* Peripheral clock enable */
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);

  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
  /**USART1 GPIO Configuration
  PA9   ------> USART1_TX
  PA10   ------> USART1_RX
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_9|LL_GPIO_PIN_10;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_7;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USART1 DMA Init */

  /* USART1_RX Init */
  LL_DMA_SetChannelSelection(DMA2, LL_DMA_STREAM_2, LL_DMA_CHANNEL_4);

  LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_STREAM_2, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);

  LL_DMA_SetStreamPriorityLevel(DMA2, LL_DMA_STREAM_2, LL_DMA_PRIORITY_LOW);

  LL_DMA_SetMode(DMA2, LL_DMA_STREAM_2, LL_DMA_MODE_NORMAL);

  LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_STREAM_2, LL_DMA_PERIPH_NOINCREMENT);

  LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_STREAM_2, LL_DMA_MEMORY_INCREMENT);

  LL_DMA_SetPeriphSize(DMA2, LL_DMA_STREAM_2, LL_DMA_PDATAALIGN_BYTE);

  LL_DMA_SetMemorySize(DMA2, LL_DMA_STREAM_2, LL_DMA_MDATAALIGN_BYTE);

  LL_DMA_DisableFifoMode(DMA2, LL_DMA_STREAM_2);

  /* USART1_TX Init */
  LL_DMA_SetChannelSelection(DMA2, LL_DMA_STREAM_7, LL_DMA_CHANNEL_4);

  LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_STREAM_7, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);

  LL_DMA_SetStreamPriorityLevel(DMA2, LL_DMA_STREAM_7, LL_DMA_PRIORITY_LOW);

  LL_DMA_SetMode(DMA2, LL_DMA_STREAM_7, LL_DMA_MODE_NORMAL);

  LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_STREAM_7, LL_DMA_PERIPH_NOINCREMENT);

  LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_STREAM_7, LL_DMA_MEMORY_INCREMENT);

  LL_DMA_SetPeriphSize(DMA2, LL_DMA_STREAM_7, LL_DMA_PDATAALIGN_BYTE);

  LL_DMA_SetMemorySize(DMA2, LL_DMA_STREAM_7, LL_DMA_MDATAALIGN_BYTE);

  LL_DMA_DisableFifoMode(DMA2, LL_DMA_STREAM_7);

  /* USART1 interrupt Init */
  NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
  NVIC_EnableIRQ(USART1_IRQn);

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  USART_InitStruct.BaudRate = 115200;
  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
  USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_8;
  LL_USART_Init(USART1, &USART_InitStruct);
  LL_USART_ConfigAsyncMode(USART1);
  LL_USART_Enable(USART1);
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

5.3 用户自定义代码

uint8_t gRxBuf[UART_DATA_MAX];

static void Init_UART1_DMA_LL( void );


void InitUart(uint32_t ulBaudrate)
{
    LL_USART_InitTypeDef UART_InitStruct = {0};
      
    UART_InitStruct.BaudRate = ulBaudrate;
    UART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
    UART_InitStruct.StopBits = LL_USART_STOPBITS_1;
    UART_InitStruct.Parity = LL_USART_PARITY_NONE;
    UART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
    UART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
    UART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_8;
    LL_USART_Init(USART1, &UART_InitStruct);
    
    Init_UART1_DMA_LL();
}

static void Init_UART1_DMA_LL( void )
{
    // initial TX
    LL_USART_SetTransferDirection(USART1, LL_USART_DIRECTION_TX_RX);
    LL_DMA_SetPeriphAddress(DMA2, LL_DMA_STREAM_7, (uint32_t)(&USART1->DR));
    LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_7, 0);
    
    LL_DMA_EnableIT_TC(DMA2, LL_DMA_STREAM_7);
    LL_USART_EnableDMAReq_TX(USART1);
    
    // initial RX
    LL_DMA_SetPeriphAddress(DMA2, LL_DMA_STREAM_2, (uint32_t)(&USART1->DR));
    LL_DMA_SetMemoryAddress(DMA2, LL_DMA_STREAM_2, (uint32_t)(gRxBuf));
    LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_2, UART_DATA_MAX);
    
    LL_DMA_EnableIT_TC(DMA2, LL_DMA_STREAM_2);
    LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_2);
    LL_USART_EnableDMAReq_RX(USART1);
  
    LL_USART_EnableIT_IDLE(USART1);
    LL_USART_EnableIT_RXNE(USART1);
}

void UartTransmit( uint8_t *pTxBuff,uint16_t uclenth)
{
    LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_7);
    LL_DMA_SetMemoryAddress(DMA2, LL_DMA_STREAM_7, (uint32_t)(pTxBuff));
    LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_7, uclenth);
    LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_7);
} 


void USART1_IRQHandler(void)
{
    static uint32_t ucRcvLen;
  
    if( LL_USART_IsActiveFlag_RXNE(USART1) )
    {     
        LL_USART_ClearFlag_RXNE(USART1); 
        LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_2);
        LL_DMA_SetMemoryAddress(DMA2, LL_DMA_STREAM_2, (uint32_t)(gRxBuf));
        LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_2,UART_DATA_MAX); 

        LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_2);
    }
    
    if( LL_USART_IsActiveFlag_TC(USART1) )
    {
        LL_USART_ClearFlag_TC(USART1);
        ucRcvLen = UART_DATA_MAX - LL_DMA_GetDataLength(DMA2, LL_DMA_STREAM_2);
    }  

    LL_USART_ClearFlag_PE(USART1);
    LL_USART_ClearFlag_FE(USART1); 
    LL_USART_ClearFlag_NE(USART1); 
    LL_USART_ClearFlag_ORE(USART1); 
    LL_USART_ClearFlag_IDLE(USART1); 
}


/**
  * @brief This function handles DMA2 stream2 global interrupt.
  */
void DMA2_Stream2_IRQHandler(void)
{
    if(LL_DMA_IsActiveFlag_TE2(DMA2) )
    {
      LL_DMA_ClearFlag_TE2(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_TC2(DMA2) )
    {
      LL_DMA_ClearFlag_TC2(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_HT2(DMA2) )
    {
      LL_DMA_ClearFlag_HT2(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_FE2(DMA2) )
    {
      LL_DMA_ClearFlag_FE2(DMA2);
    }
}

/**
  * @brief This function handles DMA2 stream7 global interrupt.
  */
void DMA2_Stream7_IRQHandler(void)
{
    if(LL_DMA_IsActiveFlag_TE7(DMA2) )
    {
      LL_DMA_ClearFlag_TE7(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_TC7(DMA2) )
    {
      LL_DMA_ClearFlag_TC7(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_HT7(DMA2) )
    {
      LL_DMA_ClearFlag_HT7(DMA2);
    }
    
    if(LL_DMA_IsActiveFlag_FE7(DMA2) )
    {
      LL_DMA_ClearFlag_FE7(DMA2);
    }
}

标签:DMA,STREAM,USART,UART,LL,DMA2,USART1,库函数
From: https://www.cnblogs.com/mftang2018/p/16617962.html

相关文章