标题:
基于LCD1602的万年历单片机源码 带闹钟
[打印本页]
作者:
yc123
时间:
2018-1-26 12:35
标题:
基于LCD1602的万年历单片机源码 带闹钟
基于LCD1602的万年历,带闹钟
单片机源程序如下:
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit lcd_rs=P2^6; //rs为寄存器选择 高电平时选择数据寄存器,低电平选择指令寄存器
sbit lcd_rw=P2^5; //R/W 为读写信号线,高电平时进行读操作,低电平进行写操作
//当 RS 和 R/W 共同为低电平时,可以写入指令或显示地址
sbit lcd_en=P2^7; //液晶控制端
sbit key_set=P1^4;//设置键
sbit key_up=P1^5; //加键同时也是闹钟能够停止按钮
sbit key_down=P1^6; // 减键同时也是翻屏按钮
sbit key_out=P1^7; //键 盘控制端口
uchar count; //定时器计数变量
uchar hour,min,sec,hour1,hour2,sec1,sec2,min1,min2; //时间变量
uchar yue, ri,nian1, nian2, nian3, nian4, yue1, yue2, ri1, ri2; //月日变量
uint nian; // 年变量
uchar nao1=0, nao2=0, nao3=0, nao11, nao12, nao21, nao22; //设置闹钟变量
uchar count1; // 星期计数变量
uchar ww=0,qq=0,nao=1,flag; //计数变量键盘设置端口,闹钟时间是否设置标志量,闹钟标志变量,设置键标志量
uchar code table[]={
0x00,0x04,0x0E,0x0E,0x0E,0x0E,0x1F,0x1F,
0x04,0x08,0x00,0x1E,0x00,0x08,0x04,0x00
};//设置闹钟图片
void lcd_delay(uint m) //延时函数 (字符型变量m定义)
{
while(m--); //无限循环体
}
void read1602() //忙检测 作用防止乱码
{
uchar i;
i=254;
P0=0xff; //
lcd_rs=0; //读写命令
lcd_rw=1; //读命令/数据
lcd_en=1; //液晶模块执行命令
while(i--);//若一段时间以后仍低,则认为是不忙
lcd_en=0;
}
void write1602(uchar wdata,bit rw)//向LCD1602写数据(rw=1)或者命令(rw=0)
{
read1602(); //防止数据丢失
lcd_rs=rw;
P0=wdata;
lcd_rw=0;
lcd_delay(1);
lcd_en=1;
lcd_delay(1);
lcd_en=0;
}
void lcd_init() //LCD1602液晶的初始化
{
lcd_delay(1500);
write1602(0x38,0); //置功能,8位数据,2行显示,5x7字符(指令6)
write1602(0x0c,0); //只打开屏显 (指令4)
write1602(0x06,0); //左到右显示,自加1 (指令3)
write1602(0x01,0); //清屏 (指令1)
write1602(0x80,0); //(指令8)
}
void init() //定时器初始化
{
count=0;
hour=23; //小时初值
min=59; //分钟初值
sec=50; //秒初值
nian=2018; //年初值
yue=01; //月初值
ri=01; //日初值
count1=1;//星期初值
TMOD=0x01; //中断T0工作方式,方式1,16位定时器
TH0=(65536-50000)/256;
TL0=(65536-50000)%256; //计数器初值,为50ms进入一次中断子程序
TR0=1; //允许T0计数
ET0=1; //定时器T0溢出中断允许
EA=1; //开中断
}
void lcd_printf(uchar *str)//显示字符串
{ read1602();
while(*str!='\0')
{
write1602(*str,1); //写入数据
str++;
lcd_delay(1);
}
}
void lcd_moveto(uchar x,uchar y)//指定显示的行列坐标
{
if(x==0)
write1602(0x80|y,0);
if(x==1)
write1602(0xc0|y,0);
}
void fengjie1(uchar a,uchar b, uchar c )//将时分秒两位数分解为两个数
{
hour1=a/10;
hour2=a%10;
min1=b/10;
min2=b%10;
sec1=c/10;
sec2=c%10;
}
void fengjie2(uint a,uchar b, uchar c ) //将年月日分解为两个数
{
nian4=a%10;
a=(a-nian4)/10;
nian3=a%10;
a=(a-nian3)/10;
nian2=a%10;
nian1=a/10;
yue1=b/10;
yue2=b%10;
ri1=c/10;
ri2=c%10;
}
void fengjie3(uchar a, uchar b )//将闹钟分解为两个数
{
nao11=a/10;
nao12=a%10;
nao21=b/10;
nao22=b%10;
}
void display1(uchar hour1,uchar hour2,uchar min1,uchar min2,uchar sec1,uchar sec2) //显示时间程序
{
lcd_moveto(1,0); //定位在第二行第一列
write1602(hour1+48,1); //字符0-9对应十进制48-57
write1602(hour2+48,1);
lcd_printf(":");
write1602(min1+48,1);
write1602(min2+48,1);
lcd_printf(":");
write1602(sec1+48,1);
write1602(sec2+48,1);
}
void display2(uchar nian1,uchar nian2,uchar nian3,uchar nian4,uchar yue1,uchar yue2, uchar ri1, uchar ri2 ) //显示日期程序
{
lcd_moveto(0,0); //定位在第一行第一列
write1602(nian1+48,1);
write1602(nian2+48,1);
write1602(nian3+48,1);
write1602(nian4+48,1);
lcd_printf("-");
write1602(yue1+48,1);
write1602(yue2+48,1);
lcd_printf("-");
write1602(ri1+48,1);
write1602(ri2+48,1);
}
void display3(uchar we) //星期送显示
{
lcd_moveto(0,12);
switch(we)
{
case 1: lcd_printf("M");
lcd_printf("0");
lcd_printf("N");
break;
case 2: lcd_printf("T");
lcd_printf("U");
lcd_printf("E");
break;
case 3: lcd_printf("W");
lcd_printf("E");
lcd_printf("D");
break;
case 4: lcd_printf("T");
lcd_printf("H");
lcd_printf("U");
break;
case 5: lcd_printf("F");
lcd_printf("R");
lcd_printf("T");
break;
case 6: lcd_printf("S");
lcd_printf("A");
lcd_printf("T");
break;
case 7: lcd_printf("S");
lcd_printf("U");
lcd_printf("N");
break;
}
}
void display4(uchar nao11,uchar nao12,uchar nao21, uchar nao22) //显示闹钟时刻
{
lcd_moveto(1,6); //定位在第二行第6列
if(nao==1) //打开闹钟
{write1602(nao11+48,1);//显示闹钟时间
write1602(nao12+48,1);
lcd_printf(":");
write1602(nao21+48,1);
write1602(nao22+48,1);
}
if(nao==0) //关闭闹钟
{lcd_printf("N");
lcd_printf("O");
lcd_printf(":");
lcd_printf("N");
lcd_printf("O");
}
}
void display5() //显示闹钟图片
{
lcd_moveto(1,13);
if(nao==1)//如果闹钟打开显示闹钟图片
{
write1602(0x00,1); //
write1602(0x01,1); //?
}
if(nao==0)
{
lcd_printf(" ");
lcd_printf(" ");
}
}
void zimo() //字模显示
{
uint i;
write1602(0x40,0); //写图片的指令
for(i=0;i<16;i++)
{
write1602(table[i],1);
}
}
void key() //键盘程序
{
if(key_set==0)
{
flag=1;
ww++;
if(ww==8)
ww=0;
while(!key_set);
}
switch(ww)
{
case 0: // 清零
if(key_up==0)
{
while(!key_up);
if(qq==1)
{
qq=0;
}
else
{
nao=!nao; //开关闹钟的作用
} }
break;
case 1: //键盘调整年
lcd_delay(1000);
lcd_moveto(0,3);
lcd_printf("-");
lcd_delay(1000);
if(key_up==0)
{
while(!key_up); //按键是否抬起
nian++;
}
if(key_down==0)
{
while(!key_down);
nian--;
}
break;
case 2: //键盘调整月
lcd_delay(1000);
lcd_moveto(0,6);
lcd_printf("-");
lcd_delay(1000);
if(key_up==0)
{
while(!key_up);
yue++;
if(yue>12)
yue=1;
}
if(key_down==0)
{
while(!key_down);
if(yue==1)
yue=12;
else
yue--;
}
break;
case 3: //键盘调节日期
lcd_delay(1000);
lcd_moveto(0,9);
lcd_printf("-");
lcd_delay(1000);
if(key_up==0)
{
while(!key_up);
ri++;
if(ri>31)
ri=1;
}
if(key_down==0)
{
while(!key_down);
if(ri==1)
ri=31;
else
ri--;
}
break;
case 4: //键盘调整星期
lcd_delay(1000);
lcd_moveto(0,12);
lcd_printf("-");
lcd_printf("-");
lcd_printf("-");
lcd_delay(1000);
if(key_up==0)
{
while(!key_up);
count1++;
if(count1>7)
count1=1;
}
if(key_down==0)
{
while(!key_down);
if(count1==1)
count1=7;
else
count1--;
}
break;
case 5: //键盘调整时
lcd_delay(1000);
lcd_moveto(1,1);
lcd_printf("-");
lcd_delay(1000);
if(key_up==0)
{
while(!key_up);
hour++;
if( hour>23)
hour=0;
}
if(key_down==0)
{
while(!key_down);
if( hour==0)
hour=23;
else
hour--;
}
break;
case 6: //键盘调整分
lcd_delay(1000);
lcd_moveto(1,4);
lcd_printf("-");
lcd_delay(1000);
if(key_up==0)
{
while(!key_up);
min++;
if( min>59)
min=0;
}
if(key_down==0)
{
while(!key_down);
if( min==0)
min=59;
else
min--;
}
break;
case 7: //键盘调整秒
lcd_delay(1000);
lcd_moveto(1,7);
lcd_printf("-");
lcd_delay(1000);
if(key_up==0)
{
while(!key_up);
sec++;
if( sec>59)
sec=0;
}
if(key_down==0)
{
while(!key_down);
if(sec==0)
sec=59;
else
sec--;
}
break;
}
if(key_out==0)
{
while(!key_out);
flag=0;
ww=0;
}
}
void key1() // 调整闹钟时间
{
if(key_set==0)
{
flag=1;
ww++;
if(ww==3)
ww=0;
while(!key_set);
}
switch(ww)
{
case 0: //退出设置
if(key_up==0)
{
while(!key_up);
nao=!nao; //如果闹钟开按下后则关,反之同理
}
if(key_down==0)
{
while(!key_down);
qq=0; //
}
break;
case 1: // 调试闹钟的时
lcd_delay(1000);
lcd_moveto(1,7);
lcd_printf("-");
lcd_delay(1000);
if(nao==1)
{if(key_up==0)
{
while(!key_up);
nao1++;
if( nao1>23)
nao1=0;
}
if(key_down==0)
{
while(!key_down);
if( nao1==0)
nao1=23;
else
nao1--;
}
break;
}
else break;
case 2: // 调试闹钟的分
lcd_delay(1000);
lcd_moveto(1,10);
lcd_printf("-");
lcd_delay(1000);
if(nao==1)
{if(key_up==0)
{
while(!key_up);
nao2++;
if( nao2>59)
nao2=0;
}
if(key_down==0)
{
while(!key_down);
if( nao2==0)
nao2=59;
else
nao2--;
}
break;
}
else break;
default:break;
}
if(key_out==0)
{
while(!key_out);
flag=0;
ww=0;
}
}
void count0(void) interrupt 1 //中断函数,进行时期的累加 12m晶振
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==20) //计时到达一秒
{
count=0;
sec++;
if(sec==60) //计时到达一分
{
sec=0;
min++;
if(min==60) //计时到达一小时
{
min=0;
hour++;
if(hour==24) //计时到达一天
{
hour=0;
ri++;
count1++;
if(count1==8) //计时到达一周
{
count1=1;
}
if(yue==1|yue==3|yue==5|yue==7|yue==8|yue==10|yue==12)
{
if(ri>31) //计时到达一个月31天
{
ri=1;
yue++;
if(yue>12) //计时到达一年
{
yue=1;
nian++;
}
}
}
if(yue==4|yue==6|yue==9|yue==11)
{
if(ri>30) //计时到达一个月30天
{
ri=1;
yue++;
if(yue>12) //计时到达一年
{
yue=1;
nian++;
}
}
}
if(yue==2)
{
if(nian%4==0)
{
if(ri>29)//计时到达一个月29天
{
ri=1;
yue++;
if(yue>12)
{
yue=1;
nian++;
}
}
}
else
{
if(ri>28) //计时到达一个月28天
{
ri=1;
yue++;
if(yue>12)
{
yue=1;
nian++;
}
}
}
}
}
}
}
}
}
void linsheng() //闹钟发生器
{ if(nao==1)
{if(hour==nao1&min==nao2&sec==nao3)//满足时间?
qq=1;//是否设置闹钟时间
if(qq==1)
{
key_out=0;
lcd_delay(10000);
key_out=1;
lcd_delay(1000);
}
}
}
void main()
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
新建文件夹.rar
(47.06 KB, 下载次数: 44)
2018-1-26 12:34 上传
点击文件名下载附件
基于LCD1602的万年历
下载积分: 黑币 -5
作者:
wang先生
时间:
2020-1-11 16:33
这个闹钟订好时间后,好像不响啊!
作者:
wang先生
时间:
2020-1-11 16:34
闹钟定好时间后,好像不响啊! 难受😫
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1