/*******************************************************************************************
課題:1602LCD顯示仿手機鍵盤按鍵
LCD接口:P0.0-P0.7 TO D0-D7
P2.0 TO RS
P2.1 TO RW
P2.2 TO E
蜂鳴器: P2.7
鍵盤: 列(ltr) P1.0-P1.2
行(utd) P1.4-P1.7
*******************************************************************************************/
#include <reg52.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char
sbit RS=P2^0;
sbit RW=P2^1;
sbit EN=P2^2;
sbit SPK=P2^7;
uchar code KeyPad_Chars[12][6]={"1 ","2ABC","3DEF","4GHI","5JKL","6MNO","7PQRS","8TUV","9WXYZ","*","0+","#"};//初始化鍵盤字庫
uchar code Line1[]=" LJL'S Cellphone";//固定字符串
uchar code Line2[]="Your Key: ";
uchar KeyNo=-1; //鍵位0~11
uchar Inner_Idx=0; //同鍵位內(nèi)部切換
uchar tSpan=0; //同鍵位連續(xù)按鍵時間間隔
/**********************毫秒延時************************************/
void DelayMS(uint ms)
{
uchar i;
while(ms--)
{
for(i=0;i<110;i++);
}
}
/************************忙檢測***********************************/
uchar Busy_Waiting()
{
uchar lcd_status;
RS=0;
RW=1;
EN=1;
DelayMS(1);
lcd_status=P0;
EN=0;
return lcd_status;
}
/************************寫數(shù)據(jù)***********************************/
void Write_LCD_DATA(uchar dat)
{
while((Busy_Waiting()&&0x80)==0x80);
RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(1);EN=0;
}
/************************寫指令********************************/
void Write_LCD_Command(uchar cmd)
{
while((Busy_Waiting()&0x80)==0x80);
RS=0;
RW=0;
EN=0;
P0=cmd;EN=1;DelayMS(1);EN=0;
}
/*****************初始化***********************************/
void Init_LCD()
{
Write_LCD_Command(0x38);
DelayMS(1);
Write_LCD_Command(0x01);
DelayMS(1);
Write_LCD_Command(0x06);
DelayMS(1);
Write_LCD_Command(0x0c);
DelayMS(1);
}
/**********************鍵盤掃描************************************/
void Keys_Scan()
{
P1=0x0f; //高四位置0
DelayMS(1);
switch(P1) //判斷列
{
case 0x0e: KeyNo=0;break;
case 0x0d: KeyNo=1;break;
case 0x0b: KeyNo=2;
}
P1=0xf0; //第四位置0
DelayMS(1);
switch(P1) //根據(jù)行數(shù)加KN
{
case 0xe0: KeyNo+=0;break;
case 0xd0: KeyNo+=3;break;
case 0xb0: KeyNo+=6;break;
case 0x70: KeyNo+=9;
}
}
/**********************蜂鳴器**************************************/
void Beep()
{
SPK=1;
DelayMS(400);
SPK=0;
}
/**********************主程序**************************************/
void main()
{
uchar i,Pre_KeyNo=-1;
IE=0x82;
TMOD=0x01;
TH0=-50000/256;
TL0=-50000%256;
P0=P2=0xff;
SPK=0;
DelayMS(10);
Init_LCD(); //初始化
Set_LCD_POS(0); //顯示第一行
for(i=0;i<16;i++)
Write_LCD_DATA(Line1[i]);
Set_LCD_POS(0x40); //顯示第二行
for(i=0;i<16;i++)
Write_LCD_DATA(Line2[i]);
while(1)
{
P1=0xf0;
if(P1!=0xf0)Keys_Scan();//按鍵檢測
else continue;
if(Pre_KeyNo!=KeyNo) //新按鍵判斷
{
Pre_KeyNo=KeyNo;
tSpan=0; //間隔請0
Inner_Idx=0; //按鍵內(nèi)部切換清0
TR0=1; //啟動定時器
}
else //如為同一按鍵
{
if(tSpan<=40)
Inner_Idx=(Inner_Idx+1)%strlen(KeyPad_Chars[KeyNo]); //顯示下一個
else
Inner_Idx=0;
tSpan=0;
}
Set_LCD_POS(0x4b);
Write_LCD_DATA(KeyPad_Chars[KeyNo][Inner_Idx]); //顯示按鍵
Beep();
DelayMS(100);
}
}
|