基于单片机的数字钟(电子日历)(转载)

合集下载

基于单片机的数字电子钟万年历课程设计

基于单片机的数字电子钟万年历课程设计

汇编语言课程设计报告书一.课程设计的题目和内容用汇编语言编写一个万年历程序系统,该系统要有进入系统的封面,要有验证用户名和密码的功能,能正确显示万年历,在推出系统的时候,要有封底。

二.系统设计及功能要求1.系统封面设计内容:题目名称,设计日期,设计者姓名。

要求:具有动感,如题目名称移动;字体具有立体感。

可插入一些图画,如学校的校徽图。

2.输入画面设计内容及要求:①密码及口令:输入,核查及修改功能。

②年份:输入及判断功能。

如:年份值是否为4位整数,不为4位,提示用户重输。

3.日历计算功能设计①求某年某月某日是星期几的子功能。

(要求编成子程序)算法:s=(y-1)+(y-1)/4-(y-1)/100+(y-1)/400+c(其中:y为年份;c为某月某日是这一年的第几天,由②求出;s为总天数。

“/”为整除。

)n=s%7 (其中:n为星期数;“%”为求余数)②求某月某日是这一年的第几天的子功能。

(要求编成子程序)二月份是否为平年(28天)或闰年(29天)的算法:y/400=0∨y/4=0∧y/100≠0 (y为年份;“/”整除),则y为以闰年;否则,y为平年。

根据①②可求出一年中的日历。

4.日历输出功能设计。

①格式及显示设计显示要求:设置显示滚动区;在该区中每次显示4个月的日历(并列排列)。

②日历打印设计:将日历按年存入磁盘不同的文件中保存,供打印或再次显示使用。

1.程序系统总体功能模块调用图及模块功能说明封面程序的功能是显示欢迎信息,并且显示制作人的信息的;验证用户名和密码的程序是验证用户是否是合法的用户的,该程序要有容错的功能;万年历程序是主程序,该程序的功能是通过用户输入年和月,来查询日历的,并且该程序还可以判断输入的年份是平年还是闰年。

封底程序是用来显示用户退出万年历系统的时候,一个感谢用户使用万年历的界面的。

2.程序系统详细的程序框图(每个子程序的流程图)①封面子程序,封底子程序的框图注:以封面程序为例,封底程序与封面程序类似②用户名和密码子程序框图注:以用户名程序为例,密码程序和用户名程序类似③求某年某月某日是星期几的子程序④..求某月某日是这一年的第几天的⑤判断是平年还是闰年的子程序⑥年份月份转化为真值的子程序四. 程序运行结果五.系统源程序.386DATA SEGMENT USE16A0 DB ' _____◆____◆____◆____◆____◆____◆_____◆_____ $' DB '※※$' DB '| |$' DB '◆◆$' DB '| ┏☆━━━━━━━━━━━━━━☆┓|$' DB '◆☆^ǒ^*☆*^ǒ^*★*^ǒ^*☆*^ǒ^*★*^ǒ^*☆◆$' DB '| ┃欢迎进入万年历系统┃|$' DB '◆☆^ǒ^*★*^ǒ^*☆*^ǒ^*★*^ǒ^*☆*^ǒ^*☆◆$' DB '| ┗☆━━━━━━━━━━━━━━☆┛|$' DB '◆◆$' DB '| |$' DB '◆制作人:某某某◆$' DB '| |$' DB '◆班级:2班◆$' DB '| |$' DB '◆学号:123456789012 ◆$' DB '| |$' DB '◆日期:08.1.15 ◆$' DB '| |$' DB '◆◆$' DB '| |$' DB '◆◆$' DB '| 版权所有,请勿仿冒|$' DB '※____◆____◆____◆____◆____◆____◆____◆____※$'A1 DB ' ◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆$' DB '◇◇$' DB '◆◆$' DB '◇◇$' DB '◆┏━☆━━━━━━★━━━━━━☆━┓◆$' DB '◇┃◆◇┃◇$' DB '◆┃请输入用户名和密码┃◆$' DB '◇┃◇↑↑↑↑↑↑↑↑↑↑↑↑↑◆┃◇$' DB '◆┗━☆━━━━━━★━━━━━━☆━┛◆$' DB '◇◇$' DB '◆◆$' DB '◇◇$' DB '◆◆$' DB '◇用户名:◇$' DB '◆◆$' DB '◇◇$' DB '◆密码: ◆$' DB '◇◇$' DB '◆◆$' DB '◇◇$' DB '◆◆$' DB '◇◇$' DB '◆◆$' DB ' ◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇$'A2 DB '******★******☆******★*******☆*******★********$' DB '☆☆$' DB '| |$' DB '★★$' DB '| *********************************** |$' DB '☆* 欢迎再次使用万年历系统* ☆$' DB '| *********************************** |$' DB '★★$' DB '| |$' DB '☆☆$' DB '| |$' DB '★☆☆★★$' DB '| 如有不足之处,请联系我☆☆|$' DB '☆☆$' DB '| ★★☆|$' DB '★我们会不断的完善的★$' DB '| |$' DB '☆^_^ ☆$' DB '| |$' DB '★ISBN 7-300-00528-9 ★$' DB '| |$' DB '☆********★******☆********★********★*********☆$'A3 DB '******************万年历*******************$' DB '** ** ** **$' DB '======================================$' DB '| S UN | MON | T UE | WED | T HU | F A I | S A T |$' DB '|=====|=====|=====|=====|=====|=====|=====|$' DB '| | | | | | | |$' DB '|=====|=====|=====|=====|=====|=====|=====|$' DB '| | | | | | | |$' DB '|=====|=====|=====|=====|=====|=====|=====|$' DB '| | | | | | | |$' DB '|=====|=====|=====|=====|=====|=====|=====|$' DB '| | | | | | | |$' DB '|=====|=====|=====|=====|=====|=====|=====|$' DB '| | | | | | | |$' DB '|=====|=====|=====|=====|=====|=====|=====|$' DB '| | | | | | | |$' DB '|=====|=====|=====|=====|=====|=====|=====|$'YEAR DW ?MONTH DB ?B DW ?C1 DW 0D1 DW 0E DW 0G DB 0T DW 0S DB 0P DW ?N DW 0Y DW 0M DW 0BUF1 DB 31,?,31,30,31,30,31,31,30,31,30,31BUF2 DB 1,2,3,4,5,6,7,8,9,10,11,12INPUT1 DB '请输入要查询的年份:$'INPUT2 DB '请输入要查询的月份:$'INPUT3 DB '该年是平年$'INPUT4 DB '该年是闰年$'INPUT5 DB '要继续查询? 1.继续查询 2.退出万年历系统$'STR5 DB 5DB 0DB 5 DUP(0)STR6 DB 3DB 0DB 3 DUP(0)BUF3 DB ' 1',0AH,0DH,'$'DB ' 2',0AH,0DH,'$'DB ' 3',0AH,0DH,'$'DB ' 4',0AH,0DH,'$'DB ' 5',0AH,0DH,'$'DB ' 6',0AH,0DH,'$'DB ' 7',0AH,0DH,'$'DB ' 8',0AH,0DH,'$'DB ' 9',0AH,0DH,'$'DB '10',0AH,0DH,'$'DB '11',0AH,0DH,'$'DB '12',0AH,0DH,'$'DB '13',0AH,0DH,'$'DB '14',0AH,0DH,'$'DB '15',0AH,0DH,'$'DB '16',0AH,0DH,'$'DB '17',0AH,0DH,'$'DB '18',0AH,0DH,'$'DB '19',0AH,0DH,'$'DB '20',0AH,0DH,'$'DB '21',0AH,0DH,'$'DB '22',0AH,0DH,'$'DB '23',0AH,0DH,'$'DB '24',0AH,0DH,'$'DB '25',0AH,0DH,'$'DB '26',0AH,0DH,'$'DB '27',0AH,0DH,'$'DB '28',0AH,0DH,'$'DB '29',0AH,0DH,'$'DB '30',0AH,0DH,'$'DB '31',0AH,0DH,'$'C DB ?D DB ?STR1 DB 20DB 0DB 20 DUP(0)STR2 DB 20DB 0DB 20 DUP(0)STR3 DB 'admin' ; 用户名COUNT1 EQU $-STR3STR4 DB 'admin' ;密码COUNT2 EQU $-STR4BUF4 DB '用户名不正确,请重新输入!$'BUF5 DB '密码不正确,请重新输入!$'DATA ENDSSTACK SEGMENT USE16 STACKDB 200 DUP(0)STACK ENDSCODE SEGMENT USE16ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACKSTART: MOV AX,DATAMOV DS,AXMOV ES,AXMOV AH,0 ;设置显示方式MOV AL,3 ;彩色文本方式INT 10H;************************封面程序************************************ MOV AH,6MOV AL,0MOV CL,0 ;清整个屏幕MOV DH,24MOV DL,79MOV BH,26INT 10HMOV CX,24MOV SI,OFFSET A0MOV B,000EHLOPA0: MOV AH,2MOV BX,0MOV DX,BINT 10HADD DX,0100HMOV B,DXMOV DX,SIMOV AH,9INT 21HADD SI,52DEC CXJNZ LOPA0MOV AH,1INT 21H;*************************用户名,密码程序****************************MOV AL,0MOV CH,0MOV CL,0 ;清整个屏幕MOV DH,24MOV DL,79MOV BH,30INT 10HMOV CX,24 ;显示用户名的密码页面,共24行,循环输出24次MOV SI,OFFSET A1MOV B,000EHLOPA1: MOV AH,2 ;定光标位置MOV BX,1MOV DX,BINT 10HADD DX,0100HMOV B,DXMOV DX,SI ; 显示字符串MOV AH,9INT 21HADD SI,52DEC CXJNZ LOPA1MOV C,3 ;容错三次LOPA2: MOV AH,2 ;设置用户名光标位置MOV BH,0 ; 页号为1(帧屏号)MOV DX,0D21HINT 10HLEA DX,STR1 ;输入用户名,保存在缓冲区STR1中MOV AH,10INT 21HMOV AL,STR1+1 ;用户名的长度送到AL中CMP AL,COUNT1 ;比较输入的用户名是否和指定的用户名长度一样JNE R ;长度不一样,跳转到PLEA SI,STR1+2LEA DI,STR3MOV CX,COUNT1REPZ CMPSB ;逐一比较两串的对应字符是否相等JNE R ;不相等,跳转到P 否则程序往下执行,输入密码MOV D,3LOPA3: MOV AH,2 ;设置密码光标位置MOV BH,0 ; 页号为1(帧屏号)MOV DX,1021HINT 10HLEA DX,STR2 ;输入密码,保存在缓冲区STR2中MOV AH,10INT 21HMOV AL,STR2+1 ;密码的长度送到AL中CMP AL,COUNT2 ;比较输入的密码是否和指定的密码长度一样JNE Q ;长度不一样,跳转到QLEA SI,STR2+2LEA DI,STR4MOV CX,COUNT2REPZ CMPSB ;逐一比较两串的对应字符是否相等JNE Q ;不相等,转QJMP T1 ;相等,转LOPA4R: MOV AH,2 ;设置显示用户名错误信息光标位置MOV BH,0 ; 页号为1(帧屏号)MOV DX,1521HINT 10HLEA DX,BUF4 ;输出用户名错误信息MOV AH,9INT 21HMOV AH,6MOV AL,1MOV CH,13MOV CL,33 ;清用户名输入行的屏幕MOV DH,13MOV DL,53MOV BH,30INT 10HINT 21HMOV AH,6MOV AL,1MOV CH,21MOV CL,33 ;清用户名出错行的屏幕MOV DH,21MOV DL,60MOV BH,20INT 10HDEC C ;循环次数减1JNZ LOPA2 ;跳转到LOPA2,重新输入用户名JE EXITQ: MOV AH,2 ;设置显示密码错误信息光标位置MOV BH,0 ; 页号为1(帧屏号)MOV DX,1521HINT 10HLEA DX,BUF5 ;输出密码错误信息MOV AH,9INT 21HMOV AH,6MOV AL,1MOV CH,16MOV CL,33 ;清密码输入行的屏幕MOV DL,53MOV BH,30INT 10HMOV AH,1INT 21HMOV AH,6MOV AL,1MOV CH,21MOV CL,33 ;清密码出错行的屏幕MOV DH,21MOV DL,60MOV BH,20INT 10HDEC D ;循环次数减1JNZ LOPA3 ;跳转到LOPA3,重新输入密码JE EXITMOV AH,1INT 21H;***********************显示万年历程序*******************************T1: MOV T,0MOV AH,6MOV AL,0MOV CL,0 ;清整个屏幕MOV DH,24MOV DL,79MOV BH,27INT 10HMOV CX,17MOV SI,OFFSET A3MOV B,0411HLOPA4: MOV AH,2MOV BX,0MOV DX,BINT 10HADD DX,0100HMOV B,DXMOV DX,SIMOV AH,9INT 21HADD SI,44DEC CXJNZ LOPA4MOV AH,2 ;定输入年份提示信息的光标MOV BX,0MOV DH,1MOV DL,17INT 10HLEA DX,INPUT1 ;提示信息,请输入要查询的年份MOV AH,9INT 21HMOV AH,2 ;定输入年份的光标MOV BX,0MOV DH,5MOV DL,19INT 10HLEA DX,STR5 ;输入年份,保存在缓冲区STR1中MOV AH,10INT 21HLEA DI,STR5+2 ; DI指向年份输入串的首地址MOV CL,STR5+1 ;输入年份字符串的长度送到CLMOV AX,0 ;年份转化为真值P1: MOV BL,[DI] ; 取字符送到BLSUB BL,30H ;字符减去30H,转化为真值MOV BH,0MOV P,10MUL PADD AX,BXINC DI ;DI指向下一个字符DEC CX ;长度减一JNZ P1MOV YEAR,AX ;把年送到YEAR中CALL PR ;调用判断平年还是闰年的程序JC L1 ;有进位,借位,跳转到L1,输出闰年,否则顺序执行,是平年MOV AH,2 ;输出平年信息的光标MOV BX,0MOV DH,1MOV DL,36INT 10HLEA DX,INPUT3 ;输出平年MOV AH,9INT 21HLEA DI,BUF1MOV [DI+1],BYTE PTR 28 ;平年把28送入BUF1中JMP J0L1: MOV AH,2 ;输出闰年信息的光标MOV BX,0MOV DH,1MOV DL,36INT 10HLEA DX,INPUT4 ; 输出闰年MOV AH,9INT 21HLEA DI,BUF1MOV [DI+1],BYTE PTR 29 ;闰年把29送入BUF1中J0: MOV AH,2 ;定输入月份提示信息的光标MOV BX,0MOV DH,2MOV DL,17INT 10HLEA DX,INPUT2 ;提示信息,请输入要查询的月份MOV AH,9INT 21HMOV AH,2 ;定输入月份的光标MOV BX,0MOV DH,5MOV DL,56INT 10HLEA DX,STR6 ;输入月份,保存在缓冲区STR2中MOV AH,10INT 21HLEA DI,STR6+2 ;DI指向月份输入串的首地址MOV CL,STR6+1 ;月份输入串的长度送到CL中MOV AX,0P2: MOV BL,[DI] ;取字符送到BL中SUB BL,30H ;字符减去30HMOV BH,0MOV S,10MUL SADD AX,BXINC DI ;DI指向下一个字符DEC CX ;长度减一JNZ P2MOV WORD PTR MONTH,AX ;月份值送到MONTH中CALL DTOB1 ;显示日历,调用DTOB1子程序返回N侄MOV DI,OFFSET BUF1DEC MONTHADD DI,WORD PTR MONTH ;取出每个月的天数MOV CL,[DI]MOV G,CLMOV SI,OFFSET BUF3MOV AL,6MUL NADD AX,19MOV B,AXMOV C1,9J1: MOV AH,2 ;确定每个月的一号的光标位置,即确定初始输入位置MOV BX, 0MOV DH,BYTE PTR C1MOV DL,BYTE PTR BINT 10HCMP DL,55JBE J2 ;DL<33,跳转到J2,否则行加1列从3开始ADD C1,2MOV B,19JMP J1J2: MOV DX,SIMOV AH,9 ;在当前光标位置显示数字INT 21HADD SI,5ADD B,6DEC GJNZ J1MOV AH,2 ;定输入月份的光标MOV BX,0MOV DH,22MOV DL,17INT 10HLEA DX,INPUT5MOV AH,9INT 21HMOV AH,1INT 21HCMP AL,31HJE T1JMP T2DTOB1 PROC NEAR ;求某年某月某日是星期几子程序PUSH AXPUSH BXPUSH CXPUSH DXPUSH SIPUSH DIMOV CX,0DEC YEARMOV AX,YEAR ;YEAR-1送入AX中MOV CX,YEARMOV DX,0MOV BL,4DIV BXMOV C1,AX ;(YEAR-1)/4送入C1中ADD CX,C1MOV AX,YEARMOV DX,0MOV BL,100DIV BXMOV D1,AX ;(YEAR-1)/100送入D中SUB CX,D1MOV AX,YEARMOV DX,0MOV BX,400DIV BXMOV E,AX ;(YEAR-1)/400 送入E中ADD CX,EMOV DX,0 ;DX清零MOV BX,0 ;BX清零MOV DL,MONTH ;求每个月的第一天是本年的第几天SUB DL,1MOV DI,OFFSET BUF2MOV SI,OFFSET BUF1R1: CMP [DI],DLJA R2 ;一月份的时候,跳转到R2MOV BL,[SI] ; 其它月份的时候,进行累加,计算每个月的第一天是该年的第几天ADD T,BXADD SI,1ADD DI,1JMP R1R2: ADD T,1ADD CX,T ;s=(y-1)+(y-1)/4-(y-1)/100+(y-1)/400+TMOV AX,CXMOV DX,0MOV BX,7 ;S%7,计算每个月的第一天是星期几DIV BXMOV N,DXPOP DIPOP SIPOP DXPOP CXPOP BXPOP AXRETDTOB1 ENDPPR PROC NEAR ;判断是平年还是闰年PUSH AXPUSH BXPUSH CXPUSH DXMOV AX,YEARMOV CX,AXMOV DX,0MOV BX,4DIV BXJNZ B1MOV AX,CXMOV BX,100DIV BXCMP DX,0JNZ B2MOV AX,CXMOV BX,400DIV BXCMP DX,0JZ B2B1: CLCJMP B3B2: STCB3: POP DXPOP CXPOP BXPOP AXRETPR ENDP;***********************底封程序*************************************T2: MOV AH,6MOV AL,0MOV CH,0MOV CL,0 ;清整个屏幕MOV DL,79MOV BH,26INT 10HMOV CX,22MOV SI,OFFSET A2MOV B,010EH LOPA5: MOV AH,2MOV BX,0MOV DX,BINT 10HADD DX,0100HMOV B,DXMOV DX,SIMOV AH,9INT 21HADD SI,52DEC CXJNZ LOPA5EXIT: MOV AH,4CHINT 21HCODE ENDSEND START六.系统设计及实现的技术特点,不足及改进的建议设计封面,封底的时候,我先开始不会用循环的方法显示封面,所以用了许多9号功能调用来显示封面,但用这样的方法,显示的封面不能太大,所以我改用了循环的方法来显示封面,这样封面就可以做的很大了,这是我的一个技术特点在编写验证用户名和密码的程序时,我原先没有弄容错的功能,但是后来经过我的思考,我加了一个循环,让输入错了再返回到原输入位置,并且用循环判断是不是到了最大的输入次数,超过最大次数就退出系统,否则继续输入。

