基于单片机的矩阵键盘&12864液晶串口显示。程序是借鉴别人的。有什么不对欢迎改进。
#include<reg52.h>
#define U8 unsigned char
#define U16 unsigned int
#include<intrins.h>
#define uchar unsignedchar
sbit sclk=P0^0; //时钟数据传送端口
sbit sid=P0^1; //串行数据
/*定义行列*/
uchar hang;
uchar lie ;
uchar key ;
uchar code table[]="0123A456B789C*0#D";
void delayms(U16 ms)//延迟
{
U16 i;
for(;ms>0;ms--)
{
for(i=124;i>0;i--);
}
}
void send_dat(U8 dat) //发送数据
{
U8 i;
for(i=0;i<8;i++)
{
sclk=0;
dat<<=1;
sid=CY;
sclk=1;
}
}
U8 get_byte() //获取数据
{
U8 i,temp1=0,temp2=0;
for(i=0;i<8;i++)
{
temp1=temp1<<1;
sclk = 0;
sclk = 1;
sclk = 0;
if(sid) temp1++;
}
for(i=0;i<8;i++)
{
temp2=temp2<<1;
sclk = 0;
sclk = 1;
sclk = 0;
if(sid) temp2++;
}
return ((0xf0&temp1)+(0x0f&temp2));
}
void check_busy()
{
do
{
send_dat(0xfc);
}
while(get_byte()&0x80);
}
void send_cmd(U8 cmd)
{
check_busy();
send_dat(0xf8); //
send_dat(cmd&0xf0); //
send_dat((cmd&0x0f)<<4); //
}
void write_char(U8 dat)
{
check_busy();
send_dat(0xfa);//rw=0;rs=1
send_dat(dat&0xf0);
send_dat((dat&0x0f)<<4);
}
void lcd_clear() //清除显示
{
send_cmd(0x01);
}
void lcd_pos(U8 y_add , U8 x_add)
{
switch(y_add)
{
case 1:
send_cmd(0X80|x_add);break;
case 2:
send_cmd(0X90|x_add);break;
case 3:
send_cmd(0X88|x_add);break;
case 4:
send_cmd(0X98|x_add);break;
default:break;
}
}
void lcd_wstr(U8 y_add , U8 x_add , U8 *str) //
{
U8 i;
lcd_pos(y_add , x_add);
for(i=0;str[i]!='\0';i++)
{
write_char(str[i]);
}
}
void write_figer(uchar y_add , uchar x_add , uchar figer)//在任何位置写数字
{
uchar d[5],i,j;
lcd_pos(y_add , x_add);
d[4]=figer%10;
d[3]=figer%100/10;
d[2]=figer%1000/100;
d[1]=figer%10000/1000;
d[0]=figer/10000;
for(i=0;i<5;i++)
{
if(d[i]!=0)break;
}
if(5==i)i--;
if(i==4) send_cmd(0x30);//数据装完,准备发送
for(j=i;j<5;j++)
{
send_cmd(d[j]|0x30);//取得的数字加上0x30也即得到该数字的ASCII码,再将该数字发送去显示
}
}
void lcd_init() //
{
delayms(1);
send_cmd(0x30);
send_cmd(0x0C);//0000,1100 整体显示,游标off,游标位置off
send_cmd(0x01);//0000,0001 清DDRAM
send_cmd(0x02);//0000
,0010 DDRAM地址归位
send_cmd(0x80);//1000,0000 设定DDRAM 7位地址000,0000到地址计数器A
}
/***************************************************************
基于单片机的矩阵键盘&12864液晶串口显示。程序是借鉴别人的。有什么不对欢迎改进。
***/
/* 名称:按键扫描函数*/
/* 功能:逐行检测是否有键按下*/
/* 有或者没有都有返回值*/
/******************************************************************/
uchar keyscan()
{
P3=0xf0;
if ((P3&0xf0)!=0xf0)
{
switch(P3)
{
case 0xe0: lie =1;break;
case 0xd0: lie =2;break;
case 0xb0: lie =3;break;
case 0x70: lie =4;break;
default: break;
}
delayms(1);
P3=0x0f;
if((P3&0x0f)!=0x0f)
{
switch(P3)
{
case 0x0e: hang =1;break;
case 0x0d: hang=2;break;
case 0x0b: hang =3;break;
case 0x07: hang =4;break;
default: break ;
}
}
return ((hang- 1)*4+lie) ;
}
else return (0);
}
main()
{
uchar key=0 ;
P0=0xff;
lcd_clear();
while(1)
{
P3=0xf0;
if((P3&0xf0)!=0xf0) //假如有键盘按下
{
key=keyscan();
}
delayms(50);
lcd_wstr(1,0,"欢
迎使用");
lcd_wstr(2,0,"仅供参考");
lcd_wstr(3,0,"请输入数字:");
delayms(50);
lcd_pos(4,0);
write_char(table[key]);
}
}
