时钟

时序在数字电路中的作用,就像通信中用到的载波,载波并不起眼,但是很重要。时钟也一样,现象上只是某种频率波峰波谷跳动,一成不变。但是有了它,就像人类的历史有了时间轴一样,什么时候该干什么事才有了可能。程序中发生的事件,能够按照自己的意愿发生。下面就以STM32开发板中最常见的STM32F103系列芯片的时钟为例,介绍一下STM32中的时钟。

时钟作用

说到时钟,你一定会问,这是用来计时的吗?没错,是用来计时的,但这只是它在STM32中的一项功能而已,下面就为你列出了时钟的具体功能。

计时作用(供给某些计数器统计时间);

控制时序(串口数据的传输,只能一位一位的传输);

控制信号(将时钟的上升下降沿作为独特的控制标志)。

STM32时钟模型

STM32内部时钟树

时钟源

时钟源就是产生时钟的电路啦,我们来一起看一下,什么样的电路可以产生时钟。

STM32中的时钟源分为以下五种:

低速内部时钟LSI:频率为40kHz ;
高速内部时钟HSI :频率为8MHz ;
低速外部时钟OSC_32:频率为32.7678kHz ;
高速外部时钟OSC:频率范围4-16MHz ;
时钟输出MCO:为其他设备提供时钟源。

在对时钟频率要求不高的情况下,我们可以选择内部RC振荡器时钟作为单片机工作的时钟源。如果对时钟精度要求较高,我们要选择外部石英晶体振荡器(晶振),作为单片机的时钟源,因为内部时钟用的是模拟电路组成的振荡器,误差较大,在实时性要求比较高的场合(串口通信、IIC通信等)容易造成不可预知的错误。

时钟相对复杂的意义主要是为不同外设提供合适的时钟频率,主要目的是为了节能、低功耗。

高速时钟:用于高速外设I/O、串口通信、SPI等等;

低速时钟:用于低速外设RTC看门狗 ;

倍频器:时钟与外设进行时钟适配。

相关寄存器讲解

PLLSRC
锁相环倍频器时钟源选择
内部高速时钟2分频
外部高速时钟

PLLMUL
锁相环时钟倍频器
将PLLSRC选择的时钟进行倍频,最大不能超过72MHz

PLLXTPRE
锁相环时钟选择
选择外部时钟作为锁相环倍频器时钟源
选择外部时钟2分频后作为锁相环倍频器时钟源

SW
系统时钟选择
选择内部高速时钟作为系统时钟
选择锁相环倍频时钟作为系统时钟
选择外部高速时钟作为系统时钟

AHB
系统时钟分频器

CSS
时钟安全监测单元
当外部时钟意外故障,CSS在短时间内切换到内部高速时钟使单片机工作不中断

RTCCLK
实时时钟时钟源选择
选择锁相环倍频器时钟源128分频作为实时时钟时钟源
选择外部低速时钟作为实时时钟时钟源
选择内部低俗时钟作为实时时钟时钟源

MCO
时钟输出控制
锁相环时钟2分频输出
内部低俗时钟输出
内部高速时钟输出
系统时钟输出

关于APB1、APB2时钟

STM32单片机外设挂接在APB1、APB2两个桥上,但两个桥允许的始终最大频率不相同,APB2最大允许72MHz,APB1最大只允许36MHz,在使用外设时应格外注意时钟,例如串口一挂接在APB2上,其余串口挂接在APB1上,在串口配置时应注意失踪频率的不同造成的波特率配置问题(库函数开发忽略此项内容)。

外部时钟晶体振荡器最好选择8MHz晶振,无论是库函数,还是Keil默认配置启动文件时钟配置均是按照外部晶体振荡器8MHz来进行的配置,系统时钟72MHz,如果采用其他型号的晶体震荡器振还需要自己配置时钟树,对于新手来说可能存在一定的困难。

来源: 无线电杂志

围观 4
1

在非常温的工作环境下,RTC时钟出现偶发性的延时或者超时现象。成熟的RTC电路设计看似简单,但如何保证RTC时钟的精确度?在出现偶发性异常现象时,如何快速定位和解决问题?本文将分享一个案例。

案例情况

工控板使用了NXP的PCF8563 RTC 芯片方案,在研发做环境温度摸底测试的时候, RTC时钟出现偶发性延时或者超前现象,于是研发展开一系列的问题定位。

排查分析

1、工控板使用了NXP的PCF8563 RTC 芯片方案,该方案是外置32.768kHz的石英晶体和电容,该RTC芯片的输出精度取决于其外接的石英晶体输出的时钟频率是否精准。

石英晶体本身输出频率带有一定的误差,常温25℃下,频率的误差为±20ppm,平均误差可达5分钟/年。且随着时间的增加,晶体电路元件的缓慢变化会造成长期性的频率漂移。同时,在外部温度较为极端的时候,时钟震荡回路可能出现异常,影响到RTC的正常计时。

2、工控板RTC芯片供电电池选用了型号为CR2032的锂二氧化锰电池,该电池理论工作温度范围是-30℃~60℃。

和其他锂电池类似,若外部温度较为极端的时候,会改变其内部的化学反应,导致电池寿命的降低或者电压异常的风险,从而影响RTC电路的正常工作。

RTC时钟偶发性延时或超时该怎么办?
图1 PCF8563参考电路图

解决方案

极限温度下长时间的高精度保证,有以下的解决方案:

1、选择带有温度补偿的RTC芯片如EPSON的RX-8025T。这款芯片是内置32.768kHz的晶体,具有高精度的温度补偿功能,输出的波形都是经过温度补偿校准过的,这样可以提高RTC的稳定性和精度。因为内嵌的晶体已经经过高温老化处理,比独立的晶体有更好的稳定性,精度误差在-40℃~85℃范围内小于±5ppm。

2、选择工业级电池(例如:FANSO ER14505)。理论上在工作温度-40~85°范围内能正常工作。参考电路图如图2所示:

RTC时钟偶发性延时或超时该怎么办?
图2 RX-8025T参考电路图

由图2可知,RTC芯片工作电源由系统VCC_3.3电源和电池电源两部分组成。此电源电路的设计目的是当有外部电源供电时,RTC时钟工作时使用由外部电源经LDO转化而来的VCC_3.3电源,当外部电源停止供电时就自动切换到电池电源供电。这样可以保证RTC芯片一直能够正常地工作,同时可以延长电池的使用时间。

此电路的设计如以下所述:

1、电源切换电路设计

由RX-8025T芯片的数据手册上可知:

  •   其工作电压范围是1.7V到5.5V;

  •   系统电源为3.3V、工业级电池ER14505电压为3.6V;

  •   可以通过二极管的正向导通特性来自动切换系统电源和电池电源的供电状态,使得RTC芯片能够保持正常工作状态。

由于系统电源电压为3.3V,电池电压为3.6V;如果要做到优先使用系统电源,那么就需要系统电源经过二极管后的电压比电池经过二极管后的电压要高,这样才能保证由系统电源优先工作。

可以通过选择两只不同管压降的二极管来实现,二极管SS14的正向导通电压为0.2V左右,1N4148的正向导通电压为0.7V左右。那么可以在系统电源线路上串接一只SS14二极管,而在电池供电线路上串接一只1N4148二极管;这样当外部供电时,系统电源经过SS14后得到的电压值大于电池经过1N4148后的电压值,此时由主电源供电;当外部电源停止供电后,电路自动切换成电池供电状态。

RTC时钟偶发性延时或超时该怎么办?
图3 电源切换电路

2、电压滞后处理

ER14505电池是一种供电电压为3.6V ,容量为2700mAh的锂亚硫酰氯电池;它的自身容量损耗极小,可以忽略不计。以待机电流为20uA计算,电池的供电可以达15年左右。

但是在实际应用中,发现在系统电源长期供电后,突然切换到电池供电时发生电压不足,导致RTC时钟出现异常,其根本原因是电池发生了钝化现象。

当RTC芯片由系统电源供电时,锂电池相当于闲置开路,如果电池闲置的时间过长,那么电池的内部会产生钝化膜,而切换到锂电池供电时,如果滞后的电压低于时钟芯片的工作电压,那么时钟芯片就会完全“失压”,系统时钟就会恢复到初始时间,导致时钟工作异常。为了消除这种现象的影响,我们可以通过在时钟芯片的电源上增加储能电容,以消除这种影响。

