万年历程序和电路图.docx

上传人:b****7 文档编号:16277965 上传时间:2023-07-12 格式:DOCX 页数:52 大小:112.20KB
下载 相关 举报
万年历程序和电路图.docx_第1页
第1页 / 共52页
万年历程序和电路图.docx_第2页
第2页 / 共52页
万年历程序和电路图.docx_第3页
第3页 / 共52页
万年历程序和电路图.docx_第4页
第4页 / 共52页
万年历程序和电路图.docx_第5页
第5页 / 共52页
万年历程序和电路图.docx_第6页
第6页 / 共52页
万年历程序和电路图.docx_第7页
第7页 / 共52页
万年历程序和电路图.docx_第8页
第8页 / 共52页
万年历程序和电路图.docx_第9页
第9页 / 共52页
万年历程序和电路图.docx_第10页
第10页 / 共52页
万年历程序和电路图.docx_第11页
第11页 / 共52页
万年历程序和电路图.docx_第12页
第12页 / 共52页
万年历程序和电路图.docx_第13页
第13页 / 共52页
万年历程序和电路图.docx_第14页
第14页 / 共52页
万年历程序和电路图.docx_第15页
第15页 / 共52页
万年历程序和电路图.docx_第16页
第16页 / 共52页
万年历程序和电路图.docx_第17页
第17页 / 共52页
万年历程序和电路图.docx_第18页
第18页 / 共52页
万年历程序和电路图.docx_第19页
第19页 / 共52页
万年历程序和电路图.docx_第20页
第20页 / 共52页
亲,该文档总共52页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

万年历程序和电路图.docx

《万年历程序和电路图.docx》由会员分享,可在线阅读,更多相关《万年历程序和电路图.docx(52页珍藏版)》请在冰点文库上搜索。

万年历程序和电路图.docx

万年历程序和电路图

引言

单片机就是微控制器,是面向应用对象设计、突出控制功能的芯片。

单片机接上晶振、复位电路和相应的接口电路,装载软件后就可以构成单片机应用系统。

将它嵌入到形形色色的应用系统中,就构成了众多产品、设备的智能化核心。

本设计就是应用单片机强大的控制功能制作而成的电子万年历,该电子万年历包括三大功能:

实时显示年、月、日、时、分、秒;实现位调;附加播放音乐功能。

本设计是基于AT89C51和LCD1602液晶显示器设计的可调式电子钟。

该单片机采用的MCU51内核,因此具有很好的兼容性,内部带有4KB的ROM,能够存储大量的程序,最突出特点是具有ISP在系统烧写功能,使得烧写程序更加方便。

显示器件采用通用型1602液晶,可显示32个字符,如果使用数码管来做显示器件需消耗大量的系统资源,因此采用低功耗的1602液晶,该液晶显示方便,功能强大,完全能满足数字万年历的显示要求。

通过此次设计能够更加牢固的掌握单片机的应用技术,增强动手能力、硬件设计能力以及软件设计能力。

第一章设计方案

1.1.硬件设计

1.1.1设计要求

实现年月日、时分秒、星期的显示功能,用两个按键来实现日期和时间的调整功能,调整要求星期能自动更新,且能实现位调。

显示格式:

四位年,两位月,两位日,星期字母前三位,两位时,两位分,两位秒。

比如:

YYYY-MM-DDWEEK

HH:

MM:

SS

1.1.2硬件框图

控制芯片

显示器

按键调整

图1-1-硬件框图

日期时间由硬件软件结合产生;按键之间相互配合完成当前日期时间的调整功能。

过程与结果由控制芯片分别输出到显示器上。

本设计附加了播放音乐的功能。

音乐从蜂鸣器产生。

1.1.3硬件选择

1).显示模块

本设计具体选用与实际应用与消耗资源相关。

万年历用到的地方大多都在室内。

现市场上与许多显示器,在日常生活中最常见的有数码管,led点阵屏,lcd液晶显示器等。

八段数码管的优点:

亮度高,显示大。

驱动部份的软件简单;缺点:

与液晶相比,耗电及体积大。

