第二部分 基础篇-第4章 定时器-CC2530中断方式使用定时器T3
程序员文章站
2022-06-11 18:43:55
...
1 理论分析
CC2530 为这两个定时器各分配了一个中断向量。当以下定时器事件之一发生时,将产生一个中断请求:
计数器达到最终计数值
比较事件
捕获事件
SFR 寄存器 TIMIF 包含定时器 3 和定时器 4 的所有中断标志。寄存器位 TIMIF.TxOVFIF 和 TIMIF.TxCHnIF 分别包含 2 个最终计数值事件,以及四个通道捕获/比较事件的中断标志。仅当设置了相应的中断屏蔽位时,才会产生一个中断请求。如果有其它未决的中断,必须通过 CPU,在一个新的中断请求产生之前,清除相应的中断标志。而且,如果设置了相应的中断标志,使能一个中断屏蔽位将产生一个新的中断请求。
2 实验详解
2.1实验目的
1)、进一步了解 CC2530 定时器 3;
2)、握定时器T3(8位)通过中断方式控制LED1周期性闪烁
2.2实验设备
硬件:PC 机一台 ZB2530(底板、核心板、仿真器、USB 线) 一套
软件:2000/XP/win7 系统,IAR 8.10 集成开发环境
2.3实验相关电路图
2.4实验分析
CC2530的T3定时器(8位)需要了解T3CTL、T3CCTL0、T3CC0、T3CCTL1、T3CC1、IEN1寄存器。 如表所示:
按照表格寄存器的内容,对T3 进行配置,由于定时器T3 为8 位所以配置稍有不同。
T3CTL |= 0x08 ; //开溢出中断
T3IE = 1; //开总中断和T3 中断
T3CTL |= 0xE0; //128 分频,128/16000000*N=0.5S,N=62500
T3CTL &= ~0x03; //自动重装00->0xff 62500/255=245(次)
T3CTL |= 0x10; //启动
EA = 1; //开总中断
注意:
(1)T3CTL &= ~0X03; 这条语句理解为:0X03=0000 0011,则 ~0X03=1111 1100;所以当执行 T3CTL &= ~0X03 后,T3CTL 其它位保持不变,D0、D1 变为 0。
(2)由于是 128 分频,则计一次数需要时间 t=128/16000000, 如果我们希望得到一个 0.5s的延时,那么 128/16000000*N=0.5S,就得计 N=65200 次数。而我们又将 Timer3 设置为自动重装 0x00—0xFF,即产生一次溢出中断计数 256 次,而我们现在是想它计算65200 次,所以,我们要累加 254 次溢出中断才让 LED1 取反。
2.5参考源码
/**Includes*********************************************************************/
#include <ioCC2530.h>
/**宏定义***********************************************************************/
//定义数据类型
typedef unsigned char uchar;
typedef unsigned int uint;
//定义控制灯的端口
#define LED1 P1_0 // P1.0口控制LED1
/**函数声明*********************************************************************/
void InitLed(void); //初始化 LED 控制 IO 口函数
void InitT3(); //定时器初始化
/**全局变量*********************************************************************/
uint count; //用于定时器计数
/**
* @brief 中断处理函数
* @param None
* @retval None
*/
//定时器T3中断处理函数
#pragma vector = T3_VECTOR
__interrupt void T3_ISR(void)
{
IRCON = 0x00; //清中断标志, 也可由硬件自动完成
if(count++ > 245) //245次中断后LED取反,闪烁一轮(约为0.5 秒时间)
{ //经过示波器测量确保精确
count = 0; //计数清零
LED1 = ~LED1; //改变LED1的状态
}
}
/**
* @brief 主函数
* @param None
* @retval None
*/
void main(void)
{
InitLed(); //设置LED灯相应的IO口
InitT3(); //设置T3相应的寄存器
while(1)
{};
}
/**
* @brief 设置LED灯相应的IO口
* @param None
* @retval None
*/
void InitLed(void)
{
P1DIR |= 0x01; //P1.0定义为输出
LED1 = 1; //使LED1灯上电默认为熄灭
}
/**
* @brief 定时器初始化,系统不配置工作时钟时默认是2分频,即16MHz
* @param None
* @retval None
*/
void InitT3()
{
T3CTL |= 0x08 ; //开溢出中断
T3IE = 1; //开总中断和T3中断
T3CTL |= 0xE0; //128分频,128/16000000*N=0.5S,N=62500
T3CTL &= ~0x03; //自动重装 00->0xff 62500/255=245(次)
T3CTL |= 0x10; //启动
EA = 1; //开总中断
}
2.6实验现象
当把程序下到开发板后,请观察D1 灯闪烁的情况,如果有LCD,请同时注意LCD 上D1 灯的状态显示。
2.7实验总结
通过本实验,大家需要掌握以下 3 点:
CC2530 定时器 3 的中断机制;
CC2530 定时器 3 中断方式使用的控制字如何配置。
CC2530 定时器 3 中断函数的编写:
#pragma vector = 中断向量
__interrupt void 任意函数名(void)
{
//中断处理,处理完成后通常需要清除中断标志
}