码迷,mamicode.com
首页 > 其他好文 > 详细

CC2530定时器使用

时间:2014-06-03 05:33:07      阅读:845      评论:0      收藏:0      [点我收藏+]

标签:c   style   a   tar   ext   color   



定时器学习

 

目录

说明... 1

协议栈函数使用... 2

设置初始化定时器... 2

回调函数(中断服务函数) 3

启动定时器... 3

停止定时器... 4

寄存器操作... 4

查询方式... 4

中断方式(使用定时器3) 7

 

 

说明

     根据数据手册可知CC2530总共有4个定时器,但是定时器2被系统占用,可用的只有三个,分别为定时器1/3/4

         Timer在协议栈的代码位置为hal_timer.c,hal_timer.h,4个定时器的ID分别为

/* Timer ID definitions */

#define HAL_TIMER_0                0x00    // 8bit timer

#define HAL_TIMER_1                0x01    // 16bit Mac timer

#define HAL_TIMER_2                0x02    // 8bit timer

#define HAL_TIMER_3                0x03    // 16bit timer

#define HAL_TIMER_MAX              4       // Max number of timer

 

 

 

 

 

 

 

 


宏定义中的TIMER_ID并非硬件中的定时器1,而是经过函数halTimerRemap映射,HAL层自定义的timerID映射为硬件的HW TIMER ID

映射的结果为

* @brief  Maps API HAL_TIMER_ID to HW Timer ID.

 *         HAL_TIMER_0 --> HW Timer 3 8bit

 *         HAL_TIMER_2 --> HW Timer 4 8bit

 *         HAL_TIMER_3 --> HW Timer 1 16bit

 

有两个方法达到定时的目的,一个是协议栈函数,一个直接寄存器操作

协议栈函数使用

         OSALmain函数中  HalDriverInit();既有对timer的初始化HalTimerInit();该函数对各个定时器进行了初始化,首先对所有定时器清中断,然后设置时钟和预分频,最后设置定时器的Channel structure.

         如果用户想使用定时器需要自己设置某一个寄存器的变量,并实现相关回调函数,最后调用HalTimerStart来启动定时器.

设置初始化定时器

         函数是uint8HalTimerConfig (uint8 timerId, uint8 opMode, uint8 channel, uint8 channelMode,bool intEnable, halTimerCBack_t cBack)

各个参数的意思

* @param  timerId - Id of the timer

 *         opMode  - Operation mode操作方式共3

 *         channel - Channel where the counter operates on 选择通道,对应IO

 *         channelMode - Mode of that channel 通道的模式

 *         intEnable - 可中断

 *         cBack - Pointer to the callback function 中断函数

示例:

HalTimerConfig(HAL_TIMER_0,HAL_TIMER_MODE_CTC,HAL_TIMER_CHANNEL_SINGLE,HAL_TIMER_CH_MODE_OUTPUT_COMPARE,TRUE,timer_callback);

此处的TimerIDHAL_TIMER_0,但是实际上使用的并非这个,而是经过函数halTimerRemap映射,HAL层自定义的timerID映射为硬件的HW TIMER ID映射的结果为

* @brief  Maps API HAL_TIMER_ID to HW Timer ID.

 *          HAL_TIMER_0 --> HW Timer 3 8bit

 *          HAL_TIMER_2 --> HW Timer 4 8bit

 *          HAL_TIMER_3 --> HW Timer 1 16bit

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

回调函数(中断服务函数)

         示例中的最后一个参数既是回调函数,回调函数可以决定定时的长短,每中断一次本函数被调用一次,如下代码

/*中断服务函数*/

volatile unsigned int n = 0; //一个volatile的全局变量

//确保本条指令不会因编译器的优化而省略,且要求每次直接读值

void timer_callback(uint8 timerId, uint8 channel, uint8 channelMode)