数码管只能单纯的显示数字,不能生动的表达各个参数的信息,消耗电力也比led液晶显示器大。

LCD液晶显示器它是一种专门用来显示字母、数字、符号等的点阵型液晶模块,在单片机系统中应用晶液显示器作为输出器件有以下几个优点:

显示质量高,由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器(CRT)那样需要不断刷新新亮点。

因此,液晶显示器画质高且不会闪烁。

数字式接口,液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。

体积小、重量轻,液晶显示器通过显示屏上的电极控制液晶分子状态来达到显示的目的,在重量上比相同显示面积的传统显示器要轻得多。

功耗低,相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多。

Lcd液晶能一屏把本设计所要显示的信息表达完整。

而且lcd耗电小,体积小很适合与室内使用。

本设计的要求日期时间以数字表示、星期用3位英文字符表示共21个字符,lcd1602能显示32个字符,足以完成显示功能。

Lcd1602有16个引脚,各个引脚功能见下表:

引脚号

引脚名

电平

输入/输出

作用

1

VSS

电源地

2

VDD

Vcc

电源(+5v)

3

VEE

对比调整电压

4

RS

0/1

输入

0=输入指令,1=输入数据

5

R/W

0/1

输入

0=向lcd写入数据或指令

1=从lcd读取数据

6

E

1,1->0

输入

使能信号,1=读取信息

1->0(下降沿)执行指令

7

DB0

0/1

输入/输出

数据总线line0

8

DB1

0/1

输入/输出

数据总线line1

9

DB2

0/1

输入/输出

数据总线line2

10

DB3

0/1

输入/输出

数据总线line3

11

DB4

0/1

输入/输出

数据总线line4

12

DB5

0/1

输入/输出

数据总线line5

13

DB6

0/1

输入/输出

数据总线line6

14

DB7

0/1

输入/输出

数据总线line7

15

A

Vcc

Lcd背光正极

14

K

Lcd背光负极

表1-1lcd1602引脚及功能

2).按键与蜂鸣器

本设计选用轻触按钮,型号为XDJT1102S。

选用压电式蜂鸣器型号PT-1540PRoHS。

3).控制芯片

根据lcd1602液晶显示器与按键的引脚I/O数量以及扩展功能的要求,所选控制芯片至少需要三组I/O口,本设计功能简单,所以程序量较小,AT89C51是一种带4K字节闪存只读存储器的低电压、高性能CMOS8位微处理器。

AT89c51是51系列基本的控制芯片,能满足本设计的要求,性价比也要低于51系列其他的芯片。

4).日期时间生成模块

为了减少成本,使用51的内部定时器中断再配合软件计数的方式来生成一秒的时间。

1.2软件设计

1.2.1编程环境及语言:

本设计的原理图实现是在proteus中实现的,本设计的程序在keilUvision4环境中进行编程与调试的,keilUvision4与proteus联调能有效的对各个设计进行测试。

编程语言51C。

1.2.2程序框图

图1-2程序框图

1).time0中断用于生成时间,具体由程序和硬件共同产生1秒的时间。

2).两个外部中断能进行时间日期的切换,和对时间日期进行调整,播放音乐,能满足对按键设置的要求。

3).主函数能及时在液晶屏上显示默认的时间和调整后的时间。

第二章系统设计

2.1硬件设计

2.1.1振荡电路

本设计51芯片选用内部振荡器方式。

由于本设计的时间由内部定时器中断与软件计数相结合产生的,所以从计算方便以及系统的效率上考虑,本设计选用12MHz频率的晶振,电路原理图如下:

图2-1AT89C51的振荡电路

经厂家推荐稳定电路的电容C1,C2=30pF+-10p(附录资料AT89C51.PDF第4-32页)。

2.1.2复位电路

本设计使用上电复位电路。

单片机晶振为12MHz,起振时间将近1ms,单片机1个机器周期的时间为1us。

单片机每次上电复位所需的最短延时应该不小于treset。

这里,treset等于上电延时与起振延时之和。

从实际上讲,延迟一个treset往往还不够,不能够保障单片机有一个良好的工作开端。

复位电路把单片机锁定在复位状态上并且维持一个延时(记作TRST),以便给予电源电压从上升到稳定的一个等待时间;在电源电压稳定之后,再插入一个延时,给予时钟振荡器从起振到稳定的一个等待时间;在单片机开始进入运行状态之前,还要至少推迟2个机器周期的延时间。

单片机是高电平的时候复位,一般是用电阻和电容组成的,电容充电的时RST复位端为高电平,此时单片机开始复位..电容充电完成,此时单片机复位完成。

由此电容值可取22uf,电阻值取10KΩ。

详细见附录文件(电容充电时间的计算方法.pdf)

图2-2AT89C51上电复位电路

2.1.3按键

选用两个轻触按键与单片机P3^2(int0)、P3^3(int1)两个引脚相接组成的独立按键。

2.1.4lcd显示电路

1).lcd的选用

本设计选用型号为LCD-016M002L显示器。

具体资料见附录文件LCD-016M002L.pdf。

2).lcd与51引脚的连接

Lcd1602引脚

AT89C51引脚

LCD1602引脚

AT89C51引脚

RS

P2^0

DB3

P0^3

R/W

P2^1

DB4

P0^4

E

P2^2

DB5

P0^5

DB0

P0^0

DB6

P0^6

DB1

P0^1

DB7

P0^7

DB2

P0^2

表2-1lcd1602与51的连接

VEE为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。

图2-31602液晶与单片机接口电路

2.1.5音乐播放电路

此模块采用蜂鸣器实现,蜂鸣器驱动电流为20mA,单片机的P1口输出电流为26mA能够直接驱动蜂鸣器。

只要编写相应的程序即可实现发出不同频率的声音,蜂鸣器与单片机的接口电路,蜂鸣器接线与单片机P1^7引脚相连。

图2-5蜂鸣器电路

2.1.6P0上拉电阻计算

由于lcd数据口是与51的P0口连接的,在P0口做一般I/O使用时要外接上拉电阻。

根据LCD-016M002L显示器的伏安特性,要保证上拉电阻明显小于lcd的阻抗,以使高电平时输出有效

Lcd工作电压:

+5V

Lcd工作电流:

20mA

lcd阻抗=5v/20mA=2.5kΩ。

上拉电阻值可以取2.2kΩ(详细见附录资料上拉电阻下拉电阻的总结.doc),由于需要八个相同的上拉电阻如图2-6所示,也可用一个排阻。

具体型号见附录表。

图2-6上拉电阻

2.2软件设计

2.2.1程序流程图

图2-6主函数流程图2-7time0中断服务程序流程

图2-8int1中断服务流程

开始

定时器停止工作,调整指针加1。

调状态标志置1,秒清零。

等待按键松开。

判断调整指针是否增到上限值(即调整完毕)

指针复位。

调整状态标志清零,定时器开始工作。

返回

图2-9int0中断服务流程

2.2.2流程的各个模块设计

全局变量

datetime数组保存日期时间星期的容器。

min[2],hour[2],day[2],mon[2],year[4];调整时候使用的中间变量。

buffer_date[16],buffer_time[16]显示缓冲区。

1).定时器中断服务程序

定时器1计时一秒。

计数初值的计算方法如下:

设晶振频率为f,则定时/计数器计数频率为f/12,定时/计数器的计数总次数T_all在方式1为216=65536,定时间隔为T,计数初值为a,则有a=-T×f/12

将计数初值a分别赋给加1计数器TH0、TL0:

TH0=(T_all-a)/256;

TL0=(T_all-a)%256;

本设计晶振频率为12MHz,定时间隔为50ms,所以

a=-0.05*12000000/12

a=50000

TH0=(65536-50000)/256

TL0=(65536-50000)%256

1s就要计20次,中断服务程序如下:

voidtime0()interrupt1using3

{

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

if(++count==20)//计时一秒

{

count=0;

DATATIME();//按实际规则日期时间更新

}

}

2).int0中断服务程序

按键1接在了int0对应的引脚P3^2。

按键2接在了int1对应的引脚P3^3。

Int0为电平触发方式,int1为边沿触发方式。

由于按键2是一键多功能,具体功能由状态标志FLAG表明。

所以在int0中断服务程序中要有对FLAG标志的置位及清位的操作。

在调整期间为了时间准确定时器不能工作,为了对日期时间的各位值进行循环调整,设置了一个计数器,它的值表明要调整的是哪位。

终端服务程序如下:

voidint0_K1()interrupt0

{

TR0=0;//定时器停止

cnum++;//计数器加1

FLAG=1;//标志位置位

datetime[0]=0;

while(K1==0);//等待按键松开

if(cnum>12)//调整结束,各个状态还原

{

TR0=1;

cnum=-1;

FLAG=0;

}

}

3).int1中断服务程序

Int1只要判断标志位执行任务就行了,中断服务程序如下:

voidint1_K2()interrupt2

{

if(FLAG==1)//调整状态下则位对应调整位的增值,正常状态则播放音乐

{

EDIT_datetime(cnum);//按计数器的值调整对应位

}

else

{

ShowString(0x00,0,"");//播放音乐是屏幕上的字幕

ShowString(0x00,1,happy);

music();

Delayms(500);

}

}

4).主函数程序

主函数对各个中断及lcd1602初始化后,就一直进行显示工作了,显示的时候判断标志FLAG以区别是正常显示还是闪烁显示。

主程序如下:

voidmain()

{

IE=0X87;//开中断ea=1,et0=1,et1=1,ex0=1

TCON=0X04;//it1为边沿触发,it0电平触发

IP=0X0a;//定时器0,1为高优先级

TMOD=0X01;//设置定时器0方式1

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

Initialize_LCD();//初始化LCD

TR0=1;

while

(1)

{

buffer_value();//设置显示缓存区的内容

if(FLAG)//调整时对应调整位置闪烁

if(++refresh==5)

{

refresh=0;

Flash(cnum);

}

DIS_buffer();//将显示缓冲区的内容输出到lcd上

}

}

5).星期在调整是是自动更新的,这要归功于蔡勒公式。

算法如下(C51表示):

unsignedcharweek()

{

unsignedinty,m,c,s;

y=datetime[5]%100;

c=datetime[5]/100;

if(datetime[4]==1)

{m=13;

y--;

}

if(datetime[4]==2)

{m=14;

y--;

}

s=y+y/4+c/4-2*c+26*(m+1)/10+datetime[3]-1;//蔡勒公式

s=s%7;

returns;

}

函数返回值:

0-星期日,1-星期一……6-星期六

6).闰年是自动判断的,算法:

(year%4==0)&&(year%100!

=0)||year%400==0

函数代码如下:

unsignedcharYnian(unsignedcharyear)

{

if((year%400==0||year%4==0)&&(year%100!

=0))

return1;

else

return0;

}

是闰年返回1,否则返回0

7).月的天数判断,由于1,3,5,7,8,10,12每月有31天;4,6,9,11每月有30天;2月闰年29天,平年28天。

所以只要判断月号是哪一类的,就返回那类的值,2月用闰年判断算法判断。

函数代码如下:

unsignedcharMON(unsignedcharmonth)

{

switch(month)

{

case1:

case3:

case5:

case7:

case8:

case10:

case12:

return31;

case4:

case6:

case9:

case11:

return30;

default:

if(Ynian(datetime[5]))//二月特殊,闰年判断

return29;

else

return28;

}

}

返回各月的天数上限。

8).日期时间更新

按照实际规则更新,60秒一分,60分一时,24小时一日,30日或31日或28日或29日一月,12月一年。

函数代码如下:

voidDATATIME()

{

datetime[0]++;

if(datetime[0]>59)//秒判断

{

datetime[0]=0;

datetime[1]++;

}

if(datetime[1]>59)//分

{

datetime[1]=0;

datetime[2]++;

}

if(datetime[2]>23)//时

{

datetime[2]=0;

datetime[3]++;

}

if(datetime[3]>MON(datetime[4]))//日

{

datetime[3]=1;

datetime[4]++;

}

if(datetime[4]>12)//月

{

datetime[4]=1;

datetime[5]++;//年

}

//时刻为进入调整状态作准备,将当前日期时间值赋给调整时的变量

datetime[6]=week();min[0]=datetime[1]%10;

min[1]=datetime[1]/10;

hour[0]=datetime[2]%10;

hour[1]=datetime[2]/10;

day[0]=datetime[3]%10;

day[1]=datetime[3]/10;

mon[0]=datetime[4]%10;

mon[1]=datetime[4]/10;

year[0]=datetime[5]%10,year[1]=datetime[5]%100/10;

year[2]=datetime[5]%1000/100,year[3]=datetime[5]/1000;

}

9).调整日期时间函数,利用cnum计数器指定当前的调整属性,函数源代码如下:

voidEDIT_datetime(charcnum)

{

switch(cnum)

{

case0:

min[0]++;

if(min[0]>9)//分低位调整限制

min[0]=0;

break;

case1:

min[1]++;

if(min[1]>5)//分高调整限制

min[1]=0;

break;

case2:

hour[0]++;

if(hour[0]>9)//时低位调整限制

hour[0]=0;

break;

case3:

hour[1]++;

if(hour[1]>2)//时高位调整限制

hour[1]=0;

break;

case4:

day[0]++;

if(day[0]>9)//日低位调整限制

day[0]=0;

break;

case5:

day[1]++;

if(day[1]>3)//日高位调整限制

day[1]=0;

break;

case6:

mon[0]++;

if(mon[0]>9)//月低位调整限制

mon[0]=0;

break;

case7:

mon[1]++;

if(mon[1]>1)//月高位调整限制

mon[1]=0;

break;

case8:

year[0]++;//年调整

if(year[0]>9)

year[0]=0;

break;

case9:

year[1]++;

if(year[1]>9)

year[1]=0;

break;

case10:

year[2]++;

if(year[2]>9)

year[2]=0;

break;

case11:

year[3]++;

if(year[3]>9)

year[3]=0;

break;

}

datetime[1]=min[0]+min[1]*10;//调整后将datetime实时更新

datetime[2]=hour[0]+hour[1]*10;

datetime[3]=day[0]+day[1]*10;

datetime[4]=mon[0]+mon[1]*10;

datetime[5]=year[0]+year[1]*10+year[2]*100+year[3]*1000;

}

调整后能及时让datetime更新。

10).将datetime的日期时间星期按照格式放到缓冲区上,格式为:

YYYY-MM-DDweek

HH:

MM:

SS

函数源代码如下:

voidbuffer_value()

{

Format_Datetime(datetime[0],buffer_time+6);//将年月日时分秒星期,

Format_Datetime(datetime[1],buffer_time+3);//放到对应缓冲区的位置上

Format_Datetime(datetime[2],buffer_time+0);//以待显示

Format_Datetime(datetime[3],buffer_date+8);

Format_Datetime(datetime[4],buffer_date+5);

Format_Datetime(datetime[5]%100,buffer_date+2);

Format_Datetime(datetime[5]/100,buffer_date+0);

buffer_date[13]=week1[week()];

buffer_date[14]=week2[week()];

buffer_date[15]=week3[week()];

}

Lcd1602显示的是字符,所以用函数转换。

Format_Datetime(数组1,数组2)

功能:

将数组1的数值转换为字符放到数组2。

11).闪烁显示,在主函数显示配合延时清空,写入缓冲区的内容,达到闪烁效果。

具体哪位闪烁还是有cnum决定。

函数源代码如下:

voidFlash(charn)

{

switch(n)

{

case0:

buffer_clr(0,4);//对应分低位置,清空

break;

case1:

buffer_clr(0,3);

break;

case2:

buffer_clr(0,1);

break;

case3:

buffer_clr(0,0);

break;

case4:

buffer_clr(1,9);

break;

case5:

buffer_clr(1,8);

break;

case6:

buffer

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2