RTC时钟偶发性延时或超时该怎么办?
图4 电压滞后处理电路图

3、控制钝化膜生成

电池的钝化膜是由于电池长时间处于闲置开路状态而形成的,那么我们可以使电池一直维持在一个较小的电流放电工作状态,这样可以减缓电池的钝化膜生成的速度。通过选择合适的电阻值,使电池处于放电状态,比如放电电流控制在待机电流20uA左右,这样电池容量足够支撑15年左右,同时不会使钝化膜过厚而出现电压滞后导致RX-8025T完全掉电现象,从而影响RTC时钟的正常工作。

  •   当系统电源供电时,Q1导通,由电池BT1、R1、Q1形成回路,实现电池的放电状态;

  •   当系统电源停止供电时,Q1截至,电池经过D2给RTC芯片U1供电。

经实测时钟芯片及电池内阻自放电的电流为8uA左右,那么我们需要控制的电阻R1的阻值为3.6V/(20-8)uA=300k。

RTC时钟偶发性延时或超时该怎么办?
图5 控制钝化膜电路图

4、PCB设计

在PCB layout的时候需要注意RX-8052T与MCU的I2C走线应该越短越好,并且远离高频、高电流的信号线。同时旁路电容也应该靠近RX-8025T的电源端,并增加地线敷铜的面积,以防止干扰的产生。

来源: ZLG致远电子

围观 32
64

对于高速的串行总线来说,一般情况下都是通过数据编码把时钟信息嵌入到传输的数据流里,然后在接收端通过时钟恢复把时钟信息提取出来,并用这个恢复出来的时钟对数据进行采样,因此时钟恢复电路对于高速串行信号的传输和接收至关重要。

CDR电路原理

时钟恢复的目的是跟踪上发送端的时钟漂移和一部分抖动,以确保正确的数据采样。时钟恢复电路(CDR:Clock Data Recovery)一般都是通过PLL(Phase lock loop)的方式实现,如下图所示。

输入的数字信号和PLL的VCO(Voltage-controlled oscillator,压控振荡器 )进行鉴相比较,如果数据速率和VCO的输出频率间有频率差就会产生相位差的变化,鉴相器对这个相位误差进行比较并转换成相应的电压控制信号,电压控制信号经过滤波器滤波后产生对VCO的控制信号从而调整VCO的输出时钟频率。

使用滤波器的目的是把快速的相位变化信息积分后转换成相对缓慢的电压变化以调整VCO的输出频率,这个滤波器有时又称为环路滤波器,通常是一个低通的滤波器。通过反复的鉴相和调整,最终VCO的输出信号频率和输入的数字信号的变化频率一致,这时PLL电路就进入锁定状态。

一文看懂时钟是怎么恢复的?

环路带宽对眼图、抖动测量的影响

值得注意的是,在真实的情况下,输入的数字信号并不是一个纯净的信号,而是包含了不同频率成分的抖动。对于低频的抖动来说,其造成的是数据速率的缓慢变化,如果这个缓慢变化的频率低于环路滤波器的带宽,输入信号抖动造成的相位变化信息就可以通过环路滤波器从而产生对VCO输出频率的调整,这时VCO的输出时钟中就会跟踪上输入信号的抖动。

而如果输入信号中抖动的频率比较高,其造成的相位变化信号不能通过环路滤波器,则VCO输出的时钟中就不会有随输入信号一起变化的抖动成分,也就是说输入信号中的高频抖动成分被PLL电路过滤掉了。

如下图所示,我们通常会用PLL电路的JTF(Jitter Transfer Function,抖动传递函数)曲线描述PLL电路对于不同频率抖动的传递能力。JTF曲线通常是个低通的特性,反映了PLL电路对于低频抖动能很好跟踪而对高频抖动跟踪能力有限的特性。

一文看懂时钟是怎么恢复的?

对于低频的抖动,PLL电路能够很好地跟踪,恢复出来的时钟和被测信号一起抖动。如果接收端的芯片用这个恢复时钟为基准对输入信号进行采样,由于此时时钟和被测信号一起抖动,所以这种低频的抖动不会被观察到,对于数据采样的建立保持时间也没有太大影响。

