[裸机应用]系统时钟和定时器

时间:2021-08-29 21:20:09

系统时钟和定时器

 

1S3C2440时钟系统................................................................................................ 2

1.1 时钟结构..................................................................................................... 2

1.2 时钟源的选择.............................................................................................. 4

1.3 锁相环PLL................................................................................................... 4

1.4 时钟控制逻辑.............................................................................................. 5

1.5 上电复位(XTIpll)........................................................................................... 5

1.6  普通模式下改变PLL设置........................................................................... 5

1.7  USB时钟控制............................................................................................ 6

1.8  FCLKHCLKPCLK................................................................................... 6

2、时钟配置特殊功能寄存器.................................................................................... 7

2.1  锁定时间计数寄存器(LOCKTIME)................................................................ 7

2.2  时钟控制寄存器(CLKCON).......................................................................... 8

2.3  时钟分频控制寄存器(CLKDIVN).................................................................. 9

2.4  时钟分频控制寄存器(CLKDIVN).................................................................. 9

2.4  摄像头时钟分频寄存器(CAMDIVN)............................................................. 9

3、定时器............................................................................................................... 10

3.1  概述......................................................................................................... 11

3.2  PWM定时器方框图................................................................................. 11

3.3  PWM定时器操作..................................................................................... 12

3.3.1  预分频器和分频器......................................................................... 13

3.3.2  基本时序操作................................................................................ 13

3.3.3  自动重载和双缓冲......................................................................... 13

3.3.4  使用手动更新位和变相位初始化定时器......................................... 13

3.4  定时器控制寄存器................................................................................... 14

3.4.1  定时器配置寄存器0(TCFG0)........................................................... 14

3.4.2  定时器配置寄存器1(TCFG1)........................................................... 14

3.4.3  定时器控制寄存器1(TCON)............................................................ 14

3.4.4  定时器0计数缓冲寄存器和比较缓冲寄存器(TCNTB0/TCMPB0)...... 15

3.4.5  定时器0计数监视寄存器(TCNTO0)................................................. 16

3.4.6  定时器1计数缓冲寄存器和比较缓冲寄存器(TCNTB1/TCMPB1)....... 16

3.4.7  定时器1计数监视寄存器(TCNTO1)................................................. 16

3.4.8  定时器2计数缓冲器和比较缓冲寄存器(TCNTB2/TCMPB2).............. 16

3.4.9  定时器2计数监视寄存器(TCNTO2)................................................. 16

3.4.10  定时器3计数缓冲寄存器和比较缓冲寄存器(TCNTB3TCMPB3). 16

3.4.11 定时器计数监视寄存器(TCNTO3).................................................... 17

3.4.12  定时器4计数缓冲寄存器(TCNTB4)............................................... 17

3.4.13  定时器4计数监视寄存器(TCNTO4)............................................... 17

3.5  定时器使用例程....................................................................................... 17

3.5.1  例程1............................................................................................ 17

 


1、S3C2440时钟系统

S3C2440A 中的时钟控制逻辑可以产生必须的时钟信号,包括 CPU 的 FCLK,AHB 总线外设的 HCLK 以及APB 总线外设的 PCLK。S3C2440A 包含两个锁相环(PLL):一个提供给 FCLK、HCLK 和 PCLK,另一个专用于USB 模块(48MHz)。时钟控制逻辑可以不使用 PLL 来减慢时钟,并且可以由软件连接或断开各外设模块的时钟,以降低功耗。

1.1 时钟结构

主时钟源来自一个外部晶振(XTIpll)或外部时钟(EXTCLK)。时钟发生包含了一个连接到外部晶振的振荡器(震荡放大器),还含有 S3C2440A 所必须的两个用于产生高频率时钟的 PLL (锁相环)。

XTIpll:外部晶振输入

EXTCLK:外部时钟

XTOpll:外部晶振输出

MPLL:主锁相环

CLKCNTL:时钟控制模块

 

 

 

 

 


1.2 时钟源的选择

下表显示了模式控制引脚(OM3、OM2)的组合关系,并为S3C2440选择时钟源。nRESET的上升沿时参考OM3和OM2引脚将OM[3:2]的状态在内部锁定。

注意:
1.
虽然 MPLL 在复位后就开始, MPLL 输出(Mpll)并没有作为系统时钟,直到软件写入有效值来设置 MPLLCON寄存器。在设置此值之前,是将外部晶振或外部时钟源提供的时钟直接作为系统时钟。即使用户不想改变 MPLLCON寄存器的默认值,用户也应当写入与之相同的值到 MPLLCON 寄存器寄存器中。
2. OM[3:2]是用于当 OM[1:0]为 11 时决定一个测试模式

