//初始化IO 串口1
//pclk2:PCLK2时钟频率(Mhz) //bound:波特率 //CHECK OK //091209
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;
GPIOA->CRH|=0X000008B0;//IO状态设置
RCC->APB2RSTR|=1<<14; //复位串口1 RCC->APB2RSTR&=~(1<<14);//停止复位 //波特率设置
USART1->BRR=mantissa; // 波特率设置 USART1->CR1|=0X200C; //1位停止,无校验位. #ifdef EN_USART1_RX //如果使能了接收 //使能接收中断
USART1->CR1|=1<<8; //PE中断使能
USART1->CR1|=1<<5; //接收缓冲区非空中断使能 MY_NVIC_Init(2,3,USART1_IRQChannel,2);//组2,最低优先级 #endif } 解释:STM32的每个串口都有一个自己独立的波特率寄存器USART_BRR,通过设置该寄存器就可以达到配置不同波特率的目的。其各位描述如下图所示:
前面提到STM32的分数波特率概念,其实就是在这个寄存器(USART_BRR)里面体现的。USART_BRR的最低4位(位[3:0])用来存放小数部分DIV_Fraction,紧接着的12位(位[15:4])用来存放整数部分DIV_Mantissa,最高16位未使用。 这里,我们简单介绍一下波特率的计算,STM32的串口波特率计算公式如下:
上式中,是给串口的时钟(PCLK1用于USART2、3、4、5,PCLK2用于USART1);USARTDIV是一个无符号定点数。我们只要得到USARTDIV的值,就可以得到串口波特率寄存器USART1->BRR的值,反过来,我们得到USART1->BRR的值,也可以推导出USARTDIV的值。但我们更关心的是如何从USARTDIV的值得到USART_BRR的值,因为一般我们知道的是波特率,和PCLKx的时钟,要求的就是USART_BRR的值。
下面我们来介绍如何通过USARTDIV得到串口USART_BRR寄存器的值。假设我们的串口1要设置为9600的波特率,而PCLK2的时钟为72M。这样,我们根据上面的公式有:
USARTDIV=72000000/(9600*16)=468.75 那么得到:
DIV_Fraction=16*0.75=12=0X0C; DIV_Mantissa= 468=0X1D4;
这样,我们就得到了USART1->BRR的值为0X1D4C。只要设置串口1的BRR寄存器值为
0X1D4C就可以得到9600的波特率。 当然,并不是任何条件下都可以随便设置串口波特率的,在某些波特率和PCLK2频率下,还是会存在误差的,具体可以参考《STM32参考手册》的第525页的表176。
接下来,我们就可以初始化串口了,需要注意的是这里初始化串口是按8位数据格式,1位停止位,无奇偶校验位的。
RCC->APB2ENR|=1<<14; //使能串口时钟 寄存器位如下: 位14 USART1EN:USART1时钟使能 由软件置’1’或清’0’ 0:USART1时钟关闭; 1:USART1时钟开启。 GPIOA->CRH&=0XFFFFF00F; GPIOA->CRH|=0X000008B0;//IO状态设置
IO设置成上啦或下拉模式,一个输入一个输出。
RCC->APB2RSTR|=1<<14; //复位串口1 RCC->APB2RSTR&=~(1<<14);//停止复位
具体查看RCC->APB2RSTR寄存器的定义。
USART1->CR1|=0X200C; //1位停止,无校验位. USART1->CR1|=1<<8; //PE中断使能
USART1->CR1|=1<<5; //接收缓冲区非空中断使能 参考控制寄存器1(USART_CR1) 参考手册496页。
MY_NVIC_Init(2,3,USART1_IRQChannel,2);//组2,最低优先级 USART1_IRQChannel是中断编号。
//#define USART1_IRQChannel ((u8)0x25) /* USART1 global Interrupt */
相关推荐: