Stm32时钟分析
最后:配置SW,以及SWS。表示启用HIS作为系统时钟。
到这一步,经过分析得知,RCC->CFGR &= 0xF8FF0000;主要是用来配置ahb等各个分频器的设置,以及将片内时钟作为系统内部时钟。
(6)
RCC->CR &= 0xFEF6FFFF;
通过分析CR寄存器可以看出,该寄存器主要涉及三个时钟PLL,CSS,HSE。
(7)
RCC->CR &= 0xFFFBFFFF;这一步有什么作用呢?查询数据手册57页可知,外部时钟源HSE有两种模式,HSEBYP设置为0时,是选择外部晶体作为外部时钟源这种时钟更加精准,当然也是和外部电路有关的。当然因为第(6)步已经设置了HSEON关闭了,所以这一步才可自由设置HSEBYP。
(8)
RCC->CFGR &= 0xFF80FFFF;
注意:在这一部中可能会有这样的疑问:
RCC->CFGR &= 0xFF80FFFF;
PLLSRC=0 HSI振荡器时钟经2分频后作为PLL输入时钟
PLLXTPRE=0,HSE分频器作为PLL输入,HSE不分频
这样不冲突吗?
答案是:以最后配置为准,就是最后一次配置会改变前一次的配置,所以说以最后一次配置为准。
也就是说后文还有其他代码对其进行定义。那干嘛还要怎么重复配置呢?
有时候是有用的。比如你想让stm32超频一会,然后又恢复正常运行,这就有用了。
(9)
RCC->CIR = 0x00000000;
(10)
#ifndef VECT_TAB_RAM
#else
#endif
下面对该函数分析:
//函数功能:设置向量表偏移地址
//NVIC_VectTab:基址
//Offset:偏移量
void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset)
{
}
前面两行是用来检查参数合法性,这里不作分析。重点看第三行
配置这个向量表有什么用?相见cortexm3权威指南113页向量表的解释
这里
#define NVIC_VectTab_RAM
#define NVIC_VectTab_FLASH
Offset的值为0x0,为偏移地址,地址必须能被64 * 4 = 256整除,具体请看权威手册113页
SCB->VTOR = NVIC_VectTab|(Offset & (u32)0x1FFFFF80);//设置NVIC的向量表偏移寄存器。
既然是设置NVIC的向量表偏移量,为什么还要和NVIC_VectTab相或呢。只设置OFFSET不就可以了吗,另外VTOR设置只有BIT【28:7】有作用啊,相或以后也放不下这么多位吧?
这个是基址。
那个7~28的,你能定义一个28位的数据出来嘛?
VTOR设置只有BIT【28:7】,你把(u32)0x1FFFFF80二进制看看是不是【28:7】。
然后再看下面一段话:
地址必须能被64*4=256整除,从而合法的起始地址可以是:0x0, 0x100, 0x200等。
答案:cortex-m3权威指南上介绍
下面我们回到例说stm32这本书61页的Stm32_Clock_Init()函数:
经过上面配置完毕后,下面开始配置外部时钟。
Ministm32开发板目前的实都是采用高速外部时钟作为时钟源,在经过MYRCC_Deinit()先将外部时钟源关闭,然后在cfgr重新配置之后,下面就准备开启高速外部时钟。
(11)
(12)
While(!(RCC->CR>>17));
对此,原子哥也说了写成(RCC-CR>>17)&0X01比较合适,但我感觉RCC-CR>>17是不准确的,比方说如果第十八位是1,那么右移17位后不管时钟是否就绪,表达式“RCC-CR>>17”的结果始终为真,这样while(!(RCC-CR>>17))不就没有意义了吗?所以写成(RCC-CR>>17)&0X01才是最准确的
)
(13)
RCC->CFGR = 0x00000400;
(14)
PLL -=2;
RCC->CFGR = PLL <<18;
设置PLL 9倍频
这里还涉及到了一个问题,如下
其实,这里今天林妹妹问了一个比较专业的问题,那就是PLL是一个u8的数据类型,为什么在这里可以右移18位呢?不是早超出了么?其实,我们看看汇编代码就明白了,汇编代码如下: 219: RCC->CFGR|=PLL<<18; //设置PLL值
(15)
//具体见《STM32闪存编程》
(16)
RCC->CR|=0x01000000;
(17)
while(!((RCC->CR>>25)&0x01));
(18)
RCC->CFGR |= 0x00000002;
(19)
Unsigned char Temp = 0;
While(Temp!=0x02)
{
}
其实这段代码就是判断SWS,等待系统时钟成功转为PLL时钟。
结合上面的分析已经明了STM32时钟一个始终配置过程,主要流程图如下:
其实个人感觉不用想mini32中自带例程配置有一些没有必要,所以自己改动了一些,发现在跑马灯程序中也能运行,目前只在跑马灯程序中试验过:
第一步:
第二步:
第三步:关闭所有外设时钟
为什么要这步因为在配置cfgr以及cr等寄存器时,一些外设时钟要关闭。
第四步:
第五步:设置分频寄存器,配置分频,使能PLLSRC ON
评论