专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

单片机键盘的扫描查询方式输入

作者:佚名   来源:本站原创   点击数:  更新时间:2008年07月06日   【字体:

//本程序用于pic单片机外接键盘的识别,通过编程,使按下K1键时第一个数码管显示1,按下K2键时第一
//个数码管上显示2,按下K3键时第一个数码管上显示3,按下K4键时第一个数码管上显示4,
//程序由http://www.51hei.com 提供,有问题请联系单片机网。
//对键盘的扫描采用查询方式。

#include "p18f458.h"

static volatile int table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
volatile unsigned char data;
unsigned int i;
unsigned char j=0;

/*初始化子程序*/
void initial()
{
 TRISA=0x00;     /*A口设置为输出*/
 TRISB=0XF0;     /*RB1输出,RB4输入*/
 TRISC=0x00;     /*SDO引脚为输出,SCK引脚为输出*/
 TRISE=0x00;     /*E口设置为输出*/
 INTCON=0x00;    /*关闭所有中断*/
 SSPCON1=0x30;    /*SSPEN=1;CKP=1,FOSC/4*/
 SSPSTAT=0xC0;    /*时钟下降沿发送数据*/
 PIR1=0;      /*清除SSPIF标志*/ 
}

/*软件延时子程序*/
void DELAY()
{
 for(i = 6553; --i ;)
 continue;
}

/*键盘扫描子程序*/
int  KEYSCAN()

 PORTBbits.RB1=0;
 PORTAbits.RA3=0;
 PORTE=0;     /*将K1,K2,K3,K4四条列线置0*/
 while(1)
 {
  if (PORTBbits.RB4==0)
  break;
 }       /*等待有键按下,RB4为0表示有键按下*/
 DELAY();     /*软件延时*/
 if (PORTBbits.RB4==0)
  KEYSERVE();    /*如果仍有键按下,则调用键服务子程序*/
 else j=0x00;     /*如果为干扰,则令返回值为0*/
 return(j);
}
 
/*键服务子程序*/
int  KEYSERVE()
{
 PORTBbits.RB1=0;    /*K1,K2置低电平,K3,K4置高电平*/
 PORTAbits.RA3=0;    /*RB4为0,表示按键为K1,K2中的一个*/
 PORTE=3;     /*RB4为1,表示按键为K3,K4中的一个*/
 if(PORTBbits.RB4==0)
 {
  PORTBbits.RB1=0;   /*K1置低电平,K2置高电平*/
  PORTAbits.RA3=1;   /*RB4为0,表示按键为K1;RB4为1,表示按键为K2*/
  if(PORTBbits.RB4==0) j=0X01;
  else {j=0X02; PORTAbits.RA3=0;}
 }
 else
 {
  PORTEbits.RE0=0;   /*K3置低电平,K4置高电平*/
  PORTEbits.RE1=1;   /*RB4为0,表示按键为K3;RB4为1,表示按键为K4*/
  if(PORTBbits.RB4==0) j=0X03;
  else {j=0X04; PORTEbits.RE1=0;}  
 }
 while(1)
 {
  if(PORTBbits.RB4==1) break; /*为了防止一次按键多次识别,等键松开才返回*/
 }
 return(j);
}

/*显示子程序*/
void SPILED(char data)
{
 PORTAbits.RA5=0;    /*LACK送低电平,为锁存做准备*/
 SSPBUF=data;     /*启动发送*/
 do
 {
 ;
 }while(PIR1bits.SSPIF==0);  /*等待发送完毕*/
 PIR1bits.SSPIF=0;    /*清除SSPIF标志*/
 PORTAbits.RA5=1;    /*最后给锁存信号,代表显示任务完成*/
}

/*键盘扫描查询方式输入主程序*/
main()
{
 initial();      /*系统初始化*/  
 while(1)
 {
  KEYSCAN();
  if(j!=0)     /*如果j=0,证明先前的按键为干扰,则不予显示*/
  {
   data=table[j];
   SPILED(data);   /*发送显示段码显示*/
  }
   }
}
 

关闭窗口