s3c2410 Timer

发布者:国宝集团最新更新时间:2016-12-02 来源: eefocus关键字:s3c2410  timer  定时器 手机看文章 扫描二维码
随时随地手机看文章

s3c2410提供了5个16位的Timer(Timer0~Timer4),其中Timer0~Timer3支持Pulse Width Modulation—— PWM(脉宽调制 )。Timer4是一个内部定时器(internal timer),他没有输出引脚(output pins)。
下面是Timer的工作原理图。

如上图所示,PCLK是Timer的信号源,我们通过设置每个Timer相应的Prescaler和Clock Divider把PCLK转换成输入时钟信号传送给各个Timer的逻辑控制单元(Control Logic),事实上每个Timer都有一个称为输入时钟频率(Timer input clock Frequency)的参数,这个频率就是通过PCLK,Prescaler和Clock Divider确定下来的,每个Timer 的逻辑控制单元就是以这个频率在工作。下面给出输入时钟频率的公式:

Timer input clock Frequency = PCLK / {prescaler value+1} / {clock divider }
{prescaler value} = 0~255
{ clock divider } = 2, 4, 8, 16

然而并不是每一个Timer都有对应的Prescaler和Clock Divider,从上面的原理图我们可以看到Timer0,Timer1共用一对Prescaler和Clock Divider,Timer2,Timer3,Timer4共用另一对Prescaler和Clock Divider,s3c2410的整个时钟系统模块只存在两对Prescaler和Clock Divider。

我曾经在讨论watchdog的文章中提到,watchdog也是一种定时器,他的工作就是在一个单位时间内对一个给定的数值进行递减和比较的操作,而我们这篇文章讨论的定时器他的工作内容和watchdog在本质上是一样的。定时器在一个工作周期(Timer input clock cycle)内的具体工作内容主要有3个。分别是:

1.        对一个数值进行递减操作
2.        把递减后的数值和另一个数值进行比较操作
3.        产生中断或执行DMA操作

在启用Timer之前我们会对Timer进行一系列初始化操作,这些操作包括上面提到的设置Prescaler和Clock Divider,其中还有一个非常重要的就是要给Timer两个数值,我们分别称之为Counter(变量,用于递减)和Comparer(定值,用于比较),Counter会被Timer 加载到COUNT BUFFER REGISTER(TCNTB),而Comparer会被Timer 加载到和COMPARE BUFFER REGISTER(TCMPB),每个Timer都有这样两个寄存器。当我们设置完毕启动Timer之后,Timer在一个工作周期内所做的就是先把TCNTB中的数值(Counter)减1,之后把TCNTB中的数值和TCMPB中的数值(Comparer)进行对比,若Counter已经被递减到等于Comparer,发生计数超出,则Timer产生中断信号(或是执行DMA操作)并自动把Counter重新装入TCNTB(刷新TCNTB以重新进行递减)。以上就是Timer的工作原理。

下面我们结合代码具体说明如何对Timer0进行初始化并开启它。
首先我假设我的PCLK是50700000Hz

// define Timer register
#define rTCFG0 (*(volatile unsigned int *)0x51000000)
#define rTCFG1 (*(volatile unsigned int *)0x51000004)
#define rTCON (*(volatile unsigned int *)0x51000008)
#define rTCNTB0 (*(volatile unsigned int *)0x5100000C)
#define rTCMPB0 (*(volatile unsigned int *)0x51000010)
#define rTCNTO0 (*(volatile unsigned int *)0x51000014)
#define rTCNTB1 (*(volatile unsigned int *)0x51000018)
#define rTCMPB1 (*(volatile unsigned int *)0x5100001C)
#define rTCNTO1 (*(volatile unsigned int *)0x51000020)
#define rTCNTB2 (*(volatile unsigned int *)0x51000024)
#define rTCMPB2 (*(volatile unsigned int *)0x51000028)
#define rTCNTO2 (*(volatile unsigned int *)0x5100002C)
#define rTCNTB3 (*(volatile unsigned int *)0x51000030)
#define rTCMPB3 (*(volatile unsigned int *)0x51000034)
#define rTCNTO3 (*(volatile unsigned int *)0x51000038)
#define rTCNTB4 (*(volatile unsigned int *)0x5100003C)
#define rTCNTO4 (*(volatile unsigned int *)0x51000040)

