串口設置的一般步驟可以總結為如下幾個步驟:
1) 串口時鍾使能,GPIO 時鍾使能
2) 串口復位
3) GPIO 端口模式設置
4) 串口參數初始化
5) 開啟中斷並且初始化 NVIC(如果需要開啟中斷才需要這個步驟)
6) 使能串口
7) 編寫中斷處理函數
淡藍色是以串口1舉例,深藍色是以結構體函數,可拿結構體復制到Keil5中,右鍵

仔細看結構體里要求的模式等
1.串口時鍾使能:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);
2.串口復位:
void USART_DeInit(USART_TypeDef* USARTx);//串口復位
假設,復位串口 1:
USART_DeInit(USART1); //復位串口
3.串口參數初始化:設置波特率,字長,停止位,奇偶校驗位,硬件數據流控制,模式(收,發):
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
假設,對串口1參數初始化
USART_InitStructure.USART_BaudRate = bound; //波特率;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為 8 位數據格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; //一個停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //無奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None; //無硬件數據流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發模式
USART_Init(USART1, &USART_InitStructure); //初始化串口
4.數據發送與接收:
STM32 庫函數操作 USART_DR 寄存器發送數據的函數是:
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
通過該函數向串口寄存器 USART_DR 寫入一個數據。
STM32 庫函數操作 USART_DR 寄存器讀取串口接收到的數據的函數是:
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
通過該函數可以讀取串口接受到的數據。
5.串口狀態:
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
RXNE:讀取數據
判斷讀寄存器是否非空(RXNE),操作庫函數的方法是:
USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
TC:發送完成
我們要判斷發送是否完成(TC),操作庫函數的方法是:
USART_GetFlagStatus(USART1, USART_FLAG_TC);
6.串口使能:
USART_Cmd(USART1, ENABLE);
7.開啟串口響應中斷:
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT,FunctionalState NewState)
收到數據產生中斷
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟中斷,接收到數據中斷
發送數據開啟中斷
USART_ITConfig(USART1,USART_IT_TC,ENABLE);
8.獲取相應中斷狀態:
USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
串口發送完成中斷,那么當中斷發生了, 我們便可以在中斷處理函數中調用這
個函數來判斷到底是否是串口發送完成中斷,方法是:
USART_GetITStatus(USART1, USART_IT_TC)
串口例子
//初始化 IO 串口 1
//bound:波特率
void uart_init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//①串口時鍾使能,GPIO 時鍾使能,復用時鍾使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能 USART1,GPIOA 時鍾
//②串口復位
USART_DeInit(USART1); //復位串口 1
//③GPIO 端口模式設置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //ISART1_TX PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1_RX PA.10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.10
//④串口參數初始化
USART_InitStructure.USART_BaudRate = bound; //波特率設置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字長為 8 位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //一個停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //無奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None; //無硬件數據流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收發模式
USART_Init(USART1, &USART_InitStructure); //初始化串口
#if EN_USART1_RX //如果使能了接收
//⑤初始化 NVIC
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ; //搶占優先級 3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優先級 3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
NVIC_Init(&NVIC_InitStructure); //中斷優先級初始化
//⑤開啟中斷
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //開啟中斷
#endif
//⑥使能串口
USART_Cmd(USART1, ENABLE); //使能串口
}