参考:https://blog.csdn.net/huangyangquan/article/details/78790443

https://www.cnblogs.com/dustinzhu/p/4149906.html

在系统启动阶段,在进入main函数之前,系统先进入SystemInit函数,代码如下:

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

在SystemInit函数中配置系统时钟,根据系统时钟定义自动选择系统时钟配置函数,代码如下所示(设置系统时钟为72MHz):

#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
/*******************************************************************************
*  Clock Definitions
*******************************************************************************/
#ifdef SYSCLK_FREQ_HSEuint32_t SystemCoreClock         = SYSCLK_FREQ_HSE;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_24MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_24MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_36MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_36MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_48MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_48MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_56MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_56MHz;        /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_72MHzuint32_t SystemCoreClock         = SYSCLK_FREQ_72MHz;        /*!< System Clock Frequency (Core Clock) */
#else /*!< HSI Selected as System Clock source */uint32_t SystemCoreClock         = HSI_VALUE;        /*!< System Clock Frequency (Core Clock) */
#endif

若未定义系统时钟或未外接晶振HSE,则默认使用内部时钟HSI,8MHzRC振荡器,若使用PLL作为,则应使用如下代码替代SystemInit函数:

void SystemInit(void)
{  RCC_DeInit();//将外设 RCC寄存器重设为缺省值  RCC_HSICmd(ENABLE);//使能HSI    while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);//等待HSI使能成功  //加上这两句才能到64M
//    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  //FLASH半周期访问
//    FLASH_SetLatency(FLASH_Latency_2);                 //设置代码延时值RCC_HCLKConfig(RCC_SYSCLK_Div1);     RCC_PCLK1Config(RCC_HCLK_Div2);  RCC_PCLK2Config(RCC_HCLK_Div1);  //设置 PLL 时钟源及倍频系数  RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);//使能或者失能 PLL,这个参数可以取:ENABLE或者DISABLE   RCC_PLLCmd(ENABLE);//如果PLL被用于系统时钟,那么它不能被失能  //等待指定的 RCC 标志位设置成功 等待PLL初始化成功  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);  //设置系统时钟(SYSCLK) 设置PLL为系统时钟源  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//选择想要的系统时钟   //等待PLL成功用作于系统时钟的时钟源  //  0x00:HSI 作为系统时钟   //  0x04:HSE作为系统时钟   //  0x08:PLL作为系统时钟    while(RCC_GetSYSCLKSource() != 0x08);//需与被选择的系统时钟对应起来,RCC_SYSCLKSource_PLL
} 

其中,FLASH相关操作未明白,暂且注释掉,暂未发现影响。

注:STM32F103最高主频72M,PLL最高倍频数16,HSI时钟精度1%,当使用内部时钟时,系统最高主频64M,具体参考时钟树配置。

正点原子配置Systick程序:

static u8  fac_us=0;                            //us延时倍乘数
static u16 fac_ms=0;                           //ms延时倍乘数,在ucos下,代表每个节拍的ms数//初始化延迟函数
//SYSTICK的时钟固定为HCLK时钟的1/8
//SYSCLK:系统时钟
void delay_init()
{SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);  //选择外部时钟  HCLK/8fac_us=SystemCoreClock/8000000;                //为系统时钟的1/8  fac_ms=(u16)fac_us*1000;              //代表每个ms需要的systick时钟数
}                                   //延时nus
//nus为要延时的us数.
void delay_us(u32 nus)
{       u32 temp;            SysTick->LOAD=nus*fac_us;                  //时间加载           SysTick->VAL=0x00;                         //清空计数器SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数    do{temp=SysTick->CTRL;}while((temp&0x01)&&!(temp&(1<<16)));     //等待时间到达   SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器SysTick->VAL =0X00;                          //清空计数器
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void delay_ms(u16 nms)
{                 u32 temp;        SysTick->LOAD=(u32)nms*fac_ms;               //时间加载(SysTick->LOAD为24bit)SysTick->VAL =0x00;                           //清空计数器SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数  do{temp=SysTick->CTRL;}while((temp&0x01)&&!(temp&(1<<16)));       //等待时间到达   SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器SysTick->VAL =0X00;                          //清空计数器
}

下面介绍STM32中的systick,Systick 部分内容属于NVIC控制部分,一共有4个寄存器,名称和地址分别是:

STK_CSR,        0xE000E010  --  控制寄存器
STK_LOAD,     0xE000E014  --  重载寄存器
STK_VAL,        0xE000E018  --  当前值寄存器
STK_CALRB,   0xE000E01C  --   校准值寄存器

首先看STK_CSR控制寄存器:寄存器内有4个位t具有意义

第0位:ENABLE,Systick 使能位  (0:关闭Systick功能;1:开启Systick功能)
第1位:TICKINT,Systick 中断使能位    (0:关闭Systick中断;1:开启Systick中断)
第2位:CLKSOURCE,Systick时钟源选择  (0:使用HCLK/8 作为Systick时钟;1:使用HCLK作为Systick时钟)
第3位:COUNTFLAG,Systick计数比较标志,如果在上次读取本寄存器后,SysTick 已经数到了0,则该位为1。如果读取该位,该位将自动清零

STK_LOAD  重载寄存器:

Systick是一个递减的定时器,当定时器递减至0时,重载寄存器中的值就会被重装载,继续开始递减。STK_LOAD  重载寄存器是个24位的寄存器最大计数0xFFFFFF。

STK_VAL当前值寄存器:

也是个24位的寄存器,读取时返回当前倒计数的值,写它则使之清零,同时还会清除在SysTick 控制及状态寄存器中的COUNTFLAG 标志。

STK_CALRB  校准值寄存器:

位31 NOREF :1=没有外部参考时钟(STCLK 不可用)0=外部参考时钟可用

位30 SKEW:1=校准值不是准确的1ms 0=校准值是准确的1ms

位[23:0] :Calibration value

当修改系统主频时,只需要修改对应的us计数器就行

ex:当修改系统主频为64M时,修改fac_us=64/8,若时钟源选择内核时钟,则fac_us=64。

ex2:内部系统时钟精确度较低,当主频为64MHz时串口容易出现问题,附上GD32F103CBT6示例程序,程序同样适用于STM32,功能为串口收发实验,改编的正点原子程序,系统主频为40MHz,串口波特率为115200,功能测试ok

https://download.csdn.net/download/sinat_36171220/20365796

STM32使用内部时钟HSI作为系统时钟及配置Systick定时器相关推荐

  1. STM32使用内部RC振荡器作为系统时钟开发项目--内晶振启动模板工程

    STM32使用内部RC振荡器时,OSC32_IN,OSC32_OUT接法: 1)对于100脚或144脚的产品,OSC_IN应接地,OSC_OUT应悬空. 2)对于少于100脚的产品,有2种接法:   ...

  2. stm32产生100k时钟信号_stm32f105/107系统时钟变慢

    问题:最近把之前stm32f103平台的工程拿到stm32f105平台编译,编译通过了,但是烧录运行时发现系统时钟慢了3倍左右. 我先上一张stm32的时钟树吧 1.通过打印SYSCLK=72MHz, ...

  3. 系统滴答及Systick定时器

    1. 概述 操作系统需要有一个系统的滴答来提供任务管理的时间依据,bcos中的任务延时及tasklet的定时都是依据系统滴答.系统滴答需要一个定时器来提供时间基准,几乎所有的CPU都会提供一个滴答定时 ...

  4. TMS320F28335之系统时钟

    TMS320F28335时钟(1) PLL作用就是对外部时钟进行倍频,降低产生高频时钟信号的成本.但是倍频配置的时候,需要在特定的条件下更改,因此需要检测PLL工作的各种状态信号,因此PLL有两个配置 ...

  5. STM32F4设置系统时钟源为内部HSI

    最近项目需要在调试STM32时遇到外部晶振时钟不稳定,查看RCC_CR寄存器的第17位始终处于0,表示外部晶振始终处于不稳定状态: 当HSE开启时,如果HSERDY一直处于0时,则芯片会启动内部16M ...

  6. STM32使用内部时钟当系统时钟

    最近刚开始接触STM32,因为项目中所使用的STM32没有外部晶振,再加上需要使用一些高频外设,所以说就只能使用内部的HSI作为PLL时钟源,作为系统时钟.下图为STM32F10时钟系统框图以及相应说 ...

  7. STM32标准库修改HSI时钟教程

    目录 前言 一.官方标准库是如何改变时钟的? 二.修改系统时钟 前言 在我们常用的STM32 Blue Pill(如下图所示)上,一般在学习时都会使用默认的72Mhz晶振.但当我们自己设计电路板时,如 ...

  8. 基于STM32F103--时钟树详解和系统时钟内部流程解析

    前言        本次我们认识一下STM32F103的时钟树架构,以及系统时钟在内部的初始化是怎么处理的,大部分是自己收集和整理,如有侵权请联系我删除. 本博客内容原创,创作不易,转载请注明 1.初 ...

  9. STM32系统时钟设置(标准库)

    1.STM32F407时钟树 2.系统时钟相关的结构 HSE高速外部时钟信号 锁相环PLL 锁相环的主要作用就是对时钟进行倍频,然后把时钟输出到各个功能部件.PLL有两个,一个主PLL,另一个是专用的 ...

最新文章

  1. 并发、并行、串行、同步、异步、阻塞、非阻塞
  2. 30212Java_数组
  3. 程序员节,10月24日!
  4. 王者齐聚!Unite 2017 Shanghai 日程讲师全揭晓
  5. 将PDF和Gutenberg文档格式转换为文本:生产中的自然语言处理
  6. Kibana Guide ( Kibana 向导 )
  7. Go实现简单的RESTful_API
  8. python爬虫ip代理池_爬虫教程-Python3网络爬虫开发——IP代理池的维护
  9. 精通Server 2008多元密码策略之PowerShell篇
  10. python自动化办公能做什么-用Python自动办公,做职场高手(完结)
  11. Oauth2.0如何理解?
  12. 大学生创新创业基础章节答案(李家华等,2021版)
  13. 第一章 SQL命令 ALTER TABLE(一)
  14. postgres常用SQL
  15. 电容上电后是短路还是开路?
  16. Linux学习笔记——Linux基本命令篇
  17. 提取最后一个星号后的数字
  18. hikari数据源配置类_SpringBoot2集成Mybatis Hikari多数据源配置
  19. 19、基于STM32的电子打铃器
  20. 抖音xg03算法逆向杂谈

热门文章

  1. Rabbitmq在工作中的应用
  2. iOS的layer的anchorpoint与posion问题
  3. 3D建模知识讲解|什么是法线贴图?
  4. onKeyDown 方法一点归纳
  5. 高通滤波法、微分算子法、神经网络方法实现图像边缘检测
  6. IP地址,网络地址,主机地址,子网掩码关系
  7. 微信公众账号开发模式2
  8. DDD的简单落地实现
  9. STM32F103ZET6串口调试与语音播报
  10. 使用react实现后台管理系统项目