文章
博客 网店

 STM32G0 LL库示例-USART



#define USART1_BUF_SIZE 128
static uint8_t g_Rx1Buffer[USART1_BUF_SIZE];//接收缓冲区
static uint8_t g_Tx1Buffer[USART1_BUF_SIZE];//发送缓冲区
uint32_t g_Rx1Index;//接收字节索引
static volatile uint8_t g_Rx1Flag;//接收数据包标志
static uint8_t g_Rx1Timer;//数据包接收完成计数器
static volatile uint8_t g_Tx1Flag;//发送数据包标志
static uint32_t g_Tx1Size;  //发送长度
static uint32_t g_Tx1Index;  //发送索引

void USART1_Init(uint32_t baud)//初始化
{

  LL_USART_InitTypeDef USART_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK1);

  //Peripheral clock enable
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
  
  LL_SYSCFG_EnablePinRemap(LL_SYSCFG_PIN_RMP_PA11);
  LL_SYSCFG_EnablePinRemap(LL_SYSCFG_PIN_RMP_PA12);

  //PA9   ------> USART1_TX
  //PA10   ------> USART1_RX
  GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;
  USART_InitStruct.BaudRate = baud;
  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_16;
  LL_USART_Init(USART1, &USART_InitStruct);
  
  LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);
  LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);
  LL_USART_DisableFIFO(USART1);
  LL_USART_ConfigAsyncMode(USART1);
  
  //中断打开
  NVIC_SetPriority(USART1_IRQn, 1);
  NVIC_EnableIRQ(USART1_IRQn);
  
  LL_USART_EnableIT_RXNE_RXFNE(USART1);//接收中断打开  
  
//  LL_USART_SetRxTimeout(USART2,39);//接收时字节间隔为3.5个字节时间时认定数据包结束
//  LL_USART_EnableRxTimeout(USART2);

       LL_USART_Enable(USART1);
  
  //状态量初始化
  g_Tx1Index=0;
  g_Tx1Size=0;
  g_Tx1Flag=0;
  
  g_Rx1Index=0;  
  g_Rx1Flag=UART_RX_IDLE;
  g_Rx1Timer=0;

  //Polling USART1 initialisation
  while((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1))))
  {
  }
}

//发送
uint32_t Serial1Write(uint8_t *buf,uint32_t len)
{
  uint8_t i;
  
  if(g_Tx1Flag) //有未发送完成数据包
    return 0;
  
  for(i=0;i<len;i++)
    g_Tx1Buffer[i]=buf[i];
  
  g_Tx1Size=len;
  g_Tx1Index=0;
  g_Tx1Flag=1;//正在发送  
  
  LL_USART_ClearFlag_TC(USART1);
  LL_USART_EnableIT_TXE(USART1);//发送寄存器空中断允许
  return i;  
}

//读接收包
uint32_t Serial1Read(uint8_t *buf)
{
  uint32_t i,len;
  
  if(g_Rx1Flag != UART_RX_READY)
    return 0;
  
  len=g_Rx1Index;
  for(i=0;i<len;i++)
    buf[i]=g_Rx1Buffer[i];
  
  do{g_Rx1Index=0;}while(g_Rx1Index);
  do{g_Rx1Flag=UART_RX_IDLE;}while(g_Rx1Flag!=UART_RX_IDLE);
  
  return len;  
}


//中断处理
void USART1_IRQHandler(void)
{
  uint8_t c;
  
  //接收到一个字节
  if(LL_USART_IsActiveFlag_RXNE_RXFNE(USART1))
  {
    c=LL_USART_ReceiveData8(USART1);
    if(g_Rx1Flag != UART_RX_READY)//没有已接收数据包
    {
      g_Rx1Timer=0;
      g_Rx1Flag=UART_RX_BUSY;
      if(g_Rx1Index<USART1_BUF_SIZE)
        g_Rx1Buffer[g_Rx1Index++]=c;
    }
    else
    {      //触发接收完成
                  //frm_set_event(EVENT_UART1_ID);
                }
  }

  //发送完成处理
  if(LL_USART_IsActiveFlag_TC(USART1))
  {
    LL_USART_DisableIT_TC(USART1);//关闭发送完成中断
    LL_USART_ClearFlag_TC(USART1);
    //LL_USART_RequestTxDataFlush(USART2);
    g_Tx1Flag=0;
  }  
  else
  {
    //发送处理
    if(LL_USART_IsActiveFlag_TXE_TXFNF(USART1))
    {
      if(g_Tx1Size > g_Tx1Index)
        LL_USART_TransmitData8(USART1, g_Tx1Buffer[g_Tx1Index++]);
      else
      {
        LL_USART_EnableIT_TC(USART1);//发送完成中断使能
        LL_USART_DisableIT_TXE(USART1);//发送寄存器空中断禁止
      }
    }        
  }
}

通常判断UART接收一个数据包完成需要一个定时器,

//1ms周期调用
void SerialTimerTick(void)
{

  if(g_Rx1Flag==UART_RX_BUSY)
  {
    if(++g_Rx1Timer>5)
    {
      g_Rx1Flag=UART_RX_READY;
      //frm_set_event(EVENT_UART1_ID);
                        //表示接收一个数据包完成
    }
  }
}




芯艺工作室    蒙ICP备06005492号
Copyright© 2004-2023 ChipArt Studio All Rights Reserved