标题:
51单片机 lcd1602 万年历时钟
[打印本页]
作者:
燎木乙
时间:
2019-9-21 22:56
标题:
51单片机 lcd1602 万年历时钟
本帖最后由 燎木乙 于 2019-9-21 23:02 编辑
lcd1602.h
#ifndef _LCD1602_H_
#define _LCD1602_H_
sbit rs = P2^6;
sbit rw = P2^5;
sbit e = P2^7;
typedef unsigned int uint8;
typedef unsigned char uchar;
void delay(uint8 i);
void wrc(uint8 cmd);
void wrd(uint8 dat);
void init();
#endif
复制代码
lcd1602.c
#include "reg52.h"
#include "lcd1602.h"
#include "intrins.h"
void delay(uint8 i)
{
while(i--);
}
//指令写入
void wrc(uint8 cmd)
{
delay(1000);
rs = 0;
rw = 0;
e = 0;
P0 = cmd;
e = 1;
delay(10);
e = 0;
}
//数据输入
void wrd(uint8 dat)
{
delay(1000);
rs = 1;
rw = 0;
e = 0;
P0 = dat;
e = 1;
delay(10);
e = 0;
rs = 0;
}
//初始化
void init()
{
delay(1000);
wrc(0x38);
wrc(0x0c);
wrc(0x06);
wrc(0x01);
wrc(0x80);
}
复制代码
main.c
#include "reg52.h"
#include "lcd1602.h"
//时间:年月日时分秒
uchar Time[7] = {20, 19, 9, 9, 13, 0, 0};
uint8 n = 0;//定时计数,50ms一次
sbit key1=P3^0;
sbit key2=P3^1;
sbit key3=P3^2;
sbit key4=P3^3;
void display();
uint8 key();
void guize();
int main()
{
EA = 1;//开总中断
EX0 = 1;//允许外部中断0
IT0 = 1;//外部中断0下降沿有效
TMOD = 0X01;//设置定时器模式
TH0 = (65535 - 46083) / 256;//延时50ms
TL0 = (65535 - 46083) % 256;
ET0 = 1;//开启定时器0中断
TR0 = 1;//开启定时器
init();//初始化lcd1602
while(1)
{
display();//显示函数
guize();
}
}
//显示函数
void display()
{
wrc(0x80|0x00);
wrd('0' + Time[0]/10);
wrd('0' + Time[0]%10);
wrd('0' + Time[1]/10);
wrd('0' + Time[1]%10);
wrd('-');
wrd('0' + Time[2]/10);
wrd('0' + Time[2]%10);
wrd('-');
wrd('0' + Time[3]/10);
wrd('0' + Time[3]%10);
wrc(0x80|0x40);
wrd('0' + Time[4]/10);
wrd('0' + Time[4]%10);
wrd(':');
wrd('0' + Time[5]/10);
wrd('0' + Time[5]%10);
wrd(':');
wrd('0' + Time[6]/10);
wrd('0' + Time[6]%10);
}
uint8 key()
{
uint8 k = 0;
P3=0x0f;
delay(100000000);
while(k == 0)
{
if(key1 == 0)
{
delay(2000);
if(key1 == 0)
return 1;
}
else if(key2 == 0)
{
delay(2000);
if(key2 == 0)
return 2;
}
else if(key3 == 0)
{
delay(2000);
if(key3 == 0)
return 3;
}
else if(key4 == 0)
{
delay(2000);
if(key4 == 0)
return 4;
}
}
}
void guize()
{
if(Time[6] >= 60)//秒
{
Time[6] = 0;
Time[5] += 1;
}
if(Time[5] >= 60)//分
{
Time[5] = 0;
Time[4] += 1;
}
if(Time[4] >= 24)//时
{
Time[4] = 0;
Time[3] += 1;
}
if(Time[3] >= 29)//日
{
if((Time[2] == 1) || (Time[2] == 3) || (Time[2] == 5) || (Time[2] == 7) || (Time[2] == 8) || (Time[2] == 10) || (Time[2] == 12))//31天数月
{
if(Time[3] > 31)
{
Time[3] = 0;
Time[2] += 1;
}
}
else if((Time[2] == 4) || (Time[2] == 6) || (Time[2] == 9) || (Time[2] == 11))//30天数月
{
if(Time[3] > 30)
{
Time[3] = 0;
Time[2] += 1;
}
}
else //2月
{
if((Time[0] * 100 + Time[1])/4 == 0)//闰年
{
if(Time[3] > 29)
{
Time[3] = 0;
Time[2] += 1;
}
}
else //平年
{
Time[3] = 0;
Time[2] += 1;
}
}
}
if(Time[2] > 12)//月
{
Time[2] = 0;
Time[1] += 1;
}
if(Time[1] > 99)//年后两位
{
Time[1] = 0;
Time[0] += 1;
}
if(Time[0] > 99)//年前两位
{
Time[0] = 0;
}
}
void duang0()interrupt 0
{
uint8 k = 0, x = 0, y = 0, i;
delay(100000000);
wrc(0x0f);//开启光标
wrc(0x02);//初始化光标位置
while(k != 3)
{
k = key();
switch(k)
{
case 1:
if(y == 0)
{
if(x == 3 || x == 5)
{
wrc(0x14);
wrc(0x14);
x++;
}
else if(x == 7)
{
for(i = 55; i > 0; i--)
{
wrc(0x14);
}
x = 0;
y = 1;
}
else
{
wrc(0x14);
x++;
}
}
else
{
if(x == 1 || x == 3)
{
wrc(0x14);
wrc(0x14);
x++;
}
else if(x == 5)
{
for(i = 57; i > 0; i--)
{
wrc(0x14);
}
x = 0;
y = 0;
}
else
{
wrc(0x14);
x++;
}
}
break;
case 2:
if(y == 0)
{
if(x == 4 || x== 6)
{
wrc(0x10);
wrc(0x10);
x--;
}
else if(x == 0)
{
for(i = 57; i > 0; i--)
wrc(0x10);
x = 5;
y = 1;
}
else
{
wrc(0x10);
x--;
}
}
else
{
if(x == 2 || x == 4)
{
wrc(0x10);
wrc(0x10);
x--;
}
else if(x == 0)
{
for(i = 55; i > 0; i--)
wrc(0x10);
x = 7;
y = 0;
}
else
{
wrc(0x10);
x--;
}
}
break;
case 4:
if(y == 0)
{
if(x == 0)
Time[0] += 10;
else if(x == 1)
Time[0] += 1;
else if(x == 2)
Time[1] += 10;
else if(x == 3)
Time[1] += 1;
else if(x == 4)
Time[2] += 10;
else if(x == 5)
Time[2] += 1;
else if(x == 6)
Time[3] += 10;
else if(x == 7)
Time[3] += 1;
}
else
{
if(x == 0)
Time[4] += 10;
else if(x == 1)
Time[4] += 1;
else if(x == 2)
Time[5] += 10;
else if(x == 3)
Time[5] += 1;
else if(x == 4)
Time[6] += 10;
else if(x == 5)
Time[6] += 1;
}
guize();
display();
if(y == 0)
{
switch(x)
{
case 0:
wrc(0x80|0x00);
break;
case 1:
wrc(0x80|0x01);
break;
case 2:
wrc(0x80|0x02);
break;
case 3:
wrc(0x80|0x03);
break;
case 4:
wrc(0x80|0x05);
break;
case 5:
wrc(0x80|0x06);
break;
case 6:
wrc(0x80|0x08);
break;
case 7:
wrc(0x80|0x09);
break;
default:break;
}
}
else
{
switch(x)
{
case 0:
wrc(0x80|0x40);break;
case 1:
wrc(0x80|0x41);break;
case 2:
wrc(0x80|0x43);break;
case 3:
wrc(0x80|0x44);break;
case 4:
wrc(0x80|0x46);break;
case 5:
wrc(0x80|0x47);break;
default:break;
}
}
break;
default: break;
}
}
wrc(0x0c);
}
void duang1()interrupt 1
{
n += 1;
if(n == 20)
{
Time[6] += 1;
n = 0;
}
TH0 = (65535 - 46083) / 256;//延时50ms
TL0 = (65535 - 46083) % 256;
}
复制代码
万年历时钟仿真电路图.PNG
(61.04 KB, 下载次数: 25)
下载附件
2019-9-21 22:52 上传
作者:
116400
时间:
2019-10-3 15:07
楼主能对代码做一些说明么?谢谢
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1