系统初始化函数SystemInit讲解

最新更新时间:1970-01-01来源: eefocus关键字:系统初始化函数  stm32 手机看文章 扫描二维码
随时随地手机看文章

要求前置技能:

 需了解系统时钟源相关知识:STM32时钟系统

 本文以HSE外接8MHz晶振,PLL倍频9倍得到72MHz的系统时钟为讲解背景


一,系统初始化函数SystemInit:

 文件路径:USER->system_stm32f10x.c->头文件system_stm32f10x.h中SystemInit(void)

 在system_stm32f10x.c文件中找到SystemInit(void)源码:

/**

  * @brief  Setup the microcontroller system

  *         Initialize the Embedded Flash Interface, the PLL and update the

  *         SystemCoreClock variable.

  * @note   This function should be used only after reset.

  * @param  None

  * @retval None

  */

void SystemInit (void)

{

  /* Reset the RCC clock configuration to the default reset state(for debug purpose) */

  /* Set HSION bit */

  RCC->CR |= (uint32_t)0x00000001;    //RCC_CR寄存器最低位置1:打开HSI(内部高速时钟8M)


  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */

#ifndef STM32F10X_CL

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

#else                      //stm32f103ZET6为大容量芯片HD

  RCC->CFGR &= (uint32_t)0xF0FF0000;     //RCC_CFGR寄存器初始化

#endif /* STM32F10X_CL */


  /* Reset HSEON, CSSON and PLLON bits */

  RCC->CR &= (uint32_t)0xFEF6FFFF;    //将RCC_CR寄存器HSEON,CSSON,PLLON位置0


  /* Reset HSEBYP bit */

  RCC->CR &= (uint32_t)0xFFFBFFFF;    //将RCC_CR寄存器HSEBYP位置0


  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */

  RCC->CFGR &= (uint32_t)0xFF80FFFF;   //将RCC_CFGR寄存器PLLSRC, PLLXTPRE,                         //PLLMUL,USBPRE/OTGFSPRE位置0


#ifdef STM32F10X_CL

  /* Reset PLL2ON and PLL3ON bits */

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


  /* Disable all interrupts and clear pending bits  */

  RCC->CIR = 0x00FF0000;


  /* Reset CFGR2 register */

  RCC->CFGR2 = 0x00000000;

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

  /* Disable all interrupts and clear pending bits  */

  RCC->CIR = 0x009F0000;


  /* Reset CFGR2 register */

  RCC->CFGR2 = 0x00000000;

#else                      //stm32f103ZET6为大容量芯片HD

  /* Disable all interrupts and clear pending bits  */

  RCC->CIR = 0x009F0000;        //关闭所有的中断和对应的位(初始化中断)

#endif /* STM32F10X_CL */


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

  #ifdef DATA_IN_ExtSRAM

    SystemInit_ExtMemCtl();

  #endif /* DATA_IN_ExtSRAM */

#endif


  /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */

  /* Configure the Flash Latency cycles and enable prefetch buffer */

  SetSysClock();


#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

}


二,默认定义系统时钟:


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

/* #define SYSCLK_FREQ_HSE    HSE_VALUE */

 #define SYSCLK_FREQ_24MHz  24000000

#else

/* #define SYSCLK_FREQ_HSE    HSE_VALUE */

/* #define SYSCLK_FREQ_24MHz  24000000 */

/* #define SYSCLK_FREQ_36MHz  36000000 */

/* #define SYSCLK_FREQ_48MHz  48000000 */

/* #define SYSCLK_FREQ_56MHz  56000000 */

#define SYSCLK_FREQ_72MHz  72000000   //默认定义系统是中文为72MHz

#endif


 在这里可以修改系统时钟值

三,SetSysClock(Void)

/**

  * @brief  Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.

  * @param  None

  * @retval None

  */

static void SetSysClock(void)

