S3C2440 Timer初始化方法

发布者:lidong4069最新更新时间:2020-01-15 来源: eefocus关键字:S3C2440  Timer  初始化方法 手机看文章 扫描二维码
随时随地手机看文章

s3c2410提供了5个16位的Timer(Timer0~Timer4),其中Timer0~Timer3支持Pulse Width Modulation—— PWM(脉宽调制 )。Timer4是一个内部定时器(internal 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;        
}


附件:


关键字:S3C2440  Timer  初始化方法 引用地址:S3C2440 Timer初始化方法

上一篇:S3C2440 LED驱动
下一篇:S3C6410移植u-boot(一)

推荐阅读最新更新时间:2024-11-09 03:59

s3c2440裸机-代码重定位-3-清bss原理及实现
1.清bss的引入(为什么要清bss) 我们先举个例子: #include s3c2440_soc.h #include uart.h char g_Char = 'A'; //.data char g_Char3 = 'a'; const char g_Char2 = 'B'; //.rodata int g_A = 0; //bss int g_B; //bss int main(void) { uart0_init(); puts( nrg_A = ); printHex(g_A); puts( nr );
[单片机]
Uboot S3C2440 BL1 的流程
1. reset 中断向量表 2. 进入reset (1) 设置svc32 模式 (2) flash I/D caches (3)disable MMU 和 cache (4)2440 没有onenand (5)bl lowlevel_init 接 (5) 1.初始化时钟 2. 初始化UART,串口 3.nandflash 简单初始化 4. 判断当前uboot 是否运行在内存中,如果不是则进行内存初始化 返回 (5)后面 跳过宏定义 从NandFlash 中拷贝bootloader到内存中 设置堆栈,为C语言做准备 清除BSS段 ub
[单片机]
S3C2440触摸屏驱动实例开发讲解
一、开发环境 主 机:VMWare--Fedora 9 开发板:Mini2440--64MB Nand, Kernel:2.6.30.4 编译器:arm-linux-gcc-4.3.2 二、前提知识 1、Linux输入子系统(Input Subsystem): 在Linux中,输入子系统是由输入子系统设备驱动层、输入子系统核心层(Input Core)和输入子系统事件处理层(Event Handler)组成。其中设备驱动层提供对硬件各寄存器的读写访问和将底层硬件对用户输入访问的响应转换为标准的输入事件,再通过核心层提交给事件处理 层;而核心层对下提供了设备驱动层的编程接口,对上又提供了事件处理层的编程接口;而事件处理层
[单片机]
<font color='red'>S3C2440</font>触摸屏驱动实例开发讲解
给ARM9(S3C2440)添加驱动的三种方法
(这里我就以beep驱动为例子) 方式一:动态添加(不推荐) 先下载或者找到驱动,一个是.c文件另一个是Makefile(注意makefile里面的命令是要修改的,参考下面的改),将两个文件储存到一个文件夹下,然后make编译,将.ko文件复制到开发板的S3C2440_recover_nogui 的home文件下使用命令insmod+drivername.ko(注释:insmod是指载入模块),利用命令lsmod查看。完毕。 方式二: 先将驱动的.c文件拷贝到/utu-Linux2.6.24_for_utu2440_2009-07-18/drivers/char目录下然后再此目录下的中的Makefile文件中添加 Obj –m
[单片机]
给ARM9(<font color='red'>S3C2440</font>)添加驱动的三种<font color='red'>方法</font>
S3C2440 开发板实战(2):start.S初认识 + SDRAM配置 + 重定位
1、看门狗部分 废话不多说,直接开始配置,首先就是要关闭暂时不使用的看门狗,找到看门狗的寄存器:WTCON,将其第0位置0,即禁用看门狗,即: # define pWTCON 0x53000000 //WTCON地址 ldr r0, =pWTCON mov r1, #0x0 str r1, //关闭看门狗 2、时钟部分 在S3C2440中有三种时钟频率,分别为FCLK, HCLK, PCLK,分别控制不同种类的外设,在时钟树中可以进行查找,这里不做过多赘述,在以后的博客中有应用。 从芯片手册中查找FCLK, HCLK, PCLK 的最高频率,在范围内我们选择设置FCLK = 400MHZ, H
[单片机]
<font color='red'>S3C2440</font> 开发板实战(2):start.S初认识 + SDRAM配置 + 重定位
S3C2440 裸机程序之音频
/**************************************************************** NAME: u2440mon.c DESC: u2440mon entry point,menu,download HISTORY: Mar.25.2002:purnnamu: S3C2400X profile.c is ported for S3C2410X. Mar.27.2002:purnnamu: DMA is enabled. Apr.01.2002:purnnamu: isDownloadReady flag is added. Apr.10.2002:purnnamu: - Select
[单片机]
MSP430F169 Timer_A原理(二)------Timer_A捕获模式
** 捕获模式 ** CAP = 1 时选择捕获模式。捕获模式用于记录时间事件。它可用于速度计算或时间测量。捕获输入 CCIxA 和 CCIxB 连接到外部引脚或内部信号,并通过 CCISx 位进行选择。 CMx 位选择输入信号的捕捉沿为上升沿、下降沿或两者兼有。捕获发生在输入信号的选定边沿。如果发生捕捉: 定时器值被复制到 TACCRx 寄存器中 中断标志 CCIFG 置位 输入信号电平可以随时通过 CCI 位读取。 MSP430x1xx 系列器件可能有不同的信号连接到 CCIxA 和 CCIxB。有关这些信号的连接,请参阅特定于器件的数据表。 捕获信号可能与定时器时钟异步并导致竞争条件。设置 SCS 位将使捕获
[单片机]
MSP430F169 <font color='red'>Timer</font>_A原理(二)------<font color='red'>Timer</font>_A捕获模式
工程师笔记|使用 TIMER 输出比较模式输出相移信号
1、前言 客户想要使用 STM32L031 产生两个特定的 PWM 波,这两个波形频率相同,占空比相同,但相位不同。经过验证,使用定时器的输出比较模式可以产生这种带相移的 PWM 波形。 下面以 STM32L031 的 TIM2 为例来介绍使用产生相移信号的方法。 2、概述 在未使能预装载寄存器时(OCxPE=0),使用输出比较模式,可以随时通过软件更新 TIM_CCRx 寄存器的值,以控制输出波形。 DMA 的循环模式,可以在最后一次数据传输完成后,自动重新加载初始编程值,内部地址寄存器会重新加载基址值,进入下一个循环。 使用输出比较模式配合 DMA 的循环模式可以不断更新 TIMx_CCR 寄存器的值,从而输出可控的波形。
[单片机]
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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