对单片机中时钟的理解:

29 篇文章 2 订阅
11 篇文章 1 订阅

1.概述

简单的说,时钟是单片机的脉搏,是单片机的驱动源,使用任何一个外设都必须打开相应的时钟。这样的好处是,如果不使用一个外设的时候,就把它的时钟关掉,从而可以降低系统的功耗,达到节能,实现低功耗的效果。每个时钟tick,系统都会处理一步数据,这样才能让工作不出现紊乱。

2.原理

首先,任何外设都需要时钟,51单片机,stm32,430等等,因为寄存器是由D触发器组成的,往触发器里面写东西,前提条件是有时钟输入。
51单片机不需要配置时钟,是因为一个时钟开了之后所有的功能都可以用了,而这个时钟是默认开启的,比如有一个水库,水库有很多个门,这些门默认是开启的,所以每个门都会出水,我们需要哪个门的水的时候可以直接用,但是也存在一个问题,其他没用到的门也在出水,即也在耗能。这里水库可以认为是能源,门可以认为是每个外设的使用状态,时钟可以认为是门的开关。stm32之所以是低功耗,他将所有的门都默认设置为disable,在你需要用哪个门的时候,开哪个门就可以,也就是说用到什么外设,只要打开对应外设的时钟就可以,其他的没用到的可以还是disable,这样耗能就会减少。
在51单片机中一个时钟把所有的都包了,而stm32的时钟是有分工的,并且每类时钟的频率不一样,因为没必要所有的时钟都是最高频率,只要够用就行,好比一个门出来水流大小,我只要洗脸,但是出来的是和洪水一样涌出来的水,那就gg了,消耗能源也多,所以不同的时钟也会有频率差别,或者在配置的时候可以配置时钟分频。

拓展:为何要先配置时钟,再配置GPIO(功能模块)

所有寄存器都需要时钟才能配置,寄存器是由D触发器组成的,只有送来了时钟,触发器才能被改写值。
任何MCU的任何外设都需要有时钟,8051也是如此;STM32为了让用户更好地掌握功耗,对每个外设的时钟都设置了开关,让用户可以精确地控制,关闭不需要的设备,达到节省供电的目的。
51单片机不用配置IO时钟,只是因为默认使用同一个时钟,这样是方便,但是这样的话功耗就降低不了。
例如,某个功能不需要,但是它还是一直运行。
stm32需要配置时钟,就可以把不需要那些功能的功耗去掉。
当你想关闭某个IO的时候,关闭它相对应的时钟使能就是了,不过在51里面,在使用IO的时候是没有设置IO的时钟的,还有在STM32中,有外部和内部时钟之分,关于时钟等好好研究
ARM的芯片都是这样,外设通常都是给了时钟后,才能设置它的寄存器(即才能使用这个外设)。STM32、LPC1XXX等等都是这样。
这么做的目的是为了省电,使用了所谓时钟门控的技术。
这也属于电路里同步电路的范畴:同步电路总是需要1个时钟。

3.分类

时钟发生器用于产生时钟,并提供给CPU和外部硬件设备。

有如下三种系统时钟。

(1)主系统时钟

①通过连接一个振荡器到X1和X2,该振荡电路产生fx=1到20MHZ的时钟;

②使用内部高速振荡器产生fRH=8MHZ的时钟。

(2)副系统时钟

①通过在XT1和XT2之间连接一个fXT=32.768KHZ的振荡器;

②通过XT2引脚提供一个外部副系统时钟fexclks=32.768KHZ。

(3)内部低速振荡时钟(看门狗定时器时钟)

①内部低速振荡器,以fRL=240KHZ的时钟振荡。该时钟不能作为CPU时钟。

4.配置

一、在STM32中,有五个时钟源,为HSIHSELSILSEPLL

HSI是高速内部时钟,RC振荡器,频率为8MHz。

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

LSI是低速内部时钟,RC振荡器,频率为40kHz。

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

PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。

二、在STM32上如果不使用外部晶振,OSC_IN和OSC_OUT的接法:如果使用内部RC振荡器而不使用外部晶振,请按照下面方法处理:

①对于100脚或144脚的产品,OSC_IN应接地,OSC_OUT应悬空。
②对于少于100脚的产品,有2种接法:第1种:OSC_IN和OSC_OUT分别通过10K电阻接地。此方法可提高EMC性能;第2种:分别重映射OSC_IN和OSC_OUT至PD0和PD1,再配置PD0和PD1为推挽输出并输出'0'。此方法可以减小功耗并(相对上面)节省2个外部电阻。

