独立按键的方式可以采用两种:
第一种是扫描的方式:
按键消抖有两个,按下时候和松手时候需要消抖,消抖一般通过延时来消除。
sbit key=P3^3; //位定义与P3^3口相连的独立按键
uchar num;
void delay(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void key_scan() 这个只是用了按下时候消除抖动,松手时候没有消抖
{
if(key==0) //判断是否按键被按下
{
delay(1); //延时用以消除抖动 消除按键按下时候的抖
if(key==0) //再次判断按键是否依然是按下状态
{
while(!key); //等待按键松手
num++;
if(num==16) //num用来指示按键按一下,就计数一次
num=0;
{这个还可以添加自己的应用程序,即按键按下时候执行相应操作,或者这里按键按下给个标志位}
}
}
}
void main()
{
while(1)
{
key_scan(); //调用按键扫描程序
P1=~num; //将结果通过P1口小灯显示
}
}
/*
按键检测流程:判断按下,延时消抖再判断,等待按键松手再操作
注:此处可以将按键结果通过数码管显示,程序自己调整
还可以按下面这样写,写两个消除抖动,进行两次消除抖动处理
void key_scan()
{
if(key==0) //判断是否按键被按下
{
delay(1); //延时用以消除抖动 消除按键按下时候的抖
if(key==0) //再次判断按键是否依然是按下状态
{
num++;
if(num==16) //num用来指示按键按一下,就计数一次
num=0;
{这个还可以添加自己的应用程序,即按键按下时候执行相应操作,或者这里按键按下给个标志位}
while((i<50)&&(key==0)) //检测按键是否松开,这里是按键松手检测
{
Delay10ms();
i++;
}
i=0;
}
}
}
下面就是用中断来实现独立按键功能
#define GPIO_LED P2
//外部中断的IO
sbit K3=P3^2;
sbit K4=P3^3;
void IntConfiguration();
void Delay(unsigned int n);
unsigned char KeyValue=0;
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main(void)
{
GPIO_LED=0Xfe;
IntConfiguration();
while(1)
{
if(KeyValue)
GPIO_LED=_crol_(GPIO_LED,1);
else
GPIO_LED=_cror_(GPIO_LED,1);
Delay(2000);
}
}
函 数 名 : IntConfiguration()
* 函数功能 : 设置外部中断
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IntConfiguration()
{
//设置INT0
IT0=1;//跳变沿出发方式(下降沿)
EX0=1;//打开INT0的中断允许。
//设置INT1
IT1=1;
EX1=1;
EA=1;//打开总中断
}
/*******************************************************************************
* 函 数 名 : Delay(unsigned int n)
* 函数功能 : 延时
* 输 入 : n
* 输 出 : 无
*******************************************************************************/
void Delay(unsigned int n) //延时50us误差 0us
{
unsigned char a,b;
for(;n>0;n--)
{
for(b=1;b>0;b--)
for(a=22;a>0;a--);
}
}
/**
/*******************************************************************************
* 函 数 名 : Int0()interrupt 0
* 函数功能 : 外部中断0的中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Int0()interrupt 0//外部中断0的中断函数
{
Delay(1); //延时消抖 这个地方是按键消抖动
if(K3==0) //判断按键按下,然后执行相应操作
KeyValue=1;
}
/*******************************************************************************
主要是中断函数怎么写 ,还有就是在中断函数中是否需要清除标志位什么的,同时是配置的上升沿触发还是下降沿触发中断(这个很重要决定了是判断k==1还是k==0)
l void int_key() interrupt 0//外部中断1服务程序
{
EX0=0;//关外部中断1
delay_ms(100);
if(s1==0) //s1是外部中断对应的IO口 判断为0,就是下降沿中断,因为没有按键时候是高电平,一按下就会出现下降沿,当手松开变成高电平,又出现上升沿。所以手按下是低电平,同时先出现的是下降沿
{
s1_num++; //这里是用户自己编写的程序
s1_num%=4;//这里是用户自己编写的程序或者标志位什么的
di();//这里是用户自己编写的程序或者函数
}
while(!s1);
EX0=1;//开外部中断
}
delay_ms(100),if(s1==0)是必需要有的,延时是为了消抖,if(s1==0)是为了看看延时后是否还为低电平,如果还为低电平那确实是按下按键了,并且这样可以有效地做到一次按键只进入一次中断,当然delay_ms(100)这个延时时间不能太长,否则正常的按键也会在延时后,因为时间太长手已经松开变为高电平,而判断错误。这个中断是下降沿触发。