stm32 时钟配置——外部时钟倍频、内部时钟倍频 【worldsing笔记】-程序员宅基地

技术标签: 嵌入式  

stm32可选的时钟源

在STM32中,可以用内部时钟,也可以用外部时钟,在要求进度高的应用场合最好用外部晶体震荡器,内部时钟存在一定的精度误差。

准确的来说有4个时钟源可以选分别是HSI、LSI、HSE、LSE(即内部高速,内部低速,外部高速,外部低速),高速时钟主要用于系统内核和总线上的外设时钟。低速时钟主要用于独立看门狗IWDG、实时时钟RTC。

①、HSI是高速内部时钟,RC振荡器,频率为8MHz,上电后默认的系统时时钟 SYSCLK = 8MHz,Flash编程时钟。

①、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。

③、LSI是低速内部时钟,RC振荡器,频率为40kHz,可用于独立看门狗IWDG、实时时钟RTC。

④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。

 

系统时钟SYSCLK输入

这里重点在高速时钟,因为大部分外设时钟都是用的高速时钟。系统内核和外设时钟的时钟只有一个源,那就是SYSCLK, 即常说的系统时钟, 他是有一个选择器SW来做选择的,有3种选择HSI、HSE和PLL, 上电后默认选择内部HSI, HSI虽然存在精度误差,但是能保证不会挂。这点比AVR单片机做的好一些,AVR单片机时钟一旦配置成外部的,如果外部时钟正常那时无法下载程序的。PLL为锁相环倍频输出,PLL时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,其输出频率最大不得超过72MHz, 也有网有超频工作的,但不提倡。

也就是说系统时钟SYSCLK最终有以下几种选择:

①、SYSCLK = HSI

①、SYSCLK = HSE

③、SYSCLK = PLL

 

image

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

关于PLL锁相环倍频(输入和输出):

将输入时钟乘以一个系数后输出时钟,可以百度PLL原理。

PLL的输入3种选择:

①、PLLi =  HSI /2

①、PLLi =  HSE /2

③、PLLi =  HSE

 

PLL的输出有15种选择: PLLout = PLLi Xn (n = 2…16)

image

 

 

关于USB时钟

STM32中有一个全速功能的USB模块,其串行接口引擎需要一个频率为48MHz的时钟源。该时钟源只能从PLL输出端获取(唯一的),,可以选择为1.5分频或者1分频,也就是,当需要使用USB模块时,PLL必须使能,并且时钟频率配置为48MHz或72MHz。

image

 

关于把时钟信号输出到外部

另外,STM32还可以选择一个时钟信号输出到MCO脚(PA8)上,可以选择为PLL输出的2分频、HSI、HSE、或者系统时钟。

 image

 

关于系统时钟SYSCLK分配

系统时钟SYSCLK,它是供STM32中绝大部分部件工作的时钟源。系统时钟可选择为PLL输出、HSI(8MHz)或者HSE(外部晶振)。系统时钟最大频率为72MHz,供给I2S音频总线和AHB总线时钟。

image

它通过AHB分频器分频后送给各模块使用,AHB分频器可选择1、2、4、8、16、64、128、256、512分频。其中AHB分频器输出的时钟送给5大模块使用:

①、内核总线:送给AHB总线、内核、内存和DMA使用的HCLK时钟。

②、Tick定时器:通过8分频后送给Cortex的系统定时器时钟。

③、I2S总线:直接送给Cortex的空闲运行时钟FCLK。

④、APB1外设:送给APB1分频器。APB1分频器可选择1、2、4、8、16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz),另一路送给定时器(Timer)2、3、4倍频器使用。该倍频器可选择1或者2倍频,时钟输出供定时器2、3、4使用。

⑤、APB2外设:送给APB2分频器。APB2分频器可选择1、2、4、8、16分频,其输出一路供APB2外设使用(PCLK2,最大频率72MHz),另一路送给定时器(Timer)1倍频器使用。该倍频器可选择1或者2倍频,时钟输出供定时器1使用。另外,APB2分频器还有一路输出供ADC分频器使用,分频后送给ADC模块使用。ADC分频器可选择为2、4、6、8分频。

