• ZigBee开发(5)--基础实验定时器


    今天找到了这个人写的教程,还挺不错,原文链接:https://www.cnblogs.com/ALittleBee/p/7078252.html

    一、定时/技术器的基本原理

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

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

    二、CC2530的定时/计数器

            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被设置。

    三、CC2530的定时/计数器中断系统

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

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

            <2> 输入捕获事件。

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

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

    【1】设置定时器1的最大计数值

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

            最大计数值 = 定时时长 / 定时器计数周期。

            在本实训中,系统时钟为16MHz,分频系数为128,要定时0.1秒,最大计数值为:

            

    【2】定时器初始化函数设计

            <1> 将定时器1的最大计数值写入T1CC0。

            <2> 通过T1CCTL0寄存器开启定时器1通道0的输出比较模式。

            <3> 设置定时器1的相关中断控制位。

            <4> 设置分频系数和工作模式并启动定时器。

    【3】定时器中断服务函数设计

           <1> 清除T1STAT的中断标志位。

           <2> 累加全局变量count。

           <3> count被10整除即1秒的定时到了。

           <4> 10秒定时到将count清零。

    #include "ioCC2530.h"
    
    #define  LED5   P1_3
    #define  LED6   P1_4
    /*===============定时器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秒到
      {
        LED5 = ~LED5;
      }
      if(count == 100)      //定时10秒到
      {
        LED6 = ~LED6;
        count = 0;
      }
    }
    /*=================端口初始化函数====================*/
    void Init_Port()
    {
      P1SEL &= ~0x18;  //将P1_3和P1_4设置为通用I/O端口
      P1DIR |= 0x18;   //将P1_3和P1_4的端口设置为输出
      LED5 = 0;
      LED6 = 0;
    } 
    /*===================主函数=========================*/
    void main()
    {
      Init_Port();
      Init_Timer1();
      while(1);
    }

     定时器1 有5个通道不怎么明白这5个通道有什么用,因为经过我的实验,这五个通道所装载的值都是通道1所装在的值

    只是产生的中断标志位不一样,并不像我想象的那样,五个通道可以装载不同的计数值

     1 #include <ioCC2530.h>
     2 
     3 #define uint unsigned int
     4 #define uchar unsigned char
     5 
     6 
     7 #define  LED1   P1_0
     8 #define  LED5   P1_1
     9 #define  LED6   P1_4
    10 /*===============定时器1初始化函数==================*/
    11 void Init_Timer1()
    12 {
    13   T1CC0L = 0xd4;        //设置最大计数值的低8位
    14   T1CC0H = 0x30;        //设置最大计数值的高8位
    15   T1CCTL0 |= 0x04;      //开启通道0的输出比较模式
    16   
    17   T1CCTL1 |= 0x04;      //开启通道1的输出比较模式 
    18   
    19   T1CCTL2 |= 0x04;      //开启通道2的输出比较模式
    20   
    21   /*T1CC1L = 0xd4;        //设置最大计数值的低8位
    22   T1CC1H = 0x10;        //设置最大计数值的高8位
    23   T1CCTL1 |= 0x04;      //开启通道1的输出比较模式 
    24   
    25   T1CC2L = 0xc4;        //设置最大计数值的低8位
    26   T1CC2H = 0x00;        //设置最大计数值的高8位
    27   T1CCTL2 |= 0x04;      //开启通道2的输出比较模式*/
    28   
    29   T1IE = 1;             //使能定时器1中断
    30   T1OVFIM = 1;          //使能定时器1溢出中断
    31   EA = 1;               //使能总中断
    32   T1CTL = 0x0e;         //分频系数是128,模模式
    33 }
    34 
    35 unsigned char count = 0;  
    36 unsigned char count1 = 0;  
    37 unsigned char count2 = 0; 
    38 /*================定时器1服务函数====================*/
    39 #pragma vector = T1_VECTOR
    40 __interrupt void Timer1_Sevice()
    41 {
    42    
    43   
    44   if((T1STAT & 0x01)  == 1)
    45   {
    46     T1STAT &= ~0x01;      //清除定时器1通道0中断标志
    47     count++;
    48     if(count == 11)     //定时1秒到
    49     {
    50       LED5 = ~LED5;
    51       count = 0;
    52     }
    53     
    54   }
    55   else if((T1STAT & 0x02)  != 0)
    56   {
    57     count1++;
    58     T1STAT &= ~0x02;      //清除定时器1通道1中断标志
    59     if(count1 == 5)
    60     {
    61       LED1 = ~LED1;
    62       count1 = 0;
    63     }
    64         
    65   }
    66   
    67   else if((T1STAT & 0x04)  != 0)
    68   {
    69     count2++;
    70     T1STAT &= ~0x04;      //清除定时器1通道2中断标志
    71     if(count2 == 2)
    72     {
    73       LED6 = ~LED6;
    74       count2 = 0;
    75     }
    76     
    77   }
    78   
    79 }
    80 /*=================端口初始化函数====================*/
    81 void Init_Port()
    82 {
    83   P1SEL &= ~0x13;  //将P1_3和P1_4设置为通用I/O端口
    84   P1DIR |= 0x13;   //将P1_3和P1_4的端口设置为输出
    85   LED1 = 0;
    86   LED5 = 0;
    87   LED6 = 0;
    88 } 
    89 /*===================主函数=========================*/
    90 void main()
    91 {
    92   Init_Port();
    93   Init_Timer1();
    94   while(1);
    95 }
  • 相关阅读:
    display,visibility,meta知识
    存储过程
    Asp.Net碎知识
    分页
    配置IIS
    SQLAlchemy(三):外键、连表关系
    SQLAlchemy(二):SQLAlchemy对数据的增删改查操作、属性常用数据类型详解
    SQLAlchemy(一):SQLAlchemy去连接数据库、ORM介绍、将ORM模型映射到数据库中
    数据可视化之DAX篇(十)在PowerBI中累计求和的两种方式
    数据可视化之DAX篇(九) 关于DAX中的VAR,你应该避免的一个常见错误
  • 原文地址:https://www.cnblogs.com/tianxxl/p/9867936.html
Copyright © 2020-2023  润新知