STM32库函数SystemInit()的理解

发布者:脑电狂潮最新更新时间:2016-12-20 来源: eefocus关键字:STM32  库函数  SystemInit() 手机看文章 扫描二维码
随时随地手机看文章

SystemInit()这个函数出现在main()函数的第一行,可以看出它的重要性。以前关于SystemInit()这个函数从来没有关心过,只知道这是进行STM32系统初始化的一个函数。今天决定仔细看看,重新开始STM32的学习。这个函数在system_stm32f10x.c中,此C文件主要就是干具体硬件配置相关的工作。

  1.  


  2.  

  3. void SystemInit (void) 


  4.  

  5.  

  6. RCC->CR |= (uint32_t)0x00000001; 


  7.  

  8. #ifndef STM32F10X_CL 

  9. RCC->CFGR &= (uint32_t)0xF8FF0000; 

  10. #else 

  11. RCC->CFGR &= (uint32_t)0xF0FF0000; 

  12. #endif  


  13.  

  14. RCC->CR &= (uint32_t)0xFEF6FFFF; 


  15.  

  16. RCC->CR &= (uint32_t)0xFFFBFFFF; 


  17.  

  18. RCC->CFGR &= (uint32_t)0xFF80FFFF; 


  19. #ifdef STM32F10X_CL 

  20.  

  21. RCC->CR &= (uint32_t)0xEBFFFFFF; 


  22.  

  23. RCC->CIR = 0x00FF0000; 


  24.  

  25. RCC->CFGR2 = 0x00000000; 

  26. #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 

  27.  

  28. RCC->CIR = 0x009F0000; 


  29.  

  30. RCC->CFGR2 = 0x00000000; 

  31. #else 

  32.  

  33. RCC->CIR = 0x009F0000; 

  34. #endif  


  35. #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) 

  36. #ifdef DATA_IN_ExtSRAM 

  37. SystemInit_ExtMemCtl(); 

  38. #endif  

  39. #endif 


  40.  

  41.  

  42. SetSysClock(); 


  43. #ifdef VECT_TAB_SRAM 

  44. SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;  

  45. #else 

  46. SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;  

  47. #endif 

  48. }



从函数说明来看,此函数功能就是初始化内部FALSH,PLL并且更新系统时钟。此函数需在复位启动后调用。

  1. RCC->CR |= (uint32_t)0x00000001;


第一行代码操作时钟控制寄存器,将内部8M高速时钟使能,从这里可以看出系统启动后是首先依靠内部时钟源而工作的。

  1. #ifndef STM32F10X_CL 

  2. RCC->CFGR &= (uint32_t)0xF8FF0000; 

  3. #else 

  4. RCC->CFGR &= (uint32_t)0xF0FF0000;


这两行代码则是操作时钟配置寄存器。其主要设置了MCO(微控制器时钟输出)PLL相关(PLL倍频系数,PLL输入时钟源),ADCPRE(ADC时钟),PPRE2(高速APB分频系数),PPRE1(低速APB分频系数),HPRE(AHB预分频系数),SW(系统时钟切换),开始时,系统时钟切换到HSI,由它作为系统初始时钟。宏STM32F10X_CL是跟具体STM32芯片相关的一个宏。

  1.  

  2. RCC->CR &= (uint32_t)0xFEF6FFFF; 


  3.  

  4. RCC->CR &= (uint32_t)0xFFFBFFFF; 


  5.  

  6. RCC->CFGR &= (uint32_t)0xFF80FFFF;


这几句话则是先在关闭HSE,CSS,,PLL等的情况下配置好与之相关参数然后开启,达到生效的目的。

  1. #ifdef STM32F10X_CL 

  2.  

  3. RCC->CR &= (uint32_t)0xEBFFFFFF; 


  4.  

  5. RCC->CIR = 0x00FF0000; 


  6.  

  7. RCC->CFGR2 = 0x00000000; 

  8. #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 

  9.  

  10. RCC->CIR = 0x009F0000; 


  11.  

  12. RCC->CFGR2 = 0x00000000; 

  13. #else 

  14.  

  15. RCC->CIR = 0x009F0000; 

  16. #endif


这一段主要是跟中断设置有关。开始时,我们需要禁止所有中断并且清除所有中断标志位。不同硬件有不同之处。 

  1. #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) 

  2. #ifdef DATA_IN_ExtSRAM 

  3. SystemInit_ExtMemCtl(); 

  4. #endif  

  5. #endif


这段跟设置外部RAM有关吧,我用到的STM32F103RBT与此无关。

  1. SetSysClock();


此又是一个函数,主要是配置系统时钟频率。HCLK,PCLK2,PCLK1的分频值,分别代表AHB,APB2,和APB1。当然还干了其它的事情,配置FLASH延时周期和使能预取缓冲期。后面的这个配置具体还不了解。

  1. #ifdef VECT_TAB_SRAM 

  2. SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;  

  3. #else 

  4. SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;  

  5. #endif


这段代码主要是实现向量表的重定位。依据你想要将向量表定位在内部SRAM中还是内部FLASH中。这个SCB开始没在STM32参考手册中发现,原来它是跟Cortex-M3内核相关的东西。所以ST公司就没有把它包含进来吧。内核的东西后面再了解,这里给自己提个醒。 


然后再看看SystemInit()中的那个函数SetClock()又做了什么吧。

  1. static void SetSysClock(void) 


  2. #ifdef SYSCLK_FREQ_HSE 

  3. SetSysClockToHSE(); 

  4. #elif defined SYSCLK_FREQ_24MHz 

  5. SetSysClockTo24(); 

  6. #elif defined SYSCLK_FREQ_36MHz 

  7. SetSysClockTo36(); 

  8. #elif defined SYSCLK_FREQ_48MHz 

  9. SetSysClockTo48(); 

  10. #elif defined SYSCLK_FREQ_56MHz 

  11. SetSysClockTo56(); 

  12. #elif defined SYSCLK_FREQ_72MHz 

  13. SetSysClockTo72(); 

  14. #endif 


  15.  

  16. }


从中可以看出就是根据不同的宏来设置不同的系统时钟,这些宏就在跟此函数在同一个源文件里。官方很是考虑周到,我们只需要选择相应宏就能达到快速配置系统时钟的目的。

  1. #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 

  2.  

  3. #define SYSCLK_FREQ_24MHz 24000000 

  4. #else 

  5.  

  6.  

  7.  

  8.  

  9.  

  10. #define SYSCLK_FREQ_72MHz 72000000 

  11. #endif


