zigbee菜鸟笔记(六)定时器-自由模式

一.定时器

(一)定时器概念

定时器是一种能够对时钟信号或外部输入信号进行计数,当计数值达到设定要求时便向CPU提出处理请求,从而实现定时或计数功能的外设。在单片机中,一般使用Timer表示定时计数器。

(二)定时器的作用
定时器的基本功能是实现定时和计数,且在整个工作过程中不需要CPU进行过多参与,它的出现将CPU从相关任务中解放出来,提高了CPU的使用效率。例,例如在前面我们在main 函数中进行delay的延时,在延时期间就不能够执行其他的功能,delay是通过cpu循环进行的延时,如果我们使用定时器,那么将不需要占用cpu的资源。

(三)定时器的原理
无论使用定时器的哪种功能,其最基本的工作原理是进行计数。定时器的核心是一个计数器,可以进行加1(或减1)计数,每出现一个计数信号,计数器就自动加1(或自动减1),当计数值从最大值变成0(或从0变成最大值)溢出时定时/计数器便向CPU提出中断请求。计数信号的来源可选择周期性的内部时钟信号(如定时功能)或非周期性的外界输入信号(如计数功能),在这里我们需要回忆前面的时钟概念,因为这里的技术器就和我们的主时钟源有着密切的关系。(详情见下)

二.CC2530的定时器

(一) CC2530共有5个定时/计数器,分别是定时器1、定时器2、定时器3、定时器4和睡眠定时器.其中定时器1是一个16位的定时器,为CC2530中功能最全的一个定时器,在 应用中应优先选用。定时器1的工作模式有三种:

1. 自由运行模式:计数器从0x0000开始,在每个活动 时钟边沿增加1,当计数器达到0xFFFF时溢出,计数器重新载入0x0000并开始新一轮的递增计数。该模式的计数周期是固定值0xFFFF,当达到最终计数 值0xFFFF时,标志位T1IF和OVFIF被设置。

zigbee菜鸟笔记(六)定时器-自由模式_第1张图片

2.模模式:计数器从0x0000开始,在每个活动时钟边 沿增加1,当计数器达到T1CC0寄存器保存的值时 溢出,计数器又将从0x0000开始新一轮的递增计数, 模模式的计数周期可由用户自行设定。

zigbee菜鸟笔记(六)定时器-自由模式_第2张图片

3. 正计数/倒计数模式:计数器反复从0x0000 开始,正计数到TICC0保存的最终计数值,然后再倒计数回0x0000,当达到最终计数值时,标志位T1IF和OVFIF被设置。

zigbee菜鸟笔记(六)定时器-自由模式_第3张图片
总结:由以上三种模式的比较可以得出:自由运行模式的溢出值为 0xFFFF不可变;而其他两种模式则通过对 T1CC0赋值,以精确控制定时器的溢出值。

三.cc2530的中断

(一)中断的概念

中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。

(二)定时器中断的来源

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

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

  2. 输入捕获事件。

  3. 输出比较事件(模模式时使用)。

使用模模式要特别注意,需要开启通道0的输出比较模式,否则计数器的 值达到T1CC0后,是不会产生溢出中断的。

(三)中断函数格式介绍

#pragma vector = <中断向量>
__interrupt void <函数名称>(void){

//在这里写中断要执行的内容

}
/*
<1> 在每一个中断服务函数之前,都要加上一句起始语句:
#pragma vector = <中断向量>
__interrupt关键字表示该函数是一个中断服务函数,<函数名称>可以 自定义,函数体不能带有参数,也不能有返回值。
*/

四.定时器寄存器以及时常计算

寄存器

(一)T1CTL:定时器1的控制寄存器。D1、D0控制运行模式;D3、D2设置分频值。
zigbee菜鸟笔记(六)定时器-自由模式_第4张图片

(二)T1STAT:定时器1的状态寄存器,D4-D0位通道4到通道0的中断标志,D5为溢出标志,当到达最终值自动置1;

在这里插入图片描述

(三)IRCON:中断标志寄存器;0为无中断请求,1为有中断请求。

在这里插入图片描述

(四)IEN1:中断允许寄存器1

在这里插入图片描述

时长计算

这里假设定时器 1s,外部时钟16M 32分频 自由模式

在这里我们是计划定时一秒 那么计数器要计多少次呢?在这里我们定义计数器次数为为number

number = 1s/(32/16000000) = 500000 //这里设计频率转换的问题不会的话留言后期加入教程

在这里我们计数器需要计数 500000 在前面我们知道 在前面我们知道自由模式需要计数器计数到 0xFFFF(65535)次才溢出一次也就是进入一次中断(中断来源第一点),那么我们让进入中断为count

count = 500000/65536 = 7.6 也就是进入中断七次 我们可以通过判断进入七次 来判断一秒的时间

定时器代码区

  T1CTL = 0x09  //0000 1001 32分频,自由模式

代码实战区

要求:使用用外部8M时钟,自由模式 定时2s,分频32分频进入中断LED闪烁`

#include "iocc2530.h"
#define D3 P1_0
#define D4 P1_1
#define D5 P1_3
#define D6 P1_4
//如有疑问请发邮件至[email protected]
unsigned int counter = 0;

void io_INIT(){

  P1SEL &= ~0x1B;
  P1DIR |= 0x1B;
  P1 &= ~0x1B;
  
}

void CLOCK_TIMER(){  使用外部8M时钟,定时2s,分频32分频
  
  CLKCONCMD &= ~0xFD; //0000 0010置零
  CLKCONCMD |= 0x02;
  while((CLKCONSTA & 0x02) == 0);
  T1CTL = 0x09;
  IEN1 |= 0x02;        //定时器中断
  EA = 1;              //这个为中断总开关
  
}

void main(){
  io_INIT();
  CLOCK_TIMER();
  while(1){
  
  }

}
#pragma vector = T1_VECTOR
__interrupt void T1_ISR(void){
  
  EA = 0;    
  counter++;
  if(counter == 8){
  counter = 0;
  P1 = ~P1;
  }
  T1IF = 0;
  EA = 1;

}

余呆呆的java基础欢迎点击

你可能感兴趣的:(菜鸟自学zigbee,zigbee入门,zigbee,物联网,zigbee)