Zigbee学习日记(四)外部中断
goJhou 发布于2017-12-29 浏览:2077 回复:3
2
收藏

外部中断是一个硬件设备所必有的功能,也是在单片机学问里必学的一项操作。

什么是外部中断?

外部中断是单片机实时地处理外部事件的一种内部机制。当某种外部事件发生时,单片机的中断系统将迫使CPU暂停正在执行的程序,转而去进行中断事件的处理;中断处理完毕后.又返回被中断的程序处,继续执行下去。

在我们自己的代码世界里,可以理解成突然有一个优先级特别特别高的线程请求CPU处理,CPU必须要先处理这个线程,处理完再返回做之前做的事。

例如,我们按下了一个物理按钮,制造了一个中断事件,按钮的功能在事件内实现,这就是外部中断的作用。

 

在书写外部中断前,要学习几个中断使能寄存器

EA 是总中断使能 它管理着单片机是否执行中断的最大的开关 0为关 1为开

当EA打开时,才会去处理中断函数,否则芯片可不睬你的中断请求

 

接着是组中断使能

在之前的学习中,我们知道CC2530标准芯片有40个外接引脚。

其中P0_0到P0_7称为P0组,共有8个脚,

P1_0到P1_7称为P1组,共有8个脚。

P2_0到P2_4共有5个脚,称为P2组。

每个组各自也各有一个组中断开关,来控制该组是否允许执行中断请求。

分别由 P0IE,P1IE,P2IE 3个使能位来控制。这3个就是组中断使能

 

之后总中断和组中断打开之后,引脚上还有一个中断开关 存于PnIEN使能寄存器中

在P0中,针对P0_0~P0_7成为P0IEN,从低到高对应P0_0到P0_7。以此类推还有P1IEN,P2IEN。

P2IEN比较特殊,第5位是对应5个脚。第6位成为USB D+中断使能位,用于检测USB挂起状态下的USB恢复事件。当USB控制器没有挂起时不设置该标志。 第6位其实我还没理解,但是日常使用不到它

 

如果说iocc2530.h比较老的话,可能不包含P1IEN和P2IEN的地址定义。

IEN2 |= 0x 10; 这是P1组的中断设置方式 P1在IEN2寄存器的第5位 
IEN2 |= 0x 02; 这是P2组的中断设置方式 P2在IEN2寄存器的第2位

 

存于PICTL寄存器中

低位第1位控制着P0组的中断触发条件

低位第2位控制着P1组的P1_0到P1_3

低位第3位控制着P1_4到P1_7 (至于为什么分成两份,我也不知道了。不过官方寄存器这么定义,就照着做吧)

低位第4位控制着P2组

以上是中断触发条件的设置 0为上升沿 1为下降沿 那什么是上升沿与下降沿呢?之后再说~先看完寄存器定义吧

高位的123都是没用的位

高位第4位控制着I/O口驱动能力,选择输出驱动能力增强来补偿引脚DVDD的低I/O电压,确保在较低的电压下的驱动能力和较高电压下相同。0为最小驱动能力增强。1为最大驱动能力增强。 这个位我也没怎么设过,基本上默认情况下不大会出现电压不稳的情况。

那什么是上升沿和下降沿呢?

要知道,在数据的世界里,万物由0和1构成。0就是低电平信号,1就是高电平信号。

像LED,通过将引脚放到低电平来点亮它,放到高电平来熄灭它。其中肯定有电平信号的高低变化

从低电平到高电平的变化 叫上升沿

从高电平到低电平的变化 叫下降沿

而在PICTL的前4位就存储这种触发时机。  0为上升沿  1为下降沿

 

 

好,到这为止所有的与中断相关的寄存器都已经出现了,来顺一下制造中断的流程

  1. 设置普通IO口 输入 输入状态
  2. 打开总中断
  3. 打开组中断
  4. 打开IO口中断
  5. 设置触发条件

我们以一个按钮按下 取反LED灯状态的栗子来上上手。

在开始前我们还要明白一个硬件知识。

物理的微动按钮,在按下的一瞬间几毫秒里,电平会有抖动,这几毫秒内的信号是不可信的,需要抛掉,几毫秒之后再确认电平信号状态来确定真正的按钮状态。我们可以通过一个简单的延时来处理掉这几个毫秒时间。

CPU在进入正常工作状态后,每一个机器周期会检查组中断标志位IFG和组总中断标志位IF。当有某个中断位为1时,就会进入中断触发。出中断时一定要将相应标志位回0,否则会无限中断出不来。

 

下方就是一个外部中断小案例的代码

#include 

//这是一段瞎写的延时代码,只要达到延时目的就行
void delay(){
  int i,j;
  for(i=0;i<1000;i++)
    for(j=0;j<30;j++)
}

void main(){
  P0SEL &= 0xDF;//1101 1111 P0_5 普通IO口模式
  P0DIR &= 0xDF;//1101 1111 P0_5 输入模式
  P0INP &= 0xDF;//1101 1111 P0_5 上下拉输入
  P0INP &= 0xDF;//1101 1111 P0_5 上拉

  EA = 1;//打开总中断
  P0IE = 1; //打开组中断
  P0IEN |= 0x20; //打开P0_5中断

  PICTL |= 0x01; //P0组下降沿触发

  while(1);
}


//#pragma vector=PxINT_VECTOR 中断函数关键字 x为组  这是cc2530已经定义好的宏,不能乱改
#pragma vector=P0INT_VECTOR
__interupt void fn()//中断函数fn.fn可改
{
  if(P0IFG & 0x20)
  {//这里确定是由P0_5发出的中断 P0IFG是P0组的中断标志位,记录了每个引脚是否有中断请求,如果为1则要中断
    delay();//延时
    
    if(0 == P0_5)
    {
      //延时后P0_5依旧低电平,表示确实是按下了,上方是消抖操作
      P1SEL &= 0xfe; //1111 1110 P1_0 普通IO口模式
      P1DIR |= 0x01; //设置P1_0为输出模式
      P1_0 ^= 1; //自己与1 异或 若为1 1异或1为0 若为0 0异或1为1。可以达到取反效果
    }  
  }

  P0IFG &= 0x DF;//1101 1111 P0_5 把P0_5的中断位消除,表示中断任务结束,不消除会死循环这个中断
  P0IF=0; //组中断标识也要擦一下
}
收藏
点赞
2
个赞
共3条回复 最后由荒墨丶迷失回复于2018-01-11
#4荒墨丶迷失回复于2018-01-11
#3 goJhou回复
定时开关机好像是程序控制主板断电的。逻辑差不多

搜噶。卡萨撒哈密达~

1
#3goJhou回复于2018-01-11
#2 荒墨丶迷失回复
定时开关机也是这个原理吗  定点自动断流~

定时开关机好像是程序控制主板断电的。逻辑差不多

1
#2荒墨丶迷失回复于2018-01-10

定时开关机也是这个原理吗  定点自动断流~

1
TOP
切换版块