//這是51hei單片機開發板附帶的一個程序,矩陣鍵盤接p3口,其中p3.0-p3.4為行,P3.5->p3.7為列
//每按一下鍵數字便可顯示在1602液晶上面,并且蜂鳴器會發出響聲.
//全部源代碼下載: http://m.izizhuan.cn/f/jz1602.rar
#include<reg52.h>
#include <Intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
sbit rs=P2^2;
sbit lcden=P2^0;
sbit rw=P2^1;
sbit BEEP=P2^3;
uchar num,temp,date,i;
uchar code table_1[]=" shu ru tiao ma ";
uchar code table_2[]=" Pro_8888 ";
uchar code dis_tab[17]=
{
0x30, //0在1602中的十六進制碼
0x31, //1在1602中的十六進制碼
0x32, //2在1602中的十六進制碼
0x33, //3在1602中的十六進制碼
0x34, //4在1602中的十六進制碼
0x35, //5在1602中的十六進制碼
0x36, //6在1602中的十六進制碼
0x37, //7在1602中的十六進制碼
0x38, //8在1602中的十六進制碼
0x39, //9在1602中的十六進制碼
0x41, //A在1602中的十六進制碼
0x42, //B在1602中的十六進制碼
0x43, //C在1602中的十六進制碼
0x44, //D在1602中的十六進制碼
0x2A, //*在1602中的十六進制碼
0x23, //#在1602中的十六進制碼
0x20, // 在1602中的十六進制碼
};
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void beep()
{
uchar i;
for (i=0;i<50;i++)
{
delay(4);
BEEP=0; //BEEP取反
}
BEEP=1; //關閉蜂鳴器
delay(100); //延時
}
void lcd_wait_busy() //1602忙檢測函數
{
P0=0xff; //數據口全部置1,為讀狀態做準備
rs=0; //選擇指令寄存器
rw=1; //選擇讀
lcden=1; //使能線電平變化
while((P0&0x80)==0x80);//讀忙狀態,不忙時退出
lcden=0; //恢復使能線電平
}
// 1602寫命令函數
void lcd_write_com(unsigned char combuf)
{
rs=0; //選擇指令寄存器
rw=0; //選擇寫
P0=combuf; //把命令字送入P2
lcden=1; //使能線電平變化,命令送入1602的8位數據口
_nop_();
lcden=0; //恢復使能線電平
}
// 1602寫命令函數(帶忙檢測)
void lcd_write_com_busy(unsigned char combuf)
{
lcd_wait_busy(); //調用忙檢測函數
lcd_write_com(combuf); //調用寫命令函數
}
// 1602寫數據函數(帶忙檢測)
void lcd_write_data(unsigned char databuf)
{
lcd_wait_busy(); //調用忙檢測函數
rs=1; //選擇數據寄存器
rw=0; //選擇寫
P0=databuf; //把數據字送入P2
lcden=1; //使能線電平變化,命令送入1602的8位數據口
_nop_();
lcden=0; //恢復使能線電平
}
// 1602顯示地址寫函數
void lcd_write_address(unsigned char x,unsigned char y)
{
y&=0x01; //行地址限制在0-1
if(y==0x00)
lcd_write_com_busy(x|0x80); //第一行的列地址寫入
else
lcd_write_com_busy((x+0x40)|0x80); //第二行的列地址寫入
}
// 指定地址寫入函數
void lcd_write_char(unsigned char x,unsigned char y,unsigned char buf)
{
lcd_write_address(x,y); //寫入地址
lcd_write_data(buf); //寫入顯示數據
}
// 液晶初始化指令
void lcd_init()
{
uchar num;
dula=0;
wela=0;
lcden=0;
lcd_write_com_busy(0x38); //設置16*2顯示,5*7點陣,8位數據接口
lcd_write_com_busy(0x0d); //關顯示 顯示光標 光標閃爍
lcd_write_com_busy(0x06); //當讀或寫一個字符后地址指針加一,且光標加一,寫一個字符,整屏顯示移動
lcd_write_com_busy(0x01); //顯示清屏:1,數據指針清零 2,所有顯示清零
lcd_write_com_busy(0x80); //80h+地址碼(0-27h,40h-67h) 設置數據地址指針
for(num=0;num<16;num++)
{
lcd_write_data(table_1[num]);
delay(5);
}
lcd_write_com_busy(0x80+0x40);
}
void key_wdat(uchar i) //按鍵寫數據
{
// dula=0;
// wela=0;
// lcden=0;
//液晶初始化指令
// write_com(0x38); //設置16*2顯示,5*7點陣,8位數據接口
// write_com(0x0d); //關顯示 顯示光標 光標閃爍
// write_com(0x06); //當讀或寫一個字符后地址指針加一,且光標加一,寫一個字符,整屏顯示移動
// write_com(0x01); //顯示清屏:1,數據指針清零 2,所有顯示清零
// write_com(0x80+0x40); //80h+地址碼(0-27h,40h-67h) 設置數據地址指針
lcd_wait_busy();
lcd_write_data(i);
delay(100);
}
// 刪除液晶第1或2行全部數據
void clear(uchar t)
{
if(t==1)
{
lcd_write_com_busy(0x80);
}
if(t==2)
{
lcd_write_com_busy(0x80+0x40);
}
for(i=0;i<15;i++)
{
lcd_write_data(dis_tab[16]);
}
lcd_write_com_busy(0x80+0x40);
}
// 產品顯示函數 待寫 如何從鍵盤輸入中提取出三位的產品號碼???????????????????
/*
void display_product()
{
}
*/
// 4*4矩陣鍵盤檢測
void keyscan()
{
lcden=1;//???
//
P3=0xfe;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:key_wdat(dis_tab[7]); beep(); // 7
break;
case 0xde:key_wdat(dis_tab[8]); beep(); // 8
break;
case 0xbe:key_wdat(dis_tab[9]); beep(); // 9
break;
case 0x7e:key_wdat(dis_tab[17]); beep(); //
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
//
P3=0xfd;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:key_wdat(dis_tab[4]); beep(); // 4
break;
case 0xdd:key_wdat(dis_tab[5]); beep(); // 5
break;
case 0xbd:key_wdat(dis_tab[6]); beep(); // 6
break;
case 0x7d:key_wdat(dis_tab[17]); beep(); //
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
//
P3=0xfb;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:key_wdat(dis_tab[1]);beep(); // 1
break;
case 0xdb:key_wdat(dis_tab[2]);beep(); // 2
break;
case 0xbb:key_wdat(dis_tab[3]);beep(); // 3
break;
case 0x7b:key_wdat(dis_tab[17]);beep(); //
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
//
P3=0xf7;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:key_wdat(dis_tab[0]); beep(); // 0
break;
case 0xd7:key_wdat(dis_tab[17]); beep(); //
break;
case 0xb7:clear(2); beep(); // 刪除液晶第二行
break;
case 0x77:beep(); // enter
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
}
//
void main()
{
lcd_init();
while(1)
{
keyscan();
}
while(1);
}
