/***********************************************************
程序功能:在12864液晶上显示一屏汉字
-----------------------------------------------------------
跳线设置:将跳线座J5的1脚(+)和2脚短接,选择并行数据传输方式
-----------------------------------------------------------
测试说明:观察液晶显示
***********************************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcden=P3^4;//数据/命令选择端
sbit lcdrs=P3^5;//使能端1使能
sbit dula=P2^6;//关短数码管因为和液晶用相同的脚
sbit wela=P2^7;//锁存端
sbit RET=P1^0;//复位端0复位
sbit PSB=P1^2;//PSB 1并行0串行
sbit s1=P3^0;
sbit s2=P3^1;
sbit s3=P3^3;
sbit rd=P3^7;
uchar count,s1num;//s1num表示s1被按下的次数
uchar shi,fen,miao,yue,nian,yuedi,run;
uchar code tabletime[]="20 - - : ";
uchar code tablesen[]="000";
uchar code tabletemp[]="000.0";
uchar code tablecurr[]="0000.0";
uint i;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);//要加分号
}
//写指令RS=0,RW=0,D0~D7=指令码,E=高脉冲注意时序
void write_com(uchar com)
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
//写数据RS=1,RW=0,D0~D7=数据,E=高脉冲注意时序
void write_date(uchar date)
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_sm(uchar add,uchar date)//写时秒函数
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x9c+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void write_fen(uchar add,uchar date)//写分函数
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x9c+add);
write_date(0x20);
write_date(0x30+shi);
write_date(0x30+ge);
}
void write_nian(uchar date)//写年函数
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x99);
write_date(0x30+shi);
write_date(0x30+ge);
}
void write_yue(uchar date)//写月函数
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x9a);
write_date(0x2d);
write_date(0x30+shi);
write_date(0x30+ge);
}
void init()
{ uchar num;
//shi==1;fen==0;miao==0;yue==1;nian==1;//时间日期初值
dula=0;
wela=0;//控制数码管的锁存端关闭防止功耗不够
RET=1;//复位端0复位
PSB=1;//PSB 1并行
lcden=0;
write_com(0x30); //基本指令集
write_com(0x02); // 地址归位
write_com(0x0c); //整体显示打开,游标关闭
write_com(0x01); //清除显示
write_com(0x06); //游标右移
write_com(0x80); //设定显示的起始地址
write_com(0x92);
write_date(0xcc);
write_date(0xec);
write_date(0xcb);
write_date(0xf3);
write_date(0xd2);
write_date(0xc7);
write_date(0xc6);
write_date(0xf7); //显示天梭仪器
delay(1000);
write_com(0x01);//清屏
write_com(0x80);
write_date(0xcc);
write_date(0xbd);
write_date(0xb2);
write_date(0xe2);
write_date(0xc6);
write_date(0xf7); //显示探测器
write_com(0x90);
write_date(0xa3);
write_date(0xd4);
write_date(0xa3);
write_date(0xbd); //第二行显示T=
write_com(0x97); //写第二行末尾的显示地址
write_date(0xa1);
write_date(0xe6); //显示温度的字符
write_com(0x88); //第三行显示地址
write_date(0x49); //显示I
write_date(0x7f);//显示三角尖
write_date(0x6e);//显示n
write_date(0x3d); //显示=
write_com(0x8f); //第三行显示地址
write_date(0x6d);
write_date(0x41); //显示mA
/*探测器指标显示*/
write_com(0x85); //写第1行中间显示探测器数值
/*write_date(0x30); //百位
write_date(0x30); //十位
write_date(0x35); //个位*/
for (num=0;num<3;num++)//共18个
{
write_date(tablesen[num]);
delay(1);
}
/*温度值显示*/
write_com(0x93); //写第2行中间显示温度数值
/*write_date(0x30); //百位
write_date(0x38); //十位
write_date(0x30); //个位
write_date(0x2e); //小数点
write_date(0x35); //小数点后一位*/
for (num=0;num<5;num++)//共18个
{
write_date(tabletemp[num]);
delay(1);
}
/*电流值显示*/
write_com(0x8b); //写第3行中间显示电流数值
/*write_date(0x35); //千位
write_date(0x30); //百位
write_date(0x30); //十位
write_date(0x35); //个位
write_date(0x2e); //小数点
write_date(0x35); //小数点后一位*/
for (num=0;num<6;num++)//共18个
{
write_date(tablecurr[num]);
delay(1);
}
/*时间值显示*/
write_com(0x98); //写第4行显示时间日期
for (num=0;num<16;num++)//共18个
{
write_date(tabletime[num]);
delay(1);
}
//shi==1;fen==0;miao==0;yue==1;nian==10;//时间日期初值
write_nian(00);
write_yue(1);
write_sm(0,1);
write_fen(1,0);
write_sm(3,0);
TMOD=0X01;//定时器0方式1
TH0=(65536-50000)/256;//12Mhz
TL0=(65536-50000)%256;//付初值
EA=1;//开总中断
ET0=1;//开定时器0
TR0=1;//启动定时器*/
}
void keyscan()
{
rd=0;
if(s1==0)
{
delay(10);
if(s1==0)
{ s1num++;
while(!s1);
if(s1num==1)
{
TR0=0;//关定时器
write_com(0x99);//移到年的地址
write_com(0x0f);//开光标开闪烁
}
}
switch (s1num)
{
case 2: write_com(0x9a);break;//移到月的地址;
case 3: write_com(0x9c);break;//移到日的地址;
case 4: write_com(0x9d);break;//移到分的地址;
case 5: write_com(0x9f);break;//移到秒个位的地址
case 6: s1num=0;write_com(0x0c);TR0=1;break;//光标不再闪烁
}
}
if(s1num!=0)
{
if(s3==0)
{
delay(10);
if(s3==0)
{
while(!s3);
switch (s1num)
{
case 1: nian++;if(nian==99)nian=10;write_nian(nian);write_com(0x99);if(nian%4==0)run=1;else run=0;break;
case 2: yue++;if(yue==13)yue=1;write_yue(yue);write_com(0x9a);break;
case 3: switch (yue)
{
case 4:
case 6:
case 9:
case 11:yuedi=31;
break;
case 2: if (run==1)yuedi=30;
else yuedi=29;
break;
default:yuedi=32;
break;
}
shi++;
if(shi==yuedi)shi=1;write_sm(0,shi);write_com(0x9c);break;
case 4: fen++;if(fen==24)fen=0;write_fen(1,fen);write_com(0x9d);break;//移到分十位的地址;
case 5: miao++;if(miao==60)miao=0;write_sm(3,miao);write_com(0x9f);break;
}
}
}
/*else if(s3==0)
{
delay(10);
if(s3==0)
{
while(!s3);
switch (s1num)
{
case 1: nian--;if(nian==0)nian=99;write_nian(nian);write_com(0x99);break;
case 2: yue--;if(yue==0)yue=12;write_yue(yue);write_com(0x9a);break;
case 3: shi--;if(shi==0)shi=31;write_sm(0,shi);write_com(0x9c);break;
case 4: fen--;if(fen==-1)fen=23;write_fen(1,fen);write_com(0x9d);break;//移到分十位的地址;
case 5: miao--;if(miao==-1)miao=59;write_sm(3,miao);write_com(0x9f);break;
}
}
}*/
}
}
/***************************主函数*************************/
void main( )
{
init(); //初始化液晶
while(1)
{
keyscan();
}
// while(1);
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==10)
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==24)
{
fen=0;
shi++;
if(shi==yuedi)
{
shi=1;
yue++;
if(yue==13)
{
yue=1;
nian++;
if(nian==99)
{
nian=0;
}
write_nian(nian);
}
write_yue(yue);
}