• CC2530定时器


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

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

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

    二、CC2530的定时/计数器

    根据数据手册可知 CC2530 总共有 4 个定时器,但是定时器 2 被系统占用,可用的只有三个,分别为 定时器 1、3、4。其中定时器 3 和定时器 4 是两个 8 位定时器,定时器 1 是一个独立的 16 位定时器。为CC2530中功能最全的一个定时/计数器,在应用中应优先选用。定时器1的工作模式有三种:

    <1> 自由运行模式:计数器从 0x0000 开始,每个活动时钟边沿增加 1。当计数器达到 0xFFFF 时(溢出),计数器载入 0x0000,继续递增它的值,如图 3.2.1 所示。当达到最终计数值 0xFFFF,设置 标志 IRCON.T1IF 和 T1STAT.OVFIF。如果设置了相应的中断屏蔽位 TIMIF.OVFIM 以及 IEN1.T1EN,将产生 一个中断请求。自由运行模式可以用于产生独立的时间间隔,输出信号频率。

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

    <3> 正计数/倒计数模式:计数器反复从 0x0000 开始,正计数直到达到 T1CC0H 与 T1CC0L 保存的值。 然后计数器将倒计数直到 0x0000,如图 3.2.3 所示。这个定时器用于周期必须是对称输出脉冲而不是 0xFFFF 的应用程序,因此允许中心对齐的 PWM 输出应用的实现。在正计数/倒计数模式,当达到最终计 数值时,设置标志 IRCON.T1IF 和 T1CTL.OVFIF。如果设置了相应的中断屏蔽位 TIMIF.OVFIM 以及 IEN1.T1EN,将产生一个中断请求。

    TIP:

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

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

            <2> 输入捕获事件。

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

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

    题目:应用定时器1的模模式实现1秒定时。

    将内部系统时钟16MHzRC振荡器128分频作为定时器1的计数信号,在模模式中实现0.1秒定时。在定时中断服务函数中对全局变量count进行累加,实现1秒定时,并将LED5作为秒闪灯,而10秒后LED6亮,再10秒后LED6...如此往复。

    思路:1.计算最大计数值,并填入T1CC0H和T1CC0L.

    2.使用模模式,记得开启通道0的输出比较模式。

    3.使能定时器1相关的中断控制位。

    4.在T1CTL寄存器设置分频系数,启动定时器。

    5.编写定时器1中断服务处理函数,在这里记得手工清除T1STAT寄存器中的中断标志位。

    6.定义一个全局变量count,进行1秒定时。

    涉及到的寄存器:

    T1CTL:定时器的模式和分频

     

    T1CCTL0寄存器——定时器10捕获/比较控制

     

    T1STAT:定时器1状态

     

    IRCON——中断标志

     

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

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

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

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

     

     

    1   T1CC0L = 0xd4;        //设置最大计数值的低8位
    2   T1CC0H = 0x30;        //设置最大计数值的高8位

    定时器初始化函数设计

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

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

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

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

     1 /*===============定时器1初始化函数==================*/
     2 void Init_Timer1()
     3 {
     4   T1CC0L = 0xd4;        //设置最大计数值的低8位
     5   T1CC0H = 0x30;        //设置最大计数值的高8位
     6   T1CCTL0 |= 0x04;      //开启通道0的输出比较模式
     7   T1IE = 1;             //使能定时器1中断
     8   T1OVFIM = 1;          //使能定时器1溢出中断
     9   EA = 1;               //使能总中断
    10   T1CTL = 0x0e;         //分频系数是128,模模式
    11 }

    定时器中断服务函数设计

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

    <2> 累加全局变量count。

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

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

     1 unsigned char count = 0;  

    #pragma vector = T1_VECTOR 2 __interrupt void Timer1_Sevice() 3 { 4 T1STAT &= ~0x01; //清除定时器1通道0中断标志 5 count++; 6 if(count%10 == 0) //定时1秒到 7 { 8 LED5 = ~LED5; 9 } 10 if(count == 100) //定时10秒到 11 { 12 LED6 = ~LED6; 13 count = 0; 14 } 15 }

    最终代码:

     1 #include "ioCC2530.h"
     2 
     3 #define  LED5   P1_3
     4 #define  LED6   P1_4
     5 /*===============定时器1初始化函数==================*/
     6 void Init_Timer1()
     7 {
     8   T1CC0L = 0xd4;        //设置最大计数值的低8位
     9   T1CC0H = 0x30;        //设置最大计数值的高8位
    10   T1CCTL0 |= 0x04;      //开启通道0的输出比较模式  0000 0100 1为比较模式
    11   T1IE = 1;             //使能定时器1中断
    12   T1OVFIM = 1;          //使能定时器1溢出中断
    13   EA = 1;               //使能总中断
    14   T1CTL = 0x0e;         //分频系数是128,模模式  0000 11 10
    15 }
    16 
    17 unsigned char count = 0;  
    18 /*================定时器1服务函数====================*/
    19 #pragma vector = T1_VECTOR
    20 __interrupt void Timer1_Sevice()
    21 {
    22   T1STAT &= ~0x01;      //清除定时器1通道0中断标志  0000 0001——>1111 1110 通道0关闭
    23   count++;
    24   if(count%10 == 0)     //定时1秒到
    25   {
    26     LED5 = ~LED5;
    27   }
    28   if(count == 100)      //定时10秒到
    29   {
    30     LED6 = ~LED6;
    31     count = 0;
    32   }
    33 }
    34 /*=================端口初始化函数====================*/
    35 void Init_Port()
    36 {
    37   P1SEL &= ~0x18;  //将P1_3和P1_4设置为通用I/O端口
    38   P1DIR |= 0x18;   //将P1_3和P1_4的端口设置为输出
    39   LED5 = 0;
    40   LED6 = 0;
    41 } 
    42 /*===================主函数=========================*/
    43 void main()
    44 {
    45   Init_Port();
    46   Init_Timer1();
    47   while(1);
    48 }

    尽力了,有点小难。。

  • 相关阅读:
    JVM笔记-temp
    Spark笔记-treeReduce、reduce、reduceByKey
    Java笔记-快速失败and安全失败
    Netty笔记--ByteBuf释放
    Spark笔记--使用Maven编译Spark源码(windows)
    MySQL笔记--查询语句实践
    Kafka笔记--指定消息的partition规则
    Spark Executor Driver资源调度小结【转】
    Spark学习笔记--Graphx
    HBase笔记--自定义filter
  • 原文地址:https://www.cnblogs.com/yuling520/p/12682944.html
Copyright © 2020-2023  润新知