利用查询IO口的方式实现按键控制LED‘灯的亮灭
#include "s3c24xx.h"
#define LED_ON 0
#define LED_OFF 1
#define KEY1_POS (0)//按键1在IO端口的位置,此处为GPF0端口,则值为0
#define KEY2_POS (2)//按键2在IO端口的位置,此处为GPF2端口,则值为
#define KEY3_POS (3)//GPG3 EINT11
#define LED1_POS (1<<4)//LED1在IO端口的位置,此处为GPF4端口,则值为4
#define LED2_POS (1<<5)//LED2在IO端口的位置,此处为GPF5端口,则值为
#define LED3_POS (1<<6) //GPF6
//软件关系,与硬件无关 buffe
#define OFS_KEY1 (0)//按键1的状态保存在变量中的位置,此处为保存在变量的第0位
#define OFS_KEY2 (1)//
#define OFS_KEY3 (2)
#define GPF4_out (1<<(4*2))//设置GPFCON的第8,9位,即设置GPF4位输出
#define GPF5_out (1<<(5*2))//设置GPFCON的第10,11位,即设置GPF5位输出
#define GPF6_out (1<<(6*2))//设置GPFCON的第12,13位,即设置GPF6位输出
#define GPF7_out (1<<(7*2))
#define hrdReadKey1 ((GPFDAT>>KEY1_POS)&0X01)//读取按键1的状态
#define hrdReadKey2 ((GPFDAT>>KEY2_POS)&0X01)//读取按键2的状态
#define hrdReadKey3 ((GPGDAT>>KEY3_POS)&0X01)//读取按键2的状态
#define hrdLed1On (GPFDAT &= (~LED1_POS))//使GPF4输出0
#define hrdLed1Off (GPFDAT |= (LED1_POS))//使GPF4输出1
#define hrdLed2On (GPFDAT &= (~LED2_POS))//使GPF5输出0
#define hrdLed2Off (GPFDAT |= (LED2_POS))//使GPF5输出1
#define hrdLed3On (GPGDAT &= (~LED3_POS))//使GPG6输出0
#define hrdLed3Off (GPGDAT |= (LED3_POS))//使GPG6输出1
typedef union
{
unsigned long byte;
struct
{
unsigned long key1 :1;
unsigned long key2 :1;
unsigned long key3 :1;
unsigned long notused :5;
}bits;
}mmiFlag_t;
mmiFlag_t mmiFlag;
#define mmiFlag_Key1 mmiFlag.bits.key1 //判断按键按下后是否为首次处理
#define mmiFlag_Key2 mmiFlag.bits.key2 //判断按键按下后是否为首次处理
#define mmiFlag_Key3 mmiFlag.bits.key3 //判断按键按下后是否为首次处理
typedef union
{
unsigned long byte;
struct
{
unsigned long led1 :1;
unsigned long led2 :1;
unsigned long led3 :1;
unsigned long notused :5;
}bits;
}ledStatus_t;
ledStatus_t ledStatus;
#define led1Status ledStatus.bits.led1
#define led2Status ledStatus.bits.led2
#define led3Status ledStatus.bits.led3
volatile unsigned long dgtInBuf=1;//保存开关量输入状态
volatile unsigned long dgtInPre;//预存存开关输入状态
volatile unsigned long dgtCount;//开关量输入的延迟计数
//初始化IO口
void ioInitialize_IO(void)
{
GPFCON |= GPF4_out; // 设置GPF4,GPF5,GPF6为输出口, 位[9:8]=0b01
GPFCON &=(~GPF5_out);
GPFCON |= GPF5_out;
GPFCON |= GPF6_out;
GPFDAT = 0x00000000; // GPF4输出0,LED1点亮
}
//刷新IO口,在此处做读取或者写IO端口操作
void ioRefresh_IO(void)
{
unsigned long buf=0;
if(hrdReadKey1==0)//读取按键1的输入状态
buf |= (1<<OFS_KEY1);//如果为0,则第0位置1
else if(hrdReadKey2==0)
buf |= (1<<OFS_KEY2);
else if(hrdReadKey3==0)
buf |= (1<<OFS_KEY3);
dgtInBuf = buf;//将读取到的按键状态保存到dgtInBuf中
}
/*延迟*/
void wait(unsigned long dly)
{
for(;dly>0;dly--);
}
/*
*******************************按键处理函数*****************************************
利用查询 IO口的方式实现,不是中断
*/
void mmiProcess_Key1(void)
{
//mmiFlag_Key1判断按键是否为首次按下,直到释放,才判断下一次的按下与否
if((dgtInBuf&(1<<OFS_KEY1))&& (mmiFlag_Key1==0))//判断按键是否按下,且为首次处理
{
mmiFlag_Key1 = 1;//标志位设为1,防止按键未释放,再次进入此判断体
if(led1Status==0)//LED灯状态翻转
{
led1Status = 1;
hrdLed1Off;
}
else
{
led1Status = 0;
hrdLed1On;
}
}
else if((dgtInBuf&(1<<OFS_KEY1))==0)//等待按键释放
{
mmiFlag_Key1 = 0;//标志位设为0,等待下次按键按下
}
}
void mmiProcess_Key2(void)
{
//mmiFlag_Key2判断按键是否为首次按下,直到释放,才判断下一次的按下与否
if((dgtInBuf&(1<<OFS_KEY2))&& (mmiFlag_Key2==0))//判断按键是否按下,且为首次处理
{
mmiFlag_Key2 = 1;//标志位设为1,防止按键未释放,再次进入此判断体
if(led2Status==0)//LED灯状态翻转
{
led2Status = 1;
hrdLed2Off;
}
else
{
led2Status = 0;
hrdLed2On;
}
}
else if((dgtInBuf&(1<<OFS_KEY2))==0)//等待按键释放
{
mmiFlag_Key2= 0;//标志位设为0,等待下次按键按下
}
}
void mmiProcess_Key3(void)
{
//mmiFlag_Key3判断按键是否为首次按下,直到释放,才判断下一次的按下与否
if((dgtInBuf&(1<<OFS_KEY3))&& (mmiFlag_Key3==0))//判断按键是否按下,且为首次处理
{
mmiFlag_Key3 = 1;//标志位设为1,防止按键未释放,再次进入此判断体
if(led3Status==0)//LED灯状态翻转
{
led3Status = 1;
hrdLed3Off;
}
else
{
led3Status = 0;
hrdLed3On;
}
}
else if((dgtInBuf&(1<<OFS_KEY3))==0)//等待按键释放
{
mmiFlag_Key3= 0;//标志位设为0,等待下次按键按下
}
}
void mmiHandle_MMI(void)
{
if(dgtInBuf!=dgtInPre)//判断按键输入状态是否与上一次一致
{
dgtInPre = dgtInBuf;//将此次状态赋值给Pre变量
dgtCount = 0;//计数清0
}
else//如果按键输入状态与上一次一致
{
dgtCount++;//计数加1
if(dgtCount>=5)//做了5*1ms=5ms的延迟,连续5次状态一致,则认为此次输入为有效输入
{
dgtCount = 0;
mmiProcess_Key1();
mmiProcess_Key2();
mmiProcess_Key3();
}
}
}
int main()
{
ioInitialize_IO();
for(;;)
{
wait(1000);// 1ms的延迟
ioRefresh_IO();
mmiHandle_MMI();
}
return 0;
}