学习stm32f103(二) 关于系统时钟

发布者:支持中文最新更新时间:2018-06-26 来源: eefocus关键字:stm32f103  系统时钟 手机看文章 扫描二维码
随时随地手机看文章

stm32中可以选择多种时钟源,可以参考stm32数据手册,这里手册中的时钟图



而在stm32f103系列的说明中,可知系统最高可以达到72M的主频,(f407等可以达到更高的主频),为了强大的性能,在不考虑功耗的前提下当然要选择72M作为我们系统的主频咯,关键是怎么来设置呢?

这里一般stm32外部有一颗8Mhz 的晶振作为芯片HSE时钟的输入,再配合PLL将HSE倍频到72M就ok了,具体怎么设置可以查看手册的相关寄存器,但这里就不劳神去看了,查看我们配置好的工程,在给的库中已经有相关的工作了。


打开starup_stm32f10x_md.s(不同芯片可能不同)文件,可以看见这是一个用来启动的汇编文件。

Reset_Handler    PROC  

                 EXPORT  Reset_Handler             [WEAK]  

     IMPORT  __main  

     IMPORT  SystemInit  

                 LDR     R0, =SystemInit  

                 BLX     R0  

                 LDR     R0, =__main  

                 BX      R0  

                 ENDP  

可以看到这么一段,这应该是复位后的位置(大概,不是很懂汇编),可以看到这里import了两个函数,一个是SystemInit, 一个是__main函数,__main函数中最后会调用我们自己写好的main函数,而systeminit函数怎么看都是个初始化函数,在system_stm32f10x.c文件中可以看到这个函数的原形。


void SystemInit (void)  

{  

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

  /* Set HSION bit */  

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

  

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

#ifndef STM32F10X_CL  

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

#else  

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

#endif /* STM32F10X_CL */     

    

  /* Reset HSEON, CSSON and PLLON bits */  

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

  

  /* Reset HSEBYP bit */  

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

  

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

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

  

#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  

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

}  


可以在最后几段看到调用了SetSysClock()函数 ,这应该就是用来设置系统时钟的函数了。

在同一个文件下也可以找到这个函数的原形



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  

  SetSysClockTo72();  

#endif  

   

 /* If none of the define above is enabled, the HSI is used as System clock 

    source (default after reset) */   

}  


可以看到,根据设置的宏不同,这个函数又会调用不同的系统时钟设置函数,这些宏也可以在同一个文件中找到


#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  

#endif  


这里通过设置不同的宏,就可以改变系统的时钟设置了,非常方便。

最后看一下设置72M时钟的函数



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 != HSE_STARTUP_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 */  

  }  

}  


关键字:stm32f103  系统时钟 引用地址:学习stm32f103(二) 关于系统时钟

上一篇:STM32F4xx时钟理解
下一篇:STM32F103系统时钟配置

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

