串口設(shè)置的一般步驟
1) 串口時鐘使能,GPIO 時鐘使能
注:串口是掛載在 APB2 下面的外設(shè)還需要需要掛載復(fù)用時鐘使能
//掛載時鐘(復(fù)用PA) 串口時鐘使能,GPIO 時鐘使能,復(fù)用時鐘使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
2) 串口復(fù)位
//系統(tǒng)剛開始配置外設(shè)的時候,都會先執(zhí)行復(fù)位該外設(shè)的操作。
void USART_DeInit(USART_TypeDef* USARTx);//串口復(fù)位
3) GPIO 端口模式設(shè)置
注意:RXT、TXT輸入輸出方向不同。
GPIO_InitTypeDef GPIO_InitTypeDef_RXDPA10;
GPIO_InitTypeDef GPIO_InitTypeDef_TXDPA9;
//PA9 TXD初始化
GPIO_InitTypeDef_TXDPA9.GPIO_Pin = GPIO_Pin_9;//PA9 TXD
GPIO_InitTypeDef_TXDPA9.GPIO_Mode = GPIO_Mode_AF_PP;////復(fù)用推挽輸出
GPIO_InitTypeDef_TXDPA9.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitTypeDef_TXDPA9);
//PA10 TXD初始化
GPIO_InitTypeDef_RXDPA10.GPIO_Pin = GPIO_Pin_10;//PA10 RXD
GPIO_InitTypeDef_RXDPA10.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_Init(GPIOA,&GPIO_InitTypeDef_RXDPA10);
4) 串口參數(shù)初始化
//初始化函數(shù)
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
//第一個入口參數(shù)是指定初始化的串口標(biāo)號
//第二個入口參數(shù)是一個 USART_InitTypeDef 類型的結(jié)構(gòu)體指針
//USART初始化配置
USART_InitTypeDef USART_InitTypeDef_USART1;
USART_InitTypeDef_USART1.USART_BaudRate = 115200;//波特率
USART_InitTypeDef_USART1.USART_WordLength = USART_WordLength_8b;//發(fā)送數(shù)據(jù)長度
USART_InitTypeDef_USART1.USART_StopBits = USART_StopBits_1; //一個停止位
USART_InitTypeDef_USART1.USART_Parity = USART_Parity_No; //無奇偶校驗位
USART_InitTypeDef_USART1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制
USART_InitTypeDef_USART1.USART_Mode = USART_Mode_Tx| USART_Mode_Rx ;//發(fā)送+接收模式
USART_Init(USART1,&USART_InitTypeDef_USART1);
5) 開啟中斷并且初始化 NVIC(如果需要使用中斷才需要這個步驟)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設(shè)置NVIC中斷分組2(mcu復(fù)位默認(rèn)2組): 2位搶占優(yōu)先級,2位響應(yīng)優(yōu)先級
NVIC_InitTypeDef NVIC_InitTypeDef_USART1;
NVIC_InitTypeDef_USART1.NVIC_IRQChannel = USART1_IRQn;// “USART1_IRQn”在固件庫“stm32f10x.h”文件可以查看
NVIC_InitTypeDef_USART1.NVIC_IRQChannelPreemptionPriority = 0X00; //搶占優(yōu)先級 3
NVIC_InitTypeDef_USART1.NVIC_IRQChannelSubPriority = 0X00; //子優(yōu)先級 3
NVIC_InitTypeDef_USART1.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
NVIC_Init(&NVIC_InitTypeDef_USART1);
//開啟中斷
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //開啟串口接受中斷
6) 使能串口
USART_Cmd(USART1, ENABLE);//使能串口
7) 編寫中斷處理函數(shù)
//串口中斷服務(wù)程序“USART1_IRQHandler”在固件庫給好了的名字
void USART1_IRQHandler()
{
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) != RESET)//判斷中斷標(biāo)志位
{
ucaRxBuf[usRxCount++] =USART_ReceiveData(USART1); //保存接收到的
}
USART_ClearFlag(USART1,USART_FLAG_RXNE);
}
/*固件庫“stm32f10x_usart.h”所給定的標(biāo)志位
USART_FLAG_CTS/*CTS標(biāo)志位*/
USART_FLAG_LBD/*LIN中斷檢測標(biāo)志位*/
USART_FLAG_TXE/*發(fā)送數(shù)據(jù)寄存器空標(biāo)志位*/
USART_FLAG_TC/*發(fā)送完成標(biāo)志位*/
USART_FLAG_RXNE/*接收數(shù)據(jù)寄存器非空標(biāo)志位*/
USART_FLAG_IDLE/*空閑總線標(biāo)志位*/
USART_FLAG_ORE/*溢出錯誤標(biāo)志位*/
USART_FLAG_NE/*噪聲錯誤標(biāo)志位*/
USART_FLAG_FE/*幀錯誤標(biāo)志位*/
USART_FLAG_PE/*奇偶錯誤標(biāo)志位*/
*/
數(shù)據(jù)的發(fā)送與接收
STM32 的發(fā)送與接收是通過數(shù)據(jù)寄存器 USART_DR 來實現(xiàn)的,這是一個雙寄存器,包含了 TDR 和 RDR。當(dāng)向該寄存器寫數(shù)據(jù)的時候,串口就會自動發(fā)送,當(dāng)收到數(shù)據(jù)的時候,也是存在該寄存器內(nèi)。
//固件庫的發(fā)送數(shù)據(jù)函數(shù)
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
//固件庫的發(fā)送數(shù)據(jù)函數(shù)
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
字符串的發(fā)送函數(shù)
固件庫給定的收函數(shù)只可以接收發(fā)送單個字,下面有兩個發(fā)送字符串的函數(shù)
void Usart_SendByte(uint8_t ch)
{
/* 發(fā)送一個字節(jié)數(shù)據(jù)到USART1 */
USART_SendData(USART1,ch);
/* 等待發(fā)送完畢 */
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //判斷讀寄存器是否非空(RXNE)
//判斷發(fā)送是否完成(TC)USART_GetFlagStatus(USART1, USART_FLAG_TC);
}
//發(fā)送給定長度的字符串
void Usart_SendStr_length(uint8_t *str,uint32_t strlen)
{
unsigned int k=0;
do
{
Usart_SendByte(*(str + k));
k++;
} while(k < strlen);
}
//發(fā)送字符串
void Usart_SendString(uint8_t *str)
{
unsigned int k=0;
do
{
Usart_SendByte(*(str + k));
k++;
} while(*(str + k)!='