1.3 锁相环PLL

时钟发生器之中作为一个电路的 MPLL,参考输入信号的频率和相位同步出一个输出信号。包含了下图中的基本模块。

 

①用于生成与输入直流电压成比例的输出频率的压控振荡器(VCO)

②用于将输入频率(Fin)按p分频的分频器P

③用于将VCO输出频率按m分频并输入到相位频率检测器(PFD)中的分频器M

④用于将VCO输出频率按s分频称为Mpll(输出频率来自MPLL模块)的分频器S

⑤鉴相器

⑥电荷泵

⑦环路滤波器

输出时钟频率 Mpll 相关参考输入时钟频率 Fin 有如下等式:


1.4 时钟控制逻辑

钟控制逻辑决定使用的时钟源,即使用 PLL 时钟(Mpll)或直接使用外部时钟(XTIpll 或 EXTCLK)。当配置了 PLL 为一个新频率值时,时钟控制逻辑先禁止 FCLK,直至使用 PLL 锁定时间使 PLL 稳定输出。时钟控制逻辑在上电复位时和从掉电模式中唤醒时同样是激活的。

1.5 上电复位(XTIpll)

图7-4 显示了上电复位期间时钟行为顺序。晶振在若干毫秒内开始振荡。当在 OSC(XTIpll)时钟稳定后释放nRESET,PLL 开始按默认 PLL 配置运行。但是通常认为上电复位后的 PLL 是不稳定的,因此在软件重新配置PLLCON 寄存器之前 Fin 代替 Mpll(PLL 输出)直接提供给 FCLK。即使用户不希望在复位后改变 PLLCON 寄存器的默认值,用户还是应该用软件写入相同的值到 PLLCON 寄存器中。
   
只有置PLL 为一个新频率后,PLL 会开始锁定连续逼近新频率。可以在锁定时间后立即配置 FCLK 为 PLL 输出(Mpll)。

 

1.6  普通模式下改变PLL设置

在2440运行在普通模式期间,用户可以通过改写PMS的值来改变频率,并且将自动插入PLL锁定时间。在锁定时间期间内,不提供给S3C2440A的内部模块。如下图所示:

PMS改变操作时序

 

 

1.7  USB时钟控制

USB主机接口和USB设备接口都需要48MHz的时钟。S3C2440A中,USB专用PLL(UPLL)生成48MHz给USB。在配置PLL(UPLL)之前不提供UCLK。

条件

UCLK状态

UPLL状态

复位后

XTIpll或EXTCLK

开启

配置UPLL后

低电平:锁定时间期间

48MHz:PLL锁定时间后

开启

CLKSLOW寄存器关闭了UPLL

XTIpll或EXTCLK

关闭

CLKSLOW寄存器开启了UPLL

48MHz

开启

 

1.8  FCLK、HCLK和PCLK

FLCK是提供给ARM920T的时钟。

HCLK是提供给用于ARM920T,存储器控制器,中断控制器,LCD控制器,DMA和USB主机模块的AHB总线的时钟。

PCLK是提供给用于外设如WDT,IIS,IIC,PWM定时器,MMC/SD接口,ADC,UART,GPIO,RTC和SPI的APB总线的时钟。

S3C2440A还支持对FCLK、HCLK、PCLK之间分频比例的选择。该比例由CLKDIVN控制寄存器中的HDIVN和PDIVN所决定。

 

......

2、时钟配置特殊功能寄存器

2.1  锁定时间计数寄存器(LOCKTIME)

2.2  时钟控制寄存器(CLKCON)

 

 

2.3  时钟分频控制寄存器(CLKDIVN)

2.4  时钟分频控制寄存器(CLKDIVN)

2.4  摄像头时钟分频寄存器(CAMDIVN)


3、定时器

3.1  概述

S3C2440有5个16位定时器。其中定时器0、1、2、3具有脉宽调制(PWM)功能。定时器4是一个无输出引脚的内部定时器。定时器0还包含用于大电流驱动的死区发生器。

定时器0和定时器1共用一个8位预分频器,定时器2、3和4共用另外的8位预分频器。每一个定时器都有一个可以生成5种不同分频信号(1/2,1/4,1/8,1/16和TCLK)的时钟分频器。每个定时器模块从相应8位预分频得到时钟的时钟分频器中得到其自己的时钟信号。8位预分频器是可编程的,并且按存储在TCFG0和TCFG1寄存器中的加载值来分配PCLK。

