单片机外部中断(按键)

单片机外部中断(按键)

12单片机外部中断,读取按键。并在数码管上显示

首先搭建数码管硬件平台,及软件显示代码。

234位共阴极数码管单片机驱动

在上面的平台基础上 ,焊接两个按键,按键的一端接地。一个按键的一端接到

P32引脚上,一个按键的一端接到P33引脚上。如果有开发板会更好一些,硬件上会有消抖处理。

所谓的下降沿,即指P32引脚上一个周期是高电平,这个周期是低电平的话,如果开启中断的话就会响应中断。

中断初始化函数书写:

void INT_Init(void)

{

IT0 =1 ;

IT1 =1; //下降沿触发方式

EX0 = 1;

EX1 = 1; //启动外部中断0,1

EA = 1; //使能所有中断

}

函数分析:(1)、上面所使用的寄存器是可以位寻址的 ,具体的寄存器地址参 数,可以查看数据手册(宏晶的比较详细)。

(2)、一般初始化代码的编写,先设置参数,然后在进行使能开启。

中断处理函数书写:

void INT0_Text() interrupt 0 using 0

{

EA = 0;

Delay10ms();

if(P32==0)

Dig_Index++;

EA = 1;

}

函数分析:(1)、INT0_Text() 中断函数的名字

(2)、interrupt 0 声明这个函数用的是0号中断,也就是外部中断 0。这个的顺序是按照我们的中断源地址进行排序的

interrupt 是keil的关键字。

(3)、using 0 表示使用的寄存器组,也是一个关键字

(4)、进入中断处理函数,首先关闭中断,然后延时一段时间在检 测一下引脚是否还保持低电平。 如果保持低电平就说明此次 按键是有效按键,然后对Dig_Index进行自加一,然后退出 中断处理函数。

整体处理函数:

#include"aconf.h"

int Dig_Index ;

void main()

{

P0M0 = 0xff;

P0M1 = 0x00;

P2M0 = 0x00;

P2M1 = 0x00;

P3M0 = 0x00;

P3M1 = 0x00;

Dig_Index = 2;

INT_Init();

while(1)

{

Dig_OutPut(Dig_Index);

}

}

void INT_Init(void)

{

IT0 = 1;

IT1 = 1 ;

EX0 = 1;

EX1 = 1;

EA = 1;

}

void INT0_Text() interrupt 0 using 0

{

EA = 0;

Delay10ms();

if(P32==0)

Dig_Index++;

EA = 1;

}

void INT1_Text() interrupt 2 using 2

{

EA = 0;

Delay10ms();

if(P33==0)

Dig_Index--;

EA = 1;

}

整体分析:(1)、头文件的包含,一遍调用其他文件的函数

(2)、int Dig_Index ;定义一个全局变量,这个实验就是通过两个 按键对这个变量增减后,然后通过数码管对这个数进行显示

(3)、中断初始化函数调用,启动中断。

(4)、数码管采用动态扫描的方式,所以调用显示函数要循环的调 用。

关键点:在于延时消抖。

低电平触发需要实现的功能:(1)、单击增减一

(2)、持续按键,快速增减。

中断函数初始化:

void INT_Init(void)

{

IT0 =0 ;

IT1 =0 ;

EX0 = 1;

EX1 = 1;

EA = 1;

}

这个初始化函数,和下降沿的方式一样,只是将参数设置成低电平处理方式。

中断处理函数:

void INT0_Text() interrupt 0 using 0

{

EA = 0;

//判断按键是单次按键还是持续按键

if(P32 == 0)

Dig_Jndex++;

else

Dig_Jndex=0;

//判断按键是单次按键还是持续按键

if(Dig_Jndex>=10)//持续按键处理

{

Delay1ms();

Dig_Index++;

Dig_OutPut(Dig_Index);

}

else //单次按键

{

Delay100ms();

Dig_Index++;

Dig_OutPut(Dig_Index);

}

EA = 1;

}

函数分析:(1)、我们通过增加一个全局变量来判断按键的接通时间,

如果接通接近2秒的话 就是持续按键。否则是单次按键。

(2)、可以分析一下首先进入这个函数 Dig_Jndex就会自加1.

这个时候执行单次按键处理,这段代码加上显示函数,加上 延时大约是150ms,我们需要执行10次后,才能定义此按键 持续性按键。也就是大约2秒。

(3)、对于这个变量我们需要进行清0,函数在主函数里。

(4)、和下降沿处理函数对比发现这里增加了显示函数,如果不

增加,由于延时函数过多,而且低电平触发 是频繁触发,

会导致显示不正常。

关键点:在于如果判断按键的时间,以及处理显示卡顿闪烁等现象。

#include"aconf.h"

int Dig_Index ;

int Dig_Jndex ;

void main()

{

P0M0 = 0xff;

P0M1 = 0x00;

P2M0 = 0x00;

P2M1 = 0x00;

P3M0 = 0x00;

P3M1 = 0x00;

Dig_Index = 2;

INT_Init();

while(1)

{

if((P32 == 1)&&(P33 == 1))

{

Delay1ms();

if((P32 == 1)&&(P33 == 1))

Dig_Jndex=0;

}

Dig_OutPut(Dig_Index);

}

}

void INT_Init(void)

{

IT0 =0 ;

IT1 =0 ;

EX0 = 1;

EX1 = 1;

EA = 1;

}

void INT0_Text() interrupt 0 using 0

{

EA = 0;

//P32 = 1;

//Delay1ms();

if(P32 == 0)

Dig_Jndex++;

else

Dig_Jndex=0;

if(Dig_Jndex>=10)

{

Delay1ms();

Dig_Index++;

Dig_OutPut(Dig_Index);

}

else

{

Delay100ms();

Dig_Index++;

Dig_OutPut(Dig_Index);

}

EA = 1;

}

void INT1_Text() interrupt 2 using 2

{

EA = 0;

if(P33 == 0)

Dig_Jndex++;

else

Dig_Jndex=0;

if(Dig_Jndex>=10)

{

Delay1ms();

Dig_Index--;

Dig_OutPut(Dig_Index);

}

else

{

Delay100ms();

Dig_Index--;

Dig_OutPut(Dig_Index);

}

EA = 1;

}

主函数:(1)、差别就是增加了对 按键类型 判断全局变量清零

(2)、以及就是对于持续按键,显示的处理。

http://pan.baidu.com/s/1eSJXksU

源码的连接 (包含 数码管的驱动。)

实际运行效果