物联网| 定时器计数器开发之中断方法|定时器中断处理函数|完整测试代码|物联网之蓝牙4.0 BLE基础-学习笔记(6)

文章目录

  • 11 定时器计数器开发之中断方法
    • Tips:定时器
    • 定时器中断处理函数:
    • 完整测试代码:

11 定时器计数器开发之中断方法

Tips:定时器

定时器计数器开发之中断,是指在使用定时器或计数器时,当计数值达到预设值时,会触发中断,然后执行相应的中断服务程序,可以通过设置定时器或计数器的TIMx->DIER寄存器来使能定时器或计数器的中断。
定时器是一种常见的嵌入式系统中的硬件设备,它可以在一定时间内触发中断,从而实现定时或计数的功能。在8位微控制器中,通常会有多个定时器,其中一些是基本定时器,只能工作在模式0下,而另一些则是高级定时器,可以工作在模式1、2、3下,并且具有自动重装功能。
##LED控制电路同前节:
物联网| 定时器计数器开发之中断方法|定时器中断处理函数|完整测试代码|物联网之蓝牙4.0 BLE基础-学习笔记(6)_第1张图片
CC2530的T3定时器(8位)需要了解T3GJL,T3CCTLO,T3CCO,T3CCTL1,T3CC寄存器。如下表所示:
物联网| 定时器计数器开发之中断方法|定时器中断处理函数|完整测试代码|物联网之蓝牙4.0 BLE基础-学习笔记(6)_第2张图片
按照表格寄存器的内容,对T3进行配置,由于定时器T3为8位所以配置稍有不同。
T3CTL = 0x08 ;
开溢出中断
T3IE= 1;
开总中断和T3中断
TRCTL = OxE0;
//128分频,128/16000000*N=0.5S,N=62500
T3CTL &=~Ox03;
自动重装00一>Oxff 62500/255=245(次)
T3CTL = Ox10;
!启动
EA= 1;
再开启一开总中断
注意:
(1)T3CTL &= ~0X03; 这条语句理解为:0X03=0000 0011,则 ~0X03=1111 1100;所以当执行 T3CTL &= ~0X03 后,T3CTL 其它位保持不变,D0、D1 变为 0。
物联网| 定时器计数器开发之中断方法|定时器中断处理函数|完整测试代码|物联网之蓝牙4.0 BLE基础-学习笔记(6)_第3张图片

(2)由于是 128 分频,则计一次数需要时间 t=128/16000000, 如果我们希望得到一个 0.5s的延时,那么 128/16000000*N=0.5S,就得计 N=65200 次数。而我们又将 Timer3 设置为自动重装 0x00—0xFF,即产生一次溢出中断计数 256 次,而我们现在是想它计算65200 次,所以,我们要累加 254 次溢出中断才让 LED1 取反。
|是按位操作,操作对象为1;&也是按位操作,但操作对象是0,~取反操作。
按位操作是一种对二进制数进行运算的方式,其中~是按位取反操作符,它将一个二进制数的每一位取反,即将0变为1,1变为0。而&也是按位操作符,但它的操作对象是0。
物联网| 定时器计数器开发之中断方法|定时器中断处理函数|完整测试代码|物联网之蓝牙4.0 BLE基础-学习笔记(6)_第4张图片
物联网| 定时器计数器开发之中断方法|定时器中断处理函数|完整测试代码|物联网之蓝牙4.0 BLE基础-学习笔记(6)_第5张图片
物联网| 定时器计数器开发之中断方法|定时器中断处理函数|完整测试代码|物联网之蓝牙4.0 BLE基础-学习笔记(6)_第6张图片

实现代码:

void T3init(void)
{
  T3CTL |= 0x08;    //0x08=1000 或操作1,仅操作第3位,不影响其他位使溢出中断可以,不操作其他位
  T3IE= 1;          //开总中断
  T3CTL |= 0xE0;   //0xE0=1110 0000 或操作1,仅操作7:5位,128分频 128/16000000*N=0.5s,N=62500
  T3CTL &= ~0x03;  //0x03=0000 0011,取反1111 1100,Free running, repeatedly count from Ox00 to OxFF

  //自动从0x00到0xff(255)重装,62500/255=245次,&操作0,1:0位置0,其他位不变
  T3CTL != 0x10;   //启动 0x10=0001 0000 或操作1,仅改变第4位,启动
  EA= 1;           //再开启一开总中断
}

定时器中断处理函数:

模板:
#pragma vector = T3_VECTOR //格式:#pragma vector = 中断向量,紧接着是中断处理程序
__interrupt void T3_ISR(void)
{

}
本案例:

#pragma vector = T3_VECTOR    //格式:#pragma vector = 中断向量,紧接着是中断处理程序
  __interrupt void T3_ISR(void)
 {
  IRCON = 0x00;//来中断就清0,防止误操作,方便下一次判断
  if(count ++ > 245) //0.5s时间
  {
    count = 0; //每次进入就计数清零
    LED1 = ~LED1;
  }
  /*Delay(10);            //去除抖动
  LED1=~LED1;             //改变LED1状态
  P0IFG = 0;             //清中断标志
  P0IF = 0;             //清中断标志
  */
 }

主程序体:

/*************************
*程序入口函数
*************************/
void main(void)
{
  ledinit();
  T3init();
  while(1)
  {
    //空循环即可
  };
};

完整测试代码:

#include 
typedef unsigned char uchar;
typedef unsigned int uint;
#define LED1 P1_0 //
uint count; //定时器计数
void ledinit(void)
{
   P1DIR |= 0x01;//输出模式
   LED1 =0;//上电默认输出0,即关灯
}
void T3init(void)
{
  T3CTL |= 0x08;    //0x08=1000 或操作1,仅操作第3位,不影响其他位使溢出中断可以,不操作其他位
  T3IE= 1;          //开总中断
  T3CTL |= 0xE0;   //0xE0=1110 0000 或操作1,仅操作7:5位,128分频 128/16000000*N=0.5s,N=62500
  T3CTL &= ~0x03;   //0x03=0000 0011,取反1111 1100,Free running, repeatedly count from Ox00 to OxFF
  //自动从0x00到0xff(255)重装,62500/255=245次,&操作0,1:0位置0,其他位不变
  T3CTL != 0x10;   //启动 0x10=0001 0000 或操作1,仅改变第4位,启动
  EA= 1;           //再开启一开总中断
}
/****************************
      定时器中断处理函数
*****************************/
#pragma vector = T3_VECTOR    //格式:#pragma vector = 中断向量,紧接着是中断处理程序
  __interrupt void T3_ISR(void)
 {
  IRCON = 0x00;//来中断就清0,防止误操作,方便下一次判断
  if(count ++ > 245) //0.5s时间
  {
    count = 0; //每次进入就计数清零
    LED1 = ~LED1;
  }
  /*Delay(10);            //去除抖动
  LED1=~LED1;             //改变LED1状态
  P0IFG = 0;             //清中断标志
  P0IF = 0;             //清中断标志
  */
 }
/*************************
*程序入口函数
*************************/
void main(void)
{
  ledinit();
  T3init();
  while(1)
  {
    //空循环即可
  };
};

你可能感兴趣的:(物联网开发入门与实战,物联网,学习,笔记)