定时器计数缓冲寄存器(TCNTBn)包含了一个当使能了定时器时的被加载到递减计数器中的初始值。定时比较缓冲寄存器(TCMPBn)包含了一个被加载到比较寄存器中的与递减计数器相比较的初始值。这种TCNTBn和TCMPBn的双缓冲特征保证了改变频率和占空比时,定时器产生稳定的输出。

每个定时器都有他自己的定时器时钟驱动的16位递减计数器。当递减计数器到达零时,产生定时器中断请求通知COU定时器操作已经完成。

当定时器计数器到达零时,相应的TCNTBn的值将自动被加载到递减计数器以继续下一次操作。然而,如果定时器停止了。例如,在定时器运行模式期间清除TCONn的定时器使能位,TCONTBn的值将不会被重新加载到计数器中。

TCMPBn的值是用于脉宽调制(PWM)。当递减计数器的值与定时器控制逻辑中的比较寄存器的值相匹配时定时器控制逻辑改变输出电平。因此,比较寄存器决定PWM输出的开启时间(或关闭时间)。

 

特性:

—五个16位定时器

—两个8位预分频器和两个4位分频器

—可编程输出波形的占空比控制(PWM)

—自动重载模式或单稳态脉冲模式

—死区发生

—本质:一个减1计数器(输入一个脉冲,计数器减1)


3.2  PWM定时器方框图

英文注释:

prescaler:预分频器

clock divider:时钟分频器

MUX:多路选择开关

Control Logic0:控制逻辑0

Dead Zone Generator:死区发生器

 


3.3  PWM定时器操作

3.3.1  预分频器和分频器

一个8位分频器(0~255)和一个4位分频器(2/4/8/16)产生以下输出频率:

3.3.2  基本时序操作

一个定时器(除了定时器通道5)包含了TCNTBn、TCNTn、TCMPBn和TCMPn。(TCNTn和TCMPn是内部寄存器的名称。从TCNTOn寄存器中可以读取TCNTn)当定时器到达0时,TCNTBn和TCMPBn被加载到TCNTn和TCMPn中。当TCNTn到达0时,如果中断使能则将发送一个中断请求。

3.3.3  自动重载和双缓冲

         S3C2440PWM定时器包含双缓冲功能,允许在不停止当前定时器操作的情况下为下次定时器操作改变重载值。所以即使设置了新的定时器值,当前定时器操作仍然顺利的被完成。         定时器值可以被写入到定时器计数缓冲寄存器(TCNTBn)中并且可以从定时器计数监视寄存器(TCNTOn)中读取当前定时器的计数值。如果读取TCNTBn,读出的值不是指示当前计数器的状态,而是下一次定时器持续时间的重载值。

自动重载操作在TCNTn到达0时复制TCNTBn到TCNTn。写入到TCNTBn的值,只有在TCNTn到达0并且使能了自动重装时才被加载到TCNTn。如果TCNTn变为0,并且自动重载位为0,TCNTn不会进一步操作。

3.3.4  使用手动更新位和变相位初始化定时器

         当递减计数器到达0时发生定时器的自动重载操作。所以必须预先由用户定义一个TCNTn的起始值。在这种情况下,必须通过手动更新位加载起始值。以下步骤描述了如何启动一个定时器:

(1)初值装到TCNTBn和TCMPBn中

(2)设置相应定时器的手动更新位。(推荐使用变相开关位)

(3)设置相应定时器的开关位来启动定时器(并且清除手动更新位)。

         如果定时器被强制停止,TCNTn保持计数器值并且不会从TCNTBn重载。如果需要设置一个新值,执行手动更新。

3.4 定时器控制寄存器

3.4.1  定时器配置寄存器0(TCFG0)

定时器输入频率=PCLK/(预分频值+1)/(分配值)

预分频值=0~255

分频值 = 2/4/8/16

 

TCFG0

描述

初始值

Reserved

[31:24]

保留

0x00

死区长度

[23:16]

该 8位决定了死区段。死区段持续为1的时间等于定时器0持续为1的时间。

0x00

Prescaler1

[15:8]

该8位决定了定时器2、3和4的预分频值

0x00

Prescaler2

[7:0]

该8位决定了定时器0和1的预分频值

0x00

 

3.4.2  定时器配置寄存器1(TCFG1)

TCFG1

描述

初始值

Reserved

[31:24]

保留

0x00

DMA模式

[23:20]

选择DMA请求通道

0000=未选择(所有中断)  0001=定时器0  0010=定时器1

0011=定时器2  0100=定时器3  0101=定时器4  0110=保留

0000

MUX4

[19:16]

选择PWM定时器4的选通输入

0000=1/2  0001=1/4  0010=1/8  0011=1/16  01xx=外部TCLK1

0000

MUX3

[19:16]

