您现在的位置: 电玩巴士 >> GBA >> 掌机学院 >> 掌机开发 >> 文章正文

GBA探索日记(六):Timer

这一节也是将来实现声音播放的基础部分.这一部分的东西十分简单,不过后一节关于中断的部分就有点困难,我们只需要知道怎么用就可以了,所以这一节总体是十分简单的.

 

首先我要自我介绍一下.写了这么多日记,大家可能还不知道我是谁.

我叫tangl_99,email:tangl_99@sohu.com,QQ:8664220(Min-Kyeong)

如果你在做GBA过程中有什么问题,可以联系我,我会尽可能地帮助你(只要你不是日本人).

 

 

GBA中的计时器有4个.就是Timer0,Timer1,Timer2,Timer3.

也是很简单地通过读写寄存器就可以实现对它们的使用了.你可以对它们任意使用.不过需要提醒的是Timer0,Timer1通常用来控制声音播放的速度.

每个Timer有两个寄存器来实现使用和控制.

我们先来看看Timer的计数器寄存器.

TMXD就是TimerX的计数器的寄存器.它们都是16位的寄存器,从Address可以看到它们的总线地址,从Attributes可以看出它们都是可读可写的寄存器.

很奇怪的第一点,在官方开发包里对应它们的定义的名字却不是TMXD,而是REG_TMXCNT_L,比如看看Timer0的计数器的定义.

#define REG_TM0CNT_L    (REG_BASE + 0x100)

 

有了计数器,你通过对它的读写,就可以知道现在时间走了多少.

 

然后我们来看看Timer的属性设置寄存器

TMXCNT就是TimerX的属性寄存器.它们的属性很简单,我们大致来看看吧.

 

7位的Timer Operation Flag就是Timer的开关.

如果设置成0,就是关于这个Timer;如果设置成1,就是开始使用这个Timer.

 

6位是Timer中断的开关.

Timer的中断是当Timer的计数器产生一个溢出,就产生一个中断.溢出简单地说就是前面的Timer的计数器的值超过了最大值(0xFFFF).至于如何编写中断服务程序我将在后面说使用的方法.

 

2位是Count-up Timing表明是否需要使用Prescalar Selection的协调

设置成0,表示使用后面的Prescalar Selection.

设置成1的时候我就不知道是什么意思了,我也从来没有用过,如果你有兴趣,你可以研究一下.AgbLib中这么描述它的.

With a setting of 0, count-up is performed in accordance with the prescalar specification in [d01-00]. With a setting of 1, overflow of the timer channel one number lower starts a count-up regardless of the prescalar specification.

This mode is suitable for purposes such as time measurement over relatively long periods.

The count-up timing specification is disabled for Timer 0, which counts up in accordance with the prescalar specification

我们一般都不管它,一般都设置0,使用.

不过对于Timer0这个选项是无效的.

 

0,1位是Prescalar Selection,就是Timer的时间标准.

所有的Prescalar都是以GBA的16.78MHz的CPU时钟频率为基础

Setting       Prescalar (Count-Up Interval) 

00            System clock   (59.595 ns) 

01            64 cycles of system clock   ( 3.814 us) 

10            256 cycles of system clock  (15.256 us) 

11            1024 cycles of system clock  (61.025 us) 

其中ns是1/10^9秒,us是1/10^6秒.

可以说都是很快的了.

比如我把它设置成11,那么每61.025 us,Timer的计数器就自加1.同理设置成10那么就是15.256 us,Timer的计数器就自加1.

 

 

好了,我们来看看一个例子,写个延时的函数(相当于Windows里的Sleep函数)

#define REG_TM0CNT      (REG_BASE + 0x100)  // Timer 0

#define REG_TM0CNT_L    (REG_BASE + 0x100)

#define REG_TM0CNT_H    (REG_BASE + 0x102)

#define REG_TM1CNT      (REG_BASE + 0x104)  // Timer 1

#define REG_TM1CNT_L    (REG_BASE + 0x104)

#define REG_TM1CNT_H    (REG_BASE + 0x106)

#define REG_TM2CNT      (REG_BASE + 0x108)  // Timer 2

[1] [2] 下一页

相关文章:
【编辑:admin】  【文章来源:tangl_99 金点时空】  【更新时间:2004-12-31 4:05:10】
巴士全站中的精华
24小时热点推荐
我们向您隆重推荐的内容