windows 下vscode+platformio开发stm32f103c8t6最小系统
最近想要写个更新航模接收机固件的小项目,移植opentx项目的部分代码到我的最小系统板上。不经意间发现vscode上也可以开发stm32了,于是,一个填坑行动开始了!!! 先写怎么才能编译调试吧! 环境: windows10x64,8G内存,i5 4200 stlink v2 1.你要有个vscode,不用我说了。 2.在vscode上装platformio插件 安装完毕,点击重新加载。之后会提示正在安装PlatformIO 核心。 再次重新加载 3.安装完毕后,在vscode的左下角会有一个家的图标,可以从这里新件工程。第一次启动也会自动打开PIO Home页面。 4.新建工程。因为它是
[单片机]
windows 下vscode+platformio开发<font color='red'>stm32f103</font>c8t6最小<font color='red'>系统</font>
STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)
一、环境介绍 工程编译软件: keil5 温湿度传感器: SHT30 MCU : STM32F103ZET6 程序采用模块化编程,iic时序为一个模块(iic.c 和 iic.h),SHT30为一个模块(sht30.c 和 sht30.h);IIC时序采用模拟时序方式实现,IO口都采用宏定义方式,方便快速移植到其他平台使用。 工程源码完整下载地址: https://download.csdn.net/download/xiaolong1126626497/18973724 二、SHT30介绍 特点: 1. 湿度和温度传感器 2. 完全校准、线性化和温度 3. 补偿数字输出,宽电源电压范围,从2.4 V
[单片机]
<font color='red'>STM32F103</font>ZE+SHT30检测环境温度与湿度(IIC模拟时序)
STM32F103ZET6 — TIM6/TIM7
介绍 STM32F103ZET6 定时器资源非常丰富,根据 datasheet 描述,涵盖如下几种类型: 高级定时器 TIM1 / TIM8 通用定时器 TIM2 / TIM3 / TIM4 / TIM5 基本定时器 TIM6/ TIM7 本次描述的重点是基本定时器 TIM6/ TIM7 基本定时器TIM6和TIM7各包含一个16位自动装载计数器,由各自的可编程预分频器驱动。它们可以作为通用定时器提供时间基准,特别地可以为数模转换器(DAC)提供时钟。实际上,它们在芯片内部直接连接到DAC并通过触发输出直接驱动DAC。这2个定时器是互相独立的,不共享任何资源。 时钟 可以看到来自 APB1 的低频时钟经过频率x2
[单片机]
<font color='red'>STM32F103</font>ZET6 — TIM6/TIM7
MSP430设置基本时钟系统
简介:上电复位后默认XT2关,ACLK来自XT1,MCLK和SMCLK都来自DCO。 掌握通过对寄存器的操作分配时钟信号: 设置ACLK来自XT1,MCLK来自XT2,SMCLK来自XT2。 各个时钟通道的分频自定。 通过这些基本的时钟模块,我们可以得到3个有用的时钟信号: ACLK辅助时钟(Auxillary Clock) ACLK是LFXT1CLK时钟源经1、2、4、8分频后得到的。 ACLK可由软件选择作为各个外围模块的时钟信号,一般用于低速外设。 MCLK主系统时钟(Main System Clock) MCLK可由软件选择来自LFXT1CLK、XT2CLK、DCOCLK三者之一,然后经1、2、4、8分频。 MCL
[单片机]
STM32的时钟系统RCC详细整理
一、综述: 1、时钟源 在 STM32 中,一共有 5 个时钟源,分别是 HSI 、 HSE 、 LSI 、 LSE 、 PLL 。 ①HSI 是高速内部时钟, RC 振荡器,频率为 8MHz ; ②HSE 是高速外部时钟,可接石英 / 陶瓷谐振器,或者接外部时钟源,频率范围是 4MHz – 16MHz ; ③LSI 是低速内部时钟, RC 振荡器,频率为 40KHz ; ④LSE 是低速外部时钟,接频率为 32.768KHz 的石英晶体; ⑤PLL 为锁相环倍频输出,严格的来说并不算一个独立的时钟源, PLL 的输入可以接 HSI/2 、 HSE 或者 HSE/2 。PLL倍频可选择为 2 – 16 倍,
[单片机]
STM32的<font color='red'>时钟</font><font color='red'>系统</font>RCC详细整理
STM32F103定时器详解
STM32F103系列的单片机一共有11个定时器,其中: 2个高级定时器 4个普通定时器 2个基本定时器 2个看门狗定时器 1个系统嘀嗒定时器 除去看门狗定时器和系统滴答定时器的八个定时器列表; 8个定时器分成3个组; TIM1和TIM8是高级定时器 TIM2-TIM5是通用定时器 TIM6和TIM7是基本的定时器 这8个定时器都是16位的,它们的计数器的类型除了基本定时器TIM6和TIM7都支持向上,向下,向上/向下这3种计数模式 计数器三种计数模式 向上计数模式:从0开始,计到arr预设值,产生溢出事件,返回重新计时 向下计数模式:从arr预设值开始,计到0,产生溢出事件,返回重新计时 中央对齐模式:从0开始向
[单片机]
<font color='red'>STM32F103</font>定时器详解
STM32F103使用SWD烧写错误提示的问题
今天使用STLINK和ULINK进行烧写,都无法成功,烧写模式为SWD! 错误提示为: flash timeout,reset the target and try it again Error: Flash Download failed - Cortex-M3 共2个错误 故网上搜索了下,得到以下解决方案: 1.对于“flash timeout,reset the target and try it again” 需在debug设置里,勾选Erase Full Chip Reset and Run program verify 2.对于 “Error: Flash Download failed - Cortex-M3 “
[单片机]
STM32F103 UART 串口
USART 通用同步收发器,UART 通用异步收发器 支持LIN(局部互联网)、智能卡协议、IrDA(红外)、以及调制解调器(CTS/RTS)等。 全双工交换数据、即收发同时进行。 接口 三个引脚:接收数据输入(RX)、发送数据输出(TX)、地(GND)。 RX:接收数据串行输入。通过采样技术来区别数据和噪音,从而恢复数据。 TX:发送数据输出。当发送器禁止时,输出引脚恢复到它的IO端口配置。当发送器激活时,不发送数据,TX引脚处于高电平。 传送速率 1波特 = 1bps(位/秒) 常用有:4800、9600、19200、115200波特等。 协议 总线在发送或接收前应该处于空闲状态;一个起
[单片机]
<font color='red'>STM32F103</font> UART 串口
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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