#include<reg52.h>
#include<intrins.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
uchar key_No[]={'1','2','3','4','5','6','7','8','9','+','-','*','/'};
sbit RS=P2^4; //寄存器选择位
sbit RW=P2^0; //读写选择位
sbit E=P2^3; //使能信号位
sbit busy=P0^7;
uchar tmp; //暂存P2的值
uchar keynum;
void show(uint sum);
void clean();
void delay(uint z);
/*void check() // 判断忙或空闲
{
do{
P0=0xFF;
RS=0; //指令
RW=1; //读
E=0; //禁止读写
delay(1); //等待,液晶显示器处理数据
E=1; //允许读写
}while(busy==1); //判断是否为空闲,1为忙,0为空闲
}*/
//毫秒级延时
void delay(uint z)
{
uint x, y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void keyscan()
{
while(1)
{
P3=0xfe; //扫描第1行
if(P1!=0xff) //有按键按下
{
tmp = P3;
delay(5);
if(P1!=0xff) //延时后确定有按键按下
{
switch(tmp)
{
case 0xfe: keynum=1;break; //第1行第1个按键按下
case 0xfd: keynum=2;break; //第1行第2个按键按下
case 0xfb: keynum=3;break; //第1行第3个按键按下
case 0xf7: keynum=4;break; //第1行第4个按键按下
case 0xef: keynum=5;break; //第1行第5个按键按下
}
while(tmp!=0xff) //等待按键松手
{
tmp=P1;////?????????????????????????????
}
}
}
delay(5);
P3=0xfd; //扫描第2行
if(P1!=0xff) //有按键按下
{
tmp = P1;
delay(5);
if(P1!=0xff) //延时后确定有按键按下
{
switch(tmp)
{
case 0xfe: keynum=9;show(6); break; //第2行第1个按键按下
case 0xfd: keynum=10;show(7);break; //第2行第2个按键按下
case 0xfb: keynum=11;show(8);break; //第2行第3个按键按下
case 0xf7: keynum=12;show(9);break; //第2行第4个按键按下
case 0xef: keynum=13;break; //第2行第5个按键按下
}
while(tmp!=0xff)
{
tmp=P1;
}
}
}
delay(5);
P3=0xfb; //扫描第3行
if(P1!=0xff) //有按键按下
{
tmp = P1;
delay(5);
if(P1!=0xff) //延时后确定有按键按下
{
switch(tmp)
{
case 0xfe: keynum=17;show(3);break; //第3行第1个按键按下
case 0xfd: keynum=18;show(4);break; //第3行第2个按键按下
case 0xfb: keynum=19;show(5);break; //第3行第3个按键按下
case 0xf7: keynum=20;show(10);break; //第3行第4个按键按下
case 0xef: keynum=21;break; //第3行第5个按键按下
}
while(tmp!=0xff)
{
tmp=P1;
}
}
}
delay(5);
P3=0xf7; //扫描第4行
if(P1!=0xff) //有按键按下
{
tmp = P1;
delay(5);
if(P1!=0xff) //延时后确定有按键按下
{
switch(tmp)
{
case 0xfe: keynum=25;show(0);break; //第4行第1个按键按下
case 0xfd: keynum=26;show(1);break; //第4行第2个按键按下
case 0xfb: keynum=27;show(2);break; //第4行第3个按键按下
case 0xf7: keynum=28;show(11);break; //第4行第4个按键按下
case 0xef: keynum=29;break; //第4行第5个按键按下
}
while(tmp!=0xff)
{
tmp=P1;
}
}
}
delay(5);
P3=0xef; //扫描第5行
if(P1!=0xff) //有按键按下
{
tmp = P1;
delay(5);
if(P1!=0xff) //延时后确定有按键按下
{
switch(tmp)
{
case 0xfe: keynum=33;break; //第5行第1个按键按下
case 0xfd: keynum=34;break; //第5行第2个按键按下
case 0xfb: keynum=35;break; //第5行第3个按键按下
case 0xf7: keynum=36;show(12);break; //第5行第4个按键按下
case 0xef: keynum=37;clean();break; //第5行第5个按键按下
}
while(tmp!=0xff)
{
tmp=P2;
}
}
}
delay(5);
}
}
void Write_com(uchar com)
{
// while(BusyTest()==1);
RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
E=0; //E置低电平(写指令时,E为高脉冲) 就是让E从0到1发生正跳变,所以应先置"0"
P0=com; //将数据送入P0口,即写入指令或地址
//check();
delay(1);
E=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
//*********************写数据
void WriteData(uchar dat)
{
// while(BusyTest()==1);
RS=1; //RS为高电平,RW为低电平时,可以写入数据
RW=0;
E=0; //(写指令时,E为高脉冲)
// 就是让E从0到1发生正跳变,所以应先置"0"
P0=dat; //将数据送入P0口,即将数据写入液晶模块
//check();
delay(1);
E=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
void Init(void)
{
Write_com(0x30); //显示模式设置:16×1显示,5×7点阵,8位数据接口
Write_com(0x0f); //显示模式设置:显示开,无光标
Write_com(0x06); //显示模式设置:光标右移,
// Write_com(0x01); //清屏幕指令,将以前的显示内容清除
}
void clean()//屏幕清零子函数。
{
Write_com(0x01); //清屏幕指令,将以前的显示内容清除
}
void show(uint sum)
{
uint a;
a=sum;
Init();
Write_com(0x80);
WriteData( key_No[a]);
delay(1);
}
void main()
{
keyscan();
}
这个程序我用protues
仿真了。遇到了两个问题:
1、按过的按键,再按就没有显示。
2、只能显示1个数字。
这个程序离我的要求还有点远啊!求大神指点!
一周热门 更多>