基于51单片机的万年历的设计(共25页).doc

上传人:飞****2 文档编号:11396418 上传时间:2022-04-18 格式:DOC 页数:25 大小:236KB
返回 下载 相关 举报
基于51单片机的万年历的设计(共25页).doc_第1页
第1页 / 共25页
基于51单片机的万年历的设计(共25页).doc_第2页
第2页 / 共25页
点击查看更多>>
资源描述

《基于51单片机的万年历的设计(共25页).doc》由会员分享,可在线阅读,更多相关《基于51单片机的万年历的设计(共25页).doc(25页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、精选优质文档-倾情为你奉上单片机课程实训SCM PRACTICAL TRAINING实训设计题目Title Of Training 万年历的设计 分院(系别)Department 专业Speciality 班 级Class 设计作者Author 完成日期Date 组 别Team 指导教师Advisor 专心-专注-专业目 录第一部分 课程设计任务书一、课程设计题目用中小规模集成芯片设计制作万年历。二、课程设计时间五天三、实训提交方式提交实训设计报告电子版与纸质版四、设计要求(1)显示年、月、日、时、分、秒和星期,并有相应的农历显示。(2)可通过键盘自动调整时间。 (3)具有闹钟功能。 (4)能

2、够显示环境温度,误差小于1 (5)计时精度:月误差小于20秒。 第二部分 课程设计报告一、单片机发展概况单片机诞生于20世纪70年代末,它的发展史大致可分为三个阶段: 第一阶段(1976-1978):初级单片机微处理阶段。该时期的单片机具有 8 位CPU,并行 I/O 端口、8 位时序同步计数器,寻址范围 4KB,但是没有串行口。 第二阶段(1978-1982):高性能单片机微机处理阶段,该时期的单片机具有I/O 串行端口,有多级中断处理系统,15 位时序同步技术器,RAM、ROM 容量加大,寻址范围可达 64KB。 第三阶段(1982-至今)位单片机微处理改良型及 16 位单片机微处理阶段民

3、用电子产品、计算机系统中的部件控制器、智能仪器仪表、工业测控、网络与通信的职能接口、军工领域、办公自动化、集散控制系统、并行多机处理系统和局域网络系统。 二、MCS-51单片机系统简介 MCS-51系列单片机产品都是以Intel公司最早的典型产品8051为核心构成的。MCS-51单片机由CPU 、RAM 、ROM 、I/O接口、定时器/计数器、中断系统、内部总线等部件组成。8051单片机的基本性能有:u 8位CPU;u 布尔代数处理器,具有位寻址能力;u 128B内部RAM,21个专用寄存器;u 4KB内部掩膜ROM;u 2个16位可编程二进制加1定时器/计数器;u 32个(48位)双向可独立

4、寻址的I/O口;u 1个全双工UART(异步串行通信口);u 5个中断源,两级中断结构 ;u 片内振荡器及时钟电路 ,晶振频率为1.2MHz12MHz;u 外部程序/数据存储器寻址空间均为64KB;u 111条指令,大部分为单字节指令;u 单一+5V电源供电,双列直插40引脚DIP封装。三、设计思想 整体设计以单片机技术为核心,采用C语言进行软件设计,增加了程序的可读性和可移植性,为了便于扩展和更改,软件的设计采用模块化结构。程序先向LCD更新时钟芯片的时间与温度传感器的时间,然后进行初始化工作。程序由一个主函数,两个定时器中断程序,一个时钟设置子程序,一个农历设置子程序,一个温度设置子程序,

5、一个延时子程序,一个调时子程序,一个显示子程序构成。程序通过按键扫描程序来确定是否调用中断程序来对时间进行调整。用一子程序完成时分的调整,通过循环扫描四个按键的电平变化来判断对应按键是否按下,并带有去抖动功能,四个按键分别有增加,减小,退出与功能选择的作用。通过功能选择时钟设置与闹钟设置,使用加或减按键进行预置,完成后可点退出键完成操作。可分为以下几个功能模块:1)主程序:定时器中断初始化、时钟与温度更新程序与键盘监控。2)计时:为定时器中断服务子程序,完成刷新计时缓冲区的功能。3)农历:由阴历换算对照表得出阳历并显示。4)闹钟:采用定时器中断方式实现闹钟与整点报时。5) 温度:由温度传感器将