三、用HSE时钟,程序设置时钟参数流程
01、将RCC寄存器重新设置为默认值   RCC_DeInit;
02、打开外部高速时钟晶振HSE    RCC_HSEConfig(RCC_HSE_ON);
03、等待外部高速时钟晶振工作    HSEStartUpStatus = RCC_WaitForHSEStartUp();
04、设置AHB时钟         RCC_HCLKConfig;
05、设置高速AHB时钟     RCC_PCLK2Config;
06、设置低速速AHB时钟   RCC_PCLK1Config;
07、设置PLL              RCC_PLLConfig;
08、打开PLL              RCC_PLLCmd(ENABLE);
09、等待PLL工作   while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
10、设置系统时钟        RCC_SYSCLKConfig;
11、判断是否PLL是系统时钟     while(RCC_GetSYSCLKSource() != 0x08)
12、打开要使用的外设时钟    RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd()

四、下面是STM32软件固件库的程序中对RCC的配置函数(使用外部8MHz晶振)

/*******************************************************************************

* Function Name  : RCC_Configuration 

* Description    :  RCC配置(使用外部8MHz晶振)

* Input            : 无

* Output         : 无

* Return         : 无

*******************************************************************************/

void RCC_Configuration(void)

{

  /*将外设RCC寄存器重设为缺省值*/

  RCC_DeInit();

  /*设置外部高速晶振(HSE)*/

  RCC_HSEConfig(RCC_HSE_ON);   //RCC_HSE_ON——HSE晶振打开(ON)

  /*等待HSE起振*/

  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if(HSEStartUpStatus == SUCCESS)        //SUCCESS:HSE晶振稳定且就绪

  {

    /*设置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_HSE_Div1, RCC_PLLMul_9);     

// PLL的输入时钟= HSE时钟频率;RCC_PLLMul_9——PLL输入时钟x 9

  /*使能PLL */

    RCC_PLLCmd(ENABLE);

    /*检查指定的RCC标志位(PLL准备好标志)设置与否*/   

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)      

       {

       }

 

    /*设置系统时钟(SYSCLK)*/ 

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); 

//RCC_SYSCLKSource_PLLCLK——选择PLL作为系统时钟

 

    /* PLL返回用作系统时钟的时钟源*/

    while(RCC_GetSYSCLKSource() != 0x08)        //0x08:PLL作为系统时钟

       { 

       }

 /*使能或者失能APB2外设时钟*/    

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | 

RCC_APB2Periph_GPIOC , ENABLE); 

//RCC_APB2Periph_GPIOA    GPIOA时钟

//RCC_APB2Periph_GPIOB    GPIOB时钟

//RCC_APB2Periph_GPIOC    GPIOC时钟

//RCC_APB2Periph_GPIOD    GPIOD时钟

}

五、时钟频率

STM32F103内部8M的内部震荡,经过倍频后最高可以达到72M。目前TI的M3系列芯片最高频率可以达到80M。

在stm32固件库3.0中对时钟频率的选择进行了大大的简化,原先的一大堆操作都在后台进行。系统给出的函数为SystemInit()。但在调用前还需要进行一些宏定义的设置,具体的设置在system_stm32f10x.c文件中。

文件开头就有一个这样的定义: 
//#define SYSCLK_FREQ_HSE    HSE_Value 
//#define SYSCLK_FREQ_20MHz 20000000 
//#define SYSCLK_FREQ_36MHz 36000000 
//#define SYSCLK_FREQ_48MHz 48000000 
//#define SYSCLK_FREQ_56MHz 56000000 
#define SYSCLK_FREQ_72MHz 72000000

ST 官方推荐的外接晶振是 8M,所以库函数的设置都是假定你的硬件已经接了 8M 晶振来运算的.以上东西就是默认晶振 8M 的时候,推荐的 CPU 频率选择.在这里选择了:
#define SYSCLK_FREQ_72MHz 72000000 
也就是103系列能跑到的最大值72M

然后这个 C文件继续往下看 
#elif defined SYSCLK_FREQ_72MHz 
const uint32_t SystemFrequency         = SYSCLK_FREQ_72MHz;    
const uint32_t SystemFrequency_SysClk = SYSCLK_FREQ_72MHz;    
const uint32_t SystemFrequency_AHBClk = SYSCLK_FREQ_72MHz;    
const uint32_t SystemFrequency_APB1Clk = (SYSCLK_FREQ_72MHz/2);
const uint32_t SystemFrequency_APB2Clk = SYSCLK_FREQ_72MHz;

这就是在定义了CPU跑72M的时候,各个系统的速度了.他们分别是:硬件频率,系统时钟,AHB总线频率,APB1总线频率,APB2总线频率.再往下看,看到这个了: 
#elif defined SYSCLK_FREQ_72MHz 
static void SetSysClockTo72(void);

这就是定义 72M 的时候,设置时钟的函数.这个函数被 SetSysClock ()函数调用,而
SetSysClock ()函数则是被 SystemInit()函数调用.最后 SystemInit()函数,就是被你调用的了

所以设置系统时钟的流程就是: 
首先用户程序调用 SystemInit()函数,这是一个库函数,然后 SystemInit()函数里面,进行了一些寄存器必要的初始化后,就调用 SetSysClock()函数. SetSysClock()函数根据那个#define SYSCLK_FREQ_72MHz 72000000 的宏定义,知道了要调用SetSysClockTo72()这个函数,于是,就一堆麻烦而复杂的设置
~!@#$%^然后,CPU跑起来了,而且速度是 72M. 虽然说的有点累赘,但大家只需要知道,用户要设置频率,程序中就做的就两个事情:

第一个: system_stm32f10x.c 中 #define SYSCLK_FREQ_72MHz 72000000 

第二个:调用SystemInit()

  • 233
    点赞
  • 721
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
### 回答1: 当我听到“51单片机”时,我首先想到的是一款基于MCS-51架构的微控制器,它在嵌入式系统广泛应用。 对于单片机设计来说,设计师需要考虑很多因素,比如系统的时钟速度、存储器的容量和接口的选择等等。时钟速度非常重要,因为它决定了单片机能够执行的指令数量。同时,存储器的容量也非常关键,因为它限制了单片机能够存储的程序和数据的大小。 当选择51单片机时,设计师需要考虑这些因素以及其他一些因素,例如应用的复杂程度和所需的性能等。然后,他们可以选择适合他们应用需求的具体型号,并设计出一个完整的系统。 总之,51单片机是一款功能强大的微控制器,它在嵌入式系统广泛使用,可以用于控制各种不同类型的设备和系统。 ### 回答2: 基于51单片机设计时钟需要进行以下步骤: 1. 硬件设计:选择适当的时钟芯片来提供外部时钟信号。这可以是晶振、时钟模块或者RTC芯片。同时,还需要设计合适的电路用于连接单片机时钟芯片。 2. 程序设计:使用汇编或C语言进行程序编写。首先,需要编写初始化代码,设置单片机相关寄存器和外部断设置。然后,编写时钟模块的代码,包括获取当前时间,显示时间和实现闹钟功能。 3. 时钟模块设计:在时钟模块,需要使用定时器来读取时钟芯片的时间,并将其转换为可读的格式。定时器可以设置一个适当的时间间隔,以确保时钟准确无误地进行。 4. 数码管显示:通过数码管显示时间,需要将时钟数值转换为数码管控制代码,并通过IO口输出到数码管。可以使用数码管显示驱动文件进行编程。 5. 闹钟功能设计:通过添加按钮和外部断实现闹钟功能。当设定的闹钟时间到达时,产生一个断信号,即触发闹钟,可以通过发出声音或者闪烁LED等方式来提醒用户。 6. 能源管理:为了保证时钟的正常运行,可以考虑添加电池供电功能,以防停电或者外部电源故障情况下时钟无法正常工作。 7. 调试和测试:完成硬件和软件的设计之后,需要对整个时钟进行调试和测试,验证时钟的准确性和稳定性。 总之,基于51单片机设计时钟需要进行硬件设计、程序设计、时钟模块设计、数码管显示、闹钟功能设计、能源管理以及调试和测试。这个过程需要综合运用电子技术、编程技术和测试技术,确保时钟的功能和性能达到要求。 ### 回答3: 设计基于51单片机时钟是一个很有趣的项目。首先,我们需要一个51单片机,这是一个非常流行且常用的单片机型号,容易获得且价格便宜。接下来,我们需要一块LCD屏幕,用于显示时间。可以使用4位数码管显示时间,但LCD屏幕更加直观且易读。还需要一个实时时钟模块,它能够提供精确的时间数据。 首先,将单片机与LCD屏幕和实时时钟模块连接。然后,编写程序来读取实时时钟模块的时间,并将其显示在LCD屏幕上。此外,还可以加入一些附加功能,如设置闹钟、显示日期等。 为了确保时钟的准确性,可以使用外部晶振来提供更稳定的时钟信号。此外,还可以添加蜂鸣器,以在设定的闹钟时间发出警报声。 在设计时钟的过程,还需要考虑电源问题。可以通过连接适当的电池来提供电源,以确保时钟在断电情况下仍能继续运行。 最后,在设计完成后,可以将时钟固定在一个漂亮的外壳,以增加外观的美观度。 总之,基于51单片机设计时钟是一个有趣的项目,它不仅能够提供准确的时间显示,还可以拥有多种功能,如设置闹钟等。同时,这个项目也可以增强我们对单片机编程和硬件设计的理解

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值