基于单片机的电子万年历设计

基于单片机的电子万年历设计

基于单片机的电子万年历设计一、概述随着科技的快速发展和人们对生活品质的追求,电子设备在日常生活中扮演着越来越重要的角色。

电子万年历作为一种集日期、时间显示于一体的实用电子产品,已经深入到人们的日常生活和工作中。

传统的机械式日历已经无法满足现代人对时间精确性和功能多样性的需求,基于单片机的电子万年历设计应运而生,成为了当前研究的热点之一。

基于单片机的电子万年历设计,旨在利用单片机(如STC89CAT89C51等)的强大计算和控制能力,结合液晶显示屏(LCD)、按键输入等外设,实现时间的准确显示、日期的自动更新、闹钟提醒、温度显示等多样化功能。

该设计不仅具有高度的集成性和可靠性,而且能够通过编程实现各种定制化的功能,满足不同用户的需求。

本文将对基于单片机的电子万年历设计进行详细的介绍和分析,包括设计思路、硬件组成、软件编程等方面。

通过本文的阅读,读者可以了解电子万年历的基本原理和设计方法,掌握单片机在电子万年历设计中的应用技巧,为实际的开发工作提供有益的参考和借鉴。

1.1 研究背景与意义随着科技的不断进步,人们日常生活和工作中对于时间的精度和便捷性的要求日益提高。

传统的机械式日历和简单的电子时钟已经无法满足现代生活的需求。

电子万年历作为一种集时间显示、日历查询、定时提醒等多功能于一体的电子装置,在日常生活、工作乃至科研领域都具有广泛的应用价值。

基于单片机的电子万年历设计,不仅可以提供准确的时间显示,还能实现复杂的日期计算、农历显示、节假日提示等功能,极大地提高了时间管理的效率和便捷性。

单片机作为一种集成度高、功耗低、价格适中的微型计算机,非常适合用于小型化、智能化的电子产品设计,如电子万年历。

本研究的意义在于,通过对基于单片机的电子万年历的设计研究,可以推动微型计算机技术和电子时钟技术的融合发展,提升电子产品的智能化水平,满足人们日益增长的生活和工作需求。

同时,该研究还可以为相关领域的技术人员提供参考和借鉴,推动电子万年历产品的不断创新和优化。

单片机制作数字钟(含万年历、秒表功能)

单片机制作数字钟(含万年历、秒表功能)

数字钟、万年历制作(基于单片机)电路原理图:程序://********************20131206****数字钟程序#pragma SMALL#include <reg51.h>#include <absacc.h>#include <intrins.h>//********************************************************* *********编译预处理void display(unsigned char *p); //显示函数,P为显示数据首地址unsigned char keytest(); //按键检测函数unsigned char search(); //按键识别函数void alarm(); //闹钟判断启动函数void ftion0(); //始终修改函数void ftion1(); //闹钟修改函数void ftion3(); //日期修改函数void cum(); //加1修改函数void minus(); //减1修改函数void jinzhi(); //进制修改函数void riqi(); //日期void stopwatch(); //秒表函数//********************************************************* *******函数声明sbit P2_7=P2^7;//********************************************************* *******端口定义unsigned char clockbuf[3]={0,0,0};unsigned char bellbuf[3]={0,0,0};unsigned char date[3]={1,1,1}; //日期存放数组unsigned char stop[3]={0,0,0};unsigned char msec1,msec2;unsigned char timdata,rtimdata,dtimdata;unsigned char count;unsigned char *dis_p;unsigned char or; //12进制控制标志unsigned char ri; //日期显示控制标志位unsigned char mb; //秒表控制标志位bit arm,rtim,rhour,rmin,hour,min,sec,day,mon,year; //定义位变量//********************************************************* *****全局变量定义void main(){unsigned char a;or=0; //12进制修改标志清零ri=0;mb=0;P2_7=0;arm=0;msec1=0;msec2=0;timdata=0;rtimdata=0;count=0;TMOD=0x12;TL0=0x06;TH0=0x06;TH1=(65536-10000)/256;TL1=(65536-10000)%256;EA=1;ET0=1;ET1=1;TR0=1;TR1=0;dis_p=clockbuf;while(1){a=keytest();if(a==0x78) //判断是否有键按下{display(dis_p);if(arm==1) alarm();}else{display(dis_p);a=keytest();if(a!=0x78){a=search();switch(a){case 0x00:ftion0();break;case 0x01:ftion1();break;case 0x02:cum();break;case 0x06:jinzhi();break;case 0x03:riqi();break;case 0x04:ftion3();break;case 0x05:minus();break;case 0x07:stopwatch();break;case 0x09:TR1=1;break;case 0x0a:TR1=0;break;case 0x0b:stop[0]=0;stop[1]=0;stop[2]=0;break;default:break;}}}}}//********************************************主函数【完】void display(unsigned char *p){unsigned char buffer[]={0,0,0,0,0,0};unsigned char k,i,j,m,temp;unsigned char led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};buffer[0]=p[0]/10;buffer[1]=p[0]%10;buffer[2]=p[1]/10;buffer[3]=p[1]%10;buffer[4]=p[2]/10;buffer[5]=p[2]%10;if((sec==0)&&(min==0)&&(hour==0)&&(rmin==0)&&(rhour==0)&&( day==0)&&(mon==0)&&(year==0)) //没有修改标志,正常显示{for(k=0;k<3;k++){temp=0x01;for(i=0;i<6;i++){P0=0x00; //段选端口j=buffer[i];P0=led[j];P1=~temp; //位选端口temp<<=1;for(m=0;m<200;m++);}}}else //若有修改标志,则按以下标志分别显示{if(sec==1||day==1){P1=0x1f;i=buffer[5];P0=led[i];for(m=0;m<200;m++);P1=0x2f;j=buffer[4];P0=led[j];for(m=0;m<200;m++);}if(min==1||rmin==1||mon==1){P1=0x3b;i=buffer[2];P0=led[i];for(m=0;m<200;m++);P1=0x37;j=buffer[3];P0=led[j];for(m=0;m<200;m++);}if(hour==1||rhour==1||year==1) {P1=0x3e;i=buffer[0];P0=led[i];for(m=0;m<200;m++);P1=0x3d;j=buffer[1];P0=led[j];for(m=0;m<200;m++);}}}//**********************************LED显示函数【完】unsigned char keytest(){unsigned char c;P2=0x78; //检测是否有键按下c=P2;c=c&0x78;return(c);}//******************************************键盘检测函数【完】unsigned char search(){unsigned char a,b,c,d,e;c=0x3f;a=0; //行号while(1){P2=c;d=P2;d=d&0x07;if(d==0x03){b=0;break;} //列号else if(d==0x05){b=1;break;}else if(d==0x06){b=2;break;}a++;c>>=1;if(a==5){a=0;c=0x3f;}}e=a*3+b;do{display(dis_p);}while((d=keytest())!=0x78);return(e);}//***********************************************查键值函数【完】void alarm(){if((clockbuf[0]==bellbuf[0])&&(clockbuf[1]==bellbuf[1])){P2_7=1;rtim=1;if(count==10){count=0;P2_7=0;arm=0;rtim=0;}}}//****************************************闹钟判断启动函数【完】void ftion0(){TR0=0;rhour=0;rmin=0;dis_p=clockbuf;rtimdata=0;timdata++;switch(timdata){case 0x01:sec=1;break;case 0x02:sec=0;min=1;break;case 0x03:min=0;hour=1;break;case 0x04:timdata=0;hour=0;TR0=1;break;default:break;}}//*********************************************时钟设置函数【完】void ftion1(){if(TR0==0) TR0=1;sec=0;min=0;hour=0;dis_p=bellbuf;timdata=0;rtimdata++;switch(rtimdata){case 0x01:rmin=1;break;case 0x02:rmin=0;rhour=1;break;case 0x03:rtimdata=0;rhour=0;arm=1;dis_p=clockbuf;break;default:break;}}//*********************************************闹钟设置函数【完】void ftion3(){if(TR0==0) TR0=1;day=0;mon=0;year=0;dis_p=date;timdata=0;rtimdata=0;dtimdata++;switch(dtimdata){case 0x01:day=1;break;case 0x02:day=0;mon=1;break;case 0x03:mon=0;year=1;break;case 0x04:dtimdata=0;year=0;dis_p=clockbuf;break;default:break;}}//*************************************************日期修改函数【完】void minus(){if(sec==1){if(0==clockbuf[2]) clockbuf[2]=59;else clockbuf[2]--;}else if(min==1){if(0==clockbuf[1]) clockbuf[1]=59;else clockbuf[1]--;}else if(hour==1){if(or==0) //判断进制{if(0==clockbuf[0]) clockbuf[0]=23;else clockbuf[0]--;}if(or==1){if(1==clockbuf[0]) clockbuf[0]=12;else clockbuf[0]--;}}else if(rmin==1){if(bellbuf[1]==0) bellbuf[1]=59;else bellbuf[1]--;}else if(rhour==1){if(or==0){if(bellbuf[0]==0) bellbuf[0]=23;else bellbuf[0]--;}if(or==1){if(bellbuf[0]==1) bellbuf[0]=12;else bellbuf[0]--;}}else if(day==1){if(date[2]==1) date[2]=31;else date[2]--;}else if(mon==1){if(date[1]==1) date[1]=12;else date[1]--;}else if(year==1){if(date[0]==1) date[0]=99;else date[0]--;}}//*************************************减1修改功能函数【完】void cum(){if(sec==1){if(59==clockbuf[2]) clockbuf[2]=0;else clockbuf[2]++;}else if(min==1){if(59==clockbuf[1]) clockbuf[1]=0;else clockbuf[1]++;}else if(hour==1){if(or==0) //判断进制{if(23==clockbuf[0]) clockbuf[0]=0;else clockbuf[0]++;}if(or==1){if(12==clockbuf[0]) clockbuf[0]=1;else clockbuf[0]++;}}else if(rmin==1){if(bellbuf[1]==59) bellbuf[1]=0;else bellbuf[1]++;}else if(rhour==1){if(or==0){if(bellbuf[0]==23) bellbuf[0]=0;else bellbuf[0]++;}if(or==1){if(bellbuf[0]==12) bellbuf[0]=1;else bellbuf[0]++;}}else if(day==1){if(date[2]==31) date[2]=1;else date[2]++;}else if(mon==1){if(date[1]==12) date[1]=1;else date[1]++;}else if(year==1){if(date[0]==99) date[0]=0;else date[0]++;}}//*************************************加1修改功能函数【完】void jinzhi(){if(or==0) or=1;else or=0;}//***********************************进制修改控制函数【完】void riqi(){if(ri==0){dis_p=date;}if(ri==1){dis_p=clockbuf;}ri++;if(ri==2) ri=0;}//********************************日期控显示函数【完】void stopwatch(){if(mb==0){dis_p=stop;mb=1;}else{mb=0;dis_p=clockbuf;}}//************秒表**********秒表**********秒表函数【完】void clock() interrupt 1{EA=0;if(msec1!=0x14) msec1++; //6MHz晶振定时10mselse{msec1=0;if(msec2!=100) msec2++; //定时1selse{if(rtim==1) count++; //闹钟启动标志计时10smsec2=0;if(clockbuf[2]!=59) clockbuf[2]++;else{clockbuf[2]=0;if(clockbuf[1]!=59) clockbuf[1]++;else{clockbuf[1]=0;if(or==0){if(clockbuf[0]!=23) clockbuf[0]++;else{clockbuf[0]=0;if((date[1]==1)||(date[1]==1)||(date[1]==1)||(date[1]==3)||(date[ 1]==5)||(date[1]==7)||(date[1]==8)||(date[1]==10)||(date[1]==12)){if(date[2]!=30) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if((date[1]==4)||(date[1]==6)||(date[1]==9)||(date[1]==11)){if(date[2]!=29) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if(date[1]==2){if((((date[0]%4==0)&&(date[0]%100!=0))||(date[0]%400==0))){if(date[2]!=28) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}else{if(date[2]!=27) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}}}}if(or==1){if(clockbuf[0]!=12) clockbuf[0]++;else{clockbuf[0]=0;if((date[1]==1)||(date[1]==1)||(date[1]==1)||(date[1]==3)||(date[ 1]==5)||(date[1]==7)||(date[1]==8)||(date[1]==10)||(date[1]==12)){if(date[2]!=30) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if((date[1]==4)||(date[1]==6)||(date[1]==9)||(date[1]==11)){if(date[2]!=29) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if(date[1]==2){if((((date[0]%4==0)&&(date[0]%100!=0))||(date[0]%400==0))){if(date[2]!=28) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}else{if(date[2]!=27) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}}}}}}}}EA=1;}//*******************************定时器0中断函数【完】void miaobiao() interrupt 3{TH1=(65536-10000)/256;TL1=(65536-10000)%256;if(stop[2]!=99) stop[2]++;else{stop[2]=0;if(stop[1]!=59) stop[1]++;else{stop[1]=0;if(stop[0]!=59) stop[0]++;else stop[0]=0;}}}//***********************************定时器1中断函数【完】。

基于单片机的电子时钟万年历设计

基于单片机的电子时钟万年历设计

(2)31 8 位暂存数据存储RAM(3)串行 I/O 口方式使得管脚数量最少(4)宽范围工作电压2.0 5.5V(5)工作电流 2.0V 时,小于300nA(6)读/写时钟或RAM 数据时有两种传送方式单字节传送和多字节传送字符组方式(7)8 脚DIP 封装或可选的8 脚SOIC 封装根据表面装配(8)简单 3 线接口(9)与 TTL 兼容Vcc=5V(10)可选工业级温度范围-40~+85优点:串行接口的日历时钟芯片,使用简单,接口容易,与微型计算机连线较少等特点,在单片机系统尤其是手持式信息设备中己得到了广泛的应用。

所以,最终选择串行时钟芯片DS1302,DS1302的管脚图如图2所示。

图2 DS1302管脚图1.2显示模块选择方案一:LED数码管显示数码管显示比较常用的是采用CD4511和74LS138实现数码转换,数码显示分动态显示和静态显示,静态显示具有锁存功能,可以使数据显示得很清楚,但浪费了一些资源。

目前单片机数码管普通采用动态显示。

编程简单,但只能显示数字,不能显示中文。

方案二:LCD1602能够显示英文和数字。

1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”。

所以最终选择LCD1602。

2.项目功能模块2.1 89C51模块Mcs-51单片机管脚图图如图3所示:单片机管脚图2.2 1602液晶显示模块1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”。

单片机课程设计(论文)电子万年历的设计

单片机课程设计(论文)电子万年历的设计

目录1设计要求 (2)2方案论证与对比 (2)液晶显示器控制方式选择 (2)2.2并行接口动态显示电路选择 (2)2.3LCD液晶显示器的接口方法选择 (3)液晶显示器限流电阻选择 (4)3系统硬件电路的设计 (5)主控模块AT89C52 (5)3.2显示模块电路设计 (6)4系统软件设计 (7)4.1系统软件概述 (7)4.2主要子程序设计 (8)4.2.1 时钟中断服务子程序设计 (8)时间调整子程序设计 (9)4.2.3 判断闰年子程序设计 (9)4.2.4 精度分析分析与计算 (10)4.2.5 第一次初值的设置 (10)4.2.6 重载初值的方法 (10)5系统仿真与测试 (11)5.1系统仿真 (11)功能测试 (11)6总结 (12)参考文献 (13)1设计要求本课题以AT89C52单片机为核心,设计并制作出智能LCD电子钟,具有以下基本功能:能进行时间、年份、日期、星期显示;能区分是否闰年;能检测室温并显示。

扩展功能部分可以通过控制按键使时间暂停、可以调整校正时间并通过按键切换轮流显示时间、年份、日期、星期。

2方案论证与对比2.1液晶显示器控制方式选择采用LCD液晶显示,具有超精致影像画质、十足平面显示、节省空间、节省能源等优点,但按控制方式不同,LCD可分为被动矩阵式LCD及主动矩阵式LCD两种。

可根据不同需要采用不同的方式。

方案一被动矩阵式LCD被动矩阵式LCD在亮度及可视角方面受到较大的限制,反应速度也较慢。

由于画面质量方面的问题,使得这种显示设备不利于发展为桌面型显示器,但成本低廉。

方案二主动矩阵式LCD目前应用比较广泛的主动矩阵式LCD,也称TFT-LCD(Thin Film Transistor-LCD,薄膜晶体管LCD)。

TFT液晶显示器是在画面中的每个像素内建晶体管,可使亮度更明亮、色彩更丰富及更宽广的可视面积。

与CRT显示器相比,LCD显示器的平面显示技术体现为较少的零件、占据较少的桌面及耗电量较小,但CRT技术较为稳定成熟。

基于单片机的电子万年历的设计-大学毕业(设计)论文

基于单片机的电子万年历的设计-大学毕业(设计)论文

学号:毕业设计题目:基于单片机的电子万年历的设计作者届别 2013院别物理与电子学院专业电子科学与技术指导老师职称讲师完成时间2013年5月毕业设计(论文)摘要智能电子万年历系统是由硬件与软件相结合而设计,而它是以AT89C55单片机作为主控核心与时钟电路、显示电路、复位电路、振荡电路、报警闹铃电路、温度检测电路、独立键盘电路等模块组成硬件系统,其中时钟电路采用了时钟芯片DS12887,显示电路采用了LCD1602液晶显示,温度检测电路采用了DS18B20温度传感器;而软件使用了Keil软件进行C语言编程、Proteus软件进行仿真测试,Altium Designer软件进行原理设计。

系统采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,且具有整点报时、时间校准及设置闹钟等功能。

关键词:单片机AT89C55 ;时钟电路;电子万年历;液晶显示毕业设计(论文)AbstractThe design of Intelligent electronic calendar system is composed of hardware and software, and it is based on A T89C55 microcontroller as the master core .It is Composed of clock circuit, display circuit, reset circuit, oscillation circuit, alarm alarm circuit, temperature detection circuit, keyboard circuit module hardware. the clock circuit using the clock chip DS12887, the display circuit displays useing LCD1602 liquid crystal, temperature detection circuit using DS18B20 temperature sensor; It is simulated by C programming language and Proteus software useing Keil software, Use Altium Designer software design principles. The system adopts visual digital display, can display year, month, day, Circle day, hours, minutes, seconds and temperature information, and with the whole point timekeeping, time and set the alarm function.keyword : MCU AT89C55; clock circuit; electronic calendar; liquid crystal display.目录第一章引言 .......................................................................................................................... 错误!未定义书签。

基于单片机的日历设计方案

基于单片机的日历设计方案

引言日历作为我们日常生活中必不可少的工具之一,是人们记录时间、安排活动以及管理生活的重要工具。

在现代科技的发展下,基于单片机的日历设计方案应运而生。

本文将介绍一种基于单片机的日历设计方案,该方案通过单片机的控制和显示功能,能够提供准确的日期和时间显示,具备一些常见的日历功能,并具备一定的扩展性和灵活性。

设计原理硬件设计单片机选择在本设计方案中,选择常见的8位单片机AT89C52作为核心控制芯片。

该单片机具备足够的IO口,能够方便地控制各个模块的输入和输出。

时钟模块为了确保日历的准确性,需要使用一个精确的时钟模块。

在本设计中,选择DS1302时钟模块用于提供稳定的时钟信号。

该模块具备低功耗、精准度高的特点,能够满足日历的需求。

显示模块为了方便用户查看日期和时间,选择一个适合的显示模块十分重要。

本设计方案中,选择TM1637四位数码管模块用于显示日期和时间。

该模块通过单片机的IO口能够方便地进行控制,并能够显示数字和一些常见的符号。

软件设计时钟控制通过单片机与DS1302时钟模块进行通信,获取当前的日期和时间信息。

通过设置注册器来读取年、月、日、时、分和秒的值,并将其保存在单片机内部的变量中。

显示控制通过单片机与TM1637数码管模块进行通信,将日期和时间的值显示在数码管上。

通过设置数码管的段选择和段数据,可以实现具体的数字和符号的显示。

日历功能在本设计方案中,实现了一些常见的日历功能,例如星期显示、日期调整、闹钟设置等。

通过单片机的按键输入,可以实现各种功能的切换和设置。

实现步骤1.连接硬件模块:将单片机、DS1302时钟模块和TM1637数码管模块按照原理图连接起来,并接上所需的电源。

2.编写主程序:使用C语言编写主程序,包括时钟控制、显示控制和日历功能的实现。

3.编译烧录:使用相应的编译器将主程序编译生成可执行文件,并将其烧录到单片机中。

4.测试调试:将单片机上电,通过按键输入进行各种功能的测试和调试,确保日历的正常工作。

基于单片机的电子日历时钟设计

基于单片机的电子日历时钟设计

#include<STC12C5A.h>#define uchar unsigned char#define uint unsigned int//----端口定义---sbit ACC_7=ACC^7;sbit RST1=P2^5;sbit IO=P2^6;sbit SCLK=P2^7;sbit k1=P3^2;sbit k2=P3^3;sbit k3=P2^2;sbit k4=P2^3;//uchar wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; // 数码的位选,左到右uchar tab_1302[7]={45,50,11,19,1,1,15};uchar tab_time[8]={0,0,10,0,0,10,0,0}; //时间uchar tab_day[8]={0,0,10,0,0,10,0,0,}; //年月日uchar tab_num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};//0 1 2 3 4 5 6 7 8 9 - {"0123456789-"}////////////=============函数声明============////////////////void display_time();void delayms(uint);void display_day();void ds1302(); //获取DS1302的时间void ds1302_init(); //DS1302的初始化void write1302(uchar,uchar); //指定地址向DS1302写数据uchar read1302(uchar); //指定地址向DS1302读数据void ds1302();void int0_init();/////////=======中断初始化=======///////////void int0_init(){EX0=1;IT0=1;EX1=1;IT1=1;EA=1;}///////////========时间显示======///////////// void display_time(){P1=0x7f;P0=tab_num[tab_time[7]];delayms(10);P1=0xbf;P0=tab_num[tab_time[6]];delayms(10);P1=0xdf;P0=tab_num[tab_time[5]];delayms(10);P1=0xef;P0=tab_num[tab_time[4]];delayms(10);P1=0xf7;P0=tab_num[tab_time[3]];delayms(10);P1=0xfb;P0=tab_num[tab_time[2]];delayms(10);P1=0xfd;P0=tab_num[tab_time[1]];delayms(10);P1=0xfe;P0=tab_num[tab_time[0]];delayms(10);}//////////=========延时函数========//////////////// void delayms(uint x){int i,j;for(i=x;i>=0;i--)for(j=0;j<=110;j++);}//////////=======日期显示======///////////void display_day(){P1=0x7f;P0=tab_num[tab_day[7]];delayms(10);P1=0xbf;P0=tab_num[tab_day[6]];delayms(10);P1=0xdf;P0=tab_num[tab_day[5]];delayms(10);P1=0xef;P0=tab_num[tab_day[4]];delayms(10);P1=0xf7;P0=tab_num[tab_day[3]];delayms(10);P1=0xfb;P0=tab_num[tab_day[2]];delayms(10);P1=0xfd;P0=tab_num[tab_day[1]];delayms(10);P1=0xfe;P0=tab_num[tab_day[0]];delayms(10);}////////////=========DS1302初始化======//////////// void ds1302_init() //DS1302初始化,设置初始时间{uchar i,add;add=0x80;write1302(0x8e,0x00);for(i=0;i<7;i++){write1302(add,tab_1302[i]);add+=2;}/* write1302(0x80,0x50); // 秒...write1302(0x82,0x59); // 分write1302(0x84,0x23); // 时write1302(0x86,0x19); // 日write1302(0x88,0x01); // 月write1302(0x8a,0x01); // 周write1302(0x8c,0x15); // 年*/write1302(0x8e,0x80);}//////////============从DS1302获取数据============///////////// uchar read1302(uchar add){uchar i,temp,dat1,dat2;RST1=0;SCLK=0;RST1=1;for(i=8;i>0;i--) //发送地址{SCLK=0;temp=add;IO=(bit)(temp&0x01);add>>=1;SCLK=1;}for(i=8;i>0;i--) //读取数据{ACC_7=IO;SCLK=1;ACC>>=1;SCLK=0;}RST1=0;dat1=ACC;dat2=dat1/16;dat1=dat1%16;dat1=dat1+dat2*10;return(dat1);}/////////============向DS1302写入数据程序================//////////// void write1302(uchar add,uchar dat){uchar i,temp;RST1=0;SCLK=0;RST1=1;for(i=0;i<8;i++) //发送地址{SCLK=0;temp=add;IO=(bit)(temp&0x01);add>>=1;SCLK=1;}temp=(dat/10<<4)|(dat%10);for(i=0;i<8;i++) //发送数据{SCLK=0;IO=(bit)(temp&0x01);temp>>=1;SCLK=1;}RST1=0;}/////////-------------获取DS1302的时间-----------////////void ds1302(){uchar i,add=0x81;write1302(0x8e,0x00); //允许向DS1302写入数据for(i=0;i<7;i++){tab_1302[i]=read1302(add); //获得的数据已转换为十进制add+=2;}write1302(0x8e,0x80); //获取完一次时间,禁止向DS1302写入数据,提高可靠}///////////============转换函数============///////////void change(){tab_time[0]=tab_1302[2]/10; //小时十位tab_time[1]=tab_1302[2]%10; //小时个位tab_time[3]=tab_1302[1]/10; //分十位tab_time[4]=tab_1302[1]%10; //分个位tab_time[6]=tab_1302[0]/10; //秒十位tab_time[7]=tab_1302[0]%10; //秒个位tab_day[0]=tab_1302[6]/10; //年十位tab_day[1]=tab_1302[6]%10; //年个位tab_day[3]=tab_1302[4]/10; //月十位tab_day[4]=tab_1302[4]%10; //月个位tab_day[6]=tab_1302[3]/10; //日十位tab_day[7]=tab_1302[3]%10; //日个位}////////////========主函数=======///////////// void main(){P2M0=0xff;P2M1=0;ds1302_init();int0_init();while(1){ds1302();change();display_time();while(!k4){ds1302();change();display_day();}}}/////========time=========////////////void int0() interrupt 0{uchar ky=0,n1,n2,n3=1,flag=1;while(flag!=0){write1302(0x8e,0x00);write1302(0x80,0x80|tab_1302[0]);P1=0xdf;P0=tab_num[tab_time[5]];delayms(10);P1=0xfb;P0=tab_num[tab_time[2]];delayms(10);if(k3==0){delayms(50);if(k3==0){ky++;while(!k3);if(ky==5){ky=0;}}}//////////=======1========////////if(ky==1){n1=tab_1302[0];if(k4==0){delayms(30);if(k4==0){n1++;while(!k4);if(n1>=60)n1=0;}}tab_1302[0]=n1;change();P1=0x7f;P0=tab_num[tab_time[7]];delayms(10);P1=0xbf;P0=tab_num[tab_time[6]];delayms(10);}////////=======2======////////if(ky==2){n2=tab_1302[1];if(k4==0){delayms(30);if(k4==0){n2++;while(!k4);if(n2>=60)n2=0;}}tab_1302[1]=n2;change();P1=0xef;P0=tab_num[tab_time[4]];delayms(10);P1=0xf7;P0=tab_num[tab_time[3]];delayms(10);P1=0x7f;P0=tab_num[tab_time[7]];delayms(10);P1=0xbf;P0=tab_num[tab_time[6]];delayms(10);}/////==3==///if(ky==3){n3=tab_1302[2];if(k4==0){delayms(10);if(k4==0){n3++;while(!k4);if(n3==24)n3=1;}}tab_1302[2]=n3;change();P1=0xfd;P0=tab_num[tab_time[1]];delayms(10);P1=0xfe;P0=tab_num[tab_time[0]];delayms(10);P1=0xef;P0=tab_num[tab_time[4]];delayms(10);P1=0xf7;P0=tab_num[tab_time[3]];delayms(10);P1=0x7f;P0=tab_num[tab_time[7]];delayms(10);P1=0xbf;P0=tab_num[tab_time[6]];delayms(10);}//////===4====////if(ky==4){flag=0;ds1302_init();}}}/////////////=============day================///////////// void int1() interrupt 2{uchar ky=0,n1,n2=1,n3=1,flag=1;while(flag!=0){write1302(0x8e,0x00);write1302(0x80,0x80|tab_1302[0]);P1=0xdf;P0=tab_num[tab_day[5]];delayms(10);P1=0xfb;P0=tab_num[tab_day[2]];delayms(10);if(k3==0){delayms(50);if(k3==0){ky++;while(!k3);if(ky==5){ky=0;}}}//////////=======1========////////if(ky==1){n1=tab_1302[6];if(k4==0){delayms(30);if(k4==0){n1++;while(!k4);if(n1==50)n1=0;}}tab_1302[6]=n1;change();P1=0xfd;P0=tab_num[tab_day[1]];delayms(10);P1=0xfe;P0=tab_num[tab_day[0]];delayms(10);}////////=======2======////////if(ky==2){n2=tab_1302[4];if(k4==0){delayms(30);if(k4==0){n2++;while(!k4);if(n2==13)n2=1;}}tab_1302[4]=n2;change();P1=0xfd;P0=tab_num[tab_day[1]];delayms(10);P1=0xfe;P0=tab_num[tab_day[0]];delayms(10);P1=0xef;P0=tab_num[tab_day[4]];delayms(10);P1=0xf7;P0=tab_num[tab_day[3]];delayms(10);}/////==3==///if(ky==3){n3=tab_1302[3];if(k4==0){delayms(10);if(k4==0){n3++;while(!k4);if(n3==31)n3=1;}}tab_1302[3]=n3;change();P1=0x7f;P0=tab_num[tab_day[7]];delayms(10);P1=0xbf;P0=tab_num[tab_day[6]];delayms(10);P1=0xef;P0=tab_num[tab_day[4]];delayms(10);P1=0xf7;P0=tab_num[tab_day[3]];delayms(10);P1=0xfd;P0=tab_num[tab_day[1]];delayms(10);P1=0xfe;P0=tab_num[tab_day[0]];delayms(10);}if(ky==4){flag=0;ds1302_init();}}}。

