串口相關寄存器即庫函數分析

庫函數及寄存器對應

在這裏插入圖片描述
上圖爲串口的框圖,主要有數據寄存器(DR)、狀態寄存器(SR)、波特比率寄存器(BRR)。
數據寄存器(DR)包含接收數據寄存器(RDR)和發送數據寄存器(TDR)等。

串口接收數據流程爲:RX接口接收到數據,通過編解碼模塊傳輸給“接收移位寄存器”,再傳遞給“接收數據寄存器(RDR)”,再傳輸給內核。
串口發送數據流程爲:內核將數據寫入“發送數據寄存器(TDR)”,再將數據存入“發送移位寄存器”,再將數據通過編解碼模塊輸出到TX接口。

圖中的發送器時鐘和接收器時鐘是通過波特比率寄存器(BRR)的設置來控制的
F103芯片的串口1的時鐘來源是PCLK2,串口2-4的時鐘開源是PCLK1,由BRR寄存器左側的“/USARTDIV”設置,參數爲1或者2,二者時鐘頻率默認均爲72MHz。

狀態寄存器(SR)用於存儲串口狀態,發送器控制單元和接收器控制單元可以對其狀態標誌位進行更改,其狀態標誌位可供中斷控制單元獲取。

控制寄存器(內部參數用於控制串口)
在這裏插入圖片描述
串口使能函數

#define CR1_UE_Set                ((uint16_t)0x2000)
#define CR1_UE_Reset              ((uint16_t)0xDFFF)
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;

void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
{
  /* Check the parameters (驗證參數)*/
  assert_param(IS_USART_ALL_PERIPH(USARTx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  /* Enable the selected USART by setting the UE bit in the CR1 register */
  /*通過在CR1寄存器中設位13來啓用所選的串口*/
  if (NewState != DISABLE)
  {  
    USARTx->CR1 |= CR1_UE_Set; 
  }
  /* Disable the selected USART by clearing the UE bit in the CR1 register */
  /*通過在CR1寄存器中設位13來禁用所選的串口*/
  else 
  {  
    USARTx->CR1 &= CR1_UE_Reset;  
  }
}

狀態寄存器(存儲串口狀態)
在這裏插入圖片描述
獲取狀態標誌位函數

typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;  
#define USART_FLAG_CTS  ((uint16_t)0x0200)

FlagStatus USART_GetFlagStatus(USART_TypeDef*  USARTx, uint16_t  USART_FLAG)
{
  FlagStatus bitstatus = RESET;  //聲明枚舉變量(狀態標記)並初始化爲0
  /* Check the parameters (驗證參數輸入是否正確)*/
  assert_param(IS_USART_ALL_PERIPH(USARTx)); //驗證是否是正確的串口名
  assert_param(IS_USART_FLAG(USART_FLAG));  //驗證標誌
  /* The CTS flag is not available for UART4 and UART5 */
  /* CTS標誌不適用於UART4和UART5。(見上圖位9)*/
  if (USART_FLAG == USART_FLAG_CTS)  //驗證串口是否是串口1、2、3
  {
    assert_param(IS_USART_123_PERIPH(USARTx)); 
  }  
  //串口號對應的SR寄存器的值與USART_FLAG進行與運算判斷對應位的值是否爲1來獲取串口的狀態,
  if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)  //若上述計算結果如果不等於0  
  { 
    bitstatus = SET;   //狀態標記設置爲1
  }       
  else 
  {
    bitstatus = RESET;   //否則爲設置0
  } 
  return bitstatus;      //返回狀態位
}

數據寄存器(存儲串口傳輸數據)
在這裏插入圖片描述在這裏插入圖片描述
串口發送函數

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) //發送數據到串口,DR寄存器
{ 
  /* Check the parameters (驗證參數) */
  assert_param(IS_USART_ALL_PERIPH(USARTx));  
  assert_param(IS_USART_DATA(Data)); 
  /* Transmit Data (發送數據)*/  //串口號對應的DR寄存器存入Data數據的9位
  USARTx->DR = (Data & (uint16_t)0x01FF);
}

串口接收函數

uint16_t USART_ReceiveData(USART_TypeDef* USARTx) //接受數據,從DR讀取接受到的數據
{  
  /* Check the parameters (驗證參數) */
  assert_param(IS_USART_ALL_PERIPH(USARTx));
  /* Receive Data(接受數據) */   //返回寄存器DR寄存器的前9位數據
  return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);
}

波特比率寄存器(設置串口通訊的波特率)
在這裏插入圖片描述
在這裏插入圖片描述

串口初始化函數中的波特率部分

void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)
{
  uint32_t  usartxbase = 0 ,  apbclock = 0x00;
  RCC_ClocksTypeDef  RCC_ClocksStatus;
  usartxbase = (uint32_t)USARTx;  //將串口的地址強制轉換成32位整數
  RCC_GetClocksFreq(&RCC_ClocksStatus);  //獲取時鐘頻率
  //如果串口地址爲串口1的地址則設置時鐘源爲PCLK2,否則爲PCLK1
  if (usartxbase == USART1_BASE)   
  {  
    apbclock = RCC_ClocksStatus.PCLK2_Frequency;  
  }
  else
  {  
    apbclock = RCC_ClocksStatus.PCLK1_Frequency;  
  }
  ……
  //將apbclock經過一系列運算(原理見上圖)得到tmpreg,並存入BRR寄存器
  USARTx->BRR = (uint16_t)tmpreg;
}

文中函數和部分內容摘自正點原子stm32資料與官方庫函數

自學新手,個人總結,如有出入,請多指教!

發佈了13 篇原創文章 · 獲贊 2 · 訪問量 2024
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章