ZigBee2-2定时器
定时器定时/计数器的基本原理
定时/计数器,是一种能够对内部时钟信号或外部输入信号进行计数,当计数值达到设定要求时向CPU提出中断处理请求,从而实现定时或者计数功能的外设。
定时/计数器的最基本工作原理是进行计数。不管是定时器还是计数器,本质上都是计数器,可以进行加1(减1)计数,每出现一个计数信号,计数展就会自动加1(自动减1)当计数值从0变成最大值(或从最大值变成0)溢出时,定时/计数器就会向CPU提出中断请求。
CC2530的定时/计数器
CC2530共有5个定时/计数器,其中定时器1是一个16位的定时器,为CC2530中功能最全的一个定时/计数器在应用中应优先选用。定时器1的工作模式有三种:
- 自由运行模式:计数器从000000开始,在每个活动时钟边沿增加1,当计数器达到 0xFFFF时道出,计数路重新载入0x0000并开始新一轮的递增计数。该模式的计数周期是因定值0xFFFF,当达到最终计数值0xFFFF时,标志位T1IF和OVFIF被设置。
- 模模式:计数器从0x0000开始,在每个活动时钟边沿增加1,当计数器达到T1CC0寄存器保存的值时溢出,计数器又将从0x0000开始新一轮的递增计数,模模式的计数周期可由用户自行设定。
- 正计数/倒计数模式:计数器反复从0x0000开始,正计数到TICC0保存的最终计数值,
然后再倒计数回0x0000当达到最终计数值时,标志位T1IF和OVFIF被设置。
CC2530的定时/计数器中断系统
定时器有3种情况能产生中断请求:
- 计数器达到最终计数值(溢出或回到零)
- 输入捕获事件。
- 输出比较事件(模模式时使用)
使用模模式要特别注意,需要开启通道0的输出比较模式,否则计数器的值达到T1CCO后,是不会产生溢出中断的。
定时器T1
1)设置定时器1的最大计数值
定时器1共有5对T1CCxH和T1CCxL寄存器,分别对应通道0到通道4。在使用定时器1的定时功能时,使用T1CCOH和T1CC0L两个寄存器存放最大计数值的高8位和低8位。
最大计数值=定时时长/定时器计数周期。如果我们要定时100ms怎么算呢?
系统在不配置工作频率时默认为2分频,即32M/2=16M,系统时钟为16MHz,分频系数为128要定时01秒,最大计数值为:
系统时钟为16MHz时,16位定时器每次溢出的值是65536,溢出时间可以按此么 T=1/(16M/128)*65536=0.524s
- CC2530的T1定时器(16位)需要配置三个寄存器T1CTL、T1STAT、IRCON。
寄存器 | 作用 | 描述 |
---|---|---|
T1CTL (0xE4) | 定时器1的控制和状态 | T1CTL(Bit 3:2) 分频器划分值,如下: 00:标记频率/1 01: 标记频率/8 10:标记频率/32 11:标记频率/128 TICTL(Bit1:0)选择定时器1模式: 00: 暂停运行。 01:自由运行,从0x0000到0xFFFF反复计数。 10: 模,从0x0000到T1CCO反复计数。 11:正计数/倒计数,从0x0000到T1CC0反复计数并且从T1CCO 倒计数到0x0000。 |
T1STAT (0xAF) | 定时器1的状态 | Bit5: 定时器计数器溢出中断标志 Bit4:定时器1通道4中断标志 Bit3:定时器1通道3中断标志 Bit2:定时器1通道2中断标志 Bit1: 定时器1通道1中断标志 Bit0:定时器1通道0中断标志 |
IRCON (0xC0) | 中断标志4 | Bit1: 定时器1中断标志。当定时器1中断发生时设为1 并且当CPU向量指向中断服务例程时清除。 0:无中断未决 1: 中断未决 |
例 定时器T1-查询方式
按照表格寄存器的内容,对Led1和T1进行配置。 Led1配置如下:
P1SEL &=0x01;//配置P1.0为通用I0口
PIDIR=0x01;//配置P1.0为输出
T1配置如下:
T1CTL=0x0d;//128分频,自动重装0x0000-0xFFFF
T1STAT=0x21;//通道0中断有效
源码分析
知识点:系统在不配置工作频率时默认为2分频,即32M/2=16M,所以定时器每次溢出时T=1/(16M/128*65536=0.524s
/****************************************************************************
* 文 件 名: main.c
* 作 者: Andy
* 修 订: 2013-01-08
* 版 本: 1.0
* 描 述: 定时器T1通过查询方式控制LED1周期性闪烁
****************************************************************************/
#include <ioCC2530.h>
typedef unsigned char uchar;
typedef unsigned int uint;
#define LED1 P1_0 // P1.0口控制LED1
/****************************************************************************
* 名 称: InitLed()
* 功 能: 设置LED灯相应的IO口
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitLed(void)
{
P1DIR |= 0x01; //P1.0定义为输出
LED1 = 1; //使LED1灯上电默认为熄灭
}
/****************************************************************************
* 名 称: InitT1()
* 功 能: 定时器初始化,系统不配置工作时钟时默认是2分频,即16MHz
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitT1()
{
T1CTL = 0x0d; //128分频,自动重装 0x0000-0xFFFF
T1STAT= 0x21; //通道0,中断有效
}
/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{
uchar count=0;
InitLed(); //调用初始化函数
InitT1();
while(1)
{
if(IRCON > 0)
{
IRCON=0;
if(count++ >= 1) //约1s周期性闪烁,示波器测大约为1025MS
{
count=0;
LED1 = !LED1; //LED1闪烁
}
}
}
}
定时器T3
系统在不配置工作频率时默认为2分频,即32M/2=16M,系统时钟为16MHz,分频系数为 128要定时01秒,最大计数值为:
要定时500ms则12500*5=62500
相关寄存器:CC2530定时器T3
例:定时器T3-中断方式
按照表格寄存器的内容,对T3进行配置,由于定时器T3为8位所以配置稍有不同。
T3CTL|= 0x08; //开溢出中断
T3IE=1; //开总中断和 T3中断
T3CTL|=0xE0; //128分频128/16000000*N=0.5SN=62500
T3CTL &= ~0x03; //自动重装00->0xff62500/255=245(次)
T3CTL= 0x10; //启动
EA=1; //开总中断
源码分析:
/****************************************************************************
* 文 件 名: main.c
* 作 者: Andy
* 修 订: 2013-01-08
* 版 本: 1.0
* 描 述: 定时器T3通过中断方式控制LED1周期性闪烁
****************************************************************************/
#include <ioCC2530.h>
typedef unsigned char uchar;
typedef unsigned int uint;
#define LED1 P1_0 // P1.0口控制LED1
uint count; //用于定时器计数
/****************************************************************************
* 名 称: InitLed()
* 功 能: 设置LED灯相应的IO口
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitLed(void)
{
P1DIR |= 0x01; //P1.0定义为输出
LED1 = 1; //使LED1灯上电默认为熄灭
}
/****************************************************************************
* 名 称: InitT3()
* 功 能: 定时器初始化,系统不配置工作时钟时默认是2分频,即16MHz
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
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; //开总中断
}
//定时器T3中断处理函数
#pragma vector = T3_VECTOR
__interrupt void T3_ISR(void)
{
IRCON = 0x00; //清中断标志, 也可由硬件自动完成
if(count++ > 244) //245次中断后LED取反,闪烁一轮(约为0.5 秒时间)
{ //经过示波器测量确保精确
count = 0; //计数清零
LED1 = ~LED1; //改变LED1的状态
}
}
/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{
InitLed(); //设置LED灯相应的IO口
InitT3(); //设置T3相应的寄存器
while(1)
{};
}