毕业设计---基于单片机的多功能电子万年历的设计

毕业设计---基于单片机的多功能电子万年历的设计

基于单片机的多功能电子万年历的设计摘要随着科技的快速发展,自从观太阳、摆钟到现在电子钟,人类不断研究,不断创新纪录。

本文主要介绍了基于单片机的智能电子万年历的研制,该万年历能够实时显示公历年、月、日、时、分、秒,以及对应的农历日期、24节气、天干地支、闹铃功能,同时还能够实时测取环境温度。

本系统的硬件部分主要由A VR单片机、时钟芯片、温度传感器等部件组成,文中给出了详细的硬件设计实现及相关电路图;软件部分主要包含公历转农历的算法设计模块、显示模块、时间的读取、温度的检测模块,按键的扫描输入模块等,文中给出了系统的软件程序流程图及各功能模块的软件程序清单,最后介绍了整体系统的设计实现、仿真及调试过程,给出了下一步的改进方案等。

关键词:单片机;液晶技术;万年历;时钟芯片Design of Multifunctional digital Perpetual Calendar Based on MCUAbstractWith the development of technology,Since the concept of the sun, Baizhong, andnow the electronic bell,human beings continue to study and constant innovation record。

This paper-based Microcontroller Development of Intelligent electronic calendar, The calendar can display real-time in the calendar year, month, day, hours, minutes and seconds,a nd the correspond ing date of the Lunar New Year, 24 Solar Terms,at the same time also to real-time measurement from the ambient temperature,In addition to the user through the keyboard input years of history,for the correspond ing period of the Lunar.The system hardware from some of the major A VR microcontroller, a number of digital control, decoder, the clock chip,temperature sensors and other components,the paper gives a detailed design and implementation of hardware and related circuit;Software contains some of the major Lunar calendar to the algorithm design module,dynamic digital display modules,time to read,temperature detection module,Press enter the scanning module.In this paper, the system software modules and flow chart of the list of software programs,Finally, the realization of the overall system design, simulation and debugging process, the next step is the improvement programmes.Keywords:MCU;crystal technology;Calendar;Clock chip目录引言 (1)第1章绪论 (2)1.1课题的背景与意义 (2)1.2 数字万年历的现状与发展 (2)1.3 论文的主要工作及章节安排 (3)1.4 本章小结 (3)第2章方案论证比较.............................................................................. (4)2.1 多功能数字万年历系统概述 (4)2.2计时方案 (4)2.3温度检测方案 (5)2.4显示方案 (5)2.5本章小结 (5)第3章系统硬件设计 (6)3.1 主控制器ATmega16 单片机介绍 (6)3.2 时钟电路DS1302 (6)3.3 温度检测DS18B20 (7)3.4 动态显示 (8)3.5 键盘接口 (8)3.6 语音闹铃模块 (8)3.7 电源设计 (9)3.8本章小结 (11)第4章系统软件设计 (12)4.1 公历计算显示程序设计 (13)4.1.1 DS1302 内部寄存器 (13)4.1.2 时间读取程序设计 (15)4.2 农历转换程序设计 (16)4.2.1 公历转农历算法研究 (16)4.2.2 干支纪年简介 (18)4.2.3 公历转农历程序 (18)4.3 温度测量程序设计 (20)4.3.1 DS18B20 的测温原理 (20)4.3.2 温度程序 (21)4.4 二十四节气算法研究 (23)4.5系统仿真 (24)4.6本章小结 (25)结论与展望 (26)致谢 (27)参考文献 (28)附录 A 电子万年历原理图 (29)附录 B 外文文献与译文 (30)英文原文: (30)中文译文: (33)附录 C 参考文献题录及摘要 (35)附录 D 电子万年历源程序 (37)插图清单图2-1 数字万年历系统框图 (4)图3-1 DS1302与ATmega16连接图 (7)图3-2 DS18B20与AtMEGA16连接图 (8)图3-3 报时电路 (9)图3-4 稳压电源原理图 (10)图3-5 电源电路 (10)图4-1 系统程序流程图 (13)图4-2 公历程序流程图 (14)图4-3 DS18B20测温原理 (21)表格清单表3-1 LCD12864显示内容 (8)表4-1 DS1302的寄存器及其控制字 (14)表4-2 RS位配置 (15)引言人类的日常生活离不开时间,任何具有周期性变化的自然现象都可以用来测量时间。

基于51单片机的可调数码日历钟的设计与制作毕业设计论文

基于51单片机的可调数码日历钟的设计与制作毕业设计论文

专科毕业设计(论文)题目基于51单片机的可调数码日历钟的设计与制作摘要单片机以其体积小、编程灵活、控制功能强大、价格低廉等特点被广泛应用在各种电子电器产品中。

单片机技术的出现和发展带来了电子技术和控制领域的一场革命。

单片机课程作为职业院校电子信息类专业一门重要的基础课程,它既是一门很有实用价值、实践性很强且很有趣味性的课程,同时它又是一门集硬件电路设计与软件编程于一体的学科,既要求我们有较好的电工电子技术基础知识,又要求有一定的逻辑思维和软件开发(编程)能力。

通过近几年对单片机的学习,我已掌握单片机的基本知识,并具备了单片机应用系统的初步开发能力。

即将毕业之际,我运用我所掌握的单片机知识设计和制作了一个基于51单片机的可调数码日历钟,这既是对我所学知识的总结与高度概括,同时也将自己所掌握的知识与实际应用结合起来,进一步提高工程实践能力。

数码日历钟是实际生活中应用较多的一个电子计时装置,可供人们查询日期、星期及掌握时间。

本文首先从数码日历钟的功能要求入手,对设计任务进行了分析,并将任务分解为若干个模块,提出在设计与制作过程中要用到的相关知识点,给出了本设计的硬件电路及软件流程,还给出了部分模块的源程序代码。

本设计经过多次调试运行无误,最终提交出一个完整的应用系统产品。

本次毕业设计的数码日历钟能在12864液晶屏上显示出年月日时分秒以及星期几,还能显示当前环境温度,并能通过按键调整日期和时间,在调整日期的同时通过相应算法自动实现星期几的调整,而且无论是否闰年、任何月份,当日期调整时都保证不会出现非法日期。

数码日历钟是一个非常实用的设计与制作,成本低廉,如能进一步完善,具有一定的推广使用价值。

本设计任务比较复杂,要考虑的问题很多,C语言的模块化程序设计思想较好地解决了这个问题,故本设计任务采用C语言编程。

关键词:51单片机,C语言,数码日历钟,毕业设计,制作I河南理工大学毕业设计论文目录摘要 (Ⅰ)1概述 (1)1.1 毕业设计的选题背景及制作意义 (1)1.1.1毕业设计的选题背景 (1)1.1.2毕业设计的制作意义 (1)1.2 数码日历钟的功能要求 (1)1.3 本设计制作的主要内容 (2)2数码日历钟的设计与制作任务分析 (3)2.1数码日历钟的设计与制作任务分析与分解 (3)2.2设计方案的论证及选择 (3)3 相关知识链接 (6)3.1 51单片机简介 (6)3.1.1 51单片机简介 (6)3.1.2 51单片机引脚功能介绍 (8)3.2由已知日期推算星期几 (11)3.2.1如何判断一个年份是否闰年 (11)3.2.2由已知日期如何推算星期几 (11)3.3 12864图形液晶的使用 (13)3.3.1 液晶概述 (13)3.3.2 LCM引脚功能介绍 (14)3.3.3 LCD12864图形液晶显示模块指令集 (15)3.3.4 LCD12864图形液晶显示模块与单片机的接口 (17)3.3.5 LCD12864图形液晶显示模块的基础函数 (17)3.4 51单片机中的中断与定时 (19)3.4.1 51单片机中的中断 (19)3.4.2 51单片机中的定时/计数器 (22)3.5数字温度传感器DS18B20的使用 (28)3.5.1 DS18B20概述 (28)3.5.2 DS18B20的内部结构 (29)3.5.3 DS18B20与单片机的接口电路 (32)3.5.4 DS18B20的操作命令 (32)-1-3.5.5 DS18B20的时序 (33)3.6 矩阵式按键的检测 (36)4系统设计与调试 (44)4.1 硬件系统设计与调试 (44)4.1.1硬件系统设计原理图 (44)4.1.2硬件系统元器件清单 (44)4.1.3硬件系统组装与调试 (45)4.2 软件系统设计与调试 (45)4.2.1软件系统设计 (45)4.2.2软件系统调试与仿真 (47)5结束语 (49)参考文献 (50)致谢 (51)-2-河南理工大学毕业设计论文 1 概述1、概述1.1 毕业设计的选题背景及制作意义1.1.1毕业设计的选题背景单片机以其体积小、编程灵活、控制功能强大、价格低廉等特点被广泛地应用在各种电子电器产品中。

单片机课程设计实验报告(时钟、日历)..

单片机课程设计实验报告(时钟、日历)..

基于单片机的电子钟设计目录第一章电子时钟设计--—--—----————-—-—-—----—-—-——-——21.1 设计原理简介--————-—----—---——---———-----——-—-—-—21.2 设计功能-——--—-—————-———-—----————---——--——-——---—3第二章主要电路元器件介绍-—-———-———-—------———---32。

1 STC89C52 单片机简介—--—--—-—-—-—-—-—---—-——-———32。

1.1 单片机简介--——--——--——---—-—--————----—————--——-—-32。

1.2 主要特性---——-------—---—-—---————-—--—--———-—-—-—32.1.3 管脚功能说明—---———-———-———-——---—-————-—-—-—-————42.1。

4 LCD1602-—------——---—--—-——--———--——------——-—-—5第三章单元电路的硬件设计—-----————————————————--63.1 硬件原理框图—-———--—--——---—--—-—---------—--———-—-63。

2 单片机 STC89C52 系统的设计-—-—-—-—-————-—————-—----63。

3 时钟电路—————-----———-—---—-——---—--—-—-—-—--————--73.4 复位电路-----——-——--———-————-———-—----———---—--—-—-------—-—--—-——---—-—————-—---——--73。

5 键盘接口电路--—---—-———--—--——--——--——----———---——-83.6 LCD1602显示——---——————--—-—-——--——----—----———-————8第四章设计总原理图—-—-—---——-----—-———-9 第五章心得体会---—-------—————--——-—-——9第六章源程序---—-—-——-—-------———---—-——————-——----10前言:摘要数字钟已成为人们日常生活中必不可少的必需品,广泛用于个人家庭以及办公室等公共场所,给人们的生活、学习、工作、娱乐带来极大的方便.由于数字集成电路技术的发展和采用了先进的石英技术,使数字钟具有走时准确、性能稳定、携带方便等优点,它还用于计时、自动报时及自动控制等各个领域。

单片机课设-电子日历(12864显示)

单片机课设-电子日历(12864显示)

温度传感器 DS18B20
t6963c控制的12864LCD
Proteus电路仿真
总电路图
制 作 实 物 图
经过调试结果
心得体会:
单片机这门课是一门实验性很强的课程,它不仅较为我们学习了 许多新知识,同时,也提高了独立分析问题、解决问题的能力和动手能 力。相信课程设计一定会为我们打下了良好的实践基础。 本系统电路较为简单,但软件工作量较大。在系统软件设计过程中, 利用C语言编程,模块化程序设计,由于程序率为复杂,数据处理指令 较多,逻辑性强,对与软件设计工作提出了较高要求。
系统设计原理框图
原来现实他们是这样的~~
设计效果图
设计以AT89C52单片机为核心,构成单片机控制电路, 结合DS1302时钟芯片和DS18B20,日历,温度,时间全部 信息用液晶12864显示。
时钟芯片DS1302
DS1302与CPU的连接需要三条 线,即SCLK(7)、I/O(6)、 RST(5)。
1.独特条口 线即可实现微处理器与DS18B20的 双向通讯。
2.测温范围 -55℃~+125℃,固 有测温误差(注意,不是分辨率, 这里之前是错误的)1℃。 3.支持多点组网功能,多个DS18B20可以 并联在唯一的三线上,最多只能并联8个, 实现多点测温,如果数量过多,会使供电 电源电压过低,从而造成信号传输的不稳 定。
电子日历设计与实现
let's
go
第八小组成员介绍
12864LCD显示
基于单片机的电子日历设计
介绍 日历是人们不可或缺的日常用品。但一般日历都为纸制用品,使用不便,寿命不 长。电子万年历采用智能电子控制和显示技术,改善了纸制日历的缺陷。本文设计的 电子万年历属于小型智能家用电子产品。利用单片机进行控制,实时时钟芯片进行记 时,外加键盘调整电路和显示电路,可实现时间的调整和显示。同时加了温度显示。

基于单片机的电子时钟的设计与实现

基于单片机的电子时钟的设计与实现

基于单片机的电子时钟的设计与实现电子时钟是一种使用微处理器或单片机作为主控制器的数字时钟。

它不仅能够显示当前时间,还可以具备其他附加功能,如闹钟、日历、温度显示等。

一、设计目标设计一个基于单片机的电子时钟,实现以下功能:1.显示时间:小时、分钟和秒钟的显示,采用7段LED数码管来显示。

2.闹钟功能:设置闹钟时间,到达设定的时间时会发出提示音。

3.日历功能:显示日期、星期和月份。

4.温度显示:通过温度传感器获取当前环境温度,并显示在LED数码管上。

5.键盘输入和控制:通过外部键盘进行时间、日期、闹钟、温度等参数的设置和调整。

二、硬件设计1.单片机选择:选择一款适合的单片机作为主控制器,应具备足够的输入/输出引脚、中断和定时器等功能,如STC89C522.时钟电路:使用晶振为单片机提供稳定的时钟源。

3.7段LED数码管:选择合适的尺寸和颜色的数码管,用于显示小时、分钟和秒钟。

4.温度传感器:选择一款适合的温度传感器,如DS18B20,用于获取环境温度。

5.喇叭:用于发出闹钟提示音。

6.外部键盘:选择一款适合的键盘,用于设置和调整时间、日期、闹钟等参数。

三、软件设计1.初始化:设置单片机定时器、外部中断和其他必要的配置。

2.时间显示:通过定时器中断,更新时间,并将小时、分钟和秒钟分别显示在相应的LED数码管上。

3.闹钟功能:设置闹钟时间,定时器中断检测当前时间是否与闹钟时间一致,若一致则触发警报。

4.日历功能:使用定时器中断,更新日期、星期和月份,并将其显示在LED数码管上。

5.温度显示:通过定时器中断,读取温度传感器的数据,并将温度显示在LED数码管上。

6.键盘输入和控制:通过外部中断,读取键盘输入,并根据输入进行相应的操作,如设置时间、闹钟、日期等。

7.警报控制:根据设置的闹钟时间,触发警报功能,同时根据用户的设置进行控制。

四、测试与调试完成软件设计后,进行系统测试与调试,包括验证显示时间、日期、温度等功能的准确性,以及闹钟和警报功能的触发与控制。

基于单片机电子日历的设计

基于单片机电子日历的设计

基于单片机的电子日历设计摘要:单片计算机即单片微型计算机。

由RAM ,ROM,CPU构成,定时,计数和多种接口于一体的微控制器。

它体积小,本钱低,功能强,广泛应用于智能产业和工业自动化上。

而51系列单片机是各单片机中最为典型和最有代表性的一种。

这次课程设计通过对它的学习,应用,从而到达学习、设计、开发软、硬的能力。

本设计主要设计了一个基于AT89C51单片机的电子日历。

能在数码管上进展年、月、日、星期、时、分、秒等自动显示。

应用Proteus软件实现了单片机电子日历系统的设计与仿真。

该方法仿真效果真实、准确,节省了硬件资源。

关键字:单片机;电子日历;仿真。

一、概述单片机因将其主要组成局部集成在一个芯片上而得名,就是把中央处理器、随机存储器、只读存储器、中断系统、定时器/计数器以及I/O接口电路等部件集成在一个芯片上。

单片机自20世纪70年代问世以来,以其极高的性能价格比,受到人们的重视和关注,应用很广、开展很快。

单片机具有体积小、功能多、价格低廉、使用方便、系统设计灵活等优点。

在我国,单片机的开发应用已有15年左右,已经形成一支庞大的技术开发队伍,为我国单片机应用积累了丰富的经历。

随着电子技术、计算机芯片技术和微电子技术的飞速开展促进了单片机技术一日千里的变化。

电子日历是一种利用数字电路来显示年、月、日、星期、时、分、秒的计时装置,由于数字集成电路的开展和石英晶体振荡器的广泛应用,使得数字钟的精度,远远超过老式钟表。

如今它已成为人们日常生活中的必需品,广泛应用于家庭、车站、码头、剧院、办公室等场所,给人们的生活、学习、工作带来极大的方便。

二、主要元件的介绍及使用方法2.1 AT89C51单片机介绍图2.1 AT89C51单片机VCC:电源。

GND:接地。

P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。

当P1口的管脚第一次写1时,被定义为高阻输入。

P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。

最新毕业设计:基于单片机的电子日历钟设计

最新毕业设计:基于单片机的电子日历钟设计

课程名称:单片机题目:电子日历钟学生姓名:喻琴学号:2071714124年级/专业:信心工程系07计科指导教师:余雷电子日历设计摘要用单片机控制时间的读取并显示在液晶屏幕上面,并可通过按键实现对时间的修改。

文中详细论述了电子日历钟设计原理、使用的各芯片的介绍,阐明了本实例所使用的设计方案、详细的电路图以及电子程序。

关键词:电子日历钟单片机 DS1302 LCD1602目录摘要................................................2 1前言.................................................5 1.1 设计任务.............................................5 1.2本设计的应用意义.....................................5 2总体设计方案.............................................5 2.1设计原理及相关说明................................5 2.2总体设计框图...............................................5 2.3电子日历钟电路图......................................5 2.4电子日历钟程序......................................5 3芯片设计及对其的调用..........................................6 3.1 DS1302实时时钟电路....................................63.1.1 DS1302的结构及工作原理............................63.1.2 引脚功能及结构...................................63.1.3 DS1302的控制字节...................................63.1.4 数据输入输出(I/O)...................................63.1.5 DS1302的寄存器...................................7 3.2LCD1602字符型液晶模块....................................73.2.1 LCD1602模块介绍...................................73.2.2 LCD1602的一些参数及操作指令..........................4系统调试...............................................124.1硬件电路调试.........................................124.2软件程序调试.........................................124.3综合调试.............................................12 参考文献.......................................................14\ 1 前言1.1 设计任务本设计实现一个小巧的电子日历钟,可以利用DS1302读取日期及时间并传至89C51,使之显示于LCD 1602 液晶显示屏上。

【单片机】c51数字时钟(带年月日显示)

【单片机】c51数字时钟(带年月日显示)

