stm32中的初始IO串口程序没有看懂,向高手请教

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stm32中的初始IO串口程序没有看懂,向高手请教相关的知识,希望对你有一定的参考价值。

//初始化 IO 串口 1
//pclk2:PCLK2 时钟频率(Mhz)
//bound:波特率
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=0X444444B4;//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(3,3,USART1_IRQChannel,2);//组 2,最低优先级
#endif

第一个问题:为什么GPIOA->CRH=0X444444B4要这么设置,除第九位复用输出外其余位为模拟输入?
第二个问题:RCC->APB2RSTR|=1<<14; //复位串口 1
RCC->APB2RSTR&=~(1<<14);//停止复位
为什么先复位又停止复位?实现的是什么?
第三个问题:
#ifdef EN_USART1_RX //如果使能了接收
USART1->CR1|=1<<8; //使能接收中断,PE 中断使能
USART1->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组 2,最低优先级
#endif
这每一句是什么意思?

首先,这段代码是对usart1 进行初始化,包括io口,时钟,波特率,接收中断以及优先级。
下面回答你第一个问题:他只是要设置GPIOA_Pin_9,这个口是usart1 的发送端,即USART1_TX,其他口无所谓。
第二个问题,对usart1先进行复位,就比如单片机使用时习惯先复位,目的是让它处于一个明确的初始状态
第三个问题,可能你参考了一些其他程序,这里先给你源函数
void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)

u32 temp,temp1;
temp1=(~NVIC_Group)&0x07;//取后三位
temp1<<=8;
temp=SCB->AIRCR; //读取先前的设置
temp&=0X0000F8FF; //清空先前分组
temp|=0X05FA0000; //写入钥匙
temp|=temp1;
SCB->AIRCR=temp; //设置分组


//设置NVIC
//NVIC_PreemptionPriority:抢占优先级
//NVIC_SubPriority :响应优先级
//NVIC_Channel :中断编号
//NVIC_Group :中断分组 0~4
//注意优先级不能超过设定的组的范围!否则会有意想不到的错误
//组划分:
//组0:0位抢占优先级,4位响应优先级
//组1:1位抢占优先级,3位响应优先级
//组2:2位抢占优先级,2位响应优先级
//组3:3位抢占优先级,1位响应优先级
//组4:4位抢占优先级,0位响应优先级
//NVIC_SubPriority和NVIC_PreemptionPriority的原则是,数值越小,越优先
//CHECK OK
//100329
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)

u32 temp;
u8 IPRADDR=NVIC_Channel/4; //每组只能存4个,得到组地址
u8 IPROFFSET=NVIC_Channel%4;//在组内的偏移
IPROFFSET=IPROFFSET*8+4; //得到偏移的确切位置
MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
temp=NVIC_PreemptionPriority<<(4-NVIC_Group);
temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
temp&=0xf;//取低四位

if(NVIC_Channel<32)NVIC->ISER[0]|=1<<NVIC_Channel;//使能中断位(要清除的话,相反操作就OK)
else NVIC->ISER[1]|=1<<(NVIC_Channel-32);
NVIC->IPR[IPRADDR]|=temp<<IPROFFSET;//设置响应优先级和抢断优先级


可能你没有看MY_NVIC_Init()
参考技术手册
USART1->CR1|=1<<8;
PEIE: PE 中断使能
软件对该位置位或者清零
0:中断被禁止;
1:当USART_SR中的PE为1 时,产生USART中断。

USART1->CR1|=1<<5;
RXNEIE: 接收缓冲区非空中断使能
软件对该位置位或者清零
0:中断被禁止;
1:当USART_SR中的ORE或者RXNE 为1时,产生USART中断。

接下来一句MY_NVIC_Init(3,3,USART1_IRQChannel,2);就是进行中断分组,优先级设置。

我也在学stm32,有什么不懂的,再一起探讨。追问

谢谢
IPROFFSET=IPROFFSET*8+4; 为什么乘以8再加4呢
2)MY_NVIC_Init(3,3,USART1_IRQChannel,2);
按这个来说,抢占优先级是3,响应优先级是3,但是抢占和响应不是一共就有4个优先级吗?
3)按MY_NVIC_Init(3,3,USART1_IRQChannel,2)来说,设置完分组之后的三句指令是不是
A.temp为三左移两位 变成001100
B.00001111右翼两位变成000011,再和3与变成000011,再和temp或,得到新的temp为001111
C.取temp低四位为1111

参考技术A 1:B代表复用输出这个没问题吧 4代表浮空输入是复位时候的状态 接收端口也设置成浮空输入。。。
2:一般在系统使用外设的时候都要先复位 开了复位 然后要关上这个不难理解吧
3:这个是用来定义接收中断
参考技术B hao a本回答被提问者采纳

以上是关于stm32中的初始IO串口程序没有看懂,向高手请教的主要内容,如果未能解决你的问题,请参考以下文章

STM32——DMA接收和发送的实现

stm32f7的串口TX如何设置

STM32串口发送接收数据

STM32串口通讯程序

STM32串口遇到的一个问题

stm32的串口1和串口2配置的区别