//实验目的:熟悉键盘矩阵的扫描方法
//程序中没有做按键去抖,也没有考虑多个键同时按下的情况。//最低两位数码管显示相应的按键(如按下S10,在显示10;按下S25,则显示25)//无按键按下的时候显示FF //按键跟按键的扫描结果满足如下关系:// 按键 扫描结果(result) 按键 扫描结果 // K10 0XE7 K18 0XB7// K11 0XEB K19 0XBB// K12 0XED K20 0XBD// K13 0XEE K21 0XBE// K14 0XD7 K22 0X77// K15 0XDB K23 0X7B// K16 0XDD K24 0X7D// K17 0XDE K25 0X7E//硬件要求:拨码开关S4全部置ON
// 拨码开关S6全部置ON,拨码开关S5第5-6位置ON,其他位置OFF// 其它拨码开关置OFF#include<pic.h> //包含单片机内部资源预定义
__CONFIG(0x1832); //芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡int result;
void delay(); //delay函数申明 void init(); //I/O口初始化函数申明 void scan(); //按键扫描程序申明 void display(int x); //显示函数申明//--------------------------------------------------- //主程序 void main(){ while(1) //循环工作 { init(); //调用初始化子程序 scan(); //调用按键扫描子程序 display(result); //调用结果显示子程序 } } //---------------------------------------------------//初始化函数void init() { ADCON1=0X07; //设置A口为普通I/O口 TRISA=0X0f; //设置A口高2位为输出,低4位为输入 TRISC=0XF0; //设置C口高4位为输入,低4位为输出 TRISD=0X00; //设置D口为输出 PORTA=0XFF; PORTD=0XFF; //先清除所有显示 }//---------------------------------------------------
//按键扫描程序void scan(){ PORTC=0XF7; //C3输出低电平,其他三位输出高电平 asm("nop"); //插入一定延时,确保电平稳定 result=PORTC; //读回C口高4位结果 result=result&0xf0; //清除低4位 if(result!=0xf0) //判断高4位是否为全1(全1代表没按键按下)? { result=result|0x07; //否,加上低4位0x07,做为按键扫描的结果 } else //是,改变低4位输出,重新判断是否有按键按下 { PORTC=0XFb; //C2输出低电平,其他三位输出高电平 asm("nop"); //插入一定延时,确保电平稳定 result=PORTC; //读回C口高4位结果 result=result&0xf0; //清除低4位 if(result!=0xf0) //判断高4位是否为全1(全1代表没按键按下) { result=result|0x0b; //否,加上低4位0xb,做为按键扫描的结果 } else //是,改变低4位输出,重新扫描 { PORTC=0XFd; //C1输出低电平,其他三位输出高电平 asm("nop"); //插入一定延时,确保电平稳定 result=PORTC; //读回C口高4位结果 result=result&0xf0; //清除低4位 if(result!=0xf0) //判断高4位是否为全1(全1代表没按键按下) { result=result|0x0d; //否,加上低4位0x0d,做为按键扫描的结果 } else //是,改变低4位的输出,重新扫描 { PORTC=0XFe; //C0输出低电平,其他三位输出高电平 asm("nop"); //插入一定延时,确保电平稳定 result=PORTC; //读回C口高4位结果 result=result&0xf0;//清除低4位 if(result!=0xf0) //判断高四位是否为全1(全1代表没有按键按下) { result=result|0x0e;//否,加上低4位0x0e,做为按键扫描的结果 } else //是,全部按键扫描结束,没有按键按下,置无按键按下标志位 { result=0xff; //扫描结果为0xff,做为没有按键按下的标志 } } } } }//----------------------------------------------------------
//显示程序void display(int x) { switch(result) { case 0xe7: PORTD=0xf9;PORTA=0X2F;delay();PORTD=0xc0;PORTA=0X1F;delay();break; //K10 case 0xeb: PORTD=0xf9;PORTA=0X2F;delay();PORTD=0xf9;PORTA=0X1F;delay();break; //K11 case 0xed: PORTD=0xf9;PORTA=0X2F;delay();PORTD=0xa4;PORTA=0X1F;delay();break; //K12 case 0xee: PORTD=0xf9;PORTA=0X2F;delay();PORTD=0xb0;PORTA=0X1F;delay();break; //K13 case 0xd7: PORTD=0xf9;PORTA=0X2F;delay();PORTD=0x99;PORTA=0X1F;delay();break; //K14 case 0xdb: PORTD=0xf9;PORTA=0X2F;delay();PORTD=0x92;PORTA=0X1F;delay();break; //K15 case 0xdd: PORTD=0xf9;PORTA=0X2F;delay();PORTD=0X82;PORTA=0X1F;delay();break; //K16 case 0xde: PORTD=0xf9;PORTA=0X2F;delay();PORTD=0XF8;PORTA=0X1F;delay();break; //K17 case 0xb7: PORTD=0xf9;PORTA=0X2F;delay();PORTD=0X80;PORTA=0X1F;delay();break; //K18 case 0xbb: PORTD=0xf9;PORTA=0X2F;delay();PORTD=0X90;PORTA=0X1F;delay();break; //K19 case 0xbd: PORTD=0xa4;PORTA=0X2F;delay();PORTD=0xc0;PORTA=0X1F;delay();break; //K20 case 0xbe: PORTD=0xa4;PORTA=0X2F;delay();PORTD=0xf9;PORTA=0X1F;delay();break; //K21 case 0x77: PORTD=0xa4;PORTA=0X2F;delay();PORTD=0xa4;PORTA=0X1F;delay();break; //K22 case 0x7b: PORTD=0xa4;PORTA=0X2F;delay();PORTD=0xb0;PORTA=0X1F;delay();break; //K23 case 0x7d: PORTD=0xa4;PORTA=0X2F;delay();PORTD=0x99;PORTA=0X1F;delay();break; //K24 case 0x7e: PORTD=0xa4;PORTA=0X2F;delay();PORTD=0x92;PORTA=0X1F;delay();break; //K25 case 0xff: PORTD=0x8e;PORTA=0X2F;delay(); PORTD=0x8e; PORTA=0X1F; delay(); //无按键按下 } }//------------------------------------------------------------------
//延时程序void delay() //延时程序 { int i; //定义整形变量 for(i=0x100;i--;); //延时 }