选择PWM定时器4的选通输入

0000=1/2  0001=1/4  0010=1/8  0011=1/16  01xx=外部TCLK1

0000

MUX2

[19:16]

选择PWM定时器4的选通输入

0000=1/2  0001=1/4  0010=1/8  0011=1/16  01xx=外部TCLK1

0000

MUX1

[19:16]

选择PWM定时器4的选通输入

0000=1/2  0001=1/4  0010=1/8  0011=1/16  01xx=外部TCLK1

0000

MUX0

[19:16]

选择PWM定时器4的选通输入

0000=1/2  0001=1/4  0010=1/8  0011=1/16  01xx=外部TCLK1

0000

 

3.4.3  定时器控制寄存器1(TCON)


3.4.4  定时器0计数缓冲寄存器和比较缓冲寄存器(TCNTB0/TCMPB0)

T--Timer定时器     CNT--count计数    B--buffer缓冲器

T--Timer 定时器    CMP--compare比较      B--buffer  缓冲器

3.4.5  定时器0计数监视寄存器(TCNTO0)

T--timer CNT--count  O--out

3.4.6  定时器1计数缓冲寄存器和比较缓冲寄存器(TCNTB1/TCMPB1)

T--Timer 定时器  CNT--count 计数  B--buffer缓冲区

T--Timer 定时器    CMP--compare 比较     B--buffer缓冲区

3.4.7  定时器1计数监视寄存器(TCNTO1)

T--timer CNT--count  O--out

3.4.8  定时器2计数缓冲器和比较缓冲寄存器(TCNTB2/TCMPB2)

T--Timer  定时器 CNT--count 计数 B--buffer缓冲器

T--Timer 定时器 CMP--compare 比较      B--buffer缓冲器

3.4.9  定时器2计数监视寄存器(TCNTO2)

T--timer CNT--count  O--out

3.4.10  定时器3计数缓冲寄存器和比较缓冲寄存器(TCNTB3和TCMPB3)

T--timer定时器  CNT--计数器    B--buffer缓冲器

T--timer定时器      CMP--compare比较      B--buffer缓冲器

3.4.11 定时器计数监视寄存器(TCNTO3)

TIMER COUNT OUT

3.4.12  定时器4计数缓冲寄存器(TCNTB4)

timer count buffer

3.4.13  定时器4计数监视寄存器(TCNTO4)

timer count out

3.5 定时器使用例程

3.5.1  例程1

任务:使用定时器0的定时功能,使LED每秒钟闪烁一次。

思路:初始化定时器,定时器定时时间到(1S),执行相应的操作(LED引脚电平翻转)。

分析:类似于单片机,定时器定时处理有两种方式——查询方式和中断方式。

这里,使用查询方式。

51单片机的定时器计时结束后(加1计时溢出后)会有一个标志位TFx 置1。我们可以查询TFx的状态来查看定时器是否计数完毕。同样,在2440里面,定时器计数结束(减一计时到0)后也会有相应位置1。

定时器中计数器的值为0时,会产生中断标志,这一位位于寄存器SRCPND(源挂起寄存器)的第10位,当该位置1时,说明定时器计数到0。我们可以查询该位的状态,以判断定时器是否计数结束。

查询该位之后,执行相应的操作,要清楚该标志,否则下一次无法查出,虽然该位是置1了,但是我们对其清0的方法确实往第10位写1,简称“写1清零”。

基本步骤如下

(1)初始化定时器

(2)查询中断标志位,检测定时器是否计数完毕

(3)执行相应操作,清除定时器中断标志位(写1清零)

 

程序内容:

1.main.c

#include"2440addr.h"

#include"timer0.h"

#include "led.h"

intled_flag=0;/*led灯亮起允许标志*/

void Main()

{

    Led_Init();

    Timer0_Init();

    while(1)

    {

        /*查询是否产生中断标志*/

        if((1<<10)==(rSRCPND&(1<<10)))

        {   /*成立,说明定时器0产生中断*/ 

            led_flag=!led_flag;

            /*清除中断标志位*/

            rSRCPND |=1<<10;/*写1清零*/

        }

        /*执行相应操作*/

        if(led_flag==1)

        {

            Led1_On();

        }

        else

        {

            Led1_Off();

        }

    }

}

2.timer0.h

#ifndef_TIMER0_H_

#define_TIMER0_H_

extern voidTimer0_Init(void);

#endif


3.timer0.c

#include"2440addr.h"

#include"timer0.h"

 

voidTimer0_Init(void)