void timer0_config()
{
/*
                Timer0的prescaler由rTCFG0 的 0~7 bit决定
                Prescaler=119
*/
                rTCFG0=119        
/*
                Timer0的divider value由TCFG1的 0~3 bit决定,设置为3表示divider value = 1/16
                rTCFG1的第20~23bit用于决定Timer计数超出后所采取的响应,我们使用了中断模式(20~23bit全部为0),
                即计数超出后产生中断
*/
                rTCFG1=3;
        
                rTCNTB0=26406;
                rTCMPB0=0;
}
由于我们的PCLK是50700000Hz, 根据Timer input clock Frequency的计算公式我们如下计算Timer0的时钟输入频率:

prescaler value = 119
divider value = 1/16
PCLK= 50700000
Timer input clock Frequency =50700000/ (119+1)/(1/16)=26406

也就是说通过设置prescaler和divider value之后,Timer0的工作频率为26406,也就是说一秒内Timer0会进行26406次递减和比较操作,假设我们现在是要让Timer0每1秒产生一次中断的话,我们应该设置Counter=26406和Camparer=0,既:
rTCNTB0=26406;
rTCMPB0=0;

如果我们要让Timer0每0.5秒产生一次中断,则我们应该设置Counter=26406/2和Camparer=0,既:
rTCNTB0=13203;
rTCMPB0=0;

如果我们要让Timer0每0.25秒产生一次中断,则我们应该设置Counter=26406/4和Camparer=0,既:
rTCNTB0=6601;
rTCMPB0=0;

初始化完Timer后我们要开启它。

void timer0_start()
{
/*
               Update TCNTB0 & TCMPB0
               rTCON寄存器的第1位是刷新Timer0的COUNT BUFFER REGISTER(TCNTB)和
                COMPARE BUFFER REGISTER(TCMPB),由于是第一次加载Counter和Comparer,
                所以我们需要手动刷新它们
*/
               rTCON|=1<<1;
/*
               置rTCON第0位为1,开启Timer0
               把rTCON第1位置为0,停止刷新TCNTB0 和 TCMPB0
               置rTCON第3位为1,设置Counter的加载模式为自动加载(auto reload),这样每当
               Timer计数超出之后(此时TCNTB的值等于TCMPB的值),Timer会自动把原来我们给
               定的Counter重新加载到TCNTB中
*/
        rTCON=0x09;        
}

要使你的Timer能够正常的工作,除了调用timer0_config()和timer0_start()之外,我们还必须设置Timer的中断服务例程并取消对Timer的中断的屏蔽

关键字:s3c2410  timer  定时器 引用地址:s3c2410 Timer

上一篇:s3c2410汇编启动代码与中断跳转分析
下一篇:s3c2410 RTC驱动框架linux内核源码分析

推荐阅读最新更新时间:2024-03-16 15:22

Linux NAND FLASH驱动代码分析
  FLASH驱动在嵌入式系统中有着举足轻重的位置,而目前市场上NAND FLASH的价格又要便宜与NOR FLASH,随着越来越多的平台支持从NAND FLASH中启动,掌握NAND flash的驱动编写有着重要的现实意义,由于内核已经完成了大部分的工作,实际工作中大部分工程师对NAND FLASH驱动只是简单的修改,对其工作原理并不太清楚,下面我们来分析一下NAND FLASH的代码流程,从中体会块设备的代码之美。   在学习NAND FLASH驱动之前,我们需要对块设备中下面的重要2点有个认识:   1.gendisk: 描述块设备实体(一整个nandflash芯片)的结构体   整个块设备的注册过程都是围绕ge