【单片机】c51数字时钟(带年月日显示)集团文件发布号:(9816-UATWW-MWUB-WUNN-INNUL-DQQTY-【单片机】c51数字时钟(带年月日显示)显示当前时间:9点58分34秒(第一个零表示闹钟未开启)当前日期:10年4月六日摘要:本设计以单片机为核心,LED数码管动态扫描显示。

采用矩阵式键盘输入能任意修改当前时间日期和设定闹钟时间。

具有显示年月日(区分闰年和二月),闹钟报警和整点报时功能说明系统的功能选择由7个按键完成。

其中,分别对应调整当前时间的时和分,为外部中断0,控制闹钟功能的开启/关闭(开启时数码管第一位显示字母’c’)用作外部中断1,当前时间的显示与闹铃时间显示切换,闹钟显示时按,可进行闹钟时分的设定,此时,led1灯灭。

闹铃时间到切闹钟开关开启时,闹铃响一分钟。

\\对年月日进行调整(第一次按,就进入了年月日的显示,现在就可对日期进行调整)。

按回到当前时间的显示状态。

整点到时:报警对应小时的次数。

程序如下:#include<>#include<>#include<>#define uchar unsigned char#define uint unsigned intuchar data keyvalue; //查到的键值uchar data keys; //转换出的数字uchar dis[8];uchar codeseg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,0x40,0x00,0x39,0xf7}; // 0 1 2 3 4 5 6 7 8 9 - 灭灯 cnsbit led_duan=P2^6;//段选通sbit led_wei=P2^7;//位选通sbit speaker=P2^3;//蜂鸣器sbit minitek=P3^0;//分校正按键sbit hourk=P3^1;//小时校正按键sbit p3_4=P3^4;//sbit yeark=P3^5;//年sbit monthk=P3^6;//月sbit dayk=P3^7;//日uchar data wei,i;bit leap_year;//闰年标志位bit dis_nyr;bit cal_year=1;bit calculate=1;//显示年月日与当前时间切换标志uchar data c_min;//闹钟‘分寄存单元uchar data c_hou;//闹钟、小时寄存单元uchar data second;//秒uchar data minite;//分变量uchar data hour;//小时变量uchar data year,month,day;//定义年月日变量uchar data CNTA;uchar data speaker_num; //蜂鸣次数bit beep; //整点报时标志bit run; //运行标志bit flash; //灭灯标志bit clarm_switch; //闹钟开关标志bit baoshi; //报时开关标志sbit led1=P1^6; // 按键标识指示灯sbit led2=P1^7; // 运行标志指示灯sbit P3_2=P3^2;sbit P3_3=P3^3;uint n,k;/*10微秒级延时*/void delay_10us(uchar n)?{ do{ _nop_();_nop_();_nop_();_nop_();_nop_();}while(--n);}/***毫秒级延时 ***/void delay_ms(uint n)?{ do delay_10us(131);while(--n);}/****** 当前时间转换******/clk_to_dis(){dis[0]=second%10;dis[1]=second/10;if(flash)dis[2]=10;else dis[2]=11;dis[3]=minite%10;dis[4]=minite/10;dis[5]=hour%10;dis[6]=hour/10;}/*****定时闹钟显示译码(用于七段码显示)*****/ clarm_to_dis(){dis[0]=c_min%10;dis[1]=c_min/10;if(flash)dis[2]=10;//亮灯else dis[2]=11; //灭灯dis[3]=c_hou%10;dis[4]=c_hou/10;dis[5]=10;dis[6]=13;}/***********年月日显示译码************/ nyr_to_dis(){dis[0]=day%10;dis[1]=day/10;dis[2]=10;//显示'-'dis[3]=month%10;dis[4]=month/10;dis[5]=10; // '-'dis[6]=year%10;dis[7]=year/10;}/*主函数*/void main(){P2=0xff;P1=0XFF;p3_4=0;run=1;led2=0;//运行指示灯亮led1=1;flash=0x00;dis[2]=10; //第三位显示“-”wei=0x7f;//选通低位 i=0;?second=21;minite=58;hour=9;CNTA=0x00;year=10;month=4;day=5;clk_to_dis(); TMOD=0x11;TH0=15560/256;TL0=15560%256;TH1=0xfc;TL1=0x18;EA=1;PT0=1;EX0=1; //开中断;EX1=1;?ET0=1;ET1=1;TR0=1;TR1=1;while(1){while(run==1){clk_to_dis();if(calculate){if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day++;?if(day>31){day=0x01;month++; if(month==13){month=1;year++;cal_year=1;}}led1=0; //指示灯亮}if(month==4|month==6|month==9|month==11){day++;if(day>30){day=0x01;month++;}led1=0; //指示灯亮}if(month==2) {if(leap_year==1){day++;if(day==30)day=1;}else {day++;if(day==29)day=1;}}while(cal_year){if((year+2000)%400==0) leap_year=1; // 被400整除为闰年else if((year+2000)%100==0) leap_year=0; //不能被400整除能被100整除不是闰年 else if((year+2000)%4==0) leap_year=1; //不能被400、100整除能被4整除是闰年 else leap_year=0;cal_year=0;}calculate=0;led1=1;}while(!minitek){for(n=0;n<1000;n++);if(!minitek==0)break; //延时防抖minite++;second=0x00;led1=0;for(n=0;n<20;n++){speaker=!speaker;delay_10us(50); //蜂鸣器响 }if(minite==60)minite=0x00; while(!minitek); //等待键松开led1=1;//显示灯}while(!hourk){for(n=0;n<1000;n++);if(!hourk==0)break;hour++;second=0x00;led1=0;。

基于单片机进行实时日历和时钟显示设计

基于单片机进行实时日历和时钟显示设计

毕业论文(设计)基于单片机进行实时日历和时钟显示设计学生姓名:指导教师:合作指导教师:专业名称:自动化所在学院:2012年6月目录摘要 (Ⅰ)Abstract (Ⅱ)第一章前言 (1)第二章设计方案论证 (2)2.1功能要求 (2)2.2方案确定 (2)第三章主控制器和外围器件 (4)3.1AT89S52单片机 (4)3.2DS1302时钟芯片 (4)3.3数码管LED (7)3.4译码器74HC138 (8)3.5锁存器74LS244 (8)第四章硬件设计 (9)4.1电路设计框图 (9)4.2系统概述 (9)4.3电源设计 (9)4.5单片机系统的晶振电路 (10)4.6主电路设计 (11)第五章软件设计 (12)5.1主程序设计 (12)5.2键盘子程序设计 (13)5.3日历时钟子程序设计 (15)5.4显示子程序设计 (17)第六章系统调试 (18)6.1软件调试 (18)6.2硬件调试 (19)第七章结论 (20)致谢 (21)参考文献 (22)附录 (26)附录Ⅰ硬件电路图 (26)附录Ⅱ主程序源代码 (27)摘要本设计是基于51系列的单片机进行的实时日历和时钟显示设计,可以显示年月日时分秒及周信息,具有可调整日期和时间功能。

在设计的同时对单片机的理论基础和外围扩展知识进行了比较全面准备。

实时日历和时钟显示的设计过程在硬件与软件方面进行同步设计。

硬件部分主要由AT89S52单片机,通过LED显示数据,所以具有人性化的操作和直观的显示效果。

软件方面主要包括时钟程序、键盘程序,显示程序等。

本系统以单片机的汇编语言进行软件设计,为了便于扩展和更改,软件的设计采用模块化结构,使程序设计的逻辑关系更加简洁明了,以便更简单地实现调整时间及日期显示功能。

所有程序编写完成后,在wave软件中进行调试,成功运行后,在Protel软件中进行仿真并调试。

关键词:AT89S52, DS1302, LEDAbstractThis design is based on 51 series monolithic integrated circuits of a real-time calendar and the clock shows the design , you can show how and when a week , has may adjust the date and time functions . in the design for monolithic integrated circuits , and peripheral to expand the basic theories of knowledge was fairly comprehensive preparation .Real-time calendar and the clock shows the design in hardware and software design of hardware that is synchronized the led display at89s52 monolithic integrated circuits, and when should the electrical circuits, the system through the led display data so be humanized operate and intuitive that effect. Including the software application programs, the keyboard, the program, etc. This system to monolithic integrated circuits of the assembly language for easily developing software design, and changes, software design to use modular design, the programming logical relationship with more and more so as to realize the time and date display the functions. all procedures in writing after wave of debugging the software and make no question of the proteus software embedded monolithic integrated circuits.Key words:AT89S52, DS1302, LED第一章前言在日新月异的21世纪里,家用电子产品得到了迅速发展。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于单片机的数字钟(电子日历)(转载)基于单片机的数字钟(电子日历)(转载)2009-06-2412:03/********************************************** ******************************//* 电子日历,有时间显示、闹铃、日期、秒表及键盘设置功能*//* 功能键A: 设置位数字+1 闹钟模式下为闹钟开关秒表模式下为记时开关*//* 功能键B: 设置位数字-1 闹钟模式下为闹钟开关*//* 功能键C:设置模式及设置位选择秒表模式下为清零键*//* 功能键D:在四种工作模式下切换设置闹钟开关*//* 曹宇03电子0201029 *//* 2006.6.3 更新*//*************************************************** *************************/#include#include/***************这里设置程序初始化时显示的时间****************/#define SET_HOUR 12 /*设置初始化小时*/#define SET_MINUTE 00 /*设置初始化分钟*/#define SET_SECOND 00 /*设置初始化秒数*//*************************系统地址****************************/#define BASE_PORT 0x8000 /*选通基地址*/#define KEY_LINE BASE_PORT+1 /*键盘行线地址*/#define KEY_COLUMN BASE_PORT+2 /*键盘列线地址*/ #define LED_SEG BASE_PORT+4 /*数码管段选地址*/#define LED_BIT BASE_PORT+2 /*数码管位选地址*/#define LED_ON(x) XBYTE[LED_BIT]=(0x01/**************在设置模式下对秒分时的宏定义*****************/#define SECOND 0 /*对应数码管右边两位*/#define MINUTE 1 /*对应数码管中间两位*/#define HOUR 2 /*对应数码管左边两位*//********************定义四种工作模式***********************/#define CLOCK clockstr /*时钟模式*/#define ALART alartstr /*闹钟模式*/#define DATE datestr /*日期模式*/#define TIMER timerstr /*秒表模式*//****************以下是所有子函数的声明*********************/void sys_init(void); /*系统的初始化程序*/void display(void); /*动态刷新一次数码管子程序*/void clockplus(void); /*时间加1S的子程序*/void update_clockstr(void); /*更新时间显示编码*/void update_alartstr(void); /*更新闹钟时间的显示编码*/ void update_datestr(void); /*更新日期显示编码*/void update_timerstr(void); /*更新秒表时间的显示编码*/ void deley(int); /*延时子程序*/void update_dispbuf(unsigned char *); /*更新显示缓冲区*/ unsigned char getkeycode(void); /*获取键值子程序*/void keyprocess(unsigned char); /*键值处理子程序*/ unsigned char getmonthdays(unsigned int,unsigned char);/*计算某月的天数子程序*//*功能键功能子函数*/void Akey(void); /*当前设置位+1 开关闹钟开关秒表*/ void Bkey(void); /*当前设置位-1 开关闹钟*/void Ckey(void); /*设置位选择秒表清零*/void Dkey(void); /*切换四种工作模式*//**********************全局变量声明部分*********************/unsigned charled[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x 6F};/*从0~9的LED编码*/unsigned char ledchar[3]={0x5c,0x54,0x71};/*o n f*///unsigned char key[24]={ /* 键值代码数组对应键位:*/// 0x70,0x71,0x72,0x73,0x74,0x75, /* 7 8 9 A TRACE RESET*/// 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5, /* 4 5 6 B STEP MON */ // 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5, /* 1 2 3 C HERE LAST */ // 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5}; /* 0 F E D EXEC NEXT */ struct{ /*时间结构体变量*/unsigned char s;unsigned char m;unsigned char h;}clock={SET_SECOND,SET_MINUTE,SET_HOUR};struct{ /*闹铃时间结构体变量*/unsigned char m;unsigned char h;}alart={SET_MINUTE,SET_HOUR};struct{ /*日期结构体变量*/unsigned int year;unsigned char month;unsigned char day;}date={6,1,1};struct{ /*秒表时间结构体变量*/unsigned char ms;unsigned char s;unsigned char m;}timer={0,0,0};unsigned char dispbuf[6]; /*显示缓冲区数组*/unsigned char clockstr[6]; /*时间显示的数码管编码数组*/ unsigned char alartstr[6]; /*闹钟显示的数码管编码数组*/ unsigned char datestr[6]; /*日期显示的数码管编码数组*/ unsigned char timerstr[6]; /*秒表显示的数码管编码数组*/ unsigned int itime=0,idot; /*定时器0中断计数*/unsigned char itime1=0; /*定时器1中断计数*/sbit P3_1=P3^1; /*外接蜂鸣器的管脚*/bdata bit IsSet=0; /*设置模式标志位0:正常走时1:设置模式*/bdata bit Alart_EN=0; /*闹铃功能允许位0:禁止闹铃1:允许闹铃*/bdata bit IsBeep=0; /*响铃标志位0:未响铃1:正在响铃*/ unsigned char SetSelect=0; /*在设置模式IsSet=1时,正在被设置的位,对应上面的宏*/unsigned char *CurrentMode; /*标志当前正设置的功能,如CurrentMode=CLOCK或CurrentMode=ALART等*/void timerplus(void);/**************************函数部分*************************/void main(void){sys_init();while(1){XBYTE[KEY_COLUMN,0x00]; /*给键盘列线赋全零扫描码,判断是否有键按下*/while((XBYTE[KEY_LINE]&0x0f)==0x0f) /*检测是否有键按下,无则一直进行LED的刷新显示*/{if(Alart_EN&&(clock.h==alart.h)&&(clock.m==alart.m)) {IsBeep=1;}else{ IsBeep=0;P3_1=0;}display();}keyprocess(getkeycode()); /*有键按下时得到键值,并送入键值处理程序*/display(); /*可要可不要*/}}void sys_init(void){TMOD=0x22; /*定时器0和1都设置为工作方式2,基准定时250×2=500us=0.5ms*/TH0=6; /*定时器0中断服务用来产生1秒时钟定时及闹钟蜂鸣器蜂鸣脉冲*/TL0=6; /*定时器1中断服务留给秒表使用,产生1/100秒定时*/TH1=6;TL1=6;ET0=1;ET1=1;EA=1;TR0=1;update_clockstr(); /*初始化时钟显示编码数组*/update_alartstr(); /*初始化闹钟显示编码数组*/update_datestr(); /*初始化日期显示编码数组*/update_timerstr(); /*初始化秒表显示编码数组*/update_dispbuf(clockstr);/*初始化显示缓冲数组*/ CurrentMode=CLOCK; /*默认的显示摸式为时钟*/P3_1=0; /*蜂鸣器接线引脚复位*/}void timer0(void) interrupt 1 using 1 /*定时器0中断服务器,用来产生1秒定时*/{itime++;if(itime==1000){if(IsSet) /*在设置模式下,对正在设置的位闪烁显示*/{dispbuf[SetSelect*2]=0; /*对正在设置的位所对应的显示缓冲区元素赋0,使LED灭*/dispbuf[SetSelect*2+1]=0;}if(IsBeep) P3_1=!P3_1; /*闹钟模式时,产生峰鸣器响脉冲*/ if(CurrentMode==CLOCK){dispbuf[2]=dispbuf[2]&0x7f;dispbuf[4]=dispbuf[4]&0x7f;}}if(itime==2000) /*两千次计数为1S 2000×0.5ms=1s*/{itime=0; /*定时1s时间到,软计数清零*/clockplus(); /*时间结构体变量秒数加1 */update_clockstr(); /* 更新时间显示编码数组*/if(CurrentMode!=TIMER) update_dispbuf(CurrentMode); /* 用时间编码数组更新显示缓冲区*/}}void timer1(void) interrupt 3 using 2 /*定时器1中断服务器,用来产生1/100秒定时*/{idot++;if(++itime1==20) /*20*0.5ms=10ms*/{itime1=0;timerplus();update_timerstr();if(CurrentMode==TIMER){update_dispbuf(timerstr);dispbuf[2]=dispbuf[2]&0x7f; /*关闭小数点的显示*/ dispbuf[4]=dispbuf[4]&0x7f;if(idot<1000) /*闪烁显示小数点*/{dispbuf[2]=dispbuf[2]|0x80;dispbuf[4]=dispbuf[4]|0x80;}else{dispbuf[2]=dispbuf[2]&0x7f;dispbuf[4]=dispbuf[4]&0x7f;}}}if(idot==2000) idot=0;}/*功能模块子函数*/void clockplus(void) /*时间加1s判断分,时子函数*/ {if(++clock.s==60) /*秒位判断*/{clock.s=0;if(++clock.m==60) /*分位判断*/{clock.m=0;if(++clock.h==24) /*时位判断*/{clock.h=0;if(++date.day==(getmonthdays(date.year,date.month)+1)){date.day=1;if(++date.month==13) date.month=1;}}}}}void timerplus() /*秒表1/100秒位加1,判断秒、分子程序*/ {if(++timer.ms==100){timer.ms=0;if(++timer.s==60){timer.s=0;if(++timer.m==60){timer.m=0;}}}}void update_clockstr(void) /*更新时钟显示代码数组clockstr*/ {clockstr[0]=led[clock.s%10]; /*给元素0赋相应数码管显示编码,编码序号是秒数的个位*/clockstr[1]=led[(int)(clock.s/10)]; /*给元素1赋相应数码管显示编码,编码序号是秒数的十位*/clockstr[2]=led[clock.m%10]; /*以下类推*/clockstr[3]=led[(int)(clock.m/10)];clockstr[4]=led[clock.h%10];clockstr[5]=led[(int)(clock.h/10)];}void update_alartstr(void) /*更新闹钟显示代码数组alartstr*/ { /*右边两位显示on:闹钟开启of:闹钟关闭*/if(Alart_EN) alartstr[0]=ledchar[1];/*显示字母n*/else alartstr[0]=ledchar[2]; /*显示字母f*/alartstr[1]=ledchar[0]; /*显示字母o*/alartstr[2]=led[alart.m%10];alartstr[3]=led[(int)(alart.m/10)];alartstr[4]=led[alart.h%10];alartstr[5]=led[(int)(alart.h/10)];}void update_datestr(void) /*更新日期显示代码数组datestr*/ {datestr[0]=led[date.day%10];datestr[1]=led[(int)(date.day/10)];datestr[2]=led[date.month%10];datestr[3]=led[(int)(date.month/10)];datestr[4]=led[date.year%10];datestr[5]=led[(int)(date.year/10)];}void update_timerstr(void) /*更新秒表显示代码数组timerstr*/ {timerstr[0]=led[timer.ms%10];timerstr[1]=led[(int)(timer.ms/10)];timerstr[2]=led[timer.s%10];timerstr[3]=led[(int)(timer.s/10)];timerstr[4]=led[timer.m%10];timerstr[5]=led[(int)(timer.m/10)];}void display(void) /*刷新显示六位LED一次*/{unsigned char i;for(i=0;i<6;i++){LED_ON(i); /*选通相应位*/XBYTE[LED_SEG]=dispbuf[i]; /*写显示段码*/deley(50); /*延时显示*/LED_OFF; /*写LED全灭段码*/}}void update_dispbuf(unsigned char *str) /*更新显示缓冲区子函数,参数为要用来更新缓冲区的源字符数组的首地址*/ {dispbuf[0]=str[0]; /*将要更新的源字符数组内容COPY至dispbuf数组,用作显示缓冲区*/dispbuf[1]=str[1];dispbuf[2]=str[2]|0x80; /*默认把时位和分位后面的小数点显示出来,根据需要再取舍*/dispbuf[3]=str[3];dispbuf[4]=str[4]|0x80;dispbuf[5]=str[5];}void deley(int i) /*延时子函数*/{while(i--);}unsigned char getkeycode(void) /*键盘扫描子程序,返回获得的键码*/{unsigned char keycode; /*键码变量,一开始存行码*/ unsigned char scancode=0x20; /*列扫描码*/unsigned char icolumn=0; /*键的列号*/display(); /*用刷新数码管显示的时间去抖*/XBYTE[KEY_COLUMN]=0x00;keycode=XBYTE[KEY_LINE]&0x0f; /*从行端口读入四位行码*/while((scancode&0x3f)!=0) /*取scancode的低六位,只要没变为全0,则执行循环*/{XBYTE[KEY_COLUMN]=(~scancode)&0x3f; /*给列赋扫描码,第一次为011111*/if((XBYTE[KEY_LINE]&0x0f)==keycode) break; /*检测按键所在的列跳出循环*/scancode=scancode>>1; /*列扫描码右移一位*/icolumn++; /*列号加1*/}keycode=keycode<<4; /*把行码移到高四位*/keycode=keycode|icolumn; /*由行码和列码组成键码*///等待按键放开XBYTE[KEY_COLUMN]=0x00;while((XBYTE[KEY_LINE]&0x0f)!=0x0f) display();return keycode;}void keyprocess(unsigned char keycode) /*键值处理函数*/ {switch (keycode){case 0x73: Akey();break;case 0xB3: Bkey();break;case 0xD3: Ckey();case 0xE3: Dkey();break;default: break;}update_dispbuf(CurrentMode);}unsigned char getmonthdays(unsigned int year,unsigned char month)/*得到某月的天数*/{unsigned char days;switch (month){case 4:case 6:case 9:case 11:days=30;break;case 2: if(year%4==0) days=29;else days=28;break;default:days=31;}return days;}/*功能键子函数部分*/void Akey(void) /*对当前设置位进行加一操作,如果设置秒位,则给秒位清零*/{if(CurrentMode==TIMER) /*秒表模式下启闭走时*/{ TR1=!TR1;return;}if(!IsSet) return; /*如果不是设置模式退出*/switch (SetSelect){case SECOND:if(CurrentMode==CLOCK){clock.s=0; /*如果当前被设置位是秒位,则清零秒位*/ update_clockstr();}if(CurrentMode==ALART){Alart_EN=!Alart_EN;update_alartstr();}if(CurrentMode==DATE){if(++date.day==(getmonthdays(date.year,date.month)+1)) date.day=1;update_datestr();}if(CurrentMode==TIMER){TR1=!TR1;}break;case MINUTE:if(CurrentMode==CLOCK){if(++clock.m==60) clock.m=0; /*如果当前被设置分位,则分位加1*/update_clockstr();}if(CurrentMode==ALART){if(++alart.m==60) alart.m=0;update_alartstr();}if(CurrentMode==DATE){if(++date.month==13) date.month=1;update_datestr();}break;case HOUR: if(CurrentMode==CLOCK){if(++clock.h==24) clock.h=0; /*如果当前被设置时位,则时位加1*/update_clockstr();}if(CurrentMode==ALART){if(++alart.h==24) alart.h=0;update_alartstr();}if(CurrentMode==DATE){if(++date.year==100) date.year=0;update_datestr();}break;default: break;}update_dispbuf(CurrentMode);}void Bkey(void) /*对当前设置位进行减一操作,如果设置秒分,则给秒位清零,类比Akey()函数*/{if(!IsSet) return;switch (SetSelect){case SECOND:if(CurrentMode==CLOCK){clock.s=0;update_clockstr();}if(CurrentMode==ALART){Alart_EN=!Alart_EN;}if(CurrentMode==DATE){if(--date.day==0x00)date.day=getmonthdays(date.year,date.month); update_datestr();}break;case MINUTE:if(CurrentMode==CLOCK) {if(--clock.m==0xff) clock.m=59;update_clockstr();}if(CurrentMode==ALART){if(--alart.m==0xff) alart.m=59;update_alartstr();}if(CurrentMode==DATE){if(--date.month==0x00) date.month=12;}break;case HOUR: if(CurrentMode==CLOCK) {if(--clock.h==0xff) clock.h=23;update_clockstr();}if(CurrentMode==ALART){if(--alart.h==0xff) alart.h=23;update_alartstr();}if(CurrentMode==DATE){if(--date.year==0xffff) date.year=99; update_datestr();}break;default: break;}update_dispbuf(CurrentMode);}void Ckey(void) /*正常走时模式和设置模式的切换*/{if(CurrentMode==TIMER){TR1=0; /*初始化定时器1设置,停止秒表记时*/TH1=6;TL1=6;timer.ms=0; /*初始化秒表数组*/timer.s=0;timer.m=0;update_timerstr();}else{if(IsSet==0) /*在非秒表模式下,第一次按下C键进入设置模式,设置时位*/{IsSet=1; /*置位标志位,进入设置模式*/SetSelect=HOUR;return;} /*第二次按C键设置分位,第三次按键设置秒位,第四次按键完成退出设置*/if(SetSelect==0) /*按到第四次,即设置完秒位后,将标志位IsSet置0,完成设置*/{IsSet=0; /*复位标志位,进入正常走时模式*/return;}if(SetSelect>0) SetSelect--; /*设置位的标志变量SetSelect=0:时位1:分位2:秒位*/}}void Dkey(void) /*工作状态切换:时钟、闹钟、日期、秒表*/{if(CurrentMode==CLOCK) /*切换至闹钟,同时开关闹钟*/ { CurrentMode=ALART;Alart_EN=!Alart_EN;update_alartstr();return;}if(CurrentMode==ALART) /*切换至日期*/{ CurrentMode=DATE;return;}if(CurrentMode==DATE) /*切换至秒表,同时关闭设置模式*/ {CurrentMode=TIMER;IsSet=0;return;}if(CurrentMode==TIMER) /*切换至时钟*/{CurrentMode=CLOCK;return;}}。

相关文档
最新文档