标题:
4X4矩阵键盘扫描lcd1602液晶显示
[打印本页]
作者:
daming
时间:
2014-12-30 01:33
标题:
4X4矩阵键盘扫描lcd1602液晶显示
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit BEEP=P3^6;
sbit RS=P2^0;
sbit RW=P2^1;
sbit E=P2^2;
sbit BF=P0^7;
uchar code digit[]="0123456789ABCDEF";
uchar code key_code[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77 };
uchar code str[]="Input Data:";
uchar key;
/************************************
函数功能:1ms基准延时
入口参数:n
************************************/
void delay1ms(unsigned int n )
{
unsigned char i;
while(n--)
for(i=0;i<115;i++);
}
/************************************
函数功能: 500us延时
************************************/
void delay500us()
{
uchar i;
for(i=0;i<57;i++);
}
/************************************
函数功能: 蜂鸣器产生1KHZ频率声音,
************************************/
void beep()
{
uchar i;
for(i=0;i<200;i++){
BEEP=~BEEP;
delay500us();
}
BEEP=1;
}
/************************************
函数功能:判断液晶的忙碌状态
返回值:result=1,忙碌;result=0,不忙
************************************/
bit BusyTest()
{
bit result;
RS=0; //读状态时,RS=0,RW=1,E=1
RW=1;
E=1;
_nop_(); //延时一个时钟周期
_nop_();
_nop_();
_nop_(); //4个周期延时,给硬件反应时间
result=BF;
E=0; //将E置0,不允许读
return result;
}
/************************************
函数功能:将模式设置指令或显示地址送入液晶
入口参数:dictate
************************************/
void WriteInstruction(uchar dictate)
{
while(BusyTest()==1); //如果忙就等待
RS=0; //写指令时,RS=0.RW=0,E=负跳变
RW=0;
E=0; //先将E拉低
_nop_();
_nop_(); //给硬件反应时间
P0=dictate; //将数据送入P0口,即指令或地址
_nop_();
_nop_();
_nop_();
_nop_(); //反应时间
E=1; //上升沿读入指令或地址
_nop_();
_nop_();
_nop_();
_nop_();
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/************************************
函数功能:指定字符显示的实际地址
入口参数:x
************************************/
void WriteAddress(uchar x)
{
WriteInstruction(x|0x80); //显示位置的确定方法为“0x80+地址码x”
}
/************************************
函数功能:将数据(ASKII码)写入液晶模块
入口参数:y(字符常量)
************************************/
void WriteData(unsigned char y)
{
while(BusyTest()==1); //如果忙碌就等待
RS=1; //写数据时RS=1,RW=0,E=负跳变
RW=0;
E=0; //先将E拉低
_nop_();
_nop_();
P0=y;
_nop_();
_nop_();
_nop_();
_nop_(); //反应时间
E=1;
_nop_();
_nop_();
_nop_();
_nop_();
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/************************************
函数功能:对LCD的显示模式进行初始化
************************************/
void LcdInt()
{
delay1ms(15); //首次写指令时给LCD一段较长的反应时间
WriteInstruction(0x38); //显示模式设置:16X2显示,5X7点阵,8位数据总线
delay1ms(5);
WriteInstruction(0x38);
delay1ms(5);
WriteInstruction(0x38);
delay1ms(5); //3次写 设置模式
WriteInstruction(0x0c); //显示模式设置:显示开,有光标,光标闪烁
delay1ms(5);
WriteInstruction(0x06); //显示模式设置:光标右移,字符不移
delay1ms(5);
WriteInstruction(0x01); //清屏
delay1ms(5);
}
/************************************
函数功能: 扫描键盘
************************************/
void key_scan()
{
uchar scan1,scan2,keycode,i;
P1=0xf0;
scan1=P1;
if((scan1&0xf0)!=0xf0){ //判断是否按键
delay1ms(15); //延时消陡
scan1=P1;
if((P1&0xf0)!=0xf0){ //二次判断是否按键
P1=0x0f; //线反转法德核心
scan2=P1;
keycode=scan1|scan2; //组合成键编码
}
for(i=0;i<16;i++){
if(keycode==key_code[i]){ //查表得键值
key=i;
}
}
}
else{
P1=0xff; //P1口写1,输入状态
}
}
/***************************************
函数功能:显示数字
***************************************/
void Display()
{
WriteAddress(0x47);
delay1ms(5);
WriteData(digit[key]);
}
/***********************************
函数功能:主函数
***********************************/
void main()
{
uchar i;
P1=0xff; //写1,读状态
delay1ms(15);
LcdInt();
WriteInstruction(0x01);
delay1ms(5);
WriteAddress(0x02);
delay1ms(5);
for(i=0;str[i]!='\0';i++){
WriteData(str[i]);
delay1ms(10);
}
WriteAddress(0x47);
delay1ms(5);
WriteData('0');
while(1){
P1=0xf0;
if((P1&0xf0)!=0xf0){
delay1ms(15);
if((P1&0xf0)!=0xf0){
key_scan();
Display();
beep();
delay1ms(200);
}
}
}
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1