阅读 81

CC2530(zigbee)入门开发: 定时器使用实例

第一章 定时器技术与CC2530时钟源介绍

1. 定时器技术

定时器在单片机里也是属于基本必备功能,非常常用;程序设计里,很多地方都需要使用到时间的概念,比如:使用定时器做一些轮询检测、精准的延时函数、串口断帧检测、定时器发送、提供心跳包等等。

定时器在CPU内部的实现原理:

定时/计数器,是一种能够对内部时钟信号或外部输入信号进行计数,当计数值达到设定要求时,向CPU提出中断处理请求,从而实现定时或者计数功能的外设。

定时/计数器的最基本工作原理是进行计数。不管是定时器还是计数器,本质上都是计数器,可以进行加1(减1)计数,每出现一个计数信号,计数器就会自动加1(自动减1),当计数值从0变成最大值(或从最大值变成0)溢出时,定时/计数器就会向CPU提出中断请求。

CC2530共有5个定时/计数器,其中定时器1是一个16位的定时器,为CC2530中功能最全的一个定时/计数器,在 应用中应优先选用。

定时器1的工作模式有三种:

<1> 自由运行模式:计数器从0x0000开始,在每个活动 时钟边沿增加1,当计数器达到0xFFFF时溢出,计数器重新载入0x0000并开始新一轮的递增计数。该模式的计数周期是固定值0xFFFF,当达到最终计数 值0xFFFF时,标志位T1IF和OVFIF被设置。 <2> 模模式:计数器从0x0000开始,在每个活动时钟边 沿增加1,当计数器达到T1CC0寄存器保存的值时 溢出,计数器又将从0x0000开始新一轮的递增计数, 模模式的计数周期可由用户自行设定。 <3> 正计数/倒计数模式:计数器反复从0x0000 开始,正计数到TICC0保存的最终计数值,然后再倒计数回0x0000,当达到最终计数值时,标志位T1IF和OVFIF被设置。 复制代码

2. 时钟源

CC2530有两个可选的时钟源,分别是内部和外部。

1、内部RC震荡器(32KHz、16MHz)

2、外部石英晶振(32.768KHz、32MHz)

注意:外部石英晶振比较稳定,在无线收发中采用外部石英晶振

3. 时钟源的切换

用于判断时钟源是否切换成功

image.png

image.png

image.png

4. 定时器中断

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

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

        2. 输入捕获事件

        3. 输出比较事件

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

第二章 相关寄存器

image.png

image.png

image.png

image.png

image.png

第三章: 示例代码

定时器1共有5对T1CCxH和T1CCxL寄存器,分别对应通道0到通道4。在使用定时器1的定时功能时,使用T1CC0H和T1CC0L两个寄存器存放最大计数值的高8位和低8位。

下面编写定时器1的使用示例代码,开启了定时器中断。分别定时1秒和10秒,在中断服务函数里进行判断,完成LED灯控制。

#include <ioCC2530.h> //定义LED灯的端口 #define LED1 P1_2 #define LED2 P1_3 /* 函数功能:LED灯IO口初始化 硬件连接:LED1-->P1_2 , LED2-->P1_3 */ void LED_Init(void) {     P1DIR |=0x3<<2;  //配置P1_2、P1_3为输出模式     LED1 = 1;     LED2 = 1; } /*延时200毫秒*/ void delay200ms(void)   //误差 -0.125us {     unsigned char a,b,c;     for(c=95;c>0;c--)         for(b=181;b>0;b--)             for(a=14;a>0;a--); } /*===============定时器1初始化函数==================*/ void Init_Timer1() {   T1CC0L = 0xd4;        //设置最大计数值的低8位   T1CC0H = 0x30;        //设置最大计数值的高8位   T1CCTL0 |= 0x04;      //开启通道0的输出比较模式   T1IE = 1;             //使能定时器1中断   T1OVFIM = 1;          //使能定时器1溢出中断   EA = 1;               //使能总中断   T1CTL = 0x0e;         //分频系数是128,模模式 } unsigned char count = 0;   /*================定时器1服务函数====================*/ #pragma vector = T1_VECTOR __interrupt void Timer1_Sevice() {   T1STAT &= ~0x01;      //清除定时器1通道0中断标志   count++;   if(count%10 == 0)     //定时1秒到   {     LED1 = !LED1;   }   if(count == 100)      //定时10秒到   {     LED2 = !LED2;     count = 0;   } } /*主函数*/ void main(void) {     LED_Init();//初始化LED灯控制IO口     Init_Timer1();     while(1)               {                        } }


作者:DS小龙哥
链接:https://juejin.cn/post/7020951041986265101


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