基于单片机的万历设计.docx
《基于单片机的万历设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的万历设计.docx(22页珍藏版)》请在冰豆网上搜索。
基于单片机的万历设计
基于单片机的万年历设计
一.题目要求
1.能星期、时、分,年、月、日正常显示,且秒闪。
2.按下KEY1,进入设置状态,根据按键次数可判断调整哪个(星期、时、分、年、月、日)。
调整星期、时、分时,对应位闪烁且四灯灭。
调整年、月、日时,对应位闪烁且四灯灭。
3.在设置状态下按下KEY2,加时间。
4.在设置状态下按下KEY3,减时间。
5.在设置状态下按下KEY4,返回(正常显示)。
二.题目分析
1.硬件部分设计。
首先要设计一个最小系统,包括晶振电路,按键复位电路。
然后是按键电路和ISP电路,显示电路。
其中显示电路就要考虑各端口的分配。
包括片选,输出端口。
2.软件部分设计。
根据硬件电路分析,要考虑怎么显示,考虑中断,定时等。
还要考虑年月日的算法问题。
三.功能描述
1.能正常显示时间(星期、时、分,年、月、日),两种状态以10S时间切换。
2.能调整时间。
四.方案论证
1.单片机芯片的选择方案和论证
方案一:
采用89C51芯片作为硬件核心,采用FlashROM,内部具有4KBROM存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP在线编程技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的多次拔插会对芯片造成一定的损坏。
方案二:
采用AT89S52,片内ROM全都采用FlashROM;能以3V的超底压工作;同时也与MCS-51系列单片机完全该芯片内部存储器为8KBROM存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,所以不会对芯片造成损坏。
所以选择采用AT89S52作为主控制系统.
2.显示模块选择方案和论证
方案一:
采用LED发光二极管,读书较困难。
方案二:
采用LCD12864,价格太贵,经济方面不予考虑。
方案三:
采用LCD1602,编程较困难。
方案四:
采用LED数码管动态扫描,LED数码管价格适中,对于显示数字最合适,而且采用动态扫描法与单片机连接时,占用的单片机口线少。
所以采用了LED数码管作为显示。
五.元器件清单
1.AT89S52单片机1个
2.芯片底座1个
3.ISP插口1个
4.USB接口1个
5.30pF瓷片电容2个、10μF电容1个
6.12M晶振1个
7.两连LED数码管3个
8.1K电阻11个、330Ω电阻8个、10K电阻1个
9.红色发光二极管5个
10.C8550三极管6个
11.按键5个
12.拨动开关1个
13.万用板一块
14.排线若干
六.电路图
1.最小系统电路图
2.ISP电路
3.显示电路
七.相关参数
1.本设计采用共阳数码管,其驱动电路采用三极管低电平驱动。
2.最小系统其构成简单,可靠。
复位电路有两种方式。
一种是上电复位,一种是按钮复位。
本设计采用电平按钮复位,通过RST端接电阻与电源Vcc接通实现。
晶振电路中晶振采用12MHZ。
八.程序
;/////////开始自定义及初始化////////////////
cBufTh0equ42h;定时器TH0基数存储单元
cBufTl0equ43h;定时器TL0基数存储单元
shuchuequP3;定义P3口为数据输出口送数码管显示
pianxuanequP2;定义P2口位片选口
cxingqiequ30h;星期存储单元
cshiequ31h;时存储单元
cfenequ32h;分存储单元
cnian1equ33H;年后两位存储单元
cyueequ34h;月存储单元
criequ35h;日存储单元
cmiaoequ36h;秒存储单元
cnian2equ37h;年前两位
cribjequ38h;最大天数
key1bit20h.1;已经按下一次的标志位
key2bit20h.2;已经按下一次的标志位
key3bit0h.3;已经按下一次的标志位
key4bit20h.4;已经按下一次的标志位
bt0bit20h.5;时间到了标志位
shezhibitP1.0;自动切换显示
jiabitP1.1;加按键
jianbitP1.2;减按键
returnbitP1.3;返回键
org0000h
ajmpstart
org000bh
ljmpT0Ser
org0030h
start:
movr0,#07fh
l0:
mov@r0,#0
djnzr0,l0
callchushihua
;///////////////十秒切换//////////////////
main:
calljianpan
callzuidashu
cjner4,#0,lei4
mova,cmiao
movb,#10
divab
movb,#2
divab
mova,b
jzxianshi2;十位为偶数显示年月日
ljmplei3;否则显示星期时分
lei4:
mova,r4
subba,#4
jnbpsw.7,xianshi2
lei3:
calldisplay1
ljmpmain
xianshi2:
calldisplay2
ljmpmain
chushihua:
movsp,#60h
movtmod,#01h;设定定时器的工作状态
movdptr,#65536-20000;20ms产生一次中断
movth0,dph
movtl0,dpl
movcBufTh0,dph
movcBufTl0,dpl
setbtr0
setbet0
setbea
movr0,#0;用来判断是否到了1S
movr4,#0;按键初始化
movcmiao,#50;50*20ms为一秒
movcfen,#59;设定初始时间
movcshi,#23
movcxingqi,#7
movcri,#28
movcyue,#2
movcnian1,#08
movcnian2,#20
clrkey1;按键清零
clrkey2
clrkey3
clrkey4
ret
display1:
setbp2.6;前两灯灭
cjner4,#0,lei
clrp2.6
lei:
mova,cxingqi
movb,#10
divab
movdptr,#tab1;星期高位
movca,@a+dptr
cjner4,#0,shanshuo;是否需要闪烁
ljmpzhengchang1;不需要闪烁跳正常显示
shanshuo:
clrp2.7
cjner4,#3,zhengchang1;判断星期是否要闪烁
jbbt0,cc1
zhengchang1:
clrp2.0;点亮第一个数码管
movshuchu,a
cc1:
lcalldelay
setbp2.0;闪烁
movdptr,#tab1;星期低位
mova,b
movca,@a+dptr
cjner4,#3,zhengchang2;判断是否星期需要闪烁
jbbt0,cc2
zhengchang2:
clrp2.1
movshuchu,a
cc2:
calldelay
setbp2.1;闪烁
mova,cshi
movb,#10
divab
movdptr,#tab1;显示时高位
movca,@a+dptr
cjner4,#2,zhengchang3;判断时是否需要闪烁
jbbt0,cc3
zhengchang3:
clrp2.2
movshuchu,a
cc3:
calldelay
setbp2.2;闪烁
movdptr,#tab1;显示时低位
mova,b
movca,@a+dptr
cjner4,#2,zhengchang4;判断时是否需要闪烁
jbbt0,cc4
zhengchang4:
clrp2.3
movshuchu,a
cc4:
calldelay
setbp2.3;闪烁
mova,cfen
movb,#10
divab
movdptr,#tab1;分高位
movca,@a+dptr
cjner4,#1,zhengchang5;判断分是否需要闪烁
jbbt0,cc5
zhengchang5:
clrp2.4
movshuchu,a
cc5:
calldelay
setbp2.4;闪烁
movdptr,#tab1;分低位
mova,b
movca,@a+dptr
cjner4,#1,zhengchang6;判断分是否需要闪烁
jbbt0,cc6
zhengchang6:
clrp2.5
movshuchu,a
cc6:
calldelay
setbp2.5;闪烁
ret
display2:
clrp2.6;点亮四个二极管
clrp2.7
mova,cnian1
movb,#10
divab
movdptr,#tab1;年高位
movca,@a+dptr
cjner4,#6,zhengchang7;判断年是否需要闪烁
jbbt0,cc7
zhengchang7:
clrp2.0
movshuchu,a
cc7:
lcalldelay
setbp2.0;闪烁
movdptr,#tab1;年低位
mova,b
movca,@a+dptr
cjner4,#6,zhengchang8;判断年是否需要闪烁
jbbt0,cc8
zhengchang8:
clrp2.1
movshuchu,a
cc8:
calldelay
setbp2.1;闪烁
mova,cyue
movb,#10
divab
movdptr,#tab1;月高位
movca,@a+dptr
cjner4,#5,zhengchang9;判断月是否需要闪烁
jbbt0,cc9
zhengchang9:
clrp2.2
movshuchu,a
cc9:
calldelay
setbp2.2;闪烁
movdptr,#tab1;月低位
mova,b
movca,@a+dptr
cjner4,#5,zhengchang10;判断月是否需要闪烁
jbbt0,cc10
zhengchang10:
clrp2.3
movshuchu,a
cc10:
calldelay
setbp2.3;闪烁
mova,cri
movb,#10
divab
movdptr,#tab1;日高位
movca,@a+dptr
cjner4,#4,zhengchang11;判断日是否需要闪烁
jbbt0,cc11
zhengchang11:
clrp2.4
movshuchu,a
cc11:
calldelay
setbp2.4;闪烁
movdptr,#tab1;日低位
mova,b
movca,@a+dptr
cjner4,#4,zhengchang12;判断日是否需要闪烁
jbbt0,cc12
zhengchang12:
clrp2.5
movshuchu,a
cc12:
calldelay
setbp2.5;闪烁
ret
;///////////////按键子程序///////////////////
jianpan:
jbshezhi,taiqi1;设置按键
jbkey1,taiqi1
setbkey1
incr4;设置哪个按键
cjner4,#7,taiqi1
movr4,#0
taiqi1:
jnbshezhi,pan1
clrkey1
pan1:
jbjia,taiqi2;加按键
jbkey2,taiqi2
setbkey2
cjner4,#0,jiaxingqi;是否需要加
ljmptaiqi2
jiaxingqi:
cjner4,#3,jiashi;判断星期是否需要加一
inccxingqi
ljmptaiqi2
jiashi:
cjner4,#2,jiafen;判断时是否需要加一
inccshi
ljmptaiqi2
jiafen:
cjner4,#1,jianian;判断分是否需要加一
inccfen
ljmptaiqi2
jianian:
cjner4,#6,jiayue;判断年是否需要加一
inccnian1
ljmptaiqi2
jiayue:
cjner4,#5,jiar;判断月是否需要加一
inccyue
ljmptaiqi2
jiar:
cjner4,#4,taiqi2;判断日是否需要加一
inccri
taiqi2:
jnbjia,pan2
clrkey2
pan2:
jbjian,taiqi3;减按键
jbkey3,taiqi3
setbkey3
cjner4,#0,jianxingqi;是否需要减
ljmptaiqi2
jianxingqi:
cjner4,#3,jianshi;星期是否需要减
deccxingqi
ljmptaiqi3
jianshi:
cjner4,#2,jianfen;时是否需要减
deccshi
ljmptaiqi3
jianfen:
cjner4,#1,jiannian;分是否需要减
deccfen
ljmptaiqi3
jiannian:
cjner4,#6,jianyue;年是否需要减
deccnian1
ljmptaiqi2
jianyue:
cjner4,#5,jianr;月是否需要减
deccyue
ljmptaiqi2
jianr:
cjner4,#4,taiqi2;日是否需要减
deccri
taiqi3:
jnbjian,pan3
clrkey3
pan3:
jbreturn,taiqi4
jbkey4,taiqi4
jbsetbkey4
taiqi4:
jnbreturn,loop1
clrkey4
ajmploop2
loop1:
movr4,#00
loop2:
ret
zuidashu:
mova,cxingqi
cjnea,#0,qq1;星期减到0则显示7
movcxingqi,#7
qq1:
cjnea,#8,dashi;星期加到8则显示1
movcxingqi,#1
movcxingqi,#1
dashi:
mova,cshi
cjnea,#255,qq2;时减到0则显示23
movcshi,#23
qq2:
cjnea,#24,dafen;时加到24则显示0
movcshi,#00
dafen:
mova,cfen
cjnea,#255,qq3;分减到0则显示59
movcfen,#59
qq3:
cjnea,#60,danian;分加到60则显示0
movcfen,#00
danian:
mova,cnian1
cjnea,#255,qq4;年减到0则显示99
movcnian1,#99
qq4:
cjnea,#100,dayue;年加到100则显示0
movcnian1,#00
dayue:
mova,cyue
cjnea,#0,qq5;月减到0则显示12
movcyue,#12
qq5:
cjnea,#13,dari;月加到13则显示1
movcyue,#01
dari:
lcallpanduan;调用panduan
mova,cri
mov40h,cribj
cjnea,#0,qq6;日减到0则显示最大数减一
deccribj
movcri,cribj
qq6:
cjnea,40h,out;日加到最大值则显示1
movcri,#01
out:
ret
;///////////////定时中断程序///////////////////
;输入:
"无"
;输出:
""
T0Ser:
pushacc
clrtr0
calljisuan
movtl0,cBufTl0
movth0,cBufTh0
setbtr0
popacc
reti
;///////////////计算子程序///////////////////
;输入:
;输出:
;实现的功能:
SECMINHOUR计算
jisuan:
incr0
cjner0,#50,tiaochu;是否来了一秒钟
movr0,#0
cplbt0
lcallpanduan
inccmiao;秒加一
cjner4,#0,lei1
cplp2.7
lei1:
mova,cmiao
cjnea,#60,tiaochu;是否加到了60
movcmiao,#00h;加到了60回0
inccfen;分加一
mova,cfen
cjnea,#60,tiaochu;是否加到60
movcfen,#00h;加到了60回0
inccshi;时加一
mova,cshi
cjnea,#24,tiaochu;是否加到了24
movcshi,#00h;加到了24回0
inccxingqi;星期加一
mova,cxingqi
cjnea,#8,jiari;是否加到了8
movcxingqi,#01h;加到了8回1
jiari:
inccri
mova,cri
cjnea,cribj,tiaochu;是否加到了最大数
movcri,#01;加到了回到1
inccyue
mova,cyue
cjnea,#13,tiaochu;是否加到了13
movcyue,#01;加到了回到1
inccnian1
mova,cnian1
cjnea,#100,tiaochu;是否加到了100
movcnian1,#00;加到了回到0
inccnian2
mova,cnian2
cjnea,#100,tiaochu
movcnian2,#00
tiaochu:
ret
panduan:
clrpsw.7
mova,cyue
subba,#8
jnbpsw.7,dayupanduan;C=0表示大月
mova,cyue;小月
movb,#2
divab
mova,b
jzpdyue2;等于0表示为双月
movcribj,#32;小月的单月最大为31天
ret
pdyue2:
mova,cyue
cjnea,#2,yuefuzhi
callrunianpd;是2月进行闰年判断
ret
runianpd:
mova,cnian1
movb,#4
divab
mova,b
jztiaochuc
movcribj,#29;不是闰年最大为28天
ret
tiaochuc:
movcribj,#30;是闰年最大为29天
ret
yuefuzhi:
movcribj,#31;不是2月最大为30天
ret
dayupanduan:
movb,#2
mova,cyue
divab
mova,b
jnzyuefuzhi;大月单月最大为30天
movcribj,#32;大月双月最大为31天
ret
;///////////延时子程序/////////////
delay:
movr6,#30
d1:
movr7,#40
djnzr7,$
djnzr6,d1
ret
tab1:
DB0C0H;0
DB0F9H;1
DB0A4H;2
DB0B0H;3
DB099H;4
DB092H;5
DB082H;6
DB0F8H;7
DB080H;8
DB090H;9
end
九.流程图(涉及到软件)
1.主流程图
中断程序
主程序
显示时间
1S
改变时间
定时50ms*20次
算
加1S
是否60S?
加分
2.阳历算法流程图
十.经费分析
元器件
数量(个)
价格(元)
元器件
数量(个)
价格(元)
AT89S芯片
1
4
两连数码管
3
12
ISP插口
1
2
发光二极管
5
2.5
芯片底座
1
2
电阻
20
6
USB接口
1
3
三极管
6
3
瓷片电容
2
1
按键
5
2.5
33P电容
1
0.5
万