📄 12864 万年历.c
字号:
/*====================================
程序设计:王树茂
程序名称:12864万年历
设计日期:2008年10月 9日-10日
=====================================*/
#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
/*口定义*/
#define lcd P0
sbit lcdrs=P1^2;
sbit lcden=P1^4;
sbit lcdpsb=P1^1;
sbit lcdwr=P1^3;
sbit tem_in=P2^3;
/*按键定义*/
sbit K1 = P3^4; //设定
sbit K2 = P3^5; //加
sbit K3 = P3^6; //减
/*变量定义*/
uchar hour,min,sec,sec100,nian,yue,ri,xq,wendu;
uchar temp_h,temp_l; //温度值变量
uint a;
uchar keynum;
/*函数声明*/
void write_op(uchar instruction);
void write_dat(uchar indata);
void ini_dis();
void lcd_ini();
void inc_sec();
void inc_min();
void inc_hour();
void inc_nian();
void inc_yue();
void inc_ri();
void inc_xq();
void dec_min();
void dec_hour();
void dec_nian();
void dec_yue();
void dec_ri();
void dec_xq();
void showxq();
void key_scan();
/*字符表*/
uchar code dis_char[16]="电气信息工程学院";
uchar code dis_char1[16]="公元08年10月01日";
uchar code dis_char2[16]="下午12时00分00秒";
uchar code dis_char3[16]="星期三温度:+00度";
uchar code dis_code[10]={'0','1','2','3','4','5','6','7','8','9'};
uchar code dis_code1[14]="一二三四五六日";
/*延时函数*/
void delayms(uint m)
{
uchar x,y;
for(x=m;x>0;x--)
for(y=110;y>0;y--);
}
/*====================================
以下是温度的函数模块
=====================================*/
void Delay_us(uchar n)
{
uchar i;
i=0;
while(i<n)
i++;
}
/*====================================
函数功能:DS18B20重设
=====================================*/
void dsreset(void)
{
uint i;
tem_in=0;
i=100;
while(i>0)i--;
tem_in=1;
i=4;
while(i>0)i--;
}
/*====================================
函数功能:直接读一字节程序
=====================================*/
uchar ReadByte(void)
{
uchar i,k;
i=8;
k=0;
while(i--)
{
tem_in=1;
Delay_us(2);
tem_in=0;
k=k>>1;
tem_in=1;
if(tem_in)
k |= 0x80;
Delay_us(2);
}
return(k);
}
/*====================================
函数功能:向B20写一字节
=====================================*/
void tmpwrite(unsigned char dat)
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{ testb=dat&0x01;
dat=dat>>1;
if(testb)
{ tem_in=0;
i++;
i++;
tem_in=1;
i=8;
while(i>0)
i--;
}
else
{
tem_in=0;
i=8;
while(i>0)
i--;
tem_in=1;
i++;
i++;
}
}
}
/*====================================
函数功能:启动温度转换
=====================================*/
void tmpchange(void)
{
dsreset(); /*复位*/
delayms(1);
tmpwrite(0xcc); //跳过序列号命令
tmpwrite(0x44); //转换命令
}
/*====================================
函数功能:将温度值读出来并转化为显示数组
=====================================*/
void tmp(void)
{
uint dis;
dsreset();
delayms(1);
tmpwrite(0xcc);
tmpwrite(0xbe);
temp_l=ReadByte();//低位在前
temp_h=ReadByte();//高位在后
if((temp_h&0xf8)==0)
{
dis=temp_h*16+temp_l/16;
write_op(0x9d);
write_dat(':');
write_dat('+');
write_op(0x9e);
write_dat(dis_code[((dis)%100)/10]);
write_dat(dis_code[((dis)%100)%10]);
}
else
{
dis=temp_h*16+temp_l/16;
dis=~dis+1;
write_op(0x9d);
write_dat(':');
write_dat('-');
write_op(0x9e);
write_dat(dis_code[dis/10]);
write_dat(dis_code[dis%10]);
}
}
/*====================================
以下是液晶12864的模块函数
=====================================*/
/*====================================
函数功能:写控制字给12864
=====================================*/
void write_op(uchar instruction)
{
delayms(5);
lcdrs=0;
lcdwr=0;
lcd=instruction;
lcden=1;
_nop_();
lcden=0;
}
/*====================================
函数功能:写显示数据给12864
=====================================*/
void write_dat(uchar indata)
{
delayms(5);
lcdrs=1;
lcdwr=0;
lcd=indata;
lcden=1;
_nop_();
lcden=0;
}
/*====================================
函数功能:初始化12864
=====================================*/
void lcd_ini()
{
lcdpsb=1;
write_op(0x30);//功能设定
write_op(0x01);//清除显示
write_op(0x0c);//显示设定
write_op(0x06);
}
/*====================================
以下是和时间相关的函数模块
=====================================*/
/*====================================
函数功能:秒加
=====================================*/
void inc_sec()
{
sec++;
tmpchange(); /*启动温度转换 每秒转换一次*/
delayms(2); /*等待转换结束,可不用,会对显示产生影响*/
tmp(); /*读取温度转换结果*/
if(sec==60)
{
sec = 0;
inc_min();
}
write_op(0x8e);
write_dat(dis_code[sec / 10]);
write_dat(dis_code[sec % 10]);
}
/*====================================
函数功能:分加
=====================================*/
void inc_min()
{
min++;
if(min ==60)
{
min = 0;
inc_hour();
}
write_op(0x8c);
write_dat(dis_code[min / 10]);
write_dat(dis_code[min % 10]);
}
/*====================================
函数功能:时加
=====================================*/
void inc_hour()
{
hour++;
if(hour == 24)
{
hour = 0;
inc_ri();
}
if(hour>=6&&hour<12)
{
write_op(0x88);
write_dat(0xc9);
write_dat(0xcf);
write_dat(0xce);
write_dat(0xe7);
}
if(hour>=12&&hour<18)
{
write_op(0x88);
write_dat(0xcf);
write_dat(0xc2);
write_dat(0xce);
write_dat(0xe7);
}
if(hour>=18&&hour<=23)
{
write_op(0x88);
write_dat(0xcd);
write_dat(0xed);
write_dat(0xc9);
write_dat(0xcf);
}
if(hour>=0&&hour<6)
{
write_op(0x88);
write_dat(0xc1);
write_dat(0xe8);
write_dat(0xb3);
write_dat(0xbf);
}
write_op(0x8a);
write_dat(dis_code[hour / 10]);
write_dat(dis_code[hour % 10]);
}
/*====================================
函数功能:日加
=====================================*/
void inc_ri()
{
ri++;
inc_xq();
showxq();
if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
{
if(ri > 31)
{
ri = 01;
inc_yue();
}
}
if(yue==4||yue==6||yue==9||yue==11)
{
if(ri > 30)
{
ri = 01;
inc_yue();
}
}
if(yue==2)
{
if(((nian+2000)%4==0&&(nian+2000)%100!=0)||((nian+2000)%400==0))
{
if(ri > 29)
{
ri = 01;
inc_yue();
}
}
else
if(ri > 28)
{
ri = 01;
inc_yue();
}
}
write_op(0x96);
write_dat(dis_code[ri / 10]);
write_dat(dis_code[ri % 10]);
}
/*====================================
函数功能:月加
=====================================*/
void inc_yue()
{
if(keynum==4)
{
if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
{
for(a=0;a<31;a++)
inc_xq();
showxq();
}
if(yue==4||yue==6||yue==9||yue==11)
{
for(a=0;a<30;a++)
inc_xq();
showxq();
}
if(yue==2)
{
if(((nian+2000)%4==0&&(nian+2000)%100!=0)||((nian+2000)%400==0))
{
for(a=0;a<29;a++)
inc_xq();
showxq();
}
else
{
for(a=0;a<28;a++)
inc_xq();
showxq();
}
}
}
yue++;
if(yue == 13)
{
yue = 01;
inc_nian();
}
write_op(0x94);
write_dat(dis_code[yue / 10]);
write_dat(dis_code[yue % 10]);
}
/*====================================
函数功能:年加
=====================================*/
void inc_nian()
{
if(keynum==5)
{
if(yue<=2&&ri<=29)
{
if(((nian+2000)%4==0&&(nian+2000)%100!=0)||((nian+2000)%400==0))
{
for(a=0;a<366;a++)
inc_xq();
showxq();
}
else
{
for(a=0;a<365;a++)
inc_xq();
showxq();
}
}
else
{
if(((nian+2001)%4==0&&(nian+2001)%100!=0)||((nian+2001)%400==0))
{
for(a=0;a<366;a++)
inc_xq();
showxq();
}
else
{
for(a=0;a<365;a++)
inc_xq();
showxq();
}
}
if((((nian+2000)%4==0&&(nian+2000)%100!=0)||((nian+2000)%400==0))&&(yue==2&&ri==29))
{
dec_ri();
}
}
nian++;
write_op(0x92);
write_dat(dis_code[nian / 10]);
write_dat(dis_code[nian % 10]);
}
/*====================================
函数功能:星期加
=====================================*/
void inc_xq()
{
xq++;
if(xq == 8)
{
xq = 1;
}
}
/*====================================
函数功能:分减
=====================================*/
void dec_min()
{
if(min==0)
{
min = 60;
dec_hour();
}
min--;
write_op(0x8c);
write_dat(dis_code[min / 10]);
write_dat(dis_code[min % 10]);
}
/*====================================
函数功能:时减
=====================================*/
void dec_hour()
{
if(hour ==0)
{
hour = 23;
dec_ri();
}
hour--;
if(hour>=6&&hour<12)
{
write_op(0x88);
write_dat(0xc9);
write_dat(0xcf);
write_dat(0xce);
write_dat(0xe7);
}
if(hour>=12&&hour<18)
{
write_op(0x88);
write_dat(0xcf);
write_dat(0xc2);
write_dat(0xce);
write_dat(0xe7);
}
if(hour>=18&&hour<=23)
{
write_op(0x88);
write_dat(0xcd);
write_dat(0xed);
write_dat(0xc9);
write_dat(0xcf);
}
if(hour>=0&&hour<6)
{
write_op(0x88);
write_dat(0xc1);
write_dat(0xe8);
write_dat(0xb3);
write_dat(0xbf);
}
write_op(0x8a);
write_dat(dis_code[hour / 10]);
write_dat(dis_code[hour % 10]);
}
/*====================================
函数功能:日减
=====================================*/
void dec_ri()
{
if(yue==2||yue==4||yue==6||yue==8||yue==9||yue==11||yue==1)
{
if(ri==1)
{
ri = 32;
dec_yue();
}
}
if(yue==5||yue==7||yue==10||yue==12)
{
if(ri ==1)
{
ri = 31;
dec_yue();
}
}
if(yue==3)
{
if(((nian+2000)%4==0&&(nian+2000)%100!=0)||((nian+2000)%400==0))
{
if(ri == 1)
{
ri = 30;
dec_yue();
}
}
else
if(ri ==1)
{
ri = 29;
dec_yue();
}
}
ri--;
dec_xq();
showxq();
write_op(0x96);
write_dat(dis_code[ri / 10]);
write_dat(dis_code[ri % 10]);
}
/*====================================
函数功能:月减
=====================================*/
void dec_yue()
{
if(keynum==4)
{
if(yue==2||yue==4||yue==6||yue==8||yue==9||yue==11||yue==1)
{
for(a=0;a<31;a++)
dec_xq();
showxq();
}
if(yue==5||yue==7||yue==10||yue==12)
{
for(a=0;a<30;a++)
dec_xq();
showxq();
}
if(yue==3)
{
if(((nian+2000)%4==0&&(nian+2000)%100!=0)||((nian+2000)%400==0))
{
for(a=0;a<29;a++)
dec_xq();
showxq();
}
else
{
for(a=0;a<28;a++)
dec_xq();
showxq();
}
}
}
if(yue==1)
{
yue = 13;
dec_nian();
}
yue--;
write_op(0x94);
write_dat(dis_code[yue / 10]);
write_dat(dis_code[yue % 10]);
}
/*====================================
函数功能:年减
=====================================*/
void dec_nian()
{
if(keynum==5)
{
if(yue<=2&&ri<=29)
{
if(((nian+1999)%4==0&&(nian+1999)%100!=0)||((nian+1999)%400==0))
{
for(a=0;a<366;a++)
dec_xq();
showxq();
}
else
{
for(a=0;a<365;a++)
dec_xq();
showxq();
}
}
else
{
if(((nian+2000)%4==0&&(nian+2000)%100!=0)||((nian+2000)%400==0))
{
for(a=0;a<366;a++)
dec_xq();
showxq();
}
else
{
for(a=0;a<365;a++)
dec_xq();
showxq();
}
}
if((((nian+2000)%4==0&&(nian+2000)%100!=0)||((nian+2000)%400==0))&&(yue==2&&ri==29))
{
dec_ri();
}
}
nian--;
write_op(0x92);
write_dat(dis_code[nian / 10]);
write_dat(dis_code[nian % 10]);
}
/*====================================
函数功能:星期减
=====================================*/
void dec_xq()
{
xq--;
if(xq==0)
{
xq = 7;
}
}
/*====================================
函数功能:显示星期
=====================================*/
void showxq()
{
write_op(0x9a);
write_dat(dis_code1[2*xq-2]);
write_dat(dis_code1[2*xq-1]);
}
/*====================================
函数功能:键盘扫描
=====================================*/
void key_scan()
{
while(1)
{
if(K1==0)
{
delayms(50);
if(K1==0)
{
while(!K1);
delayms(50);
while(!K1);
keynum++;
if(keynum==1)
{
TR0=0;
write_op(0x8c);
write_op(0x0f);
}
if(keynum==2)
{
write_op(0x8a);
}
if(keynum==3)
{
write_op(0x96);
}
if(keynum==4)
{
write_op(0x94);
}
if(keynum==5)
{
write_op(0x92);
}
if(keynum==6)
{
keynum=0;
write_op(0x0c);
TR0=1;
}
}
}
if(keynum!=0)
{
if(K2==0)
delayms(50);
if(K2==0)
{
while(!K2);
delayms(50);
while(!K2);
if(keynum==1)
{
inc_min();
write_op(0x8c);
}
if(keynum==2)
{
inc_hour();
write_op(0x8a);
}
if(keynum==3)
{
inc_ri();
write_op(0x96);
}
if(keynum==4)
{
inc_yue();
write_op(0x94);
}
if(keynum==5)
{
inc_nian();
write_op(0x92);
}
}
if(K3==0)
delayms(50);
if(K3==0)
{
while(!K3);
delayms(50);
while(!K3);
if(keynum==1)
{
dec_min();
write_op(0x8c);
}
if(keynum==2)
{
dec_hour();
write_op(0x8a);
}
if(keynum==3)
{
dec_ri();
write_op(0x96);
}
if(keynum==4)
{
dec_yue();
write_op(0x94);
}
if(keynum==5)
{
dec_nian();
write_op(0x92);
}
}
}
}
}
/*====================================
函数功能:初始化显示
=====================================*/
void ini_dis()
{
uchar i;
write_op(0x80);
for(i=0;i<16;i++)
write_dat(dis_char[i]);
write_op(0x90);
for(i=0;i<16;i++)
write_dat(dis_char1[i]);
write_op(0x88);
for(i=0;i<16;i++)
write_dat(dis_char2[i]);
write_op(0x98);
for(i=0;i<16;i++)
write_dat(dis_char3[i]);
hour=0x0c;
min=0x00;
sec=0x00;
nian=0x08;
yue=0x0a;
ri=0x01;
xq=0x03;
wendu=0x00;
}
/*====================================
函数功能:主函数
=====================================*/
void main()
{
lcd_ini();
ini_dis();
TMOD = 0x01;
TH0 = 0x4b;
TL0 = 0xf0;
EA=1;
ET0=1;
TR0 = 1;
key_scan();
}
/*====================================
函数功能:中断函数
=====================================*/
void timer0() interrupt 1
{
TH0 = 0x4b;
TL0 = 0xf0;
sec100++;
if(sec100 == 20)
{
sec100 = 0;
inc_sec();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -