C51单片机的3*3矩阵键盘程序
#include
/**延时1**/ //用于消抖
void delay1(void)
{uchar i;
for(i=0;i<200;i++);
}
/****延时2**********/
void delay2(void)
{
uchar i,j,s;
for(i=250;i>0;i--)
for(j=250;j>0;j--)
for(s=5;s>0;s--);
}
/****串口初使化****/
void chuankou_init(void)
{
TMOD=0X20;//定时器1,方式2,8位adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=17&is_app=0&jk=a379ebf740993484&k=%BC%C6%CA%FD%C6%F7&k0=%BC%C6%CA%FD%C6%F7&kdi0=0&luki=1&n=10&p=baidu&q=98059059_cpr&rb=0&rs=1&seller_id=1&sid=84349940f7eb79a3&ssp2=1&stid=0&t=tpclicked3_hc&tu=u1831118&u=http%3A%2F%2Fwww%2E51hei%2Ecom%2Fmcu%2F2174%2Ehtml&urlid=0" id="3_nwl" mpid="3" target="_blank">计数器
SCON=0x40;//方式1,而不允许接收
PCON=0X00;//波特率不翻倍
TH1=0xf4; //11.0592晶振,somd=0,波特率9600,初值=0xfa.应用sst89E564,已经倍频
TL1=0xf4;
TR1=1; //启动定时器1
}
/**键盘扫描函数**/
uchar keyscan(void)
{
uchar code_h; //行扫描值
uchar code_l; //列扫描值
P1=0xf8; //P1.0-P1.2发全0,P1.3-P1.5发1,准备读列状态
if((P1&0Xf8)!=0Xf8) //如果P1.3-P1.5不全为1,可能有键按下
{
delay1(); //消抖
if((P1&0xf8)!=0xf8) //重读列位,若还是不全为1,定有键按下
{
code_h=0xfe;//P1.0为0。开始行扫描
while((code_h&0x08)!=0x00) //判断是否为最后一行,若不是,继续扫描
{
P1=code_h; //P1口输出行扫描值
if((P1&0Xf8)!=0Xf8) //如果P1.3-P1.5不全为1,该行有键按下
{
code_l=((P1&0xf8)|0x07); //保留P3-p5位,低3位为1,作为列值
return((~code_h)+(~code_l)); //键编码=行扫描值+列扫描值,返回主程序
}
else //该行无键按下,行扫描值左移,扫描下一行
code_h=((code_h<1)|0x01);
}
}
}
return(0); //无键按下,反回0
}
/**主函数**/
void main(void)
{
uchar key;
chuankou_init(); //串口初使化
while(1)
{
key=keyscan(); //调用键盘扫描函数,返回的键值送变量key
switch(key)
{
case 0x0a:SBUF=0X00;delay2();break;
case 0x11:SBUF=0x05;delay2();break;
case 0x12:SBUF=0x04;delay2();break;
case 0x14:SBUF=0x03;delay2();break;
case 0x22:SBUF=0x01;delay2();break;
case 0x24:SBUF=0x02;delay2();break;
case 0x21:SBUF=0x06;delay2();break;
case 0x0c:break;
case 0x05:break;
default:break;
}
}
}
C51单片机矩阵键 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)