串口的使用:只要開啟串口時鍾,設置相應的I/O口的模式,然后配置下波特率、數據位長度、奇偶校驗等信息,即可使用。
一:串口的配置步驟
①串口時鍾使能
1.APB2外設時鍾使能寄存器(RCC_APB2ENR)
Eg:RCC->APB2ENR| = 1<<14; //使能串口1時鍾
2.PB1外設時鍾使能寄存器(RCC_APB1ENR)
Eg:RCC->APB1ENR| = 1<<17; //使能串口2時鍾
注意!!!!
除串口1的時鍾使能在RCC_APB2ENR寄存器,其余的時鍾使能位在寄存器RCC_APB1ENR寄存器,而APB2(72M)的頻率一般是APB1(36M)的一倍
②串口復位
一般在系統剛開始配置外設時,都會先執行復位該外設的操作,而復位后要將其結束復位。
串口復位主要在寄存器RCC_APB2RSTR(串口1的復位)和寄存器RCC_APB1RSTR(串口2-5的復位)。
1.APB2外設復位寄存器 (RCC_APB2RSTR)
Eg:RCC->APB2RSTR |= 1<<14; //復位串口1
RCC->APB2RSTR &= ~(1<<14); //停止復位
2.APB1外設復位寄存器 (RCC_APB1RSTR)
Eg: RCC->APB1RSTR |= 1<<17; //復位串口2
RCC->APB1RSTR &= ~(1<<17); //停止復位
③串口波特率設置
封裝在usart.c文件里面可以直接調用。
Eg: USART3->BRR=mantissa2;
Eg:USART1->CR1|=0X200C; //1位停止,無校驗位. 0X200C=0010 0000 0000 1100
⑤數據的發送和接收
數據寄存器(USART_DR)
Eg: COM3.Dat[COM3.len] = USART3->DR;
說明:在中斷時候 進行數據的接受
⑥串口狀態
狀態寄存器(USART_SR)
Eg:if(USART3->SR&BIT5)
在中斷中使用 用來判斷是否有數據傳輸過來
二:關於波特率的計算
1.波特率可以設置為9600 115200等
2.Tx/Rx波特率 = fPCLKx / (16*USARTDIV) 注:fPCLKx為系統時鍾屏頻率
3.USARTDIV = 72000000 / (16 * 9600) = 468.75
4.DIV_Fraction(小數部分) = 16*0.75 = 12 = 0x0C
DIV_Mantissa(整數部分) = 468 = 0x1D4
5.USART1->BRR = 0x1D4C
三:配置串口1示例程序
void uart_init(u32 pclk2,u32 bound) //時鍾頻率和波特率
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整數部分
fraction=(temp-mantissa)*16; //得到小數部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2; //使能PORTA時鍾
RCC->APB2ENR|=1<<14; //使能串口時鍾
GPIOA->CRH&=0XFFFFF00F;//IO狀態設置 PA9 PA10
GPIOA->CRH|=0X000008B0;//IO狀態設置
RCC->APB2RSTR|=1<<14; //復位串口1
RCC->APB2RSTR&=~(1<<14);//停止復位
//波特率設置
USART1->BRR=mantissa; // 波特率設置
USART1->CR1|=0X200C; //1位停止 無校驗位
#if EN_USART1_RX //如果使能了接收
//使能接收中斷
USART1->CR1|=1<<8; //PE中斷使能
USART1->CR1|=1<<5; //接收緩沖區非空中斷使能
MY_NVIC_Init(3,3,USART1_IRQn,2);//組2 最低優先級
#endif
}
void USART1_IRQHandler(void)
{
u8 res;
if(USART1->SR&(1<<5))//接收到數據
{
res=USART1->DR;
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(res!=0x0a)USART_RX_STA=0;//接收錯誤,重新開始
else USART_RX_STA|=0x8000; //接收完成了
}else //還沒收到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;//接收數據錯誤,重新開始接收
}
}
}
}