{

    /*-------------------------------分频-------------------------------------*/

    /*对时钟分频,得到定时器的输入时钟,与想要的频率相近*/

    /*对于定时器0和1,预分频寄存器使用bit[7:0],第二级分频寄存器使用bit[3:0]*/

    /*对于定时器2、3、4,预分频寄存器使用bit[15:8],第二级分频寄存器使用bit[7:4]*/

    rTCFG0 &= ~(0XFF);/*清零*/

    rTCFG0 |=(100-1);/*对PCLK进行100分频*/

    rTCFG1 &=~(0XFF);/*清零*/

    rTCFG1 |=(0x01);/*00=2分频,01=4分频,02=8分频,03=16分频*/

   

    /*------------------------------配初值------------------------------------*/

    /*定时器缓冲器初值设置*/

    rTCNTB0=62500;/*1s中断一次*/

//  /*定时器比较缓冲器值设置*/

//  rTCMPB0=62500;/*这里不要用到比较仅仅用于计时*/

   

   

    /*-----------------------------控制定时器-----------------------------------*/

    /*定时器0使用定时器控制器的bit[3:0]*/

    /*定时器1使用定时器控制器的bit[11:8]*/

    /*定时器2使用定时器控制器的bit[15:12]*/

    /*定时器3使用定时器控制器的bit[19:16]*/

    /*定时器4使用定时器控制器的bit[20:22],只要三位控制,没有变相开/关功能*/

    rTCON&=~((1<<0)|(1<<1)|(1<<2)|(1<<3));/*清零控制器功能*/

   

    /*手动更新初值到计数器*/

    rTCON|=1<<1;/*第一次使用,要手动更新初值*/

   

    /*关闭手动更新功能*/

    rTCON &=~(1<<1);/*关掉手动更新*/

   

    /*设置自动加载位,并开启定时器*/

    rTCON |=(1<<3)|(1<<0);

}

分频思路。我们一般知道的数据就是定时器的定时时间t,比如说t=1s。

定时器的工作原理:每输入一个脉冲到计数器,计数器减一计时。而一个脉冲使用多少时间呢?这个就是我们要配置的地方。

首先,我们清楚,定时器的时钟来源是HCLK,HCLK的时钟频率为100MHz,我们不需要这么高的频率,所以对它进行分频处理。那到底分多少呢?

比方说我们定时1s,ARM9的计数器为16位计数器,最大值为65535,我们假设定时器中计数器,计数65000次,达到1s时间,这时候,计数一次所用的时间为1/65000s,因为因数中有个质数13,所以难以除尽,不好计算,为了定时器的精确计时,我们另取数值。

一般我们使用62500,也就是说,定时器经过了62500次的减一计数,才达到1s,这个时候,计数器减一所用的时间为0.000016s=0.016ms=16us。

定时器中工作原理是:每输入一个脉冲,计数器减一计时。

所以,分频后的脉冲周期为Tin=16us,Fin=1/16us=62500Hz=62.5KHz

而这个频率是PCLK分频而来,我们看PCLK与Fin的关系。

PCLK/Fin=50MHz/62.5KHz=800(倍)

我们看定时器的分频系数。预分频寄存器分频值范围为0~255,第二级分频器分频系数为2/4/8/16分频,

800=16x100=4x200

两种分频方式都可以,达到的效果是一样的。这时候,就完成了初值的确定(计数次数62500)和输入时钟的分频处理。

 

4.led.h

#ifndef _LED_H_

#define _LED_H_

 

#defineLed1_On() (rGPBDAT &=~(1<<5))

#defineLed1_Off() (rGPBDAT |=(1<<5))

extern voidLed_Init();

#endif

5.led.c

#include"2440addr.h"

#include"led.h"

 

void Led_Init()

{

         /*配置引脚功能*/

         rGPBCON &=~(3<<10);/*清零GPB5引脚功能*/

         rGPBCON |=(1<<10);/*配置GPB5为输出功能*/

         rGPBUP &=~(1<<5);/*GPB5上拉使能*/

         rGPBDAT |=(1<<5);/*GPB5默认输出1,Led不亮*/

}

 

编译程序,烧写到目标板上,观察效果。

3.5.2  例程2

任务:使用ARM9定时器0的输出翻转功能,输出PWM。

思路:初始化功能引脚为第二功能,初始化定时器(配置TCON的bit2输出控制位为使能翻转),让定时器自己循环工作。

分析:ARM9的定时器0~3具有输出引脚(定时器4没有输出引脚),可以配置其电平翻转使能,当计数器减一计时到TCMP0=TCNT0时,TOUT引脚输出电平翻转。

我们对TCMPn和TCNTn装数值不是直接装载,而是把数值装到缓冲区TCMPBn和TCNTBn中,方便定时器自动重载更新。