6、温度传送到LCD显示。6)设置:由按键设置闹钟时间或时钟时间。7)键盘扫描:判断是否有键按下,并确定键号。 8)LCD显示:完成8位动态显示。四、硬件电路设计1. 总体设计 系统包括单片机主控模块,温度传感器采集模块,日历时钟模块,按键调整模块,蜂鸣器模块,闹钟模块。如图1所示为系统设计图。 日历时钟芯片 DS1302 按键调整 电路 AT89C51 单片机温度传感器 DS18B20LCD12864蜂鸣器闹钟图1 系统设计图如图2所示为系统仿真图。图2 系统仿真图2. 晶振电路 如图3所示,51单片机的内部有一个用于构成振荡器的高增益反相放大器,它的输入端为XTAL1引脚,输出端为XTAL2引

7、脚,两个跨接石英晶体及两个电容就可以构成稳定的自激振荡器。电容器通常取30pF左右。 图3 晶振电路 图4 复位电路3. 复位电路 往单片机的复位引脚上输入24个时钟周期以上的高电平,即执行复位操作。按键复位是指系统在运行时,按下一个开关,就能在RST引脚产生一段时间的高电平,使系统复位,常见的按键复位电路如图4所示。对12MHz晶振频率而言,电路中C取10pF,R取1K。4. DS1302时钟电路DS1302是一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、 时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V5.5V。采用三线接口与CPU进行同步通信,并可采用突发

8、方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个318的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后背电源双电源引脚,同时提供了对后背电源进行涓细电流充电的能力。图5示出DS1302的引脚排列,其中Vcc1为后备电源,Vcc2为主电源。在主电源关闭的情况下,也能保持时钟的连续运行。DS1302由Vcc1或Vcc2两者中的较大者供电。当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。当Vcc2小于Vcc1时,DS1302由Vcc1供电。X1和X2是振荡源,外接32.768KHz晶振。RST是复位/片

9、选线,通过把RST输入驱动置高电平来启动所有的数据传送。RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RSTS置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。上电动行时,在Vcc大于等于2.5V之前,RST必须保持低电平。中有在SCLK为低电平时,才能将RST置为高电平,I/O为串行数据输入端(双向)。SCLK始终是输入端。 图5 DS1302时钟芯片 图6 温度采集系统电路5. 温度采集系统电路 在本万年历当中温

10、度的采集采用数字温度传感器DS18B20。它属于单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。 具有如下的经济特点:(1)只要求一个端口即可实现通信。(2)在DS18B20中的每个器件上都有独一无二的序列号。(3)实际应用中不需要外部任何元器件即可实现测温。(4)测量温度范围在55。C到125。C之间。(5)数字温度计的分辨率用户可以从9位到12位选择。(6)内部有温度上、下限告警设置。如图6所示。6. 按键调整电路 按键采用4个独立的按键,一个功能键、一个退出键、一个加按键、一个减按键通过这四个按键可以来

11、合理的设置时钟的调整和闹铃的设置等。如图7所示与51单片机的P0.0P0.3的连接示意图。图7 按键调整电路7. 闹钟提示电路 当到达整点时或者当前的时间等于51单片机中设置闹钟时间时蜂鸣器便会发出声音进行提示。与单片机P0.5引脚的连接电路如图8所示。 图8 闹钟提示电路 图9 LCD显示电路8. LCD显示电路 在本万年历当中12864液晶显示当前的实时时间重要的阴阳历节日等功能。12864液晶具有如下的特性: 1)提供8位,4位并行接口及串行接口可选2)并行接口适配M6800时序3)自动电源启动复位功能4)内部自建振荡源 6416位字符显示RAM(DDRAM最多16字符4行,LCD显示范

12、围162行)(改为半角输入) 2M位中文字型ROM(CGROM),总共提供8192个中文字型(1616点阵)16K位半宽字型ROM(HCGROM),总共提供126个西文字型(168点阵)6416位字符产生RAM(CGRAM) 1516位总共240点的ICONRAM(ICONRAM)其与单片机的连接电路如图9所示。五、软件设计框图1. 主程序流程图:2. 阴阳历转换流程图:六、程序源代码1. 主程序#include #include #include #include #include #include #include #define uchar unsigned char#define ui

13、nt unsigned int/*sbit bell = P2 0; /定义蜂鸣器端口/* 定时器设置整点报时*/void Timer0_Service() interrupt 1 static uchar count = 0; static uchar flag = 0; /记录鸣叫的次数 count = 0; TR0 = 0; /关闭Timer0 TH0 = 0x3c; TL0 = 0XB0; /延时 50 ms TR0 = 1 ; /启动Timer0 count +; if( count = 20 ) /鸣叫 1 秒 bell = bell; count = 0; flag +; if(

14、 flag = 6 ) flag = 0; TR0 = 0; /关闭Timer0 /* 中断服务程序 整点报时 一分钟*/uchar HexNum_Convert(uchar HexNum)/将16进制数转换成十进制数uchar Numtemp;Numtemp=(HexNum4)*10+(HexNum&0X0F);return Numtemp;/* 函数名称:main()* 功 能:* 入口参数:* 出口参数:*/void main( void ) uchar clock_time6 = 0X00,0X59,0X23,0X09,0X04,0X11; /定义时间变量 秒 分 时 日 月 年uch

15、ar alarm_time2 = 10, 06; /闹钟设置 alarm_time0: 分钟 alarm_time1 :小时uchar temperature2; /定义温度变量 temperature0 低8位 temperature1 高8位 Lcd_Initial(); /LCD初始化Clock_Fresh( clock_time ); /时间刷新Clock_Initial( clock_time ); /时钟初试化 /*中断初始化*/ EA = 1; /开总中断 ET0 = 1; /Timer0 开中断ET2 = 1; /Timer2 开中断 TMOD = 0x01 ; /Timer0

16、 工作方式 1RCAP2H = 0x3c; RCAP2L = 0xb0; /Timer2 延时 50 ms while( 1 ) switch( Key_Scan() )/按键扫描 case up_array: Key_Idle(); /检测按键松开 break; case down_array: Key_Idle(); /检测按键松开 break; case clear_array: Key_Idle(); /检测按键松开 break; case function_array: Key_Function( clock_time, alarm_time ); case null: Clock_

17、Fresh( clock_time ); /时间刷新 Lcd_Clock( clock_time ); /时间显示 Sensor_Fresh( temperature ); /温度更新 Lcd_Temperture( temperature ); /温度显示 Calendar_Convert( 0 , clock_time ); Week_Convert( 0, clock_time ); /整点报时if( ( * clock_time = 0x59 ) & ( * ( clock_time + 1 ) = 0x59 ) ) bell = 0; TR2 = 1; /启动Timer2 /闹钟报警

