当前位置:首页 > 单片机 > 单片机
[导读]一、背景  最近做个项目,需要使用STM32,还是以前一样的观点,时钟就是MCU心脏,供血即时钟频率输出,想要弄明白一个MCU,时钟是一个非常好的切入点。言归正传,网上已经有太多大神详述过STM32的详细配置方法了,

一、背景
  最近做个项目,需要使用STM32,还是以前一样的观点,时钟就是MCU心脏,供血即时钟频率输出,想要弄明白一个MCU,时钟是一个非常好的切入点。言归正传,网上已经有太多大神详述过STM32的详细配置方法了,在此就简单介绍下STM32时钟系统,以及如何配置做个简单记录,方便以后的快速开发。

二、正文
  废话不多说,上一张STM32F10xx的时钟树图:

  

  由图可知,STM32F10XX有两级时钟
  第一级时钟
    * 高速内部时钟(HSI)
    * 锁相环时钟(PLLCLK)
    * 高速外部时钟(HSE)
  第二级时钟
    * 低速内部时钟(LSI)
    * 低速外部时钟(LSE)

  又由图可知,
    * HSE由外部晶振从"OSC_OUT","OSC_IN"两脚输入提供。
    * LSE由外部晶振从"OSC32_OUT","OSC32_IN"两脚输入提供。
    * HSI由8MHZ高速内部RC震荡电路提供。
    * LSI由40kHZ低速内部RC震荡电路提供。

  STM32F10XX还可通过MCO脚向外提供时钟输出。时钟来源有PLLCLK/HSI/HSE/SYSCLK,由MCO选择器来选择。

  研究过时钟来源,再来研究时钟的去向,MCU自身要能正常运作,即需要一个时钟,这个时钟既是系统时钟(SYSCLK),而基本上所有外设的时钟均来自于这个系统时钟(SYSCLk)。然后由系统时钟对外提供各种外设时钟。详见图。  

  当然,也有例外,USB时钟必须为48MHZ,这里的USB时钟(USBCLK)由PLLCLK直接提供,RTC时钟(RTCCLK)也不是来源于系统时钟(SYSCLK),详见图。  

  时钟结构大体也就如此,不再深究,网上有许多更加深入的讲解,接下来说说如何去配置。用代码来说明问题:

  先贴文件"system_stm32f10x.c",此文件即库文件。里面有一个很重要的函数"SystemInit()"

  解析过STM32启动代码的朋友都应该知道,这个函数跑在进入main函数之前,里面做的事情即是配置系统时钟。代码如下:

voidSystemInit(void){/*ResettheRCCclockconfigurationtothedefaultresetstate(fordebugpurpose)*//*SetHSIONbit*/RCC->CR|=(uint32_t)0x00000001;/*ResetSW,HPRE,PPRE1,PPRE2,ADCPREandMCObits*/#ifndefSTM32F10X_CLRCC->CFGR&=(uint32_t)0xF8FF0000;#elseRCC->CFGR&=(uint32_t)0xF0FF0000;#endif/*STM32F10X_CL*//*ResetHSEON,CSSONandPLLONbits*/RCC->CR&=(uint32_t)0xFEF6FFFF;/*ResetHSEBYPbit*/RCC->CR&=(uint32_t)0xFFFBFFFF;/*ResetPLLSRC,PLLXTPRE,PLLMULandUSBPRE/OTGFSPREbits*/RCC->CFGR&=(uint32_t)0xFF80FFFF;#ifdefSTM32F10X_CL/*ResetPLL2ONandPLL3ONbits*/RCC->CR&=(uint32_t)0xEBFFFFFF;/*Disableallinterruptsandclearpendingbits*/RCC->CIR=0x00FF0000;/*ResetCFGR2register*/RCC->CFGR2=0x00000000;#elifdefined(STM32F10X_LD_VL)||defined(STM32F10X_MD_VL)||(definedSTM32F10X_HD_VL)/*Disableallinterruptsandclearpendingbits*/RCC->CIR=0x009F0000;/*ResetCFGR2register*/RCC->CFGR2=0x00000000;#else/*Disableallinterruptsandclearpendingbits*/RCC->CIR=0x009F0000;#endif/*STM32F10X_CL*/#ifdefined(STM32F10X_HD)||(definedSTM32F10X_XL)||(definedSTM32F10X_HD_VL)#ifdefDATA_IN_ExtSRAMSystemInit_ExtMemCtl();#endif/*DATA_IN_ExtSRAM*/#endif/*ConfiguretheSystemclockfrequency,HCLK,PCLK2andPCLK1prescalers*//*ConfiguretheFlashLatencycyclesandenableprefetchbuffer*/SetSysClock();//此函数在该函数末尾#ifdefVECT_TAB_SRAMSCB->VTOR=SRAM_BASE|VECT_TAB_OFFSET;/*VectorTableRelocationinInternalSRAM.*/#elseSCB->VTOR=FLASH_BASE|VECT_TAB_OFFSET;/*VectorTableRelocationinInternalFLASH.*/#endif}staticvoidSetSysClock(void){//根据宏定义来设置时钟。#ifdefSYSCLK_FREQ_HSESetSysClockToHSE();#elifdefinedSYSCLK_FREQ_24MHzSetSysClockTo24();#elifdefinedSYSCLK_FREQ_36MHzSetSysClockTo36();#elifdefinedSYSCLK_FREQ_48MHzSetSysClockTo48();#elifdefinedSYSCLK_FREQ_56MHzSetSysClockTo56();#elifdefinedSYSCLK_FREQ_72MHzSetSysClockTo72();//以设置成最大频率72MHZ为例#endif/*Ifnoneofthedefineaboveisenabled,theHSIisusedasSystemclocksource(defaultafterreset)*/}staticvoidSetSysClockTo72(void){__IOuint32_tStartUpCounter=0,HSEStatus=0;/*SYSCLK,HCLK,PCLK2andPCLK1configuration---------------------------*//*EnableHSE*/RCC->CR|=((uint32_t)RCC_CR_HSEON);/*WaittillHSEisreadyandifTimeoutisreachedexit*/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){/*EnablePrefetchBuffer*/FLASH->ACR|=FLASH_ACR_PRFTBE;/*Flash2waitstate*/FLASH->ACR&=(uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR|=(uint32_t)FLASH_ACR_LATENCY_2;/*HCLK=SYSCLK*/RCC->CFGR|=(uint32_t)RCC_CFGR_HPRE_DIV1;/*PCLK2=HCLK*/RCC->CFGR|=(uint32_t)RCC_CFGR_PPRE2_DIV1;/*PCLK1=HCLK*/RCC->CFGR|=(uint32_t)RCC_CFGR_PPRE1_DIV2;#ifdefSTM32F10X_CL/*ConfigurePLLs------------------------------------------------------*//*PLL2configuration:PLL2CLK=(HSE/5)*8=40MHz*//*PREDIV1configuration:PREDIV1CLK=PLL2/5=8MHz*/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);/*EnablePLL2*/RCC->CR|=RCC_CR_PLL2ON;/*WaittillPLL2isready*/while((RCC->CR&RCC_CR_PLL2RDY)==0){}/*PLLconfiguration:PLLCLK=PREDIV1*9=72MHz*/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/*PLLconfiguration:PLLCLK=HSE*9=72MHz*/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);#endif/*STM32F10X_CL*//*EnablePLL*/RCC->CR|=RCC_CR_PLLON;/*WaittillPLLisready*/while((RCC->CR&RCC_CR_PLLRDY)==0){}/*SelectPLLassystemclocksource*/RCC->CFGR&=(uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR|=(uint32_t)RCC_CFGR_SW_PLL;/*WaittillPLLisusedassystemclocksource*/while((RCC->CFGR&(uint32_t)RCC_CFGR_SWS)!=(uint32_t)0x08){}}else{/*IfHSEfailstostart-up,theapplicationwillhavewrongclockconfiguration.Usercanaddheresomecodetodealwiththiserror*/}}

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