历史上的今天
返回首页

历史上的今天

今天是:2024年09月15日(星期日)

2020年09月15日 | STM32F4时钟设置分析

2020-09-15 来源:eefocus

环境:


主机:WIN7


开发环境:MDK4.72


MCU:STM32F407VGT6



STM32F4启动与STM32F10X不同,时钟已经默认配置好.


1.启动代码:


文件:startup_stm32f4xx.s


[cpp] view plain copy

 在CODE上查看代码片派生到我的代码片

; Reset handler  

Reset_Handler    PROC  

                 EXPORT  Reset_Handler             [WEAK]  

        IMPORT  SystemInit  

        IMPORT  __main  

  

                 LDR     R0, =SystemInit  

                 BLX     R0  

                 LDR     R0, =__main  

                 BX      R0  

                 ENDP  


可以看出,在进入main函数之前,系统调用了SystemInit函数.


2.SystemInit函数分析


SystemInit函数位于system_stm32f4xx.c文件中.此文件提供几个宏定义可以设置各个时钟:


在CODE上查看代码片派生到我的代码片

/************************* PLL Parameters *************************************/  

/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */  

#define PLL_M      25  

#define PLL_N      336  

  

/* SYSCLK = PLL_VCO / PLL_P */  

#define PLL_P      2  

  

/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */  

#define PLL_Q      7  

  

/******************************************************************************/  


而晶振频率则是在文件stm32f4xx.h中进行设置:

外部晶振:


在CODE上查看代码片派生到我的代码片

#if !defined  (HSE_VALUE)   

  #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */  

#endif /* HSE_VALUE */  


内部晶振:


在CODE上查看代码片派生到我的代码片

#if !defined  (HSI_VALUE)     

  #define HSI_VALUE    ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/  

#endif /* HSI_VALUE */   


综上,可以得出默认配置中:

锁相环压腔振荡器时钟PLL_VCO = 25 / 25 * 336 = 336MHz


系统时钟SYSCLK = 336 / 2 = 168MHz


USB,SD卡时钟 = 336 / 7 = 48MHz


时钟图:

SystemInit函数代码:


 在CODE上查看代码片派生到我的代码片

/** 

  * @brief  Setup the microcontroller system 

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

  *         SystemFrequency variable. 

  * @param  None 

  * @retval None 

  */  

void SystemInit(void)  

{  

  /* FPU settings ------------------------------------------------------------*/  

  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)  

    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */  

  #endif  

  

  /* 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  

}  


3.SetSysClock函数分析

在SetSysClock函数中,配置了系统时钟,PLL倍频以及分频系数:


 在CODE上查看代码片派生到我的代码片

/** 

  * @brief  Configures the System clock source, PLL Multiplier and Divider factors,  

  *         AHB/APBx prescalers and Flash settings 

  * @Note   This function should be called only once the RCC clock configuration   

  *         is reset to the default reset state (done in SystemInit() function).    

  * @param  None 

  * @retval None 

  */  

static void SetSysClock(void)  

{  

/******************************************************************************/  

/*            PLL (clocked by HSE) used as System clock source                */  

/******************************************************************************/  

  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;  

    

  /* Enable HSE */  

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

   

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

  do  

  {  

    HSEStatus = RCC->CR & RCC_CR_HSERDY;  

    StartUpCounter++;  

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

  

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

  {  

    HSEStatus = (uint32_t)0x01;  

  }  

  else  

  {  

    HSEStatus = (uint32_t)0x00;  

  }  

  

  if (HSEStatus == (uint32_t)0x01)  

  {  

    /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */  

    RCC->APB1ENR |= RCC_APB1ENR_PWREN;  

    PWR->CR |= PWR_CR_VOS;  

  

    /* HCLK = SYSCLK / 1*/  

    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;  

        

    /* PCLK2 = HCLK / 2*/  

    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;  

      

    /* PCLK1 = HCLK / 4*/  

    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;  

  

    /* Configure the main PLL */  

    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |  

                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);  

  

    /* Enable the main PLL */  

    RCC->CR |= RCC_CR_PLLON;  

  

    /* Wait till the main PLL is ready */  

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

    {  

    }  

     

    /* Configure Flash prefetch, Instruction cache, Data cache and wait state */  

    FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;  

  

    /* Select the main PLL as system clock source */  

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

    RCC->CFGR |= RCC_CFGR_SW_PLL;  

  

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

    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);  

    {  

    }  

  }  

  else  

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

         configuration. User can add here some code to deal with this error */  

  }  

  

}  


如果外部时钟启动失败,系统会使用内部时钟

默认配置:


HCLK = SYSCLK / 1 = 168MHz


PCLK2 = HCLK / 2 = 84MHz


PCLK1 = HCLK / 4 = 42MHz


推荐阅读

史海拾趣

Hongfa公司的发展小趣事

宏发公司的发展离不开自主研发和技术创新。1998年,宏发成立了精合公司,开启了自主研发自动化设备设计及制造的征程。此后,公司不断加大在技术研发上的投入,建立了博士后科研工作站和院士专家工作站,形成了从产品研发、模具制造、零件制造到自动化成品装配及在线检测的一体化全产业链。通过技术创新,宏发不仅提升了产品性能和质量,还成功打破了国外技术垄断,实现了高端继电器的自主研发和生产。

上海如韵(CONSONANCE)公司的发展小趣事