比如这里我需要配置系统时钟为72MHZ,则只需要将#define SYSCLK_FREQ_72MHz  72000000两边的注释符去掉。 
这个函数里面又有SetSysClockTo72()函数,这个函数就是具体操作寄存器进行配置了。

  1. #elif defined SYSCLK_FREQ_72MHz 

  2.  

  3. static void SetSysClockTo72(void) 


  4. __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 


  5.  

  6.  

  7. RCC->CR |= ((uint32_t)RCC_CR_HSEON); 


  8.  

  9. do 


  10. HSEStatus = RCC->CR & RCC_CR_HSERDY; 

  11. StartUpCounter++; 

  12. } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 


  13. if ((RCC->CR & RCC_CR_HSERDY) != RESET) 


  14. HSEStatus = (uint32_t)0x01; 


  15. else 


  16. HSEStatus = (uint32_t)0x00; 



  17. if (HSEStatus == (uint32_t)0x01) 


  18.  

  19. FLASH->ACR |= FLASH_ACR_PRFTBE; 


  20.  

  21. FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 

  22. FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; 



  23.  

  24. RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 


  25.  

  26. RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 


  27.  

  28. RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 


  29. #ifdef STM32F10X_CL 

  30.  

  31.  

  32.  


  33. RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 

  34. RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 

  35. RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 

  36. RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 


  37.  

  38. RCC->CR |= RCC_CR_PLL2ON; 

  39.  

  40. while((RCC->CR & RCC_CR_PLL2RDY) == 0) 





  41.  

  42. RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 

  43. RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 

  44. RCC_CFGR_PLLMULL9); 

  45. #else 

  46.  

  47. RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | 

  48. RCC_CFGR_PLLMULL)); 

  49. RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); 

  50. #endif  


  51.  

  52. RCC->CR |= RCC_CR_PLLON; 


  53.  

  54. while((RCC->CR & RCC_CR_PLLRDY) == 0) 




  55.  

  56. RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 

  57. RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 


  58.  

  59. while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 




  60. else 

  61. {  



  62. #endif


上面的代码需要细细看。SystemInit()差不多就是这样了。


关键字:STM32  库函数  SystemInit() 引用地址:STM32库函数SystemInit()的理解

上一篇:STM32通用定时器---基本定时学习
下一篇:STM32的库如何实现对同一组IO口的一部分引脚进行读写

推荐阅读最新更新时间:2024-03-16 15:26

stm32虚拟串口安装失败的原因
本人在网上也看到了好多说,按照以下步骤可以解决问题,但是不幸的是我的盗版系统不行: 将mdmcpq.inf复制到c:\windows\inf 将usbser.sys复制到c:\windows\system32\drivers 但是,还是借助于这个思路去找一些原因最后发现,在c:\windows\inf 文件夹下,有一个名叫mdmcpq2.inf的文件,突发奇想将2去掉试试可不可以,后来一试可以了,成功安装了!
[单片机]
基于STM32的0.96寸OLED时钟程序
用的是stm32自带的RTC时钟。硬件连接很简单,当然程序也是比较简单的,只写了温度(DS18B20),stm32自带RTC和OLED显示,大家可自行删改功能。 硬件连接: SDA --》PB13 SCL --》PB12 DS18B20----》PA15 OLED和DS18B20直接5V供电就成,效果如下: 单片机源程序如下: #include sys.h #include usart.h #include delay.h #include led.h #include key.h #include oled.h #include beep.h #include rtc.h #include ds18b20
[单片机]
基于<font color='red'>STM32</font>的0.96寸OLED时钟程序
ST最新开发工具为了解基于STM32 ARM Cortex-M3 MCU开方便之门
完整的低成本的评估开发工具通过图形界面探索微控制器的性能和功能 中国,2007年11月6日 — 意法半导体(纽约证券交易所:STM)今天公布了一个价格非常低廉的微控制器开发套件STM32 PerformanceStick,这套开发工具是近日推出的基于ARM Cortex-M3内核的STM32系列微控制器的配套产品。ST设计这套紧凑的开发工具是为了便于用户了解新微控制器的功能和性能,特别值得一提的是,用户可以通过一个图形界面查看微控制器在不同条件下的性能特性。为了鼓励和帮助设计工程师修改和重新编写应用程序源代码,工具包还含有示例应用软件和一套完整的Hitex软件工具。 STM32 PerformanceStick是一套功能完整
[单片机]
stm32控制4位数码管_stm32控制共阴数码管
1、stm32控制4位共阳数码管输出计数 用stm32控制4位数码管,需要用到GPIO口 PA0~PA11共12个引脚。首先我们来看看数码管的原理图。 因为是共阳所以12,9,8,6为电源输入,其他引脚均为接地,所以对于芯片来说12,9,8,6高位输出,其他设定为低位即可。 //设定下GPIO口 void GPIO_Num_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE
[单片机]
用<font color='red'>stm32</font>控制4位数码管_<font color='red'>stm32</font>控制共阴数码管
简单初始化STM32的RTC
RTC嘛 就跟DS1302 差不多吧...当然了可分频又有32位的计数器...报警、秒、溢出中断.....等等。RTC在APB1总线上.... 要使用 RTC,一般来说也顺带地使用上后备寄存器 这是因为RTC 是一个简单的秒中断 定时器,年月日时分秒的信息必须要找个地方能掉电保存才有意义.STM32 的备份寄存器(BKP)是42个16位的寄存器,可用来存储84个字节的用户应用程序数据。他们处在备份域里,当VDD电源被切断,他们仍然由VBAT维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位。 此外,BKP控制寄存器用来管理侵入检测和RTC校准功能。 复位后,对备份寄存器和RTC的访问被禁止,并且备份域被
[单片机]
简单初始化<font color='red'>STM32</font>的RTC
STM32入门系列-学习STM32要掌握的内容
STM32芯片架构 STM32F103系列芯片的系统架构如下: STM32芯片基于ARM公司的Cortex-M3内核,由ST公司设计生产,内核与总线矩阵之间有I(指令)、S(系统)、D(数据)三条信号线。内核通过总线矩阵与FLASH、SRAM、外设连接。而外设包括GPIO、USART、I2C、SPI等。 STM32芯片系统结构 STM32F103 系列芯片(不包含互联网型)的系统结构如下: 从上图可以看出,在小容量、中容量和大容量产品中,主系统由以下部分构 成: 四个驱动单元: Cortex-M3 内核 DCode 总线(D-bus) Cortex-M3 内核系统总线(S-bus) 通用 DMA1
[单片机]
<font color='red'>STM32</font>入门系列-学习<font color='red'>STM32</font>要掌握的内容
STM32 芯片 IWDG 关闭 停用 方法
百度搜索真心是开发者的敌人,开发工作很多时候也是浪费青春和生命的工作,你费大把时间,解决的无非是写鸡毛蒜皮无关痛痒的问题,百度上还找不到这样的小问题的答案。 stm32 芯片 IWDG 怎么停用 我再一个项目上开启了IWDG,后来意外的把代码刷到了另一个产品上,产品就打开了IWDG 因为我需要进行调试,所以得先关掉,但是IWDG 断电都保存,就这小问题费了2 3 个小时, 百度给出的结论是,不能关闭,只能复位/重启??????(所以什么叫重启,怎么样重启?) 上google一搜索,发现 使用这个 可以在调试模式下关闭 IWDG,实际也是把WDG_SW设置为了1 __HAL_DBGMCU_FREEZE_IWD
[单片机]
<font color='red'>STM32</font> 芯片 IWDG 关闭 停用 方法
STM32之DAC君
先来张比如花漂亮的照片、大家请尽情欣赏:因为其够美丽了、所以我就不展现我美丽而销魂的涂鸦了、 鉴赏过之后、我们来看看STM32之DAC的Resume(简历简介): 2个DAC转换器:每个转换器对应1个输出通道 ● 8位或者12位单调输出 ● 12位模式下数据左对齐或者右对齐 ● 同步更新功能 ● 噪声波形生成 ● 三角波形生成 ● 双DAC通道同时或者分别转换 ● 每个通道都有DMA功能 ● 外部触发转换 ● 输入参考电压VREF+ 哇、、哇、、哇、、好多特征呀、、还记得上篇博客中ADC也有很多功能吗?在这里,我觉得,因为其功能多、所以其复杂、、这也没什么奇怪的哈、、 那我
[单片机]
<font color='red'>STM32</font>之DAC君
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved