上次看了圈圈的按键程序,就自己依葫芦画瓢的把4X4的键盘写成了那种形式。 //////////////////////////////////////////// //4X4键盘转化成0-15,状态存储在KeyPress中。 //按下为0,弹起为1. // 0 1 2 3 // 4 5 6 7 // 8 9 10 11 // 12 13 14 15 ///////////////////////////////////////////////
虽然程序是写出来了,测试了下程序,还行。但是好像太占RAM了。
void Key_Init() { #ifdef MATRIX KeyOld=0xffff; KeyLast=0xffff; #else KeyOld=0xf0; KeyLast=0xf0; #endif
KeyCount=0; KeyDown=0; KeyUp=0; }
uchar KeyScan4X4() { uchar sccode,recode,key_temp; HCODE&=0xf0; LCODE|=0xf0; KeyPress=0xffff; key_temp=0xff; if((LCODE&0xf0)!=0xf0) { sccode=0xfe; //行扫描 while(sccode != 0xef) //将扫描4次,key_temp为每次键值相 或的值 // { HCODE= sccode; recode=0xff; // 输出行扫描码 // if ((LCODE&0xf0) != 0xf0) // 本行有键按下 // { recode = (LCODE&0xf0)|0x0f; // 只要高位,低位置1 // key_temp&=(sccode&recode); } KeyPress=(KeyPress>>4)|0xf000; KeyPress&=(((recode>>4)<<12)|0x0fff); //当前行 >>4得到列值 <<12与KeyPress格式对齐 sccode = (sccode << 1)|0x01; // 扫描码0向高位移动 // } } return key_temp; } void KeyState0() { KeyCurrent=KeyScan(); //获取当前键值 if(KeyCurrent!=KeyOld) //与上一次键值不等,说明发生了改变。 { KeyOld=KeyCurrent; //保存新键值。 KeyCount=0; return; } else { KeyCount++; if(KeyCount>=KEYCOUNT) //确认为有效按键(包括空键). { KeyCount=KEYCOUNT; //停止计数
#ifndef MATRIX KeyPress=KeyOld; //保存当前按键 #endif
KeyDown|=((~KeyPress)&KeyLast); //按下的键(不会自动清除,若用完后应把相应位清除) KeyUp|=(KeyPress&(~KeyLast)); //弹起的键(不会自动清除,若用完后应把相应位清除) KeyLast=KeyPress; } } }
void main() { SFR_Init(); Key_Init(); while(1) { //4X4键盘 if(KeyUp&0x8000) //Key15弹起执行 { KeyUp&=0x7fff; //清弹起标志 P00=~P00; } if(KeyUp&0x0001) //Key0弹起执行 { KeyUp&=0xfffe; P01=~P01; } if(KeyUp&0x0002) { KeyUp&=0xfffd; P02=~P02; } if(KeyUp&0x0004) { KeyUp&=0xfffb; P03=~P03; } ////////////////////////////////// if(KeyUp&0x1000 ) { KeyDown&=0xefff; KeyUp&=0xefff; } if(KeyUp&0x2000) { KeyDown&=0xdfff; KeyUp&=0xdfff; }
if(KeyDown&0x1000) //Key12与Key13按下时,执行。 { if(KeyDown&0x2000) { P0=~P0; KeyDown&=0xdfff; } } /////////////////////////////////////// } }
void timer1() interrupt 3 //按键扫描 { TH1= (-10000)/256; TL1= (-10000)%256; KeyState0(); } |