定时器

在讲定时器之前,我们先提一下晶振的概念:单片机想要正常运行,需要有一个频率,而晶振就是给单片机提供一个时钟频率的器件,时钟频率越快,运行的速度就越快;

cc2530有一个32MHZ的外部晶振,在默认情况下,外部晶振到单片机分频模块就自动2分频,即为16MHZ;16MHZ的含义是每秒产生16M次脉冲,对定时器来说,高电平到低电平就计数一次,当定时器的存储空间计满后就产生中断,将中断标志位(IRCON) 置1,;我们可以通过查询IRCON的方式判断存储空间是否计满,也可以通过执行中断服务函数来实现程序效果;

对于CC2530来说,有高速模块和低速模块,而低速模块可能只需要1MHZ就可以正常工作,这时我们的分频模块就会对频率源进行分频操作,将分频后的频率给模块;

定时器中断的配置方法:

  1. 设置定时器分频方式
  2. 设置定时器技术方式
  3. 开启溢出中断
  4. 开启总中断
  5. 开启定时器中断使能
  6. 启动定时器

下面我们通过程序先来看一下怎样通过查询的方式进行处理:

#include <ioCC2530.h>

//端口定义
#define led P1_0  

/********************************************************
 * function name : LedInit
 * function      : 配置led相关寄存器并设置led初始状态
 * prarmeter     : 无
 * returned value: 无
********************************************************/
void LedInit(void)
{
    P1DIR |= 0X01;  //P1_0设置为输出模式
    P1SEL &= ~0X01; //P1_0设置为通用IO

    led = 1;  //初始状态为熄灭
}

/*******************************************************
 * function name : Timer1Init
 * function      : 配置timer1相关寄存器
 * prarmeter     : 无 
 * returned value: 无
*******************************************************/
void Timer1Init(void)
{
    T1CTL = 0X0D;       //设置定时器1为128分频,计数模式为0X0000~0xFFFF反复计数 
    T1STAT= 0X21;       //设置通道0,中断有效   
}

/***********************************************
 * function name : main
 * function      : 初始化LED和TIMER,实现LED每一秒改变一次状态
 * prarmeter     : 无
 * returned value: 无
************************************************/
void main(void)
{
    LedInit();
    Timer1Init();

    int i = 0;

    while(1)
    {
        //查询方式
        if(IRCON > 0)
        {
            IRCON=0; //清除中断标志位
            if(++i > 1)
            { 
                led = ~led;
                i = 0;  
            }    
        }
    }
}

定时器1寄存器

上图是定时器1的相关寄存器参数配置图,通过程序和数据手册我们可以知道,在此程序中定时器1设置的是128分频,采用从0X0000~0XFFFF的计数模式;由128分频我们可得(16MHZ / 128=131072)每秒产生131072次脉冲,即每秒计数131072次;由从0X0000~0XFFFF的计数模式我们可知,要想产生中断需要计数65535次,两者结合看,我们可以得出,我们一秒可以产生两次中断;

下面我们看看通过中断的方式我们要怎样处理:

#include <ioCC2530.h>

//端口定义
#define led P1_0  

/********************************************************
 * function name : LedInit
 * function      : 配置led相关寄存器并设置led初始状态
 * prarmeter     : 无
 * returned value: 无
********************************************************/
void LedInit(void)
{
    P1DIR |= 0x01;  //P1_0设置为输出模式
    P1SEL &= ~0x01; //P1_0设置为通用IO

    led = 1;  //初始状态为熄灭
}

/*******************************************************
 * function name : TimerInit
 * function      : 配置timer3相关寄存器,实现更改led状态的效果
 * prarmeter     : n_ms 用于设置延时的时间,单位为毫秒
 * returned value: 无
*******************************************************/
unsigned int ms_count = 0;  //计数累加
unsigned int ms_value = 0;  //用于存储延时的时间

void Timer3Init(unsigned int n_ms)
{
    ms_value = n_ms;

    T3CTL |= 0xC0;           //设置定时器为64分频
    T3CTL &= ~0x03;          //设置计数模式为 0X0000~0XFFFF

    T3CTL |= 0x08 ;          //开启溢出中断    
    EA = 1;                  //开启总中断 
    T3IE = 1;                //IEN1的第三位,置1开启定时器3中断使能
    T3CTL |= 0x10;           //启动定时器
}

//中断服务函数,实现效果
#pragma vector = T3_VECTOR 
__interrupt void T3_ISR(void) 
{ 
    ms_count++;  //开始计数

    if(ms_count >= ms_value)  //如果超过所设置的时间则实现效果
    {
        ms_count = 0;  //计数清零
        led = ~led;  //更改led状态
    }   
}

/***********************************************
 * function name : main
 * function      : 初始化LED和TIMER,实现LED每一秒改变一次状态
 * prarmeter     : 无
 * returned value: 无
************************************************/
void main(void)
{
    LedInit();
    Timer3Init(1000);

    while(1)
    {
    }
}

数据手册——T3CTL

相信看完程序你们心里有个疑问,你怎么就知道这样就是延时了1秒呢?这中间又有什么不为人知的秘密嘛?我们来分析一下:

我们之前设置的定时器分频模式是64分频,前面我们也讲了,CC2530外接的是32MHZ的晶振,到单片机内部自动2分频,再64分频后每秒可以产生262144次脉冲,即计时器每秒可以计数262144次,每毫秒可以计数262次;通过0X0000~0XFFFF的计数模式我们可以得出,每秒我们可以将计数空间计满256次;这里我们可以看见262是近似于256的,在毫秒级别,这点误差我们基本可以忽略不计,所以延时效果就是这么来的;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值