在国内市场取得一定成绩后,如韵开始将目光投向海外市场。为了拓展国际业务,公司在香港设立了研发中心,以便更好地了解国际市场需求和技术趋势。同时,如韵积极参加国际电子展会和交流活动,与多家国际知名企业建立了合作关系。

经过一段时间的努力,如韵的产品逐渐在海外市场上获得了认可。公司的出口额逐年增长,为如韵带来了更多的发展机遇。海外市场的成功拓展,不仅提升了公司的品牌影响力,也为公司带来了更多的国际合作机会。

振华(CEC)公司的发展小趣事

面对激烈的市场竞争,振华始终将技术创新作为企业发展的核心动力。公司投入大量资金进行技术研发,积极引进国内外先进技术,并与高校、科研机构建立紧密的合作关系。通过持续的技术创新,振华在电子产品领域取得了多项重要突破,推出了一系列具有自主知识产权的高新产品,引领了市场潮流。

General Electric Solid State公司的发展小趣事

为了进一步提升企业的竞争力和市场份额,振华积极实施国际化战略。公司加强与国外企业的合作与交流,积极参与国际市场竞争,通过引进外资、设立海外研发机构等方式,不断拓展海外市场。同时,振华还注重提升产品的国际竞争力,加强与国际标准的对接和认证工作,确保产品能够满足不同国家和地区的市场需求。

Crystalfontz America Inc公司的发展小趣事

随着公司业务的不断发展壮大,Crystalfontz America Inc公司开始实施全球化战略。公司积极拓展海外市场,通过设立分支机构或建立合作伙伴关系等方式进入更多国家和地区。同时,公司还加强与国际同行的交流与合作,引进先进技术和管理经验,推动公司的全球化发展进程。这些举措为公司带来了更广阔的市场空间和更多的发展机遇。

需要注意的是,以上故事仅为基于公开信息和一般行业趋势的推测性构建,并不代表Crystalfontz America Inc公司的实际发展历程。如果需要了解该公司更具体的发展故事和详细信息,建议查阅相关新闻报道、行业分析报告或联系公司本身以获取更准确的信息。

CoolerMaster公司的发展小趣事

林仁政跳出已有的框架,不断思考机箱的设计。他敏锐地觉察到人们对于免工具安装的主板散热片的偏好,并深知散热效果不仅仅取决于散热片和风扇,更需要考虑空气的流动情况。结合日本高水准的立体设计灵感,林仁政带领工程师挑战困难,成功设计出了一台铝制机箱。这一机箱不仅具有高度的创新性,更因其纯手工制作的特性而显得弥足珍贵,对Cooler Master的发展具有重要意义。

问答坊 | AI 解惑

寻找问题根源,优化GPRS网络

随着通用无线分组业务(GPRS)的推出并与现有GSM共存,移动网络运营商正面临新的挑战。与任何新系统一样,GPRS网络在发展初期也经历了成长的痛苦,运营商需要迅速解决用户的问题,从而争取更多用户并最大程度取得投资回报。本文介绍用协议测试仪对流 ...…

查看全部问答>

当油变成奶,奶变成油……

2008年,对于中国来说,的确是不平凡的一年。大灾大幸,大起大落。奥运会刚刚闭幕,奶和油又掀起了新一轮的波澜。 “三鹿门”转瞬之间由小变大,数千个孩子的生命安全引起了全社会的关注。短短几天,二十多家奶制品厂被查出添加有毒物质,包括全国 ...…

查看全部问答>

分享 视频编码电路

视频编码电路图下载 http://www.fosvos.com/datasheet/gticc/gm7113/gm7113.pdf [ 本帖最后由 福跃电子 于 2009-3-5 23:10 编辑 ]…

查看全部问答>

FatFs下目录扫描出现问题了,高手帮忙啊

在读取文件目录时,调用sprintf函数时,总是出错,不知问题在哪里,高手帮忙啊。 /*************************************************************************************** FunctionName   : AppScanFiles()* Description &nbs ...…

查看全部问答>

SystemState changed绑定一个事件没有执行

SystemState status = new SystemState(SystemProperty.PowerBatteryBackupStrength); status.Changed += new ChangeEventHandler(status_Changed); status绑定的是现有电池量的changed事件 当我电视改变,应该调用status_Changed这个函数 我是 ...…

查看全部问答>

VS2005CE中如何使用MD5

如题。 用vs2005 C# CE做的程序,里面有一个要用到MD5算法的(这是客户要求的,必须),但在CF中没有MD5的用法,不知道如何解决??…

查看全部问答>

关于msgQSend的问题!!!急等~~

刚学习vxWorks,今天碰到了一个问题,想请教一下各位!先谢谢了! 今天看到了一个这样的函数,是有关msgQSend的! int DataProcess(char *pData, int DataLen) {     char *ReceivePack = NULL;     MNREMSG msgSend; &n ...…

查看全部问答>

请教一个WINCE的问题:

  各位朋友是这样的:WINCE控制面板里的程序一打开,为什么它们的窗口大小和我们的屏幕的大小不一致呢?怎么样可以让它们和我们的屏幕大小一致辞呢?…

查看全部问答>

如何取得当前系统是CE或者Mobile

怎么获得当前系统是Windows CE或者Windows Mobile …

查看全部问答>

用过Q64的请进来 过于GPIO的

AT指令和OpenAT都控制不了IO口?…

查看全部问答>