在以上的时钟输出中,有很多是带使能控制的,例如AHB总线时钟、内核时钟、各种APB1外设、APB2外设等等。当需要使用某模块时,记得一定要先使能对应的时钟。

需要注意的是定时器的倍频器,当APB的分频为1时,它的倍频值为1,否则它的倍频值就为2。

连接在APB1(低速外设)上的设备有:电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3、SPI2、窗口看门狗、Timer2、Timer3、Timer4。注意USB模块虽然需要一个单独的48MHz时钟信号,但它应该不是供USB模块工作的时钟,而只是提供给串行接口引擎(SIE)使用的时钟。USB模块工作的时钟应该是由APB1提供的。

连接在APB2(高速外设)上的设备有:UART1、SPI1、Timer1、ADC1、ADC2、所有普通IO口(PA~PE)、第二功能IO口。

对于单片机系统来说,CPU和总线以及外设的时钟设置是非常重要的,因为没有时钟就没有时序。

由于时钟是一个由内而外的东西,具体设置要从寄存器开始。
RCC 寄存器结构,RCC_TypeDeff,在文件“stm32f10x.h”中定义如下: (v3.4库)

1059行->1081行。

  1. typedef struct
  2. {
  3.   __IO uint32_t CR;
  4.   __IO uint32_t CFGR;
  5.   __IO uint32_t CIR;
  6.   __IO uint32_t APB2RSTR;
  7.   __IO uint32_t APB1RSTR;
  8.   __IO uint32_t AHBENR;
  9.   __IO uint32_t APB2ENR;
  10.   __IO uint32_t APB1ENR;
  11.   __IO uint32_t BDCR;
  12.   __IO uint32_t CSR;
  13. #ifdef STM32F10X_CL
  14.   __IO uint32_t AHBRSTR;
  15.   __IO uint32_t CFGR2;
  16. #endif /* STM32F10X_CL */
  17. #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
  18.   uint32_t RESERVED0;
  19.   __IO uint32_t CFGR2;
  20. #endif /* STM32F10X_LD_VL || STM32F10X_MD_VL || STM32F10X_HD_VL */
  21. } RCC_TypeDef;

一般板子上只有8Mhz的晶振,而增强型最高工作频率为72Mhz,显然需要用PLL倍频9倍,这些设置都需要在初始化阶段完成。

 

 

 

使用外部高速HSE时钟,程序设置时钟参数流程:
     1、将RCC寄存器重新设置为默认值      RCC_DeInit;
     2、打开外部高速时钟晶振HSE           RCC_HSEConfig(RCC_HSE_ON);
     3、等待外部高速时钟晶振工作           HSEStartUpStatus = RCC_WaitForHSEStartUp();
     4、设置AHB时钟                          RCC_HCLKConfig;
    5、设置高速AHB时钟                      RCC_PCLK2Config;
    6、设置低速速AHB时钟                   RCC_PCLK1Config;
    7、设置PLL                                 RCC_PLLConfig;
    8、打开PLL                                 RCC_PLLCmd(ENABLE);
    9、等待PLL工作                            while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
   10、设置系统时钟                          RCC_SYSCLKConfig;
   11、判断是否PLL是系统时钟              while(RCC_GetSYSCLKSource() != 0x08)
   12、打开要使用的外设时钟               RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd()

为了方便说明,借用一下例程的RCC设置函数,并用中文注释的形式加以说明:

static void RCC_Config(void) { 
/* 这里是重置了RCC的设置,类似寄存器复位 */ 
RCC_DeInit(); 

/* 使能外部高速晶振 */ 
RCC_HSEConfig(RCC_HSE_ON); 

/* 等待高速晶振稳定 */ 
HSEStartUpStatus = RCC_WaitForHSEStartUp(); 

if (HSEStartUpStatus == SUCCESS) 
{ 
    /* 使能flash预读取缓冲区 */ 
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); 

    /* 令Flash处于等待状态,2是针对高频时钟的,这两句跟RCC没直接关系,可以暂且略过 */ 
    FLASH_SetLatency(FLASH_Latency_2); 

    /* HCLK = SYSCLK 设置高速总线时钟=系统时钟*/ 
    RCC_HCLKConfig(RCC_SYSCLK_Div1); 

    /* PCLK2 = HCLK 设置低速总线2时钟=高速总线时钟*/ 
    RCC_PCLK2Config(RCC_HCLK_Div1); 

    /* PCLK1 = HCLK/2 设置低速总线1的时钟=高速时钟的二分频*/ 
    RCC_PCLK1Config(RCC_HCLK_Div2); 

    /* ADCCLK = PCLK2/6 设置ADC外设时钟=低速总线2时钟的六分频*/ 
    RCC_ADCCLKConfig(RCC_PCLK2_Div6); 

    /* Set PLL clock output to 72MHz using HSE (8MHz) as entry clock */ 
    //这句很关键 
    /* 利用锁相环讲外部8Mhz晶振9倍频到72Mhz */ 
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); 

    /* Enable PLL 使能锁相环*/ 
    RCC_PLLCmd(ENABLE); 

   /* Wait till PLL is ready 等待锁相环输出稳定*/ 
   while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) ;

    /* Select PLL as system clock source 将锁相环输出设置为系统时钟 */ 
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); 

    /* Wait till PLL is used as system clock source 等待校验成功*/ 
    while (RCC_GetSYSCLKSource() != 0x08);
} 

/* Enable FSMC, GPIOD, GPIOE, GPIOF, GPIOG and AFIO clocks */ 
//使能外围接口总线时钟,注意各外设的隶属情况,不同芯片的分配不同,到时候查手册就可以 
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | 
                         RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG | 
                         RCC_APB2Periph_AFIO, ENABLE); 
} 


 

使用内部高速HSI时钟,程序设置时钟参数流程:
     1、将RCC寄存器重新设置为默认值      RCC_DeInit;
     2、设置AHB时钟                           RCC_HCLKConfig;
     3、设置高速AHB时钟                      RCC_PCLK2Config;
     4、设置低速速AHB时钟                   RCC_PCLK1Config;
    5、设置PLL选择时钟源和倍频数         RCC_PLLConfig(RCC_PLLSource_HSI_Div2, 倍频数); 

6、打开PLL                                 RCC_PLLCmd(ENABLE);
     7、等待PLL工作                            while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
     8、设置系统时钟                           RCC_SYSCLKConfig;
     9、判断是否PLL是系统时钟               while(RCC_GetSYSCLKSource() != 0x08)
   10、打开要使用的外设时钟                 RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd()

 

void RCC_Configuration(void){

    /*将外设RCC寄存器重设为缺省值*/
    RCC_DeInit();
 
    /*设置AHB时钟(HCLK)*/ 
    RCC_HCLKConfig(RCC_SYSCLK_Div1);  //RCC_SYSCLK_Div1——AHB时钟= 系统时钟

    /* 设置高速AHB时钟(PCLK2)*/ 
    RCC_PCLK2Config(RCC_HCLK_Div1);   //RCC_HCLK_Div1——APB2时钟= HCLK

    /*设置低速AHB时钟(PCLK1)*/    
    RCC_PCLK1Config(RCC_HCLK_Div2);   //RCC_HCLK_Div2——APB1时钟= HCLK / 2

    /*设置FLASH存储器延时时钟周期数*/
    FLASH_SetLatency(FLASH_Latency_2); //FLASH_Latency_2  2延时周期

    /*选择FLASH预取指缓存的模式*/  
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);       // 预取指缓存使能

    /*设置PLL时钟源及倍频系数*/ 
    RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_12);        

    /*使能PLL */
    RCC_PLLCmd(ENABLE); 

    /*检查指定的RCC标志位(PLL准备好标志)设置与否*/   
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) ;
 
    /*设置系统时钟(SYSCLK)*/ 
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); 

    /* PLL返回用作系统时钟的时钟源*/
    while(RCC_GetSYSCLKSource() != 0x08);                 //0x08:PLL作为系统时钟
}

PLL的设定需要在使能之前,一旦PLL使能后参数不可更改。

在STM32中,连接在APB1(低速外设)上的设备有:电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3、SPI2、窗口看门狗、Timer2、Timer3、Timer4 。

连接在APB2(高速外设)上的设备有:GPIO_A-E、USART1、ADC1、ADC2、ADC3、TIM1、TIM8、SPI1、ALL。

程序举例:

APB1(低速外设)

RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);

