CC2541蓝牙学习——定时器1模模式

学习目标:I/O口的配置,掌握定时器1的模模式,两种实现方式,查询方式和中断方式

模模式】:

当定时器运行在模模式,16位计数器从0x0000开始,每个活动时钟边沿增加1。当计数器达到T1CC0,寄存器T1CC0H:T1CC0L保存的最终计数值,计数器将复位到0x0000,并继续递增。如果定时器开始于T1CC0以上的一个值,当达到最终计数值(0xFFFF)时,设置标志IRCON.T1IFT1STAT.CH0IF(注意不是T1STAT.OVFIF。如果设置了相应的中断屏蔽位TIMIF.OVFIMT1CCTL0.IM、IEN1.T1EN和总中断IEN0.EA,计数器溢出将产生一个中断请求。模模式可以用于周期不是0xFFFF的应用程序。

使用模模式时,必须要开启通道0的输出比较功能,所以,此时不仅仅只是简单的中断溢出。主要的注意事项如下:

1) 模模式需要开启通道0的输出比较模式,否则计数器到了0xFFFF时,才会产生溢出中断,也就是说如果没有设置通道0的输出比较模式,计数器的值到了T1CC0H:T1CC0L设置的比较值后也不会产生溢出中断。

2) T1的模模式不是普通的溢出中断,和连续计数模式不同,它必须设置通道0的输出比较功能,使能中断时,也是使能通道0的输出比较中断屏蔽位。产生中断时的中断标志也是通道0的输出比较中断标志,而不是计数溢出标志

计数器的操作展示如下图:

模模式查询方式下,初始化程序

 1  1 /******************************************************************************
 2  2 *函 数 名:InitT1
 3  3 *功    能:定时器1初始化,系统不配置时钟默认2分频,即16M
 4  4 *入口参数:无
 5  5 *出口参数:无
 6  6 ******************************************************************************/
 7  7 void InitT1(void)
 8  8 {
 9  9   T1CTL  = 0x0e;     //定时器1设置为128分频,模计数器模式
10 10   T1CC0L = 0xff;     //模值1024,定时器1通道0捕获/比较值低位
11 11   T1CC0H = 0x9f;     //定时器1通道0捕获/比较值高位
12 12   T1CCTL0 = 0x44;    //通道0比较功能,并且开通道0中断
13 13   T1STAT = 0X21;     //通道0,中断有效。这一句在裸机程序中可有可无
14 14 }
 1  1 /******************************************************************************
 2  2 *程序入口函数
 3  3 ******************************************************************************/
 4  4 int main(void)
 5  5 {
 6  6   InitClock();
 7  7   InitLED(1);                //LED初始化,熄灭LED1
 8  8   InitT1();                  //定时器1初始化
 9  9    
10 10   while(1)
11 11   {
12 12     if(T1STAT & (1<<0))       //检测定时器1通道0是否中断
13 13     {
14 14       T1STAT &= ~(1<<0);      //清中断标志
15 15       LED1 = !LED1;          //LED闪烁
16 16     }
17 17   }
18 18 }

这里判断的是T1STAT.CH0IF(定时器1通道0中断标志),经过实验验证也可以判断IRCON.T1IF(定时器1中断标志)。

定时器初始化程序

 1 /******************************************************************************
 2 *函 数 名:InitT1
 3 *功    能:定时器1初始化,系统不配置时钟默认2分频,即16M
 4 *入口参数:无
 5 *出口参数:无
 6 ******************************************************************************/
 7 void InitT1(void)
 8 {
 9   T1CTL  = 0x0e;     //定时器1设置为128分频,模计数器模式
10   T1CC0L = 0xff;     //模值1024,定时器1通道0捕获/比较值低位
11   T1CC0H = 0x9f;     //定时器1通道0捕获/比较值高位
12   T1CCTL0 = 0x44;    //通道0比较功能,并且开通道0中断
13   T1STAT = 0X21;     //通道0,中断有效。这一句在裸机程序中可有可无
14   TIMIF |= (1<<6);   //定时器1溢出中断使能
15   IEN1  |= (1<<1);   //定时器1中断使能
16   EA = 1;            //开总中断
17 }

中断服务程序

 1 /******************************************************************************
 2 *函 数 名:Timer1_ISR
 3 *功    能:定时器1中断服务程序
 4 *入口参数:无
 5 *出口参数:无
 6 ******************************************************************************/
 7 #pragma vector = T1_VECTOR 
 8 __interrupt void Timer1_ISR(void) 
 9 { 
10   LED1 = !LED1;
11   IRCON &= ~0x02;
12   T1STAT &= ~0x01; 
13 }

第12行产生的中断是定时器1通道0中断,而不是定时器1的溢出中断,故只需要清除T1STAT的第1位,不需要清除第5位

原文地址:https://www.cnblogs.com/chenzhao207/p/4497934.html