STM32F207(2) systemInit函数

环境:STM32F207

内容:SystemInit到底做了啥


Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main
                 LDR     R0, =SystemInit  ;现在着重讲这个地方
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

事先说明:我对整个流程并不是很清楚,所以我只会站在一个初学者的角度来写这篇文章,老手们就请见谅

言归正传:

贴上函数说明,来自stm32固件库:

/**
  * @brief  Setup the microcontroller system
  *         Initialize the Embedded Flash Interface, the PLL and update the 
  *         SystemFrequency variable.
  * @param  None
  * @retval None
  */
这段话的意思大概为:初始化FLASH接口,锁相环和更新系统时钟

源代码如下:

void SystemInit(void)
{
  /* Reset the RCC clock configuration to the default reset state ------------*/
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;

  /* Reset CFGR register */
  RCC->CFGR = 0x00000000;

  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;

  /* Reset PLLCFGR register */
  RCC->PLLCFGR = 0x24003010;

  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;

  /* Disable all interrupts */
  RCC->CIR = 0x00000000;

#ifdef DATA_IN_ExtSRAM
  SystemInit_ExtMemCtl(); 
#endif /* DATA_IN_ExtSRAM */
         
  /* Configure the System clock source, PLL Multiplier and Divider factors, 
     AHB/APBx prescalers and Flash settings ----------------------------------*/
  SetSysClock();

  /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}


代码分析:

①:

  /* Reset the RCC clock configuration to the default reset state ------------*/
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;
这里是什么意思?不懂我们就看看stm32f207上面是怎么说CR寄存器的:



这句代码对应的寄存器如上,他其实要做的事情就是一个,打开HSI(内部高速晶振).我们再大致看看HISION说明:大概意思就是我们不能够将这一位清零,为啥?

他说,当我们离开待机模式的时候硬件强制将HISION置1,或者当我们外部晶振起振失败,我们也会直接或者间接使用到HSI。所以意思就是,我们只能开,不能关。

其实我们也可以反问自己一句,我们复位的时候还没有启动外部晶振同时也没有手动将HISON打开,为什么我们CPU能够跑,他是用的HSI 还是LSI?这个问题,我也不知道,

只能下来看看。能够想到这点就可以了。

  /* Reset CFGR register */
  RCC->CFGR = 0x00000000;
这里来了个新的寄存器CFGR,他说将CFGR复位,为啥复位成0,不是FFF,不是DDDD,那也要看看datasheet里面每一项怎么写的,再看手册之前,先说一下

CFGR的作用就是如下图:


是的,CFGR的作用就是配置SYSCLK的,其实我们现在不看手册自己也会有几个疑问,如果系统启动,我们系统时钟是多少?时钟源是什么?所以这里就会有答案


我们上一张图片说的大概意思就是CFGR作用是选择系统时钟源什么的,现在这张图片就是写了CFGR有哪些位,我们肉眼看看也能够知道SW代表switch,pre代表预分频,所以我们知道

这里肯定是做的是系统时钟相关的时钟源选择切换和预分频处理相关动作,那么我们要好好看看一下sw0,sw1...,看了之后就知道为什么上电复位成为0了。


sw=0,表示系统时钟使用的是HSI。sws=0,也是同样意思,其实sws不能够设置,只能够查看。

下面我将列出其他位代表的意思:

HPRE:0000  代表不对系统时钟进行分频,时钟树里面中间框框AHB PRESC

PPREX(1,2):0000  代表APB2,APB1时钟来源都直接是AHB,并没有经过AHB分频,上面时钟树

RTCPRE:0000  不将HSE时钟提供给RTC,因为现在时钟本来就不精确,所以上电就给RTC,没有这个必要

I2SSC: 0000  选择PLLI2S时钟为I2S的时钟


好了,这句话,我们就引出了这么多内容,先说明:我在写文章的时候是边写边查,所以希望初学者按照我的思路来走,不要觉得文章太长没意思,有意思的文章不多,

也不是我能够一时半会儿写得出来的,所以请将就一下,至少对你会有很大帮助。


  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;

又来操作CR了,上面我们的CFGR主要做的是时钟源的设置,这个CR主要做的事情就是打开某些东西,比如PLLCSS,HSE等,至于为什么要先设置CFGR再设置CR,

很明显了,我们刚才设置CFGR目的是让系统先跑起来,使用HSI为系统时钟,跑起来之后再进行HSE,PLL等设置,这也合情合理。

我们知道&=的作用主要是清零,|=的作用主要是置一,那么我们看看这里CR想要将哪几位清零呢,为什么清零

0XFEF6FFFF=


主要是讲bit15之上的某些位给置零了。



其实这些值的大概意思就是上面备注写的:reset HSEON CSSON PLLON具体这些做什么用,除了CSSON以外,我觉得新手都应该看得懂。

CSSON,大概就是启用安全时钟系统,我理解为当HSE运行稳定了,打开这个,它相当于是去检测HSE是否正常工作。老手看到请指证


  /* Reset PLLCFGR register */
  RCC->PLLCFGR = 0x24003010;
上面有个CFGR事用来配置系统时钟的,主要是系统时钟预分频器还有就是各种switch,那么PLLCFGR是什么意思就很好理解了,当然是

对锁相环进行操作的寄存器。具体每个值是多少,以及这个寄存器的作用是什么,我们后面来看,因为在sysclock函数里面要对每个值进行设置。所以这里只需要知道,这里是进行了PLLCFG的复位操作


  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;
这里说说HSE bypass是什么意思,bypass的意思就是直通,hse bypass就是说,信号源不是来自晶振了,而是另外的时钟源,比如信号发生器等。这里意思肯定是禁止bypass,如果我们打开,那么我们晶振就可以

不用初始化了。


  /* Disable all interrupts */
  RCC->CIR = 0x00000000;

这里说的是关闭中断,其实这个要分开理解,我们一般理解的终端是在终端向量表里面列出来的终端,比如定时器,外部中断,但是这里的中断是什么呢,主要是一些和时钟相关的中断。这里注意一下就可以了,

后面我们会看到另外一个关中断操作。


  SetSysClock();

这个函数主要就是重新操作我们上面列出的一些寄存器,具体操作我们暂时和systemInit函数分开,我们下一节来讲这个SetSysClock.


  /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
设置中断向量表,这个地方我们会参考另外一个PDF文档<Cortex M3权威指南.pdf>



OK,做一个总结,其实SystemInit()这个函数只有这么几句话,但是用了很大篇幅来写,为什么,为的就是了解STM32相关的寄存器,不是说我们以后每次

使用STM32都必须亲自设置,而是我们要对此有个比较清晰的了解,技术,就要死磕到底。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值