18、if( * alarm_time = HexNum_Convert(* ( clock_time + 1 ) )/分钟相吻if( * ( alarm_time + 1 ) = HexNum_Convert(*( clock_time + 2 ) ) /小时相吻合 bell = 0;TR2 = 1; /启动Timer2 break; 2. 温度控制程序#ifndef _SENSOR#define _SENSOR#define uchar unsigned char#define uint unsigned int/*DS18B20管脚配置*/sbit dq = P2 1; /*DS18B20软件

19、延时专用*/void Sensor_Delay(uchar count)/延时函数 while(count-);/*从DS18B20读一个字节*/uchar Sensor_Read_Byte(void) uchar i = 0; uchar temp = 0; for(i=8;i0;i-) dq = 0; / 给脉冲信号 temp = 1; dq = 1; / 给脉冲信号 if(dq) temp |= 0x80; Sensor_Delay(20); return (temp);/*向DS18B20写一个字节*/void Sensor_Write_Byte(uchar temp) uchar i

20、 = 0; for(i=8;i0;i-) dq = 0; dq = temp&0x01; Sensor_Delay(20); dq = 1; temp=1; /*DS18B20初始化*/uchar Sensor_Initial(void) uchar i = 0; dq = 1; / DQ复位 Sensor_Delay(1); / 稍做延时 dq = 0; / 单片机将DQ拉低 Sensor_Delay(100); / 精确延时,大于480us dq = 1; / 拉高总线 Sensor_Delay(6); / 稍做延时后 i = dq; / 若x=0则初始化成功,若x=1则初始化失败 Sen

21、sor_Delay(130); return (i);/*读取并显示温度*/void Sensor_Fresh(uchar * temperature ) Sensor_Initial(); Sensor_Write_Byte( 0xCC ); / 跳过读序号列号的操作 Sensor_Write_Byte( 0x44 ); / 启动温度转换 Sensor_Initial(); Sensor_Write_Byte( 0xCC ); / 跳过读序号列号的操作 Sensor_Write_Byte( 0xBE ); / 读取温度寄存器 temperature 0 = Sensor_Read_Byte(

22、);/低位 temperature 1 = Sensor_Read_Byte(); /高位#endif3. 日历设置程序#ifndef _SUN_MOON#define _SUN_MOON/*/#define uchar unsigned char#define uint unsigned int#include #include /* 功能: 读取数据表中农历的大月或小月 ,如果大月返回1, 小月返回0*/bit get_moon_day( uchar month_p,uint calendar_address ) uchar temp,temp1;temp1=(month_p+3)/8;t

23、emp=0x80(month_p+3)%8);temp=year_codecalendar_address+temp1&temp;if(temp=0)return(0);elsereturn(1);/* 功能: 输入BCD的阳历数据, 输出BCD阴历数据( 1901 - 2099 ) c_flag:阳历的世纪标志 clock_time: 时钟地址* 说明: c_flag = 0 :21世纪 c_flag = 1 :19世纪 */void Calendar_Convert( uchar c_flag, uchar * clock_time ) bit flag_month, flag_year;

24、 uchar year, month, day, month_point; /定义 年 月 天 uchar temp1, temp2, temp3; uint calendar_address; /定义农历地址 uint day_number; uchar clock_moon3; /定义阴历 clock_time += 3; /指向日 day = ( * clock_time 4 ) * 10 + ( *clock_time & 0x0f ); /BCD转换十进制 clock_time +; /指向月 month = ( * clock_time 4 ) * 10 + ( * clock_t

25、ime & 0x0f ); /BCD转换十进制 clock_time +; /指向年 year = ( * clock_time 4 ) * 10 + ( * clock_time & 0x0f ); /BCD转换十进制 /定位日历地址 if( c_flag = 0 ) calendar_address = ( year + 99 ) * 3; else calendar_address = ( year - 1 ) * 3; /春节(正月初一)所在的阳历月份 temp1 = year_code calendar_address + 2 & 0x60; /Bit6Bit5:春节所在的阳历月份

26、temp1 = 5 ; /春节(正月初一)所在的阳历日期 temp2 = year_code calendar_address + 2 & 0x1f; /Bit4Bit0:春节所在的阳历日期 /计算春节(正月初一)离当年元旦 1月1日(阳历) 的天数;春节只会在阳历的1月 或 2月 /*if( temp1 = 1 ) temp3 = temp2 - 1; else temp3 = temp2 + 31 - 1; */temp3=temp2-1;if(temp1!=1) temp3+=0x1f; /计算阳历月离当年元旦 1月1日(阳历) 的天数 if( month 10 ) day_number

27、 = day_code1 month - 1 + day ; else day_number = day_code2 month - 10 + day ; /如果阳历的月大于2 且该年的2月为闰月,天数加1 /闰年指的就是阳历有闰日或阴历有闰月的一年; /阳历四年一闰,在二月加一天,这一天叫做闰日: /农历三年一闰,五年两闰,十九年七闰,每逢闰年所加的一个月叫做闰月。 if( ( month = 2 ) | ( year % 0x04!= 0) ) day_number-=1; / day_number +; / if (month= temp3 ) /阳历在春节之后 或者 春节当日 day_

28、number -= temp3; month = 1; month_point = 1; / month_point 为月份指向,阳历日在春季前就是春季 flag_month = get_moon_day( month_point, calendar_address ); /检查该阴历月的大小 大月返回1 小月返回0 flag_year = 0; /* if( flag_month ) temp1 = 30; /大月30天 else temp1 = 29; /小月29天 */ if (flag_month=0) temp1=29; elsetemp1=30; /闰月所在的月分 temp2 =

29、year_code calendar_address & 0xf0; temp2 = 4; /提取高四位 假如是0 表示没有闰月 while( day_number = temp1 ) day_number -= temp1; month_point +; if( month = temp2 ) flag_year = flag_year; if( flag_year = 0 ) month +=1; else month + ; flag_month = get_moon_day( month_point, calendar_address ); if( flag_month ) temp1

30、 = 30; else temp1 = 29; day = day_number + 1; else /阳历在春节之前使用以下代码进行运算 temp3 -= day_number; if( year = 0 ) year = 0xe3; c_flag = 1; else year -= 1; calendar_address -= 3; month = 0xc; temp2 = year_code calendar_address & 0xf0; temp2 = 4; /提取高4位 flag_year=0; if( temp2 = 0 ) month_point = 12; else mont

31、h_point = 13; /flag_year = 0; flag_month = get_moon_day( month_point, calendar_address ); if( flag_month ) temp1 = 30; else temp1 = 29; while( temp3 temp1 ) temp3 -= temp1; month_point -; if( flag_year = 0 ) month -=1; if( month = temp2 ) flag_year = flag_year; flag_month = get_moon_day( month_point

32、, calendar_address ); if( flag_month ) temp1 = 0x1e; else temp1 = 0x1d; day = temp1 - temp3 + 1; /HEX-BCD ,运算结束后,把数据转换为BCD数据 temp1 = year / 10; temp1 = 4; clock_moon2 = temp1 | ( year % 10 ); temp1 = month / 10; temp1 = 4; clock_moon1 = temp1 | ( month % 10 ); temp1 = day / 10; temp1 = 4; clock_moon0 = temp1 | ( day % 10 ); Lcd_Lunar_Calendar( clock_moon );/*算法: ( 日期 + 年份 + 所过闰年 + 月校正 ) / 7 的余数就是星期 如果是闰年又不到 3 月份上述之和 要减一天 再*

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