[操作环境]:KEIL MDK4.10  Lib_V3.5.0

阅读了STM32F10x_StdPeriph_Lib_V3.5.0库关于时钟部分代码,发现设备初始化时钟默认为外部晶振8MHz,经过PLL倍频后,内部核心时钟为72MHz.

其处理流程大致如下:
1、启动文件(startup_stm32f10x_md.s)里有如下代码:

; Reset handler
Reset_Handler    PROCEXPORT  Reset_Handler             [WEAK]IMPORT  __mainIMPORT  SystemInitLDR     R0, =SystemInitBLX     R0LDR     R0, =__mainBX      R0ENDP

2、系统复位后,会先执行SystemInit函数,这个函数位于库\CMSIS\CM3\DeviceSupport\ST\STM32F10x\system_stm32f10x.c文件中,该函数的主要功能是配置RCC的相关寄存器,如CR、CFGR、CIR等,
先将这些寄存器进行复位,然后调用SetSysClock()来设置系统时钟,SetSysClock()函数代码如下:

static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSESetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHzSetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHzSetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHzSetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHzSetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHzSetSysClockTo72();
#endif/* If none of the define above is enabled, the HSI is used as System clocksource (default after reset) */
}

这个函数是通过宏定义来区分调用不同的时钟频率设置函数。在文件system_stm32f10x.c的第83行处,定义了默认的系统时钟为72MHz。

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_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
#endif

如需更改成其它值的系统时钟,有两种方式:1、在这里把默认的宏定义注释掉,然后打开其他的宏定义;2、或者这里只注释掉宏定义,然后再KEIL-MDK编译器中设置该宏,设置方法如图:

这样在编译的过程中,编译器会自动将设置的宏定义传入代码中。

3、SetSysClockTo72()函数,功能是开启外部时钟控制位及其他配置寄存器,以使时钟达到预期值。函数代码如下:

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);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}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;    /* 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;#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    /*  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);
#endif /* STM32F10X_CL *//* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    /* 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 configuration. User can add here some code to deal with this error */}
}

其中有一段代码:

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

3.5库默认是外部晶振为8M,所以这样的倍频系数选择为9,这样可以达到72M。如果外面是12M晶振,那这里的倍频系数是否要改成6呢??答案是,可以更改,也可以不用更改。为什么不用改?不更改的话,那岂不是要到108MHz啦?超频啦!!不会超频的,因为STM32F10x芯片最高时钟为72M,不会超过这个值。看下面的时钟树图,就能找到答案。

4、执行完上面的SetSysClock()函数,库的时钟初始化就算完成了,接下来启动文件会将程序指针指向用户的main()函数,由用户做其他工作。

问题:如何更改外部晶振的默认值,比如由8M更改到12M?

有两种方式可以达成目的:
1、通过修改库源文件,在文件stm32f10x.h第95行宏定义了外部晶振的值。
2、不修改源文件,直接在编译器里面添加宏定义,通过宏定义传值给代码,如图:

如果传递多个宏定义值的话,每个定义之前用空格隔开。

转载于:https://www.cnblogs.com/swblog/p/3349137.html

