今天自己把ARM7的按键防抖程序写出来了,全部代码如下:
#include "config.h"
#include "delay.h"
/****************************************************************************
* 名称:
#define KEY1 1<<3 //p0.3
#define KEY2 1<<6 //p0.6
#define KEY3 1<<7 //p0.7
#define KEY4 1<<15 //p0.15
#define KEY5 1<<30 //p0.30
#define BEEP 1<<5 //p0.5
#define LED1 1<<16 //p1.16
#define LED2 1<<17 //p1.17
#define LED3 1<<18 //p1.18
#define LED4 1<<19 //p1.19
#define LED1_TO_4 (LED1|LED2|LED3|LED4)
* 功能:宏定义
* 说明:宏定义的值,实际上是一个32位的2进制,通过二进制位移表示可以增强可读性,3各个引脚在CPU上并没有实际的2位的2进制的地址,这样定义只是为了方便操作寄存器,给寄存器赋值、寄存器和引脚进行逻辑运算提供方便,这是很聪明的方法,所以我们以后理解ARM7的引脚、寄存器,对它们进行操作,必须从2进制的角度去理解。
****************************************************************************/
#define KEY1 1<<3 //p0.3
#define KEY2 1<<6 //p0.6
#define KEY3 1<<7 //p0.7
#define KEY4 1<<15 //p0.15
#define KEY5 1<<30 //p0.30
#define BEEP 1<<5 //p0.5
#define LED1 1<<16 //p1.16
#define LED2 1<<17 //p1.17
#define LED3 1<<18 //p1.18
#define LED4 1<<19 //p1.19
#define LED1_TO_4 (LED1|LED2|LED3|LED4)
/****************************************************************************
* 名称:initSystem()
* 功能:初始化IO
****************************************************************************/
void initSystem(void)
{
IO0DIR = BEEP;
IO0CLR = BEEP;
IO1DIR = LED1_TO_4;
IO1SET = LED1_TO_4;
}
/****************************************************************************
* 名称:anti_Shake(uint32 key)
* 功能:防抖程序
* 说明:
第一次判断低电平,若是低电平,继续执行
延时程序;
第二次判断低电平,若是低电平,继续执行
第三次判断高电平 若是高电平,继续执行,难点在于如何判断高电平和跳出判断执行后面的语句,通过while判断若是低电平,继续判断,若是高电平,则不执行while,执行后面的语句。应该好好思考while它在应用在什么条件下。和if else、for的区别。
****************************************************************************/
void anti_Shake(uint32 key)
{
delay(4);
if((IO0PIN&key)==0)
{
while((IO0PIN&key)==0);
}
}
/****************************************************************************
* 名称:SCAN_KEY(void)
* 功能:扫描键盘
* 说明:
1、IO0PIN、IO1PIN寄存器,IO0PIN的32位控制P0.0-P0.31的32个引脚,IO1PIN的32位控制PIN1.0-PIN1.31的32个引脚,IO0PIN、IO1PIN寄存器的复位值没有定义的,IO0PIN的32位的二进制是xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx ,若想读引脚P0.3控制KEY1的IO0PIN的位的值,通过IO0PIN与KEY1(1<<3),xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx &0000 0000 0000 0000 0000 0000 0000 1000=xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1xxx ,就可以读到IO0PIN的位的值,与运算是有0为0,有1的得对方的值,或运算是有1为1,都为0为。
2、实现若LED亮,按一次灭,若LED灭,按一次亮的功能,代码如下
if((IO0PIN&KEY1)==0)
{
anti_Shake(KEY1);
if((IO0PIN&BEEP)==0)
{
IO0SET=BEEP;
}
else
{
IO0CLR=BEEP;
}
KEY1是输入设备,进行操作才能判断,默认不操作为高电平,操作为低电平。BEEP是输出设备,有两种状态高电平和低电平,也就是0和1.
所以分两步实现:
第一步判断若KEY1为低电平,执行if里面语句,若为高电平,则不执行
第二步分两种状态,判断BEEP若状态为高电平则输出低电平;若状态是低电平,则输出高电平,这样KEY1为低电平就可以实现,BEEP高低电平转化。
****************************************************************************/
void SCAN_KEY(void)
{
if((IO0PIN&KEY1)==0)
{
anti_Shake(KEY1);
if((IO0PIN&BEEP)==0)
{
IO0SET=BEEP;
}
else
{
IO0CLR=BEEP;
}
}
if((IO0PIN&KEY2)==0)
{
anti_Shake(KEY2);
if((IO1PIN&LED1)==0)
{
IO1SET=LED1;
}
else
{
IO1CLR=LED1;
}
}
if((IO0PIN&KEY3)==0)
{
anti_Shake(KEY3);
if((IO1PIN&LED2)==0)
{
IO1SET=LED2;
}
else
{
IO1CLR=LED2;
}
}
if((IO0PIN&KEY4)==0)
{
anti_Shake(KEY4);
if((IO1PIN&LED3)==0)
{
IO1SET=LED3;
}
else
{
IO1CLR=LED3;
}
}
if((IO0PIN&KEY5)==0)
{
if((IO1PIN&LED4)==0)
{
IO1SET=LED4;
}
else
{
IO1CLR=LED4;
}
}
}
/****************************************************************************
* 名称:main()
* 功能:主函数
* 说明:while(1)保持程序可以不断可以执行,但初始化指令 initSystem(); 不要放到循环体中。
****************************************************************************/
int main(void)
{
initSystem();
while(1)
{
SCAN_KEY();
}
return 0;
}
用户1617991 2012-6-2 17:18
用户1617991 2012-3-16 19:06
用户1617991 2012-3-16 19:05
用户1555641 2012-3-16 08:57
用户1406868 2012-3-16 08:51
程序有很大问题啊,如果键按着的话界面就会死住,要加上超时
用户1640327 2012-3-15 10:20
用户1602177 2012-3-14 13:42