发新帖我要提问
12
返回列表
打印
[Zigbee]

5、ZigBee基础实验——图文与代码详解定时器1(16位定时器)

[复制链接]
楼主: functions
手机看帖
扫描二维码
随时随地手机跟帖
21
functions|  楼主 | 2020-1-5 17:59 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
12、定时器1 DMA 触发

  有三种DMA 触发与定时器1 有关。这些是DMA 触发T1_CH0,T1_CH1 和T1_CH2,分别在以下定时器比较事件上产生:

● T1_CH0 – 通道0 比较
● T1_CH1 – 通道1 比较
● T1_CH2 – 通道2 比较

  通道3 和4 没有相关的触发。

使用特权

评论回复
22
functions|  楼主 | 2020-1-5 17:59 | 只看该作者
13、定时器1 寄存器

  本节描述了定时器1 的寄存器,由以下寄存器组成:

● T1CNTH – 定时器1 计数高位
● T1CNTL – 定时器1 计数低位
● T1CTL – 定时器1 控制
● T1STAT –定时器1 状态
● T1CCTLn – 定时器1 通道n 捕获/比较控制
● T1CCnH – 定时器1 通道n 捕获/比较高位值
● T1CCnL – 定时器1 通道n 捕获/比较低位值

  TIMIF.OVFIM 寄存器位驻留在TIMIF 寄存器,和定时器3 和定时器4 寄存器一起描述。

使用特权

评论回复
23
functions|  楼主 | 2020-1-5 17:59 | 只看该作者
14、作为数组访问定时器1 寄存器

  定时器1 捕获/比较通道寄存器可以在XDATA 存储空间中作为一个连续的区域被访问。这使得可以作为一个简单的索引结构方便地访问寄存器。5 个捕获/比较控制寄存器映射到0x62A0 - 0x62A4。16 位捕获/比较值映射到0x62A6 - 0x62AF。0x62A5 不使用。

使用特权

评论回复
24
functions|  楼主 | 2020-1-5 18:01 | 只看该作者
15、代码示例

15.1、定时器轮训方式

  下面代码展示了通过设置定时器1计数来控制LED闪烁,这里没有采用中断方式,而是采用普通的轮训。关于LED的初始化我在前几节已经介绍了。这里重点看和定时器1相关的部分:

  ① 第33行将T1CTL设置为0x0d=0000 1101,参考下面寄存器表可知是通过设置定时器1的控制和状态寄存器来将定时器设置为:128分频,自由运行,从0x0000到0xFFFF反复计数。由于系统在没配置工作频率时默认是2分频,即32MHz/2=16MHz,因此定时器每次溢出的时间T=1/(16MHz/128)*65536=0.524s

  

  ② 第34行将T1STAT设置为0x21=0010 0001,参考下面的寄存器表知为使用定时器1的通道0,且中断有效。



  ③ 在49行一旦IRCON>0表明发生了某个中断,在该例程中我们仅仅用了TIMER1的中断,因此表明TIMER1中断发生:



  因此下面整个程序实现的功能是:利用定时器1的通道0产生0.524s的周期性中断,每次发生中断系统会自动置IRCON的第1位为1,在main函数的轮训中一旦检测到该信息,则让计数变量count加1,一旦count计数大于1时,就让LED状态翻转,实现1SLED闪烁控制。

/****************************************************************************
* 文 件 名: main.c
* 版    本: 1.0
* 描    述: 定时器T1通过查询方式控制LED1周期性闪烁
****************************************************************************/
#include <ioCC2530.h>

typedef unsigned char uchar;
typedef unsigned int  uint;

#define LED1 P1_0       // P1.0口控制LED1

/****************************************************************************
* 名    称: InitLed()
* 功    能: 设置LED灯相应的IO口
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitLed(void)
{
    P1DIR |= 0x01;      //P1.0定义为输出
    LED1 = 1;           //使LED1灯上电默认为熄灭     
}

/****************************************************************************
* 名    称: InitT1()
* 功    能: 定时器初始化,系统不配置工作时钟时默认是2分频,即16MHz
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitT1()
{
    T1CTL = 0x0d;       //128分频,自动重装 0x0000-0xFFFF
    T1STAT= 0x21;       //通道0,中断有效   
}

/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{
    uchar count=0;
   
    InitLed();             //调用初始化函数
    InitT1();
   
    while(1)
    {
        if(IRCON > 0)
        {
            IRCON=0;
            if(count++ >= 1) //约1s周期性闪烁,示波器测大约为1025MS
            {
              count=0;
              LED1 = !LED1;  //LED1闪烁        
            }
        }
    }
}

使用特权

评论回复
25
functions|  楼主 | 2020-1-5 18:01 | 只看该作者
15.2、定时器中断方式

  上面采用轮训的方法是比较占资源的,类似我们按键那节中介绍的,除了轮训我们还可以用中断方式!在黄色初始化部分比采用轮训方式多了使能T1中断和总中断的部分(35、36行代码)。我之前没有加这两句代码,结果橙色部分的定时器1中断回调函数无法被触发!查datasheet发现Interrupt Overview:如果想触发回调函数,需要将EA开关和T1IE开关打开才行!



/****************************************************************************
* 文 件 名: main.c
* 版    本: 1.0
* 描    述: 定时器T1通过查询方式控制LED1周期性闪烁
****************************************************************************/
#include <ioCC2530.h>

typedef unsigned char uchar;
typedef unsigned int  uint;

#define LED1 P1_0       // P1.0口控制LED1

/****************************************************************************
* 名    称: InitLed()
* 功    能: 设置LED灯相应的IO口
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitLed(void)
{
    P1DIR |= 0x01;      //P1.0定义为输出
    LED1 = 1;           //使LED1灯上电默认为熄灭     
}

/****************************************************************************
* 名    称: InitT1()
* 功    能: 定时器初始化,系统不配置工作时钟时默认是2分频,即16MHz
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitT1()
{
    T1CTL = 0x0d;       //128分频,自动重装 0x0000-0xFFFF
    T1STAT= 0x21;       //通道0,中断有效  
    T1IE = 1;                //开总中断和T1中断
    EA = 1;                  //开总中断
}

//定时器T1中断处理函数
#pragma vector = T1_VECTOR
__interrupt void T1_ISR(void)
{
    static uchar count=0;
    IRCON = 0x00;            //清中断标志, 也可由硬件自动完成
    if(count++ >= 1) //约1s周期性闪烁,示波器测大约为1025MS
    {
      count=0;
      LED1 = !LED1;  //LED1闪烁        
    }
}

/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{
    InitLed();             //调用初始化函数
    InitT1();
   
    while(1){}
}

使用特权

评论回复
26
functions|  楼主 | 2020-1-5 18:02 | 只看该作者
Zigbee系列**:

[ZigBee] 1、 ZigBee简介   https://bbs.21ic.com/icview-2894000-1-1.html

[ZigBee] 2、 ZigBee开发环境搭建   https://bbs.21ic.com/icview-2894002-1-1.html

[ZigBee] 3、ZigBee基础实验——GPIO输出控制实验-控制Led亮灭   https://bbs.21ic.com/icview-2894004-1-1.html

[ZigBee] 4、ZigBee基础实验——中断   https://bbs.21ic.com/icview-2894006-1-1.html

使用特权

评论回复
27
nawu| | 2020-2-1 09:39 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
28
qcliu| | 2020-2-1 10:31 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
29
tfqi| | 2020-2-1 10:36 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
30
wiba| | 2020-2-1 10:38 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
31
zljiu| | 2020-2-1 10:45 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
32
coshi| | 2020-2-1 10:49 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
33
aoyi| | 2020-2-1 10:58 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
34
drer| | 2020-2-1 11:02 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
35
gwsan| | 2020-2-1 11:08 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
36
kxsi| | 2020-2-1 11:12 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则