{

#ifdef SYSCLK_FREQ_HSE

  SetSysClockToHSE();

#elif defined SYSCLK_FREQ_24MHz

  SetSysClockTo24();

#elif defined SYSCLK_FREQ_36MHz

  SetSysClockTo36();

#elif defined SYSCLK_FREQ_48MHz

  SetSysClockTo48();

#elif defined SYSCLK_FREQ_56MHz

  SetSysClockTo56();

#elif defined SYSCLK_FREQ_72MHz     //默认定义的系统时钟是72MHz

  SetSysClockTo72();

#endif


四,SetSysClockTo72(Void)

/**

  * @brief  Sets System clock frequency to 72MHz and configure HCLK, PCLK2

  *          and PCLK1 prescalers.

  * @note   This function should be used only after reset.

  * @param  None

  * @retval None

  */

static void SetSysClockTo72(void)

{

  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;


  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/

  /* Enable HSE */

  RCC->CR |= ((uint32_t)RCC_CR_HSEON);    //使能HSE:RCC_CR_HSEON=0x00010000(修改的是第16位HSEON)


  /* Wait till HSE is ready and if Time out is reached exit */

  do

  {

    HSEStatus = RCC->CR & RCC_CR_HSERDY;     //开启并就绪:RCC_CR_HSERDY=0x00020000(第17位HSERDY置1)

    StartUpCounter++;

  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); //循环直到HSE稳定


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

  {

    HSEStatus = (uint32_t)0x01;               //就绪后赋值标志位HSEStatus

  }

  else

  {

    HSEStatus = (uint32_t)0x00;

  }


  if (HSEStatus == (uint32_t)0x01) //判断就绪

  {

    /* Enable Prefetch Buffer */

    FLASH->ACR |= FLASH_ACR_PRFTBE;


    /* Flash 2 wait state */

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

    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;     //cpu的速度比芯片速度快的多        设置FLASH等待:两个等待状态


    /* HCLK = SYSCLK */

    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;//配置AHB预分频器分频系数为1,使HCLK = SYSCLK=72M

                                                                                      //RCC_CFGR_HPRE_DIV1=0x00000000(见手册)


    /* PCLK2 = HCLK */

    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;//配置PCLK2预分频器分频系数为1,使PCLK2 = HCLK=72M

                                                                                        //RCC_CFGR_PPRE2_DIV1=0x00000000(见手册)

    /* PCLK1 = HCLK/2 */

    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;//设置PCLK1预分频器分频系数为2,使PCLK1 = HCLK/2=36M

                                                                                       //RCC_CFGR_PPRE1_DIV2=0x00000400(见手册)

                                                                                       //RCC->CFGR第10,9,8位设置为100 (设置为2分频)

#ifdef STM32F10X_CL

    /* Configure PLLs ------------------------------------------------------*/

    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */

    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */


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

                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);

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

                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);


    /* Enable PLL2 */

    RCC->CR |= RCC_CR_PLL2ON;

    /* Wait till PLL2 is ready */

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

    {

    }


    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */

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

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

                            RCC_CFGR_PLLMULL9);

#else                         //stm32f103ZET6为大容量芯片HD

    /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */

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

                                        RCC_CFGR_PLLMULL));

    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);//HSE为时钟源且PLL倍频系数为9(8*9=72兆)

#endif /* STM32F10X_CL */


    /* Enable PLL */

    RCC->CR |= RCC_CR_PLLON;          //使能PLL时钟,RCC->CR寄存器第24位置1

                          //RCC_CR_PLLON=0x01000000


    /* Wait till PLL is ready */

    while((RCC->CR & RCC_CR_PLLRDY) == 0)  //等待PLL时钟源就绪    

                            //RCC_CR_PLLRDYRCC->CR寄存器第25位

    {

    }


    /* Select PLL as system clock source */

    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));//配置PLL作为系统时钟来源

    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;        //RCC_CFGR_SW_PLL=0x00000002(RCC->CFGR第1,0位设置为10,见手册)


    /* Wait till PLL is used as system clock source */

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

    {

    }

  }

  else

  { /* If HSE fails to start-up, the application will have wrong clock

[1] [2]
关键字:系统初始化函数  stm32 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic556240.html

上一篇:STM32 LED跑马灯-位操作
下一篇:STM32 串口通信实验

推荐阅读

STM32F103之系统时钟初始化及延迟函数
一、简介本文以STM32F103编程为例,介绍STM32F103系统时钟初始化及延迟函数编写二、实验平台电脑平台:Windows7 64位旗舰编译软件:Keil5硬件平台:STM32F103RC三、版权声明四、实验前提1、在进行本文步骤前,请先安装keil5版本;准备好STM32F103RC硬件平台。五、基础知识暂无六、源码地址暂无七、关联文章暂无八、实验内容1.初始化系统时钟/*外部时钟最高72MHz  内部时钟最高64MHz*/typedef enum{    HAL_CLOCK_HSE_SYS = (unsigned char)0x01,       
发表于 2020-02-10
STM32F4 (7) Systemlinit时钟系统初始化函数剖析
作为时钟输入,在我们系统初始化的时候(正点原子)使用的是HSE(高速的外部时钟),这里选用的HSE是8M,计算公式在上一讲已经讲过,经过计算后 就得到168Mhz的时钟。正点原子的SYSteminit()函数在system——stm32xx.h里面,在系统复位之后 是先执行这个SYSteminit()函数的,在系统复位之后,为什么要先调用这个函数再调用mian函数呢?在CORE文件中的startup_stm32f40_41xx.s中有几行代码, 这几行代码我们不深究,他是说明在执行mian函数之前先执行systeminit这个函数。接下来我们看systeminit()这个函数,FPU seting是 浮点运算的配置,到后面再讲解下面这几
发表于 2019-09-09
STM32F4 (7) Systemlinit时钟<font color='red'>系统</font><font color='red'>初始化</font><font color='red'>函数</font>剖析
STM32系统初始化模板函数
第一次写,也不知道写些啥,就copy一个STM32 系统时钟初始化模板函数吧,以来分享给新手参考,而来自己当做备份一下。有大神看到觉不妥之处请指出,勿喷!谢谢!void SYS_Init(void){uint8_t HSEStartUpStatus;RCC_DeInit(); //将RCC设置为默认的重置状态RCC_HSEConfig(RCC_HSE_ON); //配置外部高速晶振  (HSE - ON)HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部时钟就绪if(HSEStartUpStatus == SUCCESS)   //SUCCESS:外部
发表于 2018-10-16
STM32系统初始化函数
;SystemCoreClockUpdate 后者是改变内核时钟时候才用。下面是重点了(讲了systeminit这个函数是如何定义时钟,以及他定义了哪些时钟)打开system_stm32f10x.c这个文件,他的代码解释如下:首先是一个芯片选择定义,如果选择定义了CL级别芯片,则预定义 系统时钟频率=72M  #define SYSCLK_FREQ_72MHz  72000000然后问是否定义了外接SRAM一般都没有外接(这句就可忽略了)然后就是定义矢量表偏移 0x0 如果前面定义了外接SRAM就要偏移0X200接着定义了一个数组__I uint8_t AHBPrescTable[16
发表于 2017-11-05
STM32单片机-汇编指令1
--------------------------------------------说明:STM32单片机汇编指令使用一STM32单片机汇编指令使用二ARM单片机汇编指令的查找见“STM32单片机二之十五、查找汇编指令”。--------------------------------------------.macro restore_user_regs //宏   ldr r1,[sp, #S_PSR]   ldr lr,[sp, #S_PC]!   @ !用来控制基址变址寻址的最终新地址是否进行回写操作,         
发表于 2022-01-12
<font color='red'>STM32</font>单片机-汇编指令1
AD转换汇总(STM32、取平均、过采样)
}-----------------------------------------------------------------------------------------------------三、STM32关于使用定时器触发ADC转换以STM32 ADC的常规通道为例(注入通道类似):配合上ADC外设的框图:如上图,STM32 ADC的常规通道可以由以上6个信号触发任何一个,我们以使用TIM2_CH2触发ADC1,独立模式,每次仅测一条通道,则ADC的配置如下:(以下代码使用STM32固件库V3.5)void ADC_Configuration(void){    ADC_InitTypeDef ADC_InitStructure;    ADC_InitStructure.ADC_Mode
发表于 2022-01-12
AD转换汇总(<font color='red'>STM32</font>、取平均、过采样)

推荐帖子

我想用VS2005来开发移动程序.
我想用VS2005来开发PocketPC,SmartPhone与WinCE5.0的程序.并且只用VC++开发. 目前已经安装了VS2005(仅选择了VC++).我想还要个模拟器,方便仿真. 下面还要安装什么内容,安装顺序怎样? (手头有PB5.0等软件)我想用VS2005来开发移动程序.
tpcore 嵌入式系统
CCS3.3中的view-->graph 功能,在CCS5.2中怎么找不到?求高手指导,谢谢
CCS3.3中的view-->graph功能,在CCS5.2中怎么找不到?求高手指导,谢谢CCS3.3中的view-->graph功能,在CCS5.2中怎么找不到?求高手指导,谢谢
506977544 微控制器 MCU
2010年山东省大学生电子设计竞赛
本帖最后由paulhyde于2014-9-1504:18编辑2010年山东省大学生电子设计竞赛 2010年山东省大学生电子设计竞赛
白丁 电子竞赛
wince iimage encoder
有哪位大侠实现过winceiimage组件的encoder 目前小弟困在IImageEncoder::GetEncodeSink(IImageSink**sink)的实现上, 小弟是先CreateNewBitmap一个bitmap然后queryinterface得到imagesink, 但是不知道CreateNewBitmap中的width,height,pixelFormat参数是该怎么填写, winceiimag
elehlw WindowsCE
超声波同时穿透几种材料的问题
超声波同时穿透几种材料的问题 超声波测距和测厚都是指声波穿透一种介质到达另一种介质时返回的过程。有什么方法能让声波同时透过几种不同的介质呢?简单的说,如管道中不同介质对声波的影响不同,而管道材料不同对声波的影响也不同,如何让声波从管道一表面穿透管壁,再穿透介质到达管壁另一表面后信号被接收到。 我想用51单片机做一个,但遇到软件、硬件的问题实在是太多了,想请朋友们帮帮忙。超声波同时穿透几种材料的问题
rose6045 51单片机
BLDC无刷电机驱动器
画了个无刷电机FOC矢量控制驱动器:开源地址https://github.com/Cuixudong/BLDC_DRV BLDC无刷电机驱动器
lovelessing 电机驱动控制(Motor Control)
小广播
何立民专栏 单片机及嵌入式宝典

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

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