STM32时钟初始化研究

发布者:玉树琼花最新更新时间:2018-12-18 来源: eefocus关键字:STM32  时钟初始化 手机看文章 扫描二维码
随时随地手机看文章

时钟是一个MCU的脉搏,研究清楚脉搏才能更清楚的把握整个MCU的运行。本文主要研究STM32F10x系列,利用官方库文件进行初始化设置。开发环境为MDK4.6,库文件V3.5版本,STM32参考手册。


利用MDK自带仿真器,仿真发现。芯片启动首先打开system_stmf10x.c文件,调用void SystemInit(void)函数。下面贴上代码和中文注释


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

//SW:HSI(内部高速8M RC震荡器)作为时钟源

//AHB(SYSCLK)不分频

//APB1,APB2不分频

// PCLK2 2分频后作为ADC时钟

// HSI时钟2分频后作为PLL输入时钟

//MCO没有时钟输出

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

 

/* Reset HSEON, CSSON and PLLON bits */

//HSE振荡器关闭, 时钟安全系统监测器关闭PLL关闭

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

 

/* Reset HSEBYP bit */

//清零来旁路外部晶体振荡器。只有在外部4-25MHz振荡器关闭的情况下,才能写入该位。

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

 

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

//HSI时钟2分频后作为PLL输入时钟

//HSE不分频器作为PLL输入

//0000:PLL 2倍频输出

//0:PLL时钟1.5倍分频作为USB时钟

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

 

/* Disable all interrupts and clear pending bits  */

RCC->CIR = 0x009F0000;

 

/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */

/* Configure the Flash Latency cycles and enable prefetch buffer */

SetSysClock();

 

SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */

}


主要是用于重置RCC寄存器,既重置STM32的时钟树。


初始化重置时钟后的时钟树图:


上文中还有个函数叫SetSysClock用于设置MCU系统时钟,贴入代码:


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

}

 

static void SetSysClockTo72(void)

{

__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

 

/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    

 

 

/* Enable HSE */    

/*define C_CR_HSEON                        (int32_t)0x00010000)   */

/*!< External High Speed clock enable */

//开启HSE振荡器

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

 


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

//等待HSE起振

//#define HSEStartUp_TimeOut   HSE_STARTUP_TIMEOUT

//#define HSE_STARTUP_TIMEOUT   ((uint16_t)0x0500)

/*!< Time out for HSE start up */

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

//#define  RCC_CFGR_HPRE_DIV1      ((uint32_t)0x00000000)        /*!< SYSCLK not divided */

//HCLK  :AHB总线时钟,由系统时钟SYSCLK 分频得到,不分频

RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

 

 

/* PCLK2 = HCLK */

// #define  RCC_CFGR_PPRE2_DIV1    ((uint32_t)0x00000000)        /*!< HCLK not divided */

//APB2由AHB分频而来,不分频。

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

 


/* PCLK1 = HCLK */

//#define  RCC_CFGR_PPRE1_DIV2                 ((uint32_t)0x00000400)        /*!< HCLK divided by 2 */

//APB1由AHB分频而来,2分频。

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

 

/*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */

//设置PLLCLK时钟源为HSE,且PLL9倍频

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

 


/* Enable PLL */

//使能倍频器

RCC->CR |= RCC_CR_PLLON;

 

 

/* Wait till PLL is ready */

//等待PLL稳定运行

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

{

}


/* Select PLL as system clock source */

//设置PLL作为系统时钟源

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

//等待PLL用于系统时钟源

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

}

 

}


初始化重置时钟后的时钟树图:

关键字:STM32  时钟初始化 引用地址:STM32时钟初始化研究

上一篇:stm32时钟初始化分析
下一篇:STM32F4各外设时钟配置总结

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

STM32】系统时钟RCC详解(超详细,超全面)
1什么是时钟 时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。时钟系统就是CPU的脉搏,决定cpu速率,像人的心跳一样 只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理 (点灯,串口,ADC),时钟的重要性不言而喻。 为什么 STM32 要有多个时钟源呢? STM32本身十分复杂,外设非常多 但我们实际使用的时候只会用到有限的几个外设,使用任何外设都需要时钟才能启动,但并不是所有的外设都需要系统时钟那么高的频率,为了兼容不同速度的设备,有些高速,有些低速,如果都用高速时钟,势必造成浪费 并且,同一个电路,时钟越快功耗越快,同时抗电磁干扰能力也就越弱,所以较为复杂的
[单片机]
【<font color='red'>STM32</font>】系统<font color='red'>时钟</font>RCC详解(超详细,超全面)
浅谈STM32_RTC闹钟
今天讲解“STM32F103RTC闹钟”,说起“闹钟”大家肯定不会陌生,基本上我们每天都在接触。今天说的“RTC闹钟”就是我们现实生活中的闹钟,只是今天站在技术知识的角度来看待“闹钟”。由于这一阶段定位的是基础的知识,所以今天提供的软件例程也是相对简单一点的,但明白今天的知识,相信自己都会写闹钟程序了,后期我会更新日历及闹钟的综合知识。 每天提供下载的“软件工程”都是在硬件板子上进行多次测试、并保证没问题才上传至360云盘。 今天的软件工程下载地址(360云盘): https://yunpan.cn/cSsN8ExwLMBbj访问密码 529c STM32F10x的资料可以在我360云盘下载: https://yunpan
[单片机]
浅谈STM32_RTC闹钟
STM32入门学习之ADC(STM32F030F4P6基于CooCox IDE)
#include stm32_lib/inc/stm32f0xx_rcc.h #include stm32_lib/inc/stm32f0xx_adc.h #include stm32_lib/inc/stm32f0xx_gpio.h int main(void) { //时钟配置 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); //ADC IO配置,此处定义PA0口为ADC端口 GPIO_InitTypeDef PORT_ADC; PORT_AD
[单片机]
STM32—串口使用总结
一.仅向上位机打印调试信息 单纯利用串口向上位机打印调试信息,程序如下: void USART1_Init( uint32_t btl ) { GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE ); GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;//Tx
[单片机]
<font color='red'>STM32</font>—串口使用总结
零基础入门stm32需要掌握的知识有那些
  1.首先我们先看看与STM32相关的文档   我们假定大家已经对STM32的书籍或者文档有一定的理解。如不理解,请立即阅读STM32的文档,以获取最基本的知识点。   如果你手上拥有ST官方主推的STM32神舟系列的板子,那么光盘都会配好这些文档,STM32的学习与ARM9的学习有一个很大的区别。ARM9的学习   一般是需要购买书籍的。比如三星的S3C2440,官方的文档都是英文的,大部分工程师只能去看国内出版的书籍。英文好的同学,请不要以为   你很牛,可以只看英文文档。毕竟你是中国人,你最熟悉的,理解最好的还是中文。看英文的速度还是比看中文慢一些,我们要的是最短的时   间,而不是追求短时间内记住所有细节。当然,如果是一
[单片机]
怎样去设计一种基于STM32单片机的智能手环脉搏心率计步器
一:功能 基于STM32单片机智能手环心率计步器体温显示设计 本设计由STM32F103C8T6单片机核心板电路+ADXL345传感器电路+心率传感器电路+温度传感器+lcd1602电路组成。 1、通过重力加速度传感器ADXL345检测人的状态,计算出走步数、走路距离和平均速度。 2、通过心率传感器实时检测心率,通过温度传感器检测温度。 3、lcd1602实时显示步数、距离和平均速度、心率以及温度值。 二:电路图 三:源代码 #include led.h #include delay.h #include sys.h #include usart.h #include #include t
[单片机]
怎样去设计一种基于<font color='red'>STM32</font>单片机的智能手环脉搏心率计步器
stm32库函数GPIO_Init()解析
GPIO_Init函数是IO引脚的初始化函数,进行个个引脚的初始化配置,主要接受两个参数,一个是配置引脚组(GPIO_TypeDef* GPIOx),一个是配置的参数( GPIO_InitTypeDef* GPIO_InitStruct),具体如下 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) /*其中第一个参数为那组引脚,每组拥有16个引脚,每组都具有不同的寄存器配置地址,第二个参数是一个数据结构,也就是将基本配置信息放在这个数据结构里面,再将这个结构传入函数进行配置*/ //其中数据机构可以表示为如下 typedef str
[单片机]
STM32系统架构
在小容量、中容量和 大容量产品中,主系统由以下部分构成: ● 四个驱动单元: ─ Cortex-M3内核DCode总线(D-bus),和系统总线(S-bus) ─ 通用DMA1和通用DMA2 ● 四个被动单元 ─ 内部SRAM ─ 内部闪存存储器 ─ FSMC ─ AHB到APB的桥(AHB2APBx),它连接所有的APB设备 这些都是通过一个多级的AHB总线构架相互连接的,如下图所示: 在互联型产品中,主系统由以下部分构成: ● 五个驱动单元: ─ Cortex-M3内核DCode总线(D-bus),和系统总线(S-bus) ─ 通用DMA1和通用DMA2 ─ 以太网DMA ● 三个被动单元 ─ 内部SRAM ─ 内部闪存
[单片机]
<font color='red'>STM32</font>系统架构
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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