zigbee笔记:五、定时器/计数器

一、zigbee定时器基础

1、定时器的概念

        定时/计数器,是一种能够对内部时钟信号外部输入信号进行计数 ,当计数值达到设定要求时向 CPU 提出中断处理请求,从而实现定时或者计数功能的外设。
        定时/计数器的最基本工作原理是进行计数。不管是定时器还是计数器,本质上都是计数器,可以进行加 1(减1)计数,每出现一个计数信号,计数器就会自动加1(自动减1),当计数值从0变成最大值(或从最大值变成 0)溢出时,定时/计数器就会向 CPU 提出中断请求。

2、zigbee的定时器资源介绍(CC2530为例)

        CC2530 共有5 个定时/计数器,其中定时器1是一个 16 位的定时器,其他的为8位定时器(定时器3、4)。定时器的几种工作模式有:

(1)自由运行模式:计数器从0x0000开始,在每个活动 时钟边沿增加1,当计数器达到0xFFFF时溢出,计数器重新载入0x0000并开始新一轮的递增计数。该模式的计数周期是固定值0xFFFF。当达到最终计数值 0xFF(发生了一个溢出),就设置中断标志 TIMIF.TxOVFIF。如果设置了相应的中断屏蔽位 TxCTL.OVFIM,就产生一个中断请求。

(2)模模式:计数器从0x0000开始,在每个活动时钟边沿增加1,当计数器达到T1CC0寄存器设定的值时溢出,计数器又将从0x0000开始新一轮的递增计数, 模模式的计数可以用于周期不是 0xFF 的应用程序 。当发生溢出时,设置标志 TIMIF.TxOVFIF 。如果设置了相应的中断屏蔽位 TxCTL.OVFIM,就产生一个中断请求。

(3) 倒计数模式:在倒计数模式,定时器启动之后,计数器载入 TxCC0 的内容。然后计数器倒计时,直到 0x00。当达到 0x00时,设置标志 TIMIF.TxOVFIF。如果设置了相应的中断屏蔽位 TxCTL.OVFIM,就产生一个中断请求。

(4)正计数/倒计数模式:计数器反复从0x0000 开始,正计数到TICC0保存的最终计数值,然后再倒计数回0x0000。在正计数/倒计数模式,当达到最终计数值时,设置标志IRCON.T1IF 和 T1CTL.OVFIF。如果设置了相应的中断屏蔽位 TIMIF.OVFIM 以及 IEN1.T1EN,将产生一个中断请求。

3、定时中断来源

定时器有3种情况能产生中断请求:

   (1)计数器达到最终计数值(溢出或回到零)

   (2)输入捕获事件

  (2)输出比较事件(模模式时使用)

二、定时器寄存器

1、定时器1

定时器1是一个 16 位的定时器,有5个捕获/比较通道 ,2个备选位置(如下图所示),通过设置PERCFG.T1CFG寄存器选择是否使用备用位置 1 或备用位置 2。

(1)定时器 1 计数器高/低位寄存器( T1CNTH和T1CNTL)

定时器1时时是16位的定时器,可以通过这两个寄存器来读取定时器的当前计数值

(2)定时器 1 的控制和状态寄存器(T1CTL)

控制开启/关闭定时器的使用,对系统提供的时钟频率是否进行分频使用

(3)定时器 1 中断标志寄存器(T1STAT)

当定时器 1使用定时/计数功能时,达到相应的条件,相应的中断标志位会被设置

(4)定时器1 通道0 相关寄存器

定时器1共有5个捕获/引脚比较通道,引通道0为例,余同。定时器1使用通道0可以实现相关计数、比较输出等功能,相关寄存器如下。

(5)定时器1中断开启

(1)设置 IEN0 中的 EA 位为 1 使能全局中断;

(2)设置寄存器IEN1  中对应的中断使能位为 1;

(3)设置 SFR 寄存器中对应的各中断使能位为 1,如果有;

(4)清除中断标志

2、定时器3、4

        定时器3、4寄存器与定时器1大同小异。定时器3、4为8位定时器,但有2个捕获/比较通道 ,2个备选位置,通过设置PERCFG.T3CFG、PERCFG.T4CFG寄存器选择是否使用备用位置 1 或备用位置 2。

        以定时器3寄存器为例:

三、案例

1、使用定时器3定时中断,使得LED灯闪烁

 

#include<iocc2530.h>

#define LED2 P1_1
void initTimerForTiming() ;
void initLED2();

int count = 0;
void main()
{

    initTimerForTiming() ;
    initLED2();
    while(1);


}

//初始化T3定时进行定时
void initTimerForTiming()
{
    T3CTL |= 0xf8; //128分频,开启定时器,使能中断,自由运行模式
    T3IE = 1; //定时器3中断使能
    EA = 1; //总中断开启
    T3IF = 0; //初始化 定时器3中断标志
    T3OVFIF = 0;

}

//初始化LED灯

void initLED2()
{
    // P1SEL &= ~0x02;
    P1DIR |= 0x02;
    LED2 = 1;
}

#pragma vector=T3_VECTOR
__interrupt void T3_interrupt(void)
{
    if(++count == 255)
    {
        count = 0;
        LED2 = !LED2;
    }
    T3OVFIF = 0;//清除中断标志
    T3IF = 0;//清除中断标志

}

2、使用定时器4计数中断,每按键三次使得LED灯亮暗翻转

#include<iocc2530.h>

#define LED2 P1_1
void initLED2();
void initTimerForCount();
void initKey2();

int count = 0;
void main()
{

    initTimerForCount();
    initKey2();
    initLED2();
    count=0;
    while(1);
}


//初始化T4定时器进行计数
void initTimerForCount()
{
    PERCFG |= 0x10 ;//有选用备用通道1
    T4CCTL0 |= 0x01;
    T4CCTL0 |= 0x40;
    T4CC0 = 0; //捕获值清空
    T4IF = 0; //初始化 定时器3中断标志
    T4CH0IF = 0; //定时器4通道0中断标志
    T4IE = 1; //定时器3中断使能
    EA = 1; //总中断开启

}

//初始化LED灯

void initLED2()
{
    P1SEL &= ~0x02;
    P1DIR |= 0x02;
    LED2 = 0;
}

//初始化  P2_0 按键
void initKey2()
{
    P2SEL &= ~0x01;
    P2DIR &= ~0x01;
    P2INP &= ~0x81;
}
//延时函数
void delayms( unsigned int a )  //@16MHz
{
    unsigned char i, j;
    for( int s = 0; s < a; s++ )
    {
        i = 3;
        j = 148;
        do
        {
            while( --j );
        }
        while( --i );
    }
}

#pragma vector=T4_VECTOR
__interrupt void T4_interrupt(void)
{
    if(T4CH0IF == 1)
    {
         delayms(20);
      
        if(++count == 3)
        {
            count = 0;
            LED2 = !LED2;
        }
    }

    T4IF = 0;
    T4CH0IF = 0;
}

  • 27
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值