STM32串口的設(shè)置和庫(kù)函數(shù)的介紹
串口設(shè)置的一般步驟可以總結(jié)為如下幾個(gè):
1) 串口時(shí)鐘使能, GPIO時(shí)鐘使能
2) 串口復(fù)位
3)GPIO 端口模式設(shè)置
4) 串口參數(shù)初始化
5) 開(kāi)啟中斷并且初始化 NVIC(如果需要開(kāi)啟中斷才這個(gè)步驟) (如果需要開(kāi)啟中斷才這個(gè)步驟)
6) 使能串口 使能串口
7) 編寫(xiě)中斷處理函數(shù)
下面,我們就簡(jiǎn)單介紹這幾個(gè)與串口基本配置直接相關(guān)的固件庫(kù)函數(shù)。這些函數(shù)和 定義主要分布在 stm32f10x_usart.h ,stm32f10x_usart.c 文件中。
1.串口時(shí)鐘使能。串口是掛載在APB2上的,所以使能函數(shù)為:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1)
2.串口復(fù)位。當(dāng)外設(shè)出現(xiàn)異常的時(shí)候可以通過(guò)復(fù)位置 ,實(shí)現(xiàn)該外設(shè)的復(fù)位,然后重新配置這個(gè)外設(shè)讓其重新工作的目。一般在系統(tǒng)剛開(kāi)始配置時(shí)候,都會(huì)先執(zhí)行復(fù)位該這個(gè)外 設(shè)達(dá)到讓其重新工作的目。復(fù)位是在函數(shù) USART_DeInit()完成:
void USART_DeInit(USART_TypeDef* USARTx)
3串口參數(shù)初始化
void USART_Init()函數(shù):
voidUSART_Init(USART_TypeDef*USARTx,USART_InitTypeDef*USART_InitStruct);
作用:
根據(jù)指定參數(shù)初始化相應(yīng)串口(波特率,字長(zhǎng),停止位,奇偶校驗(yàn),硬件流控制等)
主要是用來(lái)初始化寄存器BRR以及CR1,CR2,CR3控制寄存器
使用范例:
USART_InitTypeDefUSART_InitStructure;
USART_InitStructure.USART_BaudRate= 9600;//波特率設(shè)置;
USART_InitStructure.USART_WordLength= USART_WordLength_8b;//字長(zhǎng)為8位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits= USART_StopBits_1;//一個(gè)停止位
USART_InitStructure.USART_Parity= USART_Parity_No;//無(wú)奇偶校驗(yàn)位
USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None; //無(wú)硬件數(shù)據(jù)流控制
USART_InitStructure.USART_Mode= USART_Mode_Rx| USART_Mode_Tx; //收發(fā)模式
USART_Init(USART1,&USART_InitStructure);//初始化串口
4.void USART_Cmd()函數(shù):
原型:
voidUSART_Cmd(USART_TypeDef*USARTx,FunctionalStateNewState);
作用:
使能相應(yīng)的串口,用來(lái)設(shè)置寄存器CR1的串口使能位
使用范例:
USART_Cmd(USART1,ENABLE); //使能串口1
5.void USART_ITConfig()函數(shù):
原型:voidUSART_ITConfig(USART_TypeDef*USARTx,
uint16_t USART_IT, FunctionalStateNewState);
作用:開(kāi)啟串口相應(yīng)中斷,設(shè)置串口控制寄存器
使用范例:
USART_ITConfig(USART1,USART_IT_RXNE, ENABLE); //開(kāi)啟讀數(shù)據(jù)寄存器非空中斷
6.USART_SendData()函數(shù):
原型:
voidUSART_SendData(USART_TypeDef* USARTx, uint16_t Data);
作用:
發(fā)送數(shù)據(jù)到串口。
使用范例:
USART_SendData(USART1,0x12);
7.uint16_tUSART_ReceiveData()函數(shù):
原型: uint16_t USART_ReceiveData(USART_TypeDef*USARTx)
獲取串口最新接受的值。
使用范例:
USART_ReceiveData(USART1);
8.四個(gè)狀態(tài)標(biāo)志相關(guān)的函數(shù):
FlagStatusUSART_GetFlagStatus(USART_TypeDef*USARTx,uint16_t USART_FLAG);
void USART_ClearFlag(USART_TypeDef*USARTx,uint16_t USART_FLAG);
ITStatusUSART_GetITStatus(USART_TypeDef*USARTx,uint16_t USART_IT);
void USART_ClearITPendingBit(USART_TypeDef*USARTx,uint16_t USART_IT);
以下是一個(gè)完整的初始化串口函數(shù)和一個(gè)中斷服務(wù)函數(shù):
//初始化IO 串口1
//bound:波特率
void uart_init(u32 bound){
//GPIO端口設(shè)置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);//使能USART1,GPIOA時(shí)鐘
USART_DeInit(USART1); //復(fù)位串口1
//USART1_TX PA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//復(fù)用推挽輸出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
//USART1_RX PA.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優(yōu)先級(jí)3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//子優(yōu)先級(jí)3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure);//根據(jù)指定的參數(shù)初始化VIC寄存器
//USART 初始化設(shè)置
USART_InitStructure.USART_BaudRate = bound;//一般設(shè)置為9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長(zhǎng)為8位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個(gè)停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//無(wú)奇偶校驗(yàn)位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無(wú)硬件數(shù)據(jù)流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收發(fā)模式
USART_Init(USART1, &USART_InitStructure); //初始化串口
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開(kāi)啟中斷
USART_Cmd(USART1, ENABLE); //使能串口
}
void USART1_IRQHandler(void) //串口1中斷服務(wù)程序
{
u8 Res;
#ifdef OS_TICKS_PER_SEC //如果時(shí)鐘節(jié)拍數(shù)定義了,說(shuō)明要使用ucosII了.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中斷(接收到的數(shù)據(jù)必須是0x0d 0x0a結(jié)尾)
{
Res =USART_ReceiveData(USART1);//(USART1->DR);//讀取接收到的數(shù)據(jù)
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收錯(cuò)誤,重新開(kāi)始
else USART_RX_STA|=0x8000;//接收完成了
}
else //還沒(méi)收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收數(shù)據(jù)錯(cuò)誤,重新開(kāi)始接收
}
}
}
}
#ifdef OS_TICKS_PER_SEC//如果時(shí)鐘節(jié)拍數(shù)定義了,說(shuō)明要使用ucosII了.
OSIntExit();
#endif
}