STM32F10x_StdPeriph_Lib_V3.5.0库时钟分析及如何配置相关推荐

  1. STM32F10x_StdPeriph_Lib_V3.5.0库与系统滴答定时器(Systick)

    在V3.5的库中,关于系统滴答的配置是在core_cm3.h文件中,其代码如下: static __INLINE uint32_t SysTick_Config(uint32_t ticks) { i ...

  2. 8266+ds3231时钟之arduino官网发布的DS3231库的分析【二】

    这个时钟系列目前五篇分别是: <8266+DS3231时钟之开发个时钟遇到的N个坑[一]> <8266+ds3231时钟之arduino官网发布的DS3231库的分析[二]> ...

  3. 易语言.尘土界面库2.0版源代码分析(1):缘起

    作者:liigo 原文链接:http://blog.csdn.net/liigo/archive/2009/06/23/4292691.aspx 转载请注明出处:http://blog.csdn.ne ...

  4. Adafruit_GFX matrix ws2812像素屏库使用教程AWTRIX2.0像素时钟

    AWTRIX2.0像素时钟很炫酷但必须要与服务器配合使用.这个库可以做自己的点阵时钟离线版.想怎么玩就怎么玩不受服务器牵绊. 第一步:下载mixy库然后倒入,必须有以下库文件: Adafruit_GF ...

  5. android6.0源码分析之Zygote进程分析

    在android6.0源码分析之Runtime的初始化一文中,对Zygote进程的初期的Runtime初始化过程进行了分析,在Runtime启动结束后,会对Zygote进程进行初始化,其它Java进程 ...

  6. android6.0源码分析之Runtime的初始化

    Android运行时作为android架构的一部分,起着非常重要的作用,它和核心库(Core Libraries)组成了Android运行时库层.本文将依据android源码对AndroidRunti ...

  7. android6.0源码分析之Camera2 HAL分析

    1.Camera HAL的初始化 Camera HAL的初始加载是在Native的CameraService初始化流程中的,而CameraService初始化是在Main_mediaServer.cp ...

  8. zookeeper客户端库curator分析

    zookeeper客户端库curator分析 前言 综述 zookeeper保证 理解zookeeper的顺序一致性 之前使用zookeeper客户端踩到的坑 curator 连接保证 连接状态监控以 ...

  9. 【转】DICOM:DICOM三大开源库对比分析之“数据加载”

    背景: 上一篇博文DICOM:DICOM万能编辑工具之Sante DICOM Editor介绍了DICOM万能编辑工具,在日常使用过程中发现,"只要Sante DICOM Editor打不开 ...

最新文章

  1. LeetCode_97.交错字符串_没懂
  2. ObjectArx创建指定块
  3. WebMagic学习总结
  4. 信息学奥赛一本通(1157:哥德巴赫猜想)
  5. Android 应用开发(29)---android 开发环境搭建
  6. 计算机丢失twitchsdk,修复twitchsdk_32_release.dll
  7. 微型计算机原理IMUL指令,微机原理与系统设计实验
  8. Hobo 4: Total War
  9. c语言万能编程模板_C语言实现模板
  10. 从动物科学到乐队鼓手,腾讯技术小哥的开源人生
  11. Mybatis 特殊符号(大于,小于,不等于)及常用函数总结
  12. 修改IE地址栏Tomcat小猫咪图标
  13. 七夕表白之Python画玫瑰花
  14. php薄饼,薄饼的做法大全
  15. 台式计算机启动时 每次按f1,开机按f1的解决方法_电脑开机每次都要按F1,怎么解决...
  16. 触控手机、握笔握手、拎箱包、拿鸡蛋 可穿戴仿生手将投入量产!
  17. Java 8 中 GZIPInputStream 类源码分析
  18. 郭昌洪畅谈—物业管理工作三大论述
  19. Android平台上集成大华SDK
  20. 【无标题】麻烦大佬有偿帮弄一下这个截图只是一部分有意的大佬加我

热门文章

  1. 大数据,只是为了赚钱么?
  2. css3制作一个漂亮的按钮
  3. 计算机组成原理 — CPU — 主存访问
  4. 互联网协议 — RIP 路由信息协议
  5. 互联网协议 — PPP 点对点协议
  6. 通过 vSphere WS API 获取 vCenter Datastore Provisioned Space 置备空间
  7. Keil仿真出现Can not read register xx while CPU is running
  8. 记录Flex布局的属性
  9. Cocos坐标之convertToNodeSpace、convertToWorldSpace、convertToNodeSpaceAR、convertToWorldSpaceAR区别和用法...
  10. [Android]实现类似微信的延迟加载的Fragment——LazyFragment