相反地,高频的抖动会被PLL电路过滤掉,因此输出的时钟里不包含这些高频的抖动成分。如果用这个时钟对数据信号进行采样,就会观察到输入信号里明显的抖动。接收端用恢复时钟进行采样时能够看到的抖动与抖动频率间的关系有时我们会用OJTF(Observed Jitter Transfer Function,观察到的抖动传递函数)曲线来描述,其随频率的变化曲线正好JTF曲线相反。

正因为时钟恢复电路对于低频抖动的跟踪特性,因此很多高速串行总线的接收芯片对于低频抖动的容忍能力会远远超过对高频抖动的容忍能力。下图是USB3.0总线对于接收端芯片对于不同频率抖动容忍能力的要求的一条曲线,可以看到其对低频的容忍能力非常大,甚至可以远超过1个UI(数据比特宽度)。

一文看懂时钟是怎么恢复的?

时钟恢复电路的PLL的环路带宽设置不同,对于不同频率抖动跟踪能力也不一样。一般情况下,PLL的带宽设置越窄,恢复出来的时钟越纯净,但是对于抖动的跟踪能力越弱,用这个时钟为基准对数据做采样时看到的信号上的抖动会越多,看到的信号的眼图会越恶劣。

相反,如果PLL的带宽设置越宽,对于抖动的跟踪能力越强,恢复出来的时钟和信号的抖动越接近,用这个时钟为基准对数据做采样时看到的信号上的抖动会越少,看到的信号的眼图会越好。下图反映出的就是不同的PLL带宽设置对于恢复时钟抖动和以这个恢复时钟为基准对信号进行采样时看到的眼图的情况。

一文看懂时钟是怎么恢复的?

转自:至秦单片机

围观 31
868

Graham Mostyn Microchip 时序和通信部 应用工程经理

几乎每个电子器件都需要一个时钟源。例如,单片机(MCU)使用振荡器来前进到下一条指令,无线电需要通过精确的振荡器来将射频信号混合到基带中加以处理。

智能联网设备的出现对时钟性能提出了更高的要求。本文解释了设计师如何在应对这些挑战的同时降低技术风险、缩短设计时间以及削减物料清单。我们着眼于采用石英和基于MEMS的技术的石英晶体、石英晶振(XO)和高度集成的时钟解决方案。

智能联网设备需要复杂的时钟树

MCU通常包括用于非精密计算应用的内部RC移相振荡器。这些振荡器使用集成的电阻-电容对来创建控制振荡器频率的时间常数。此类振荡器具有大约1%的精度并且表现出高抖动(在时钟转换的时序中会出现意外的随机波动)。 它们适用于不注重转换时序的应用,例如为计算用MCU提供时钟以及驱动一个简单的七段数字液晶显示屏(LCD)。显示屏需要多个时钟波形,但转换时序容差为几毫秒。此外,也可实现高达几Mbps的UART通信,这种情况下的时序容差为几百纳秒,但这同时也代表着简单RC振荡器的限值。

智能联网产品通过Bluetooth®、有线以太网、Wi-Fi®或其他连接协议与云端进行网络通信。由于涉及无线电和/或高速数据,因此需要精度达百万分之几(ppm)的低抖动精密时钟。

生成精密时钟所需的关键因素是稳定的参考频率,而这需要使用谐振器。谐振器是一种电子无源器件,在某些(谐振)频率下自然振荡的幅度高于其他频率——小提琴琴弦就是一个简单的例子。电子器件通常选用石英晶体和MEMS谐振器。

谐振器的要求如下:

1. 谐振频率随时间和温度变化呈稳定态势。这样可以避免时钟频率漂移。
2. 高品质因数(Q),确保谐振器只响应很窄的频带。
3. 能够在高信号电平下工作,从而在输出端达到良好的信噪比

第二项和第三项对于确保低抖动时钟信号至关重要,可实现稳定的时序转换。

由于谐振器是无源器件,因此需要受控的能量来维持振荡并产生参考频率。将谐振器以反馈配置耦合到维持放大器可实现这种稳定的振荡。如果石英晶体或MEMS谐振器配有合适放大器,会非常适合作为10 Mbps及以上域中数据传输的频率参考。

