定时器1使用总结

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

定时器 1 使用总结——溢出中断
1 目的说明
实现定时器最简单的溢出中断 实现定时器最简单的溢出中断,结合我手头的开发板,使得位于 P10 的 LED 灯, 2HZ ,以 的速度不断闪烁。这样的实验还是非常亲切的 这样的实验还是非常亲切的,让我想起了第一次在 51 上实现了这样的代 码,自己第一次在 CC2430 上实现 上实现,依然非常激动。
2
使用方法概述
需要使用定时器的中断, 需要知道如何操作才可以产生这个中断请求 数据手册中提到 需要知道如何操作才可以产生这个中断请求。 需要两个条件, 第一 IEN1.T1EN 需要置位 第二 TIMIF.OVFIM 需要置位。 需要置位, 代码中使用 modulo、 modulo 模式,使用该模式可以改变定时器溢出的频率 使用该模式可以改变定时器溢出的频率。
3
代码总览
先来看看所有的代码,然后再分 然后再分步解释。 //头文件 #include "hal.h" //函数声明 void Timer1_Init(); //主函数 void main(){ //初始化外部时钟 SET_MAIN_CLOCK_SOURCE(CRYSTAL); //P1_0 输出 IO_DIR_PORT_PIN(1,0,IO_OUT); //初始化定时器 1 Timer1_Init(); while(1){ }

} void Timer1_Init(){ //定时器 1 复位 TIMER1_INIT(); //设定定时器相关参数 //128 分频 0000 1100 T1CTL = 0x0c; //溢出值低 8 位 T1CC0L=0x24; //溢出值高 8 位 T1CC0H=0xF4; //定时器 T1 溢出中断使能 TIMER1_ENABLE_OVERFLOW_INT(TRUE); //定时器 T1 中断使能 INT_ENABLE(INUM_T1,INT_ON); //全局中断使能 INT_GLOBAL_ENABLE(INT_ON); //启动定时器 1 TIMER1_RUN(TRUE); } //定时器 1 中断函数 #pragma vector=T1_VECTOR __interrupt void Timer1_ISR(void) { //检查中断标志位 if(T1CTL & 0x10){ //LED 灯反转 P1_0 = !P1_0; //清中断标志 T1CTL &= ~0x10; } }
4 主函数说明
//初始化外部时钟 SET_MAIN_CLOCK_SOURCE(CRYSTAL); //P1_0 输出

IO_DIR_PORT_PIN(1,0,IO_OUT); //初始化定时器 1 Timer1_Init(); 先指定系统时钟,这是一个好习惯。由于定时器时钟和系统 由于定时器时钟和系统时钟频 操作 CC2430 之前,先指定系统时钟 率有关,所以必须要设定好系统的时钟 所以必须要设定好系统的时钟。在 SET_MAIN_CLOCK_SOURCE()在这个动作宏中 在这个动作宏中, 把系统时钟设定为 32MHz。 该宏前面的文章已经提到,不多做说明) (该宏前面的文章已经提到 请注意定时器的时钟频率 默认为 16MHz,而不是 32MHz。 请注意 CLKCON 的 5:3 位, 该 3 位组成了一个定时器时钟的分频器,该参数决定了定 该参数决定了定 时器的时钟频率。在定时器 1 的相关操作中还有定时器时钟的分频系数设置 那是定时器 1 的相关操作中还有定时器时钟的分频系数设置,那是定时器 特有的,这里的定时器分频参数是分频了定时器 1,3,4 的时钟。相见数据手册或下图 这里的定时器分频参数是分频了定时器 相见数据手册或下图:
为了操作 IO 口,定义 LED 相关的 IO 口为输出。IO_DIR_PORT_PIN()的相关操作如下面的 的相关操作如下面的 代码所示: #define IO_DIR_PORT_PIN(port, pin, dir) \ do { \ if (dir == IO_OUT) \ P##port##DIR |= (0x01<<(pin)); \ else \ P##port##DIR &= ~(0x01<<(pin)); \ }while(0) 该宏操作了 PXDIR 寄存器,定义了 IO 口的方向。 定义了
5 定时器初始化操作
TIMER1_INIT()把定时器 1 的寄存器全部复位 的寄存器全部复位。具体的代码如下: #define TIMER1_INIT() \ do { \ T1CTL = 0x00; \ T1CCTL0 = 0x00; \ T1CCTL1 = 0x00; \ T1CCTL2 = 0x00; \ TIMIF &= ~0x40; \ } while (0) 从这个代码中也可以看出定时器 1 的操作和哪些寄存器有关。 看出定时器 具体的定义可以查看数据 手册,这里不多做说明。
6
设定定时器中断频率
操作代码如下

//128 分频 0000 1100 T1CTL = 0x0c; //溢出值低 8 位 T1CC0L=0x24; //溢出值高 8 位 T1CC0H=0xF4; 由于 CC2430 的运行速度比较快,所以需要对定时器 1 进行分频。由于 T1CTL 在前面的 函数中已经被全部复位,所以可以舒服的操作 T1CTL 寄存器。在这里把系统时钟设定为 128 分频,定时器 T1 的运行速度只有 125K。这个速度对于 0.5 闪烁来说,还是非常快的。 接着设定 T1CC0 寄存器。这个寄存器还是非常特殊的。请注意,T1CC0 在 modulo 模式 和 up-down 模式中,始终作为定时器 T1 计数的最大值。数据手册上说定时器 1 有 3 个比较 匹配中断,其实这个和 AVR 的定时器 1 有的两个比较匹配时一样的,因为 CC2430 没有一个 专用寄存器储存计数的最大值,那么定时器 1 的比较通道 0 就“牺牲”了比较通道的作用。 所以要产生两路频率指定的 PWM 波的时候, T1CC0 作为最大值决定 PWM 的频率, T1CC1 而 和 T1CC2 决定 PWM 的相位。 下面再讲讲计数值的计算方法。我是从分频的角度思考的,写出这个等式: Ftimer/(N*T1CC0) = Fdesi。 其中 Ftimer 为定时器的运行时钟,此处为 16,000,000Hz;N 为分频系数,此处为 128; T1CC0 为定时器的计数值;Fdesi 为期望溢出频率,此处为 2Hz。带入这个等式可以计算出 T1CC0 的值为 62500,写成 16 进制为 F424。如果计算出来的结果大于 65536,那么只能进 一步降低定时器的运行频率,在这里只能调整 Ftimer 了。
7 使能该使能的内容
//定时器 T1 溢出中断使能 TIMER1_ENABLE_OVERFLOW_INT(TRUE); //定时器 T1 中断使能 INT_ENABLE(INUM_T1,INT_ON); //全局中断使能 INT_GLOBAL_ENABLE(INT_ON); 开篇的时候就说了需要操作哪两个寄存器——第一 IEN1.T1EN,第二 TIMIF.OVFIM。操作 时分别使用了以下两个宏。具体的代码如下: #define TIMER1_ENABLE_OVERFLOW_INT(val) \ (TIMIF = (val) ? TIMIF | 0x40 : TIMIF & ~0x40) #define INT_ENABLE(inum, on) \ do { \ if (inum==INUM_RFERR) { RFERRIE = on; } \ else if (inum==INUM_ADC) { ADCIE = on; } \ else if (inum==INUM_URX0) { URX0IE = on; } \ else if (inum==INUM_URX1) { URX1IE = on; } \ else if (inum==INUM_ENC) { ENCIE = on; } \ else if (inum==INUM_ST) { STIE = on; } \ else if (inum==INUM_P2INT) { (on) ? (IEN2 |= 0x02) : (IEN2 &= ~0x02); } \ else if (inum==INUM_UTX0) { (on) ? (IEN2 |= 0x04) : (IEN2 &= ~0x04); } \

相关文档
最新文档