APB2(高速外设)

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA  , ENABLE);

 

 

STM32和其它单片机相比时钟更为复杂,就是为了灵活配置,降低功耗,不用的外设可以关闭时钟,看似复杂但是,打开时钟树一看,就是几个根的选择,和几个枝叶的选择。

转载于:https://www.cnblogs.com/worldsing/p/3433529.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30575309/article/details/98232358

智能推荐

Eclipse中配置WebMagic(已配置好Maven)_使用eclipse搭建webmagic工程-程序员宅基地

文章浏览阅读364次。1.WebMagicWebMagic是一个简单灵活的Java爬虫框架。基于WebMagic,你可以快速开发出一个高效、易维护的爬虫。2.在Eclipse中配置WebMagic1.首先需要下载WebMagic的压缩包官网地址为:WebMagic官网最新版本为:WebMagic-0.7.3,找到对应版本,打开下载界面,注意,下载要选择Source code(zip)版本,随便下载到哪里都可以;2.下载好的压缩包需要解压,此时解压到的位置即为后续新建的Eclipse的project位置,比如我的Ecli_使用eclipse搭建webmagic工程

linux启动mysql_linux如何启动mysql服务_linux启动mysql服务命令是什么-系统城-程序员宅基地

文章浏览阅读1.9k次。mysql数据库是一种开放源代码的关系型数据库管理系统,有很多朋友都在使用。一些在linux系统上安装了mysql数据库的朋友,却不知道该如何对mysql数据库进行配置。那么linux该如何启动mysql服务呢?接下来小编就给大家带来linux启动mysql服务的命令教程。具体步骤如下:1、首先,我们需要修改mysql的配置文件,一般文件存放在/etc下面,文件名为my.cnf。2、对于mysql..._linux中 mysql 启动服务命令

php实现在线oj,详解OJ(Online Judge)中PHP代码的提交方法及要点-程序员宅基地

文章浏览阅读537次。详解OJ(Online Judge)中PHP代码的提交方法及要点Introduction of How to submit PHP code to Online Judge SystemsIntroduction of How to commit submission in PHP to Online Judge Systems在目前常用的在线oj中,codeforces、spoj、uva、zoj..._while(fscanf(stdin, "%d %d", $a, $b) == 2)

java快捷键调字体_设置MyEclipse编码、补全快捷键、字体大小-程序员宅基地

文章浏览阅读534次。一、设置MyEclipse编码(1)修改工作空间的编码方式:Window-->Preferences-->General-->Workspace-->Text file encoding(2)修改一类文件的编码方式:Window-->Preferences-->General-->content Types-->修改default Encoding(..._java修改快捷缩写内容

解析蓝牙原理_蓝牙原理图详解-程序员宅基地

文章浏览阅读1.4w次,点赞19次,收藏76次。1.前言市面上关于Android的技术书籍很多,几乎每本书也都会涉及到蓝牙开发,但均是上层应用级别的,而且篇幅也普遍短小。对于手机行业的开发者,要进行蓝牙模块的维护,就必须从Android系统底层,至少框架层开始,了解蓝牙的结构和代码实现原理。这方面的文档、网上的各个论坛的相关资料却少之又少。分析原因,大概因为虽然蓝牙协议是完整的,但是并没有具体的实现。蓝牙芯片公司只负责提供最底层的API_蓝牙原理图详解

从未在一起更让人遗憾_“从未在一起和最终没有在一起哪个更遗憾”-程序员宅基地

文章浏览阅读7.7k次。图/源于网络文/曲尚菇凉1.今天早上出门去逛街,在那家冰雪融城店里等待冰淇淋的时候,听到旁边两个女生在讨论很久之前的一期《奇葩说》。那期节目主持人给的辩论题是“从未在一起和最终没有在一起哪个更遗憾”,旁边其中一个女生说,她记得当时印象最深的是有个女孩子说了这样一句话。她说:“如果我喜欢一个人呢,我就从第一眼到最后一眼,把这个人爱够,把我的感觉用光,我只希望那些年让我成长的人是他,之后的那些年他喝过..._从未在一起更遗憾

随便推点

Spring Cloud Alibaba 介绍_sprngcloud alba-程序员宅基地

文章浏览阅读175次。Spring Cloud Alibaba 介绍Sping体系Spring 以 Bean(对象) 为中心,提供 IOC、AOP 等功能。Spring Boot 以 Application(应用) 为中心,提供自动配置、监控等功能。Spring Cloud 以 Service(服务) 为中心,提供服务的注册与发现、服务的调用与负载均衡等功能。Sping Cloud介绍官方介绍​ Tools for building common patterns in distributed systems_sprngcloud alba

测试 数据类型的一些测试点和经验_基础字段的测试点-程序员宅基地

文章浏览阅读3.2k次,点赞4次,收藏21次。我这里是根据之前在测试数据类项目过程中的一些总结经验和掉过个坑,记录一下,可以给其他人做个参考,没什么高深的东西,但是如果不注意这些细节点,后期也许会陷入无尽的扯皮当中。1 需求实现的准确度根据产品需求文档描述发现不明确不详细的或者存在歧义的地方一定要确认,例如数据表中的一些字段,与开发和产品确认一遍,如有第三方相关的,要和第三方确认,数据类项目需要的是细心,哪怕数据库中的一个字段如果没有提前对清楚,后期再重新补充,会投入更大的精力。2 数据的合理性根据业务场景/常识推理,提..._基础字段的测试点

一文看懂:行业分析怎么做?_码工小熊-程序员宅基地

文章浏览阅读491次。大家好,我是爱学习的小xiong熊妹。在工作和面试中,很多小伙伴会遇到“对XX行业进行分析”的要求。一听“行业分析”四个字,好多人会觉得特别高大上,不知道该怎么做。今天给大家一个懒人攻略,小伙伴们可以快速上手哦。一、什么是行业?在做数据分析的时候,“行业”两个字,一般指的是:围绕一个商品,从生产到销售相关的全部企业。以化妆品为例,站在消费者角度,就是简简单单的从商店里买了一支唇膏回去。可站在行业角度,从生产到销售,有相当多的企业在参与工作(如下图)在行业中,每个企业常常扮._码工小熊

LLaMA 简介:一个基础的、650 亿参数的大型语言模型_llma-程序员宅基地

文章浏览阅读1.6w次,点赞2次,收藏2次。还需要做更多的研究来解决大型语言模型中的偏见、有毒评论和幻觉的风险。我们在数万亿个令牌上训练我们的模型,并表明可以仅使用公开可用的数据集来训练最先进的模型,而无需诉诸专有和不可访问的数据集。在大型语言模型空间中训练像 LLaMA 这样的小型基础模型是可取的,因为它需要更少的计算能力和资源来测试新方法、验证他人的工作和探索新的用例。作为 Meta 对开放科学承诺的一部分,今天我们公开发布 LLaMA(大型语言模型元 AI),这是一种最先进的基础大型语言模型,旨在帮助研究人员推进他们在 AI 子领域的工作。_llma

强化学习在制造业领域的应用:智能制造的未来-程序员宅基地

文章浏览阅读223次,点赞3次,收藏5次。1.背景介绍制造业是国家经济发展的重要引擎,其产能和质量对于国家经济的稳定和发展具有重要意义。随着工业技术的不断发展,制造业的生产方式也不断发生变化。传统的制造业通常依赖于人工操作和手工艺,这种方式的缺点是低效率、低产量和不稳定的质量。随着信息化、智能化和网络化等新技术的出现,制造业开始向智能制造迈出了第一步。智能制造的核心是通过大数据、人工智能、计算机视觉等技术,实现制造过程的智能化、自动化...

ansible--安装与使用_pip安装ansible-程序员宅基地

文章浏览阅读938次。系列文章目录文章目录系列文章目录 前言 一、ansible是什么? 二、使用步骤 1.引入库 2.读入数据 总结前言菜鸟一只,刚开始使用,仅作以后参考使用。边学习,边记录,介绍一下最基础的使用,可能会有理解不到位的地方,可以共同交流,废话不多说,走起。一、ansible 简介?ansible是自动化运维工具的一种,基于Python开发,可以实现批量系统配置,批量程序部署,批量运行命令,ansible是基于模块工作的,它本身没有批量部署的能力,真正.._pip安装ansible

推荐文章

热门文章

相关标签