[单片机]
STM32定时器配置,定时计数模式下总结
文章结构: ——   一、定时器基本介绍 ——   二、普通定时器详细介绍TIM2-TIM5 ——   三、定时器代码实例 一、定时器基本介绍 之前有用过野火的学习板上面讲解很详细,所以直接上野火官方的资料吧,作为学习参考笔记发出来 二、普通定时器详细介绍TIM2-TIM5 2.1 时钟来源 计数器时钟可以由下列时钟源提供: ·内部时钟(CK_INT) ·外部时钟模式1:外部输入脚(TIx) ·外部时钟模式2:外部触发输入(ETR) ·内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。
[单片机]
STM32<font color='red'>定时器</font>配置,定时计数模式下总结
嵌入式学习笔记10——51单片机之中断定时器中断
1. CPU时序的有关知识 (1)振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期)。 (2)状态周期:2个振荡周期为1个状态周期,用S表示。振荡周期又称S周期或时钟周期。 (3)机器周期:1个机器周期含6个状态周期,12个振荡周期(使用计时器时,每隔一个机器周期计时器加1)。 (4)指令周期:完成1条指令所占用的全部时间,它以机器周期为单位。 2. 学习定时器前须明白: (1)51单片机有2组定时器/计数器(52单片机有三组),可定时或计数。 (2)定时器/计数器和单片机的CPU是相互独立的,定时器/计数器工作的过程是自动完成的,不需要CPU的参与。 (3)51单片机中的定时器/计
[单片机]
嵌入式学习笔记10——51单片机之中断<font color='red'>定时器</font>中断
STM8学习笔记---定时器 TIM2功能实现
STM8的TIM2、TIM3、TIM5是16位通用寄存器,他们的操作方法一样。 主要功能如下 相关寄存器如下: 如果只用到定时功能的话,需要用到的寄存器有自动装载寄存器ARR、预分频寄存器PSCR、事件产生寄存器EGR、状态寄存器SR、控制寄存器CR、中断使能寄存器IER。 此处用TIM2实验,定时器2初始化代码如下: void Timer2_Init( void ) { TIM2_ARRH = ( unsigned char )( 1000 8 ); //定时1ms TIM2_ARRL = ( unsigned char )( 1000 ); TIM2_PSCR = 0x04; //
[单片机]
STM8学习笔记---<font color='red'>定时器</font> TIM2功能实现
[单片机框架] [app_led] 利用软定时器实现闪烁和呼吸等灯光模式
使用例子: 任意地点初始化:app_led_init(); app_led_indicate(灯号,灯光类型,周期时间,重装载值); 注:需要先实现对应PWM函数 文件代码如下 app_led.c /******************************************************************************** * @file app_led.c * @author jianqiang.xue * @Version V1.0.0 * @Date 2021-04-20 * @brief LED灯光效果 *******************************
[单片机]
s3c2410物理地址和虚拟地址空间
下面是物理地址空间(没有包括物理寄存器的物理地址空间)分布图:
[单片机]
<font color='red'>s3c2410</font>物理地址和虚拟地址空间
《初学者C51自学笔记》之定时器代码(三)
初始化程序: 对TMOD赋值,以确定T0和T1的工作方式。 计算初值,并将其写入TH0、TL0或TH1、TL1。 中断方式时,则对EA赋值,开放定时器中断。 使TR0或TR1置位,启动定时/计数器定时或计数。 //实现功能:数码管一秒加一; #include reg52.h #define uchar unsigned char #define uint unsigned int unsigned char code smg_du ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; void
[单片机]
S3C2410设计的无线数据采集系统
手持终端的功能越来越强大,数据处理能力也越来越强,人们对其无线通信功能的要求也越来越高。为此,各种无线设备进入人们的生活,在此基础之上,大量的无线设备业已进入工业生产领域。在工业或者工厂底层环境中,使用无线技术具有很多优势;利用无线技术可以解决工业生产中线路布局烦琐的困境,也可以避免恶劣环境对线路腐蚀等问题。 1 系统设计 在此,把嵌入式技术与无线电台通信技术相结合,设计一种无线数据采集系统。该系统分为数据采集模块、数据传输/接收模块、数据处理模块,如图1所示。数据采集模块通过将传感器得到的模拟信号转换成数字信号,再用无线芯片发送出去。A/D转换芯片采用MAX132;数据传输芯片采用无线传输/接收芯片IA4421。用单片机配置
[模拟电子]
<font color='red'>S3C2410</font>设计的无线数据采集系统
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved