历史上的今天
返回首页

历史上的今天

今天是:2024年12月14日(星期六)

2021年12月14日 | STM32系统时钟RCC工作流程详解+配置函数中文注释+使用HSE代码

2021-12-14 来源:eefocus

前言

STM32系统时钟RCC工作流程详解


提示:以下是本篇文章正文内容


一、时钟树

在这里插入图片描述

二、工作流程

1.配置外部高速时钟HSE

在这里插入图片描述

HSE 是高速的外部时钟信号,可以由有源晶振或者无源晶振提供,频率从 4-16MHZ 不等。

HSE 最常使用的就是 8M 的无源晶振。当确定 PLL 时钟来源的时候,HSE 可以不分频或者 2 分频,这个由时钟配置寄存器 CFGR 的 位 17:PLLXTPRE 设置。

配置:设置为 HSE 不分频。


2.配置锁相环PLL时钟源

在这里插入图片描述

PLL时钟来源可以有两个,一个来自HSE,另外一个是 HSI/2,具体用哪个由时钟配置寄存器 CFGR 的位 16:PLLSRC 设置。

HSI 是内部高速的时钟信号,频率为 8M,根据温度和环境的情况频率会有漂移,一般不作为 PLL的时钟来源

配置:选 HSE作为 PLL的时钟来源。


3.配置锁相环PLL倍频因子得PLL 时钟 PLLCLK

在这里插入图片描述

通过设置 PLL 的倍频因子,可以对 PLL 的时钟来源进行倍频,倍频因子可以是:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],具体设置成多少,由时钟配置寄存器 CFGR 的位21-18:PLLMUL[3:0]设置。

配置:设置为 9 倍频


4.配置系统时钟 SYSCLK

在这里插入图片描述

系统时钟来源可以是:HSI、PLLCLK、HSE,具体的时钟配置寄存器 CFGR 的位 1-0:SW[1:0]设置。

配置:设置系统时钟:SYSCLK = PLLCLK = 72M。


5.配置AHB总线分频因子

在这里插入图片描述

系统时钟 SYSCLK 经过 AHB 预分频器分频之后得到时钟叫 APB 总线时钟,即 HCLK,分频因子可以是:[1,2,4,8,16,64,128,256,512],具体的由时钟配置寄存器 CFGR的位 7-4 :HPRE[3:0]设置。片上大部分外设的时钟都是经过 HCLK 分频得到,至于 AHB总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好 APB 的时钟即可。

配置:里设置为 1 分频,即 HCLK=SYSCLK=72M。


6.配置APB1总线分频因子

在这里插入图片描述

APB1 总线时钟 PCLK1 由 HCLK 经过低速 APB 预分频器得到,分频因子可以是:[1,2,4,8,16],具体的由时钟配置寄存器 CFGR 的位 10-8:PRRE1[2:0]决定。HCLK1 属于低速的总线时钟,最高为 36M,片上低速的外设就挂载到这条总线上,比如USART2/3/4/5、SPI2/3,I2C1/2等。至于 APB1总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好 APB1 的时钟即可。

配置:设置为 2 分频,即 PCLK1 = HCLK/2 = 36M。


7.配置APB2总线分频因子

在这里插入图片描述

APB2总线时钟 PCLK2由 HCLK经过高速 APB2预分频器得到,分频因子可以是:[1,2,4,8,16],具体由时钟配置寄存器 CFGR的位 13-11:PPRE2[2:0]决定。HCLK2属于高速的总线时钟,片上高速的外设就挂载到这条总线上,比如全部的 GPIO、USART1、SPI1 等。至于 APB2 总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好 APB2 的时钟即可。

配置:设置为 1 分频,即 PCLK2 = HCLK =72M。


三、时钟配置函数中文注释

static void SetSysClockTo72(void)

{

  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

  

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

  /* 使能 HSE */    

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

 

  /* 等待HSE就绪并做超时处理 */

  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;

  }  


  // 如果HSE启动成功,程序则继续往下执行

  if (HSEStatus == (uint32_t)0x01)

  {

    /* 使能预取指 */

    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 = 72M */

    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

      

    /* PCLK2 = HCLK = 72M */

    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

    

    /* PCLK1 = HCLK = 36M*/

    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

    

    /*  锁相环配置: 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);


    /* 使能 PLL */

    RCC->CR |= RCC_CR_PLLON;


    /* 等待PLL稳定 */

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

    {

    }    

    /* 选择PLLCLK作为系统时钟*/

    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    


    /* 等待PLLCLK切换为系统时钟 */

    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)

    {

    }

  }

  else

  { /* 如果HSE 启动失败,用户可以在这里添加处理错误的代码 */

  }

}


