串口的使用:只要开启串口时钟,设置相应的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;//接收数据错误,重新开始接收
}
}
}
}