{

    n++;  //每次调用此函数,n1

         if(n ==5000) {  //n加到一个自定义的数值后,就执行相关任务,然后将n清零

                                     //改变这个值即可控制定时的长短

                   /*do something...*/

        HalUARTWrite(0,"20000000000\n",13);  //定时到后执行任务

                   n =0;//重新定时

         }

         /*TODO...*/

    return;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


启动定时器

         重点函数HalTimerStart(uint8 timerId, uint32 timePerTick),参数定义

* @param   timerId      - ID of the timer

 *         timerPerTick - number of micro sec per tick, (ticks x prescale) / clock= usec/tick

 第一个是定时器的ID,第二个未理解,但是数值越小,定时器时间间隔越小.

 

实例:

HalTimerStart (HAL_TIMER_0,65536);

 

 

 

 

 

 

 

 

 

停止定时器

         函数HalTimerStop(uint8 timerId),指定timerID即可停止某一个定时器

实例: HalTimerStop (HAL_TIMER_0)

/*中断服务函数*/

volatile unsigned int n = 0,stop=0;

void timer_callback(uint8 timerId, uint8 channel, uint8 channelMode)

{

         n++;

         if(n == 5000) {

        HalUARTWrite(0,"20000000000\n",13);

        LED1 = ~LED1;

        stop++;

        if(stop == 10)  //将会在led灯闪烁5次之后关闭定时器

            HalTimerStop(HAL_TIMER_0); 

                   n =0;

         }

    return;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


寄存器操作

本段参考网蜂团队的第二章基础实验2.4定时器

分为两种方式:查询模式,中断模式,相比查询模式中断模式更节省cpu资源,效率更高!

 

查询方式

CC2530 T1 定时器 16 位) 我们需要配置三个寄存器 T1CTL T1STATIRCONIO 口配置请留意第一节教程内容。各寄存器功能如下表所示:(详细参考 CC2530 datasheet.pdf

T1CTL(0XE4) Timer1  控制寄存器:

Bit3:Bit2 : 定时器时钟分频倍数选择:

00:不分频  018分频  10 32分频  11128分频

Bit1:Bit0 :   定时器模式选择:

00  暂停

01  自动重装  0X0000-0XFFFF

10  比较计数  0X0000-T1CC0 

11  PWM  方式

T1STAT(0XAF) Timer1  状态寄存器:

Bit5:  OVFIF  定时器溢出中断标志,在计数器达到计数终值时置位 1.

Bit4:   定时器  1  通道 4  中断标志位

Bit3:   定时器  1  通道 3  中断标志位

Bit2:   定时器  1  通道 2  中断标志位

Bit1:   定时器  1  通道 1  中断标志位

Bit0:   定时器  1  通道 0  中断标志位

IRCON(0XC0)  中断标志位寄存器,只要轮询此标志位即可

 

实现代码

/**************************************

程序描述:通过定时器 T1 查询方式控制

LED1 周期性闪烁

**************************************/

#include <ioCC2530.h>

#define uint unsigned int

#define uchar unsigned char

//定义控制 LED 灯的端口

#define LED1 P1_0      //定义 LED1 P10 口控制

//函数声明

void Delayms(uint xms);    //延时函数

void InitLed(void);        //初始化 P1

void InitT1();              //初始化定时器 T1

 

/****************************

//延时函数

*****************************/

void Delayms(uint xms)     //i=xms  即延时 i 毫秒

{

uint I,j;

for(i=xms;i>0;i--)

for(j=587;j>0;j--);

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

/***************************

主函数

***************************/

void main(void)

{

uchar count;

InitLed();         //调用初始化函数

InitT1();                  //初始化定时器

while(1)                  //轮询查看IRCON寄存器的状态

{

if(IRCON>0)  //查询方式

{

IRCON=0;

if(++count==1)          // 1s 周期性闪烁

{

count=0;

LED1 = !LED1;          //LED1 闪烁

}

}

}

/****************************

//初始化程序

*****************************/

void InitLed(void)

{

P1DIR |= 0x01;     //P1_0 定义为输出

LED1 = 1;          //LED1 灯初  始化熄灭

}

//定时器初始化

void InitT1()  //系统不配置工作时钟时使用内部 RC 振荡器,即16MHz

{

T1CTL = 0x0d;    //128 分频,自动重装  0X0000-0XFFFF

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


重点:系统在不配置工作频率时默认为 2 分频,即 32M/2=16M,所以定时

器每次溢出时 T=1/(16M/128)*655360.5s,  所以总时间Ta=T*count=0.5*1=0.5S

切换 1 次状态。所以看起来是 1S 闪烁 1 次。

 

中断方式(使用定时器3)

CC2530 T3 定时器主要是配置三个寄存T3CTL,T3CCTL0,T3CC0,T3CCTL1,T3CC1

T3CTL(0XCB)  Timer3  控制寄存器:

Bit7:Bit5 :   定时器时钟分频倍数选择:

000:不分频,0012分频,0104分频, 0118分频,10016分频,10132分频,11064分频,111:128 分频

Bit4 :   T3  起止控制位

Bit3 :   溢出中断掩码  0:关溢出中断  1:开溢出中断

Bit2 :   清计数值  高电平有效

Bit1:Bit0: T3 模式选择

00:自动重装  0X00-0XFF 

01  DOWN ( T3CC0  0X00 计数一次)

10  模计数(反复从  0X00 T3CC0  计数)

11  UP/DOWN(反复从 0X00 T3CC0  计数再到 0X00)

T3CCTL0(0XCC)  T3    通道 0  捕获/  比较控制寄存器:

Bit6:  T3 通道  0  中断掩码  0:关中断  1:开中断

Bit5: Bit3   T3  通道 0  比较输出模式选择

Bit2: T3 通道 0  模式选择:  0:捕获  1  :比较

Bit1: Bit0:     T3 通道 0  捕获模式选择

00   没有捕获  01     上升沿捕获

10  下降沿捕获      11     边沿捕获

T3CC0(0XCD)  T3 通道 0   捕获/  比较值寄存器

T3CCTL1(0XCE)  T3  通道 1  捕获/  比较控制寄存器:

Bit6:  T3 通道1  中断掩码  0:关中断  1:开中断

Bit5: Bit3   T3  通道 1  比较输出模式选择

Bit2: T3 通道 1  模式选择:  0:捕获  1  :比较

Bit1: Bit0:     T3 通道 1  捕获模式选择

00   没有捕获  01     上升沿捕获

10  下降沿捕获  11     边沿捕获

T3CC1(0XCF)    T3 通道 1   捕获/  比较值寄存器

 

上例 T1 定时器查询方式的区别就是此处使用 T3 定时器(8 位),中断方式。寄存器配置如下:

T3CTL |= 0x08 ;   //开溢出中断

T3IE  = 1;   //开总中断和 T3 中断

T3CTL |=0XE0;    //128 分频,128/16000000*N=0.5S,N=65200

T3CTL &= ~0X03;       //自动重装 00>0xff65200/256=254()

T3CTL |=0X10;    //启动

EA = 1;  //开总中断

 

 

代码实现

//定时器初始化

void InitT3()

{  

T3CTL |= 0x08 ;    //开溢出中断

T3IE = 1;    //开总中断和 T3 中断

T3CTL|=0XE0;    //128 分频,128/16000000*N=0.5S,N=65200

T3CTL &= ~0X03;    //自动重装 00>0xff   65200/256=254()

T3CTL |=0X10;    //启动

EA = 1;     //开总中断

}

 

 

 

 

 

 

 

 

 

 

 

 


中断函数

/************************************

中断函数

************************************/

#pragma vector = T3_VECTOR     //定时器 T3

__interrupt void T3_ISR(void)

{

IRCON = 0x00;    //清中断标志, 也可由硬件自动完成

if(++count>254)   //254 次中断后 LED 取反,闪烁一轮(约为 0.5 秒时间)

{

count = 0;   // 计数清零 

LED1=~LED1; //led闪烁

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Main函数

/***************************

//主函数

***************************/

void main(void)

{

InitLed();       //调用初始化函数

InitT3();

while(1){ }

}

 

 

 

 

 

 

CC2530定时器使用,布布扣,bubuko.com

CC2530定时器使用

标签:c   style   a   tar   ext   color   

原文地址:http://blog.csdn.net/jk110333/article/details/27552497

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!