石英谐振器具有高Q值和高输出能力,适用于抖动必须极低的应用。 可以实现100飞秒的相位噪声(在传统的12 kHz至20 MHz带宽中测量)。MEMS谐振器能够以非常稳定的频率在扩展级温度下工作,而且兼具极高的可靠性以及抗冲击和振动性能,并能够实现超小型时钟解决方案(接近1平方毫米)。 MEMS谐振器具有较高的Q值和较低的输出;可实现500飞秒的相位噪声,而近期的谐振器设计也在不断降低该值。例如,许多现代网络应用(例如PCIe)都支持较小的集成带宽,因此这两种技术都非常合适。

在嵌入式系统中实现时钟

在嵌入式系统中,可通过三种常见的谐振器实现来产生时钟信号。

  •   将石英晶体直接连接到“目标SoC”(将由时钟驱动)

是时候改进您的时钟了!
图1:两个晶体直接连接到MCU,显示负载电容和串联电阻


  •   通过石英晶振(XO)为整个系统创建一个时钟输出
是时候改进您的时钟了!
图2:晶振由石英晶片组成,传统上采用陶瓷封装并带有金属盖


  •   基于石英或MEMS的时钟发生器(以低频和高频[>50 MHz]创建一个或多个时钟输出)
是时候改进您的时钟了!
图3:集成时钟发生器将MEMS(或晶体)谐振器与振荡器相结合,并通过可编程PLL和缓冲输出级扩展功能

点击下载pdf格式

围观 22
1027

一、RCC是什么?

RCC: Reset Clock Control,时钟和复位控制器

二、RCC的主要作用

1、设置系统时钟SYSCLK

2、设置AHB分频因子(决定HCLK等于多少)

3、设置APB2分频因子(决定PCLK2等于多少)

4、设置APB1分频因子(决定PCLK1等于多少)

5、设置各个外设的分频因子

6、控制AHB、APB2和APB1三条总线时钟的开启、控制每个外设时钟的开启。

注意:STM32库函数中时钟的标准配置为PCLK2=HCLK=SYSCLK=PLLCLK=72M,PCLK1=HCLK/2=36M

三、系统时钟库函数

对于系统时钟的配置,在固件库文件system_stm32f10x.c中。如下所示:

static void SetSysClockTo72(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
  /* Enable HSE */    
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);

  /* Wait till HSE is ready and if Time out is reached exit */
  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 */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

    /* PCLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

    /* PCLK1 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

#ifdef STM32F10X_CL
    /* Configure PLLs ------------------------------------------------------*/
    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */

    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);

    /* Enable PLL2 */
    RCC->CR |= RCC_CR_PLL2ON;
    /* Wait till PLL2 is ready */
    while((RCC->CR & RCC_CR_PLL2RDY) == 0)
    {
    }

    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 
    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
                            RCC_CFGR_PLLMULL9); 
#else    
    /*  PLL configuration: 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_PLLMULL6);               //12*6=72M
#endif /* STM32F10X_CL */

    /* Enable PLL */
    RCC->CR |= RCC_CR_PLLON;

    /* Wait till PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }

    /* Select PLL as system clock source */
    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 */
    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的HSE时钟

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

HSE最常用的是8M的无源晶振。当外部晶振为8M时,不需要对固件库中的系统时钟配置函数进行修改,但是,如果我们选择的外部晶振不是8M的,则需要对固件库中的系统时钟的配置做一修改。如我们所使用的外部晶振为12M,则需要做如下修改。

1、修改stm32f10x.h文件

打开stm32f10x.h文件,修改如下代码(119行)

#define HSE_VALUE ((uint32_t)8000000) //修改之前

#define HSE_VALUE ((uint32_t)12000000) //修改之后

2、修改system_stm32f10x.c中的系统时钟配置函数

打开system_stm32f10x.c文件,修改如下代码(1056行)

RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); //修改之前,HSE=8M,9倍频之后为8*9=72M

RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6); //修改之后,HSE=12M,6倍频之后为12*6=72M

转自:Tangledice

