1602数字万年历单片机课程设计.docx
《1602数字万年历单片机课程设计.docx》由会员分享,可在线阅读,更多相关《1602数字万年历单片机课程设计.docx(25页珍藏版)》请在冰点文库上搜索。
![1602数字万年历单片机课程设计.docx](https://file1.bingdoc.com/fileroot1/2023-4/29/95316521-4a87-4165-b180-ca166790e8f1/95316521-4a87-4165-b180-ca166790e8f11.gif)
1602数字万年历单片机课程设计
单片机原理及应用课程设计
设计题目:
1602数字万年历
姓名:
班级:
学号:
指导教师:
成绩评定:
2013年01月17日
目录
一设计目的
1.1通过单片机课程设计,熟练掌握c51语言的编程方法和keil2的运用方法,将理论联系到实践中去,提高我们的动脑和动手的能力。
1.2通过数字秒表系统的设计,掌握外围器件如1602液晶的编程思想,独立键盘的编程思想及它们和单片机I/O口的使用方法,还有简单程序的编写,最终提高我们的逻辑抽象能力。
二设计任务和要求
2.1任务:
设计一个能够在1602液晶上跑动的以独立键盘调整年月日时分秒的数字万年历
2.2要求:
利用单片机实现上述任务即可
三设计原理分析
3.1最小系统的构建
基本组成:
89c52芯片,时钟系统电路,复位电路,串口通信电路,电源电路。
时钟系统是一个由振荡器产生的89c52系统工作所需的时钟信号;复位电路产生系统复位功能;串口通信电路通过电脑与单片机连接通信作用,在此用到了max232芯片,一般作为pc机向单片机烧程序的作用;电源电路为89c52系统提供稳定的电源。
下面介绍以上电路原理图:
80C51信号引脚图
时钟系统电路复位电路
串口通讯电路和MX232芯片图
3.2液晶1602原理
3.2.1液晶显示原理及各参数引脚介绍
3.2.5电路图
通过最小系统与1602液晶各个端口的连接,确保1602液晶正常工作,再根据1602液晶时序图在keil2中写出相关程序,即可通过80c51来控制液晶显示。
四硬件资源及其分配
主要用到的硬件:
80c51的P3端口,P2端口,1602液晶,独立键盘
硬件分配:
P2口全部作为1602液晶的数据传输口,P3口的0,1,2作为1602的控制端口,(3,4,5)口作为独立键盘的接口
五硬件图
六程序清单
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitlcden=P3^0;
sbitrs=P3^2;
sbitrw=P3^1;
sbitk1=P3^4;
sbitk3=P3^3;
sbitk2=P3^5;
ucharcount,nian=13,yue=1,ri=17,day=4,shi=8,fen,miao,k1num;
ucharcodetable[]="2013-01-17THU";
ucharcodetable1[]="08:
00:
00";//预设时间
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=6;y>0;y--);
}
voidwrite_com(ucharcom)
{
rs=0;
lcden=0;
P2=com;
delay(50);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_date(uchardate)
{
rs=1;
lcden=0;
P2=date;
delay(50);
lcden=1;
delay(5);
lcden=0;
}
voidinit()
{
ucharnum;
rw=0;
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x01);
write_com(0x06);
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay
(2);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay
(2);
}
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
voidtimer0()interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
}
voidwrite_sfm(ucharadd,uchardate)
{
ucharshi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);//详细见码表
write_date(0x30+ge);
}
voidwrite_nyr(ucharadd,uchardate)
{
ucharshi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+add);
write_date(0x30+shi);//详细见码表
write_date(0x30+ge);
}
voidkeyscan()
{
if(k1==0)
{
delay(50);//延时消抖
if(k1==0)
{
k1num++;
while(!
k1);
if(k1num==1)//进入年设置选项
{
TR0=0;//时间停止
write_com(0x80+2);
write_com(0x0f);//此时设置为显示光标,光标闪烁
}
}
if(k1num==2)//进入月设置选项
{
write_com(0x80+5);
}if(k1num==3)//日设置选项
{
write_com(0x80+8);
}if(k1num==4)//星期设置选项
{
write_com(0x80+12);
}
if(k1num==5)//时设置选项
{
write_com(0x80+0x40+4);
}
if(k1num==6)//分设置选项
{
write_com(0x80+0x40+7);
}
if(k1num==7)//秒设置选项
{
write_com(0x80+0x40+10);
}
if(k1num==8)//退出设置
{
k1num=0;
write_com(0x0c);
TH0=(65536-50000)/256;//设置完成后再次讲定时器装初值,以免影响计时准确度
TL0=(65536-50000)%256;
TR0=1;//时间继续走
}
}
if((k1num!
=0)&&(k1num!
=8))//判定是否进入设置状态
{
if(k2==0)//按键2,加数据
{
delay(20);
if(k2==0)
{
while(!
k2);
if(k1num==1)//调节年的数据
{
nian++;
if((nian==0)||(nian>99))
nian=0;
write_nyr(2,nian);
write_com(0x80+2);
}
if(k1num==2)//调节月的数据
{
yue++;
if((yue==0)||(yue>12))
yue=1;
write_nyr(5,yue);
write_com(0x80+5);
}
if(k1num==3)//调节日的数据
{
ri++;
if((ri==0)||(ri>31))
ri=1;
write_nyr(8,ri);
write_com(0x80+8);
}
if(k1num==4)//调节星期的数据
{
day++;
if((day==0)||(day>7))
day=1;
write_com(0x80+12);
switch(day)
{
case1:
write_date(0x4D);
write_date(0x4F);
write_date(0x4E);
write_com(0x80+12);
break;
case2:
write_date(0x54);
write_date(0x55);
write_date(0x45);
write_com(0x80+12);
break;
case3:
write_date(0x57);
write_date(0x45);
write_date(0x44);
write_com(0x80+12);
break;
case4:
write_date(0x54);
write_date(0x48);
write_date(0x55);
write_com(0x80+12);
break;
case5:
write_date(0x46);
write_date(0x52);
write_date(0x54);
write_com(0x80+12);
break;
case6:
write_date(0x53);
write_date(0x41);
write_date(0x54);
write_com(0x80+12);
break;
case7:
write_date(0x53);
write_date(0x55);
write_date(0x4E);
write_com(0x80+12);
break;
}
}
if(k1num==5)
{
shi++;
if((shi==0)||(shi>23))
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
if(k1num==6)
{
fen++;
if((fen==00)||(fen>59))
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(k1num==7)
{
miao++;
if((miao==00)||(miao>59))
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
}
}
if(k3==0)//按键3,减数据
{
delay(20);
if(k3==0)
{
while(!
k3);
if(k1num==1)
{
if((nian==0)||(nian>99))
nian=100;
nian--;
write_nyr(2,nian);
write_com(0x80+2);
}
if(k1num==2)
{
yue--;
if((yue==0)||(yue>12))
yue=12;
write_nyr(5,yue);
write_com(0x80+5);
}
if(k1num==3)
{
ri--;
if((ri==0)||(ri>31))
ri=31;
write_nyr(8,ri);
write_com(0x80+8);
}
if(k1num==4)
{if(day==0)
day=2;
if((day==1)||(day>7))
day=8;
day--;
write_com(0x80+12);
switch(day)
{
case1:
write_date(0x4D);
write_date(0x4F);
write_date(0x4E);
write_com(0x80+12);
break;
case2:
write_date(0x54);
write_date(0x55);
write_date(0x45);
write_com(0x80+12);
break;
case3:
write_date(0x57);
write_date(0x45);
write_date(0x44);
write_com(0x80+12);
break;
case4:
write_date(0x54);
write_date(0x48);
write_date(0x55);
write_com(0x80+12);
break;
case5:
write_date(0x46);
write_date(0x52);
write_date(0x54);
write_com(0x80+12);
break;
case6:
write_date(0x53);
write_date(0x41);
write_date(0x54);
write_com(0x80+12);
break;
case7:
write_date(0x53);
write_date(0x55);
write_date(0x4E);
write_com(0x80+12);
break;
}
}
if(k1num==5)
{
shi--;
if((shi==0)||(shi>24))
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
if(k1num==6)
{
if((fen==00)||(fen>59))
fen=60;
fen--;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(k1num==7)
{
if((miao==00)||(miao>59))
miao=60;
miao--;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
}
}
}
}
voidmain()
{uchara,b;
init();
while
(1)
{
keyscan();
if((yue==1)||(yue==3)||(yue==5)||(yue==7)||(yue==8)||(yue==10)||(yue==12))//判断月份的天数
a=31;
if(((yue==4)||(yue==6)||(yue==9)||(yue==11)))
a=30;
if(yue==2)//判断是否为闰年
{
if(nian%4==0)
b=29;
else
b=28;
}
if(count==20)//定时器计数满20次为一秒,秒数加1
{
count=0;
miao++;
if(miao==60)//秒等于60的时候将miao清零,同时fen加1。
下同
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
day++;
ri++;
if(day==8)//星期的选择,用的case语句
day=1;
switch(day)
{
case1:
write_com(0x80+12);
write_date(0x4D);
write_date(0x4F);
write_date(0x4E);
write_com(0x0c);
break;
case2:
write_com(0x80+12);
write_date(0x54);
write_date(0x55);
write_date(0x45);
write_com(0x0c);break;
case3:
write_com(0x80+12);
write_date(0x57);
write_date(0x45);
write_date(0x44);
write_com(0x0c);
break;
case4:
write_com(0x80+12);
write_date(0x54);
write_date(0x48);
write_date(0x55);
write_com(0x0c);
break;
case5:
write_com(0x80+12);
write_date(0x46);
write_date(0x52);
write_date(0x54);
write_com(0x0c);
break;
case6:
write_com(0x80+12);
write_date(0x53);
write_date(0x41);
write_date(0x54);
write_com(0x0c);
break;
case7:
write_com(0x80+12);
write_date(0x53);
write_date(0x55);
write_date(0x4E);
write_com(0x0c);
break;
}
}
}
}
if(yue==2)//是否为二月的判断
{
if(ri>b)
{
ri=1;
yue++;
}
}
if(yue!
=2)
{