四、使用HSE配置代码

HSE固件库配置.c


#include "bsp_rccclkconfig.h"


void HSE_SetSysClk( uint32_t RCC_PLLMul_x )

{

ErrorStatus HSEStatus;

// 把RCC 寄存器复位成复位值

RCC_DeInit();


// 使能 HSE 

RCC_HSEConfig(RCC_HSE_ON);

HSEStatus = RCC_WaitForHSEStartUp();

if( HSEStatus == SUCCESS )

{

// 使能预取指

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

FLASH_SetLatency(FLASH_Latency_2);

RCC_HCLKConfig(RCC_SYSCLK_Div1);

RCC_PCLK1Config(RCC_HCLK_Div2);

RCC_PCLK2Config(RCC_HCLK_Div1);

// 配置 PLLCLK = HSE * RCC_PLLMul_x

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_x);

    // 使能PLL

RCC_PLLCmd(ENABLE);

// 等待PLL稳定

while( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET );

    // 选择系统时钟

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    while( RCC_GetSYSCLKSource() != 0x08 );

}

else

  {

/* 如果HSE 启动失败,用户可以在这里添加处理错误的代码 */

}

}


void HSI_SetSysClk( uint32_t RCC_PLLMul_x )

{

__IO uint32_t HSIStatus = 0;

// 把RCC 寄存器复位成复位值

RCC_DeInit();


// 使能 HSI 

RCC_HSICmd(ENABLE);

HSIStatus = RCC->CR & RCC_CR_HSIRDY;

if( HSIStatus == RCC_CR_HSIRDY )

{

// 使能预取指

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

FLASH_SetLatency(FLASH_Latency_2);

RCC_HCLKConfig(RCC_SYSCLK_Div1);

RCC_PCLK1Config(RCC_HCLK_Div2);

RCC_PCLK2Config(RCC_HCLK_Div1);

// 配置 PLLCLK = HSE * RCC_PLLMul_x

    RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_x);

    // 使能PLL

RCC_PLLCmd(ENABLE);

// 等待PLL稳定

while( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET );

    // 选择系统时钟

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    while( RCC_GetSYSCLKSource() != 0x08 );

}

else

  {

/* 如果HSI 启动失败,用户可以在这里添加处理错误的代码 */

}

}


void MCO_GPIO_Config()

{

GPIO_InitTypeDef  GPIO_InitStruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStruct);

}


HSE固件库配置.h


#ifndef __BSP_RCCCLKCONFIG_H

#define __BSP_RCCCLKCONFIG_H


#include "stm32f10x.h"


void HSE_SetSysClk( uint32_t RCC_PLLMul_x );

void MCO_GPIO_Config();

void HSI_SetSysClk( uint32_t RCC_PLLMul_x );

#endif /*__BSP_RCCCLKCONFIG_H */


main.c


#include "stm32f10x.h"   // 相当于51单片机中的  #include

#include "bsp_led.h"

#include "bsp_rccclkconfig.h"



void Delay( uint32_t count )

{

for(; count!=0; count--);

}


int main(void)

{

// 来到这里的时候,系统的时钟已经被配置成72M。

//HSE_SetSysClk( RCC_PLLMul_9 );

//HSI_SetSysClk( RCC_PLLMul_16 );

MCO_GPIO_Config();

RCC_MCOConfig(RCC_MCO_SYSCLK);

//RCC_MCOConfig(RCC_MCO_HSI);

LED_GPIO_Config();

while(1)

{

LED_G(OFF);

Delay(0xFFFFF);

LED_G(ON);

Delay(0xFFFFF);

}

}


五、收获

1.系统时钟的配置逻辑

配置外部高速时钟HSE

配置锁相环PLL时钟源

配置锁相环PLL倍频因子得PLL 时钟 PLLCLK

配置系统时钟 SYSCLK

配置AHB总线分频因子

配置APB1总线分频因子

配置APB2总线分频因子


2. CSS时钟安全系统的作用

当外部HSE时钟发生故障,HSE振荡器被自动关闭,时钟失效事件将被送到高级定时器(TIM1和TiM8)的刹车输入端,并产生时钟安全中断CSSI,允许软件完成营救操作。此CSSI中断连接到NMI中断(不可屏蔽中断)。

在这里插入图片描述

如果HSE时钟发生故障,可以选择HSI时钟,配置8M经过二分频变为4M。时钟安全系统最重要的作用是提醒用户时钟故障,因尽快保存数据。

推荐阅读

史海拾趣

Gulf Semiconductor公司的发展小趣事

Gulf Semiconductor在电子行业中的五个发展故事

故事一:进入中国市场与本地化生产

Gulf Semiconductor(海湾电子)自1987年起便踏入中国市场,成为较早一批在中国设立生产基地的国际化整流二极管制造商。公司迅速适应了中国市场的需求,并建立了完善的管理体系,通过了ISO14001:2004、ISO9001:2000、ISO/TS 16949:2002等质量及环境管理体系认证。这一举措不仅提升了产品质量,还增强了客户信心,使Gulf Semiconductor在照明、电源、消费类电子等领域迅速占据一席之地。通过本地化生产,公司有效降低了成本,提高了竞争力,并成功吸引了如Samsung、LG、Philips等国际知名企业的合作。

故事二:技术创新与产品升级

Gulf Semiconductor始终将技术创新视为企业发展的核心动力。公司不断投入研发,掌握了先进的光阻玻璃烧结、特制的SIPOS工艺等多种工艺技术,这些技术使得公司产品在高压、高温等极端环境下依然能够保持高可靠性。特别是公司主推的GP类产品(玻融钝化整流器),凭借其出色的性能,获得了众多国际客户的全面认证和使用。此外,公司还积极开发世界著名整流器制造商的替用产品,产品性能可达到原厂的同等水平,进一步提升了市场竞争力。

故事三:客户服务与售后支持

Gulf Semiconductor深知客户满意是企业发展的关键。公司建立了完善的客户服务体系,为客户提供从产品设计、试产到批量投产的全程支持。在产品应用过程中,一旦出现个别产品缺陷或失效,公司能够迅速响应,分析问题原因,并采取纠正及预防措施,确保客户利益最大化。这种以客户为中心的服务理念,赢得了广大客户的信任和好评。

故事四:市场拓展与国际合作

随着全球电子行业的快速发展,Gulf Semiconductor不断拓宽市场领域,积极与国际知名企业建立合作关系。公司通过参加国际展会、举办技术交流会等方式,向世界展示其先进的技术和产品。同时,公司还加强与国际同行的交流与合作,共同推动电子行业的发展。这些努力不仅提升了Gulf Semiconductor在国际市场的知名度,还为其带来了更多的商业机会。

故事五:可持续发展与环保理念

作为一家负责任的企业,Gulf Semiconductor始终将可持续发展和环保理念贯穿于生产经营的全过程。公司积极采用节能减排技术,减少碳排放,并致力于绿色生产。此外,公司还积极参与社会公益活动,为环保事业贡献自己的力量。这些举措不仅提升了公司的社会形象,还为其赢得了更多消费者的青睐。在未来,Gulf Semiconductor将继续坚持可持续发展和环保理念,为推动电子行业的绿色发展贡献更多力量。

Empro Technology Corp公司的发展小趣事

为了进一步提升市场竞争力,Empro Technology Corp开始实施国际化战略,积极开拓海外市场。公司设立了多个海外分支机构,与当地企业建立了合作关系,共同开拓市场。同时,公司还积极参加国际电子展等交流活动,与国际同行进行深入交流与合作。

请注意,以上故事均为虚构内容,不代表Empro Technology Corp公司的实际发展情况。如需了解该公司的真实信息,请查阅相关公开资料或联系公司官方渠道。

Greenwich Instruments Ltd公司的发展小趣事

面对日益激烈的市场竞争和不断变化的客户需求,Greenconn Corp积极推动智能制造转型。公司引进先进的生产设备和技术,优化生产流程和管理模式,提高生产效率和产品质量。同时,公司还加强与高校、科研机构的合作,共同研发智能制造关键技术,推动智能制造技术在连接器生产领域的应用。这些努力不仅提升了Greenconn Corp的竞争力,还为公司的可持续发展奠定了坚实基础。

CET Technology公司的发展小趣事

CET Technology一直以来都高度重视产品质量和技术研发。为了保障产品的品质和可靠性,公司建立了完善的实验室体系,包括电磁兼容实验室、电气综合实验室等多个专业实验室。这些实验室配备了先进的实验仪器设备,为公司研发高品质产品提供了有力保障。近期,CET的实验室成功获得了CNAS实验室能力认证,这是对公司技术实力和质量管理水平的高度认可。此次认证将进一步提升CET在国际市场上的竞争力,为公司未来的发展奠定了坚实基础。

以上就是关于CET Technology公司在电子行业中的5个发展故事。这些故事展示了CET在技术创新、业务拓展、智慧化转型和品质保障等方面的努力和成果,也体现了公司在电子行业中的领先地位和影响力。

DIOTEC公司的发展小趣事

为了进一步拓展欧洲市场,DIOTEC于1989年在斯洛文尼亚的特尔博夫列建立了第二家工厂。这座工厂成为了DIOTEC在欧洲的重要生产基地,不仅提高了产能,还使得公司能够更好地服务欧洲客户。斯洛文尼亚工厂的建成,标志着DIOTEC在欧洲市场的地位得到了进一步巩固。

EEMB Co Ltd公司的发展小趣事

EEMB集团成立于1995年,初期以外销为主,总部位于武汉东西湖金银湖畔。公司创始人们凭借对电子行业的敏锐洞察力和对锂电池技术的深入研究,决定专注于锂电池的研发与生产。他们组建了一支技术实力强大的研发团队,并开始着手设计和生产高性能的锂电池产品。在初期的几年里,公司逐渐在市场上建立起了一定的声誉,并开始与一些知名的工业企业和设备制造商建立合作关系。

问答坊 | AI 解惑

用Atmega8单片机自制智能型液晶显示充电器 (527DZ作品)

一、概述:    移动通讯、消费类数码产品、笔记本电脑、便携仪器等便携设备市场的不断扩张,使得我们对电池的性能和工作寿命的要求不断地提高。从20世纪60年代的商用镍镉和密封铅酸电池到近几年的镍氢和锂离子技术,可充电电池容量和性能得到 ...…

查看全部问答>

经典面试题

大唐电信 DTT笔试题 1.数列6,10,18,32,“?”,问“?”是几? 2.某人出70买进一个x,80卖出,90买回,100卖出,这桩买卖怎么样? 3.月球绕地球一圈,至少要多少时间? 4.7个人用7小时挖了7米的沟,以同样的速度在50小时挖50米的沟要 ...…

查看全部问答>

一个遥控器程序(汇编)

一个遥控器程序(汇编),有一个错误,找人帮我看看!…

查看全部问答>

volatile是什么声明?【详细介绍】

将一个变量说明为volatile表示这个变量是“易变的”。如果一个变量会被其它引用改变,或在其它并行的任务中会被改变(例如中断服务程序),都要显式地说明为“volatile”,否则在编译器优化阶段会作出错误的判断,例如将这个变量读入寄存器以后,在 ...…

查看全部问答>

有人保护投资房产者的利益,谁来保护上大学者的投资.

有人保护投资房产者的利益,谁来保护上大学者的投资…

查看全部问答>

请教一个arm语法的问题

比如下面这段代码,请问“b”是什么意思? ExceptionVec         b                 ResetHandler         b             &nb ...…

查看全部问答>

安装evc4.0的问题(愁的头发白了,高手一定帮帮忙啊!!)

我在最近学习wince,因为周围就我一人在搞,导师还在催,天天郁闷 现在装evc4.0时,按照网上给的步骤装的: 1、安装ACTIVE  SYNC(MSASYNC.EXE)   2、安装EVC4.0   3、安装evc4sp2.exe   4、安装Mic ...…

查看全部问答>

伺服这个行业前景很好吗

来自:电子工程师技术交流(12425841)…

查看全部问答>

单片机C语言 keilc 编写的问题

#include<stdio.h>#include<reg51.h>//实例12:用自增运算控制P0口8位LED流水花样#include<reg51.h>   //包含单片机寄存器的头文件/******************************************************函数功能:延时一段时间************** ...…

查看全部问答>

C语言 流水灯,数码管编程

1、P2口接8个LED灯,实现花样流水灯表演。 2、P0口接一位共阳数码管(例如:0901051101),重复显示。或者每隔一秒钟时间,显示下一位数字。例如:先显示数字0;隔一秒钟时间,显示数字9,再隔一秒钟,显示数字0。 3、P1.6接继电器(常开触点一个 ...…

查看全部问答>