围观 19
977

一、在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。

①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()

转自: kevinhg

围观 36
1440

本文提到的有以下内容:

• 时钟系统与总线矩阵
• SysTick系统定时器
• RTC实时时钟
• 看门狗定时器
• 通用定时器

一、时钟系统与总线矩阵

stm32F4的时钟树如下图所示:

stm32之时钟控制

在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。

HSI是高速内部时钟,RC振荡器,频率为8MHz。
HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。
LSI是低速内部时钟,RC振荡器,频率为40kHz。
LSE是低速外部时钟,接频率为32.768kHz的石英晶体。
PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。

我们在学习51单片机的时候,其内部是没有晶振的,而stm32是有的。stm32可以通过RCC(时钟控制寄存器)对时钟进行参数配置以及使能。我们还可以通过修改system_stm32f4xx.c文件,来配置上述时钟树上的一些分频、倍频参数,得到理想的频率。

在单片机系统中,CPU和总线以及外设的时钟设置是非常重要的,因为没有时钟就没有时序,组合电路需要好好理解清楚。我们先来看一下总线矩阵。

stm32之时钟控制

片上总线标准种类繁多,而由ARM公司推出的AMBA片上总线受到了广大IP开发商和SoC系统集成者的青睐,已成为一种流行的工业标

准片上结构。AMBA规范主要包括了AHB(Advanced High performance Bus)系统总线和APB(Advanced Peripheral Bus)外围总线。二者分别适用于高速与相对低速设备的连接。

一般性的时钟设置需要先考虑系统时钟的来源,是内部RC还是外部晶振还是外部的振荡器,是否需要PLL。然后考虑内部总线和外部总线,最后考虑外设的时钟信号。遵从先倍频作为CPU时钟,然后在由内向外分频,下级迁就上级的原则。

二、SysTick系统定时器  

SysTick—系统定时器是属于CM4内核中的一个外设,内嵌在NVIC中。系统定时器是一个24bit的向下递减的计数器,计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK等于180M。当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。

因为SysTick是属于CM4内核的外设,所以所有基于CM4内核的单片机都具有这个系统定时器,使得软件在CM4单片机中可以很容易的移植。

系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。

一般用于系统内部运行以及延时函数。

三、RTC实时时钟

RTC(Real-Time Clock)实时时钟为操作系统提供了一个可靠的时间,并且在断电的情况下,RTC实时时钟也可以通过电池供电,一直运行下去。

RTC通过STRB/LDRB这两个ARM指令向CPU传送8位数据(BCD码)。数据包括秒,分,小时,日期,天,月和年。RTC实时时钟依靠一个外部的32.768Khz的石英晶体,产生周期性的脉冲信号。每一个信号到来时,计数器就加1,通过这种方式,完成计时功能。

RTC实时时钟有如下一些特性:

1,BCD数据:这些数据包括秒、分、小时、日期、、星期几、月和年。
2,闰年产生器
3,报警功能:报警中断或者从掉电模式唤醒
4,解决了千年虫问题 (详见
http://baike.baidu.com/view/9349.htm
5,独立电源引脚RTCVDD
6,支持ms中断作为RTOS内核时钟
7,循环复位(round reset)功能

stm32之时钟控制

如图,RTC实时时钟的框架图,XTIrtc和XTOrtc产生脉冲信号,即外部晶振。传给2^15的一个时钟分频器,得到一个128Hz的频率,这个频率用来产生滴答计数。当时钟计数为0时,产生一个TIME TICK中断信号。时钟控制器用来控制RTC实时时钟的功能。复位寄存器用来重置SEC和MIN寄存器。闰年发生器用来产生闰年逻辑。报警发生器用来控制是否产生报警信号。

四、看门狗定时器

看门狗定时器又分为独立看门狗IWDG和窗口看门狗WWDG。

1、独立看门狗

独立看门狗IWDG其实是一个12位递减计数器,有故障时,计数器减到0,产生复位,无故障时,计数器减到0之前就刷新计数值(喂狗),不进行复位。其采用独立时钟,主要用于监视硬件错误(不受系统时钟影响)。

2、窗口看门狗

窗口看门狗WWDG其实是一个7位递减计数器,有计数上下限,下限位0x40,上限由用户指定,上下限之间刷新计数值则不复位,其他都复位。采用系统时钟,主要用于监视软件错误。

五、通用定时器

stm32的定时器有基本定时器、通用定时器和高级定时器。这里以通用定时器为例,其内部结构如下图所示,需要设置预分频系数,并不是直接使用APB1的时钟。

stm32之时钟控制

通用定时器的计数模式分为5种:

• 向上计数:计数器从0计数到自动装载值。
• 向下计数:从自动装载值计数到0。
• 向上向下计数(中心对齐计数):计数器从0计数到自动装载值,再从自动装载值计数到0,反复循环。
• 输入捕获:测量输入信号的脉宽、PWM波的占空比等。
• 输出比较:PWM波用的就是这种模式。

定时器的时间公式:T=((n-1)*(pre-1))/Tclk,其中n为计数值,pre为预分频系数,Tclk为定时器时钟。

为什么计数值和预分频系数要减一?因为计数是从0开始的,而预分频系数为0时,表示不分频。

定时器用于中断时,注意更新中断标志位。

转自: steed-博客

围观 50
1187

MSP430根据型号的不同最多可以选择使用3个振荡器。我们可以根据需要选择合适的振荡频率,并可以在不需要时随时关闭振荡器,以节省功耗。

这3个振荡器分别为:

(1)DCO 数控RC振荡器。

它在芯片内部,不用时可以关闭。DCO的振荡频率会受周围环境温度和MSP430工作电压的影响,且同一型号的芯片所产生的频率也不相同。但DCO的调节功能可以改善它的性能,他的调节分为以下3步:
a:选择BCSCTL1.RSELx确定时钟的标称频率;
b:选择DCOCTL.DCOx在标称频率基础上分段粗调;
c:选择DCOCTL.MODx的值进行细调。

(2)LFXT1 接低频振荡器。

典型为接32768HZ的时钟振荡器,直接连接在XIN与XOUT之间,此时振荡器不需要接负载电容。也可以接450KHZ~8MHZ的标准晶体振荡器,此时需要接负载电容.LXFT1产生的频率信号为ACLK.低速时钟需要上百毫秒的建立时间才能稳定下来.

(3)XT2 接450KHZ~8MHZ的标准晶体振荡器。

外部标准晶体振荡器接在XT2IN和XT2OUT之间,此时需要接负载电容,不用时可以关闭。

低频振荡器主要用来降低能量消耗,如使用电池供电的系统,高频振荡器用来对事件做出快速反应或者供CPU进行大量运算。

MSP430的3种时钟信号:

MCLK系统主时钟;
SMCLK系统子时钟;
ACLK辅助时钟。

(1)MCLK系统主时钟。除了CPU运算使用此时钟以外,外围模块也可以使用。MCLK可以选择任何一个振荡器所产生的时钟信号并进行1、2、4、8分频作为其信号源。

(2)SMCLK系统子时钟。供外围模块使用。并在使用前可以通过各模块的寄存器实现分频。SMCLK可以XT2CLK或者DCOCLK振荡器所产生的时钟信号并进行1、2、4、8分频作为其信号源。

(3)ACLK辅助时钟。供外围模块使用。并在使用前可以通过各模块的寄存器实现分频。但ACLK只能由LFXT1进行1、2、4、8分频作为信号源。可以作为后台时钟用来唤醒CPU.

(4)ACLK/N, ACK缓冲输出,他可以有ACL.1.2.4.8分频获得 ,且只能为外部所用.

PUC复位后,MCLK和SMCLK的信号源为DCO,DCO的振荡频率为800KHZ。ACLK的信号源为LFXT1。

MSP430内部含有晶体振荡器失效监测电路,监测LFXT1(工作在高频模式)和XT2输出的时钟信号。当时钟信号丢失50us时,监测电路捕捉到振荡器失效。如果MCLK信号来自LFXT1或者XT2,那么MSP430自动把MCLK的信号切换为DCO,这样可以保证程序继续运行。但MSP430不对工作在低频模式的LFXT1进行监测。

来源: 电子工程世界

围观 20
1448

页面

订阅 RSS - 时钟