庫函數及寄存器對應
上圖爲串口的框圖,主要有數據寄存器(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資料與官方庫函數
自學新手,個人總結,如有出入,請多指教!