LCD显示电子万年历
基于单片机控制的LCD显示万年历制作

据传 送到 总线 的器 件作 为发 送器 。任 何从 总 线接 收数 据 的器 件 为接 收器 。数据 传送 是 由产生 串行 时钟和
[ 收稿 日期]2 0 1 3一O 5 —1 2 [ 作者简介]苏畅 ( 1 9 7 7一 ) ,女 ,硕士 ,讲师 ,现主要从事计算机硬件方面的教学与研究工作。
2 系统硬 件 设计
在控 制 系统硬 件 电路设 计 中还要 注 意环境 因素对 系 统 的干扰情 况 ,系统抗 干扰 的措施 主要 有 以下几 种 :① 电源干 扰 的抑 制 。直流 电源滤 波效 果不 好将 引起 电源波 动 ,直接 造成对 单 片机不稳 定 的影 响 ,应 该 选用各 种参 数较 好 的电源 以及隔 离性 能较好 的设 备来 屏蔽 电缆 、高压 泄放元 件等 ,防止干 扰信号 的传 送 。② 变压器 干扰 的抑制 。可 以使 用一 些隔离 物来 对变 压器产 生 的干扰 进行屏 蔽 ,例如 使用 滤波器 ,就
机 兼 容 ,具 有抗 干 扰 能 力 强 、操 作 简 单 等 优 点 ;万 年 历 数 据 由最 常 用 的 D S 1 3 0 2提 供 , 它 是 一 种 高 性 能 、
低 功 耗 、 带有 片 内 RA M 的 实 时 万 年 历 电 路 , 可 分 别 对 年 、月 、 日、周 、时 、 分 、秒 进 行 计 时 ,还 具 有
・
7 8・
理 工 上 旬 刊 *计 算 机 科 学 与 电 子 信 息 工 程
2 0 1 3年 8月
所有起 始停 止信号 的 主器件控 制 的 。主器件 和从器 件都 可 以作 为 发送器 或 接 收器 ,但 由主器件 控制传 送
数据 ( 发送或接 收) 的模 式 ,由 于 A0 、A1和 A 2可 以组 成 0 0 0 1 1 1 八 种 情况 ,即通过 器 件地 址输 人 端 A 0 、A1 和 A 2可 以实 现将 最多 8个 A T2 4 C 0 2 器件连 接到总线上 ,通过进行不 同的配 置进行选择器件 。
万年历与LCD时间显示

> ds1302+LCD1602.rar > 万年历.C/******************************************************************** * 标题: xl 系列单片机实验仪1602 液晶万年历演示程序** 文件: XLLCDWNL.c ** 日期: 2006-1-5 ** 版本: 3.0 (试验通过版)可用xl600-xl1000 单片机综合试验仪试验** 作者: 部分程序参考网上修改而成,本站最终改编测试,特别对原作致敬!* * 邮箱: sxj1974@ ** 网站: ********************************************************************** *日历时钟**按K1,进入设置状态**按k2, 停止闹钟声音**按k3, 依次进入闹钟功能是否启用,闹钟时,分秒,年,月,日及时间时,分,秒的设置,**直到退出设置状态**按k4, 调整是否起用闹钟和调节闹钟时,分,秒,年,月,日,时间的时,分,秒的数字**LCD 第二排中间显示小喇叭,表示启用闹钟功能,无则禁止闹钟功能* 8888*(可在调整状态进行设置)**正常状态,LCD 上排最前面显示自定义字符,LCD 下排最前面闪动"XUELIN" * *设置状态,LCD 上排最前面显示"P", 下排最前面在设置闹钟时间时显示"alarm:", **其它状态显示"time" **年代变化2000--2099, 星期自动转换**程序中有自定义字符写入********************************************************************** * 【版权】Copyright(C) 深圳市学林电子有限公司 ** 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息! ** 【技术支持】请访问/bbs/index.asp 官方论坛********************************************************************** #include <reg51.h>#include <intrins.h>unsigned char code dis_week[]={"SUN,MON,TUE,WED,THU,FRI,SAT"}; unsigned char code para_month[13]={0,0,3,3,6,1,4,6,2,5,0,3,5}; // 星期月参变数unsigned char data dis_buf1[16]; //lcd 上排显示缓冲区unsigned char data dis_buf2[16]; //lcd 下排显示缓冲区unsigned char data year,month,date,week;// 年、月、日、星期unsigned char data armhour,armmin,armsec;// 闹钟时、分、秒unsigned char data hour,min,sec,sec100;// 时、分、秒、百分之一秒unsigned char data flag,vkey,skey;// 设置状态计数标志、按键先前值、按键当前值bit alarm; //标识是否启用闹钟,1--启用,0--关闭sbit rs = P2^0; //LCD 数据/命令选择端(H/L)sbit rw = P2^1; //LCD 读/写选择端(H/L)sbit ep = P2^2; //LCD 使能控制sbit PRE = P1^0; //调整键(k3)sbit SET = P1^1; //调整键(k4)sbit SPK = P2^3;void delayms(unsigned char ms); // 延时程序bit lcd_busy(); //测试LCD 忙碌状态程序void lcd_wcmd(char cmd); //写入指令到LCD 程序void lcd_wdat(char dat); //写入数据到LCD 程序void lcd_pos(char pos); //LCD 数据指针位置程序void lcd_init(); //LCD 初始化设定程序void pro_timedate(); //时间日期处理程序void pro_display(); //显示处理程序void pro_key(); //按键处理程序void time_alarm(); //定时报警功能(闹钟)unsigned char scan_key(); //按键扫描程序unsigned char week_proc(); //星期自动计算与显示函数bit leap_year(); //判断是否为闰年void lcd_sef_chr(); //LCD 自定义字符程序void update_disbuf(unsigned char t1,unsigned char t2[],unsigned char dis_h,unsigned char dis_m,unsigned char dis_s); //更新显示缓冲区函数// 延时程序void delay(unsigned char ms){ while(ms--){ unsigned char i;for(i = 0; i< 250; i++){_nop_(); //执行一条_nop_() 指令为一个机器周期_nop_();_nop_();_nop_();}}}//测试LCD 忙碌状态bit lcd_busy(){bit result;rs = 0;rw = 1;ep = 1;_nop_();_nop_();_nop_();_nop_();result =(bit)(P0&amt;0x80); //LCD 的D0--D7 中,D7=1 为忙碌,D7=0 为空闲ep = 0;return result;}//写入指令到LCDvoid lcd_wcmd(char cmd)while(lcd_busy()); //当lcd_busy 为1 时,再次检测LCD 忙碌状态,lcd-busy 为0 时,开始写指令rs = 0;rw = 0;ep = 0;_nop_();_nop_();P0 = cmd;_nop_();_nop_();_nop_();_nop_();ep = 1;_nop_();_nop_();_nop_();_nop_();ep = 0;}//写入数据到LCDvoid lcd_wdat(char dat){while(lcd_busy()); //当lcd_busy 为1 时,再次检测LCD 忙碌状态,lcd-busy 为0 时,开始写数据rs = 1;rw = 0;ep = 0;P0 = dat;_nop_();_nop_();_nop_();_nop_();ep = 1;_nop_();_nop_();_nop_();_nop_();ep = 0;}//LCD 数据指针位置程序void lcd_pos(char pos){lcd_wcmd(pos|0x80); // 数据指针=80+ 地址码(00H~27H,40H~67H)}//设定二个自定义字符,(注意:LCD1602 中自定义字符的地址为0x00--0x07, 即可定义8 个字符)//这里我们设定把一个自定义字符放在0x00 位置(000),另一个放在0x01 位子(001)void lcd_sef_chr(){ //第一个自定义字符lcd_wcmd(0x40);lcd_wdat(0x1f);lcd_wcmd(0x41); //"01 000 001" 第2 行地址lcd_wdat(0x11); //"XXX 10001" 第2 行数据lcd_wcmd(0x42); //"01 000 010" 第3 行地址lcd_wdat(0x15); //"XXX 10101" 第3 行数据lcd_wcmd(0x43); //"01 000 011" 第4 行地址lcd_wdat(0x11); //"XXX 10001" 第4 行数据lcd_wcmd(0x44); //"01 000 100" 第5 行地址lcd_wdat(0x1f); //"XXX 11111" 第5 行数据lcd_wcmd(0x45); //"01 000 101" 第6 行地址lcd_wdat(0x0a); //"XXX 01010" 第6 行数据lcd_wcmd(0x46); //"01 000 110" 第7 行地址lcd_wdat(0x1f); //"XXX 11111" 第7 行数据lcd_wcmd(0x47); //"01 000 111" 第8 行地址lcd_wdat(0x00); //"XXX 00000" 第8 行数据//第二个自定义字符lcd_wcmd(0x48); //"01 001 000" 第1 行地址lcd_wdat(0x01); //"XXX 00001" 第1 行数据lcd_wcmd(0x49); //"01 001 001" 第2 行地址lcd_wdat(0x1b); //"XXX 11011" 第2 行数据lcd_wcmd(0x4a); //"01 001 010" 第3 行地址lcd_wdat(0x1d); //"XXX 11101" 第3 行数据lcd_wcmd(0x4b); //"01 001 011" 第4 行地址lcd_wdat(0x19); //"XXX 11001" 第4 行数据lcd_wcmd(0x4c); //"01 001 100" 第5 行地址lcd_wdat(0x1d); //"XXX 11101" 第5 行数据lcd_wcmd(0x4d); //"01 001 101" 第6 行地址lcd_wdat(0x1b); //"XXX 11011" 第6 行数据lcd_wcmd(0x4e); //"01 001 110" 第7 行地址lcd_wdat(0x01); //"XXX 00001" 第7 行数据lcd_wcmd(0x4f);//"01 001 111" 第8 行地址lcd_wdat(0x00); //"XXX 00000" 第8 行数据}//LCD 初始化设定void lcd_init(){lcd_wcmd(0x38); //设置LCD 为16X2 显示,5X7 点阵,八位数据借口delay(1);lcd_wcmd(0x0c); //LCD 开显示及光标设置(光标不闪烁,不显示"-")delay(1);lcd_wcmd(0x06); //LCD 显示光标移动设置(光标地址指针加1,整屏显示不移动) delay(1);lcd_wcmd(0x01); //清除LCD 的显示内容delay(1);}//闰年的计算bit leap_year(){bit leap;if((year>4==0&amt;&amt;year>100!=0)||year>400==0)// 闰年的条件leap=1;elseleap=0;return leap;}//星期的自动运算和处理unsigned char week_proc(){ unsigned char num_leap;unsigned char c;num_leap=year/4-year/100+year/400;// 自00 年起到year 所经历的闰年数if( leap_year()&amt;&amt; month<=2 ) //既是闰年且是1 月和2 月c=5;elsec=6;week=(year+para_month[month]+date+num_leap+c)>7;// 计算对应的星期return week;}//更新显示缓冲区void update_disbuf(unsigned char t1,unsigned char t2[],unsigned char dis_h,unsigned char dis_m,unsigned char dis_s){ dis_buf1[0]=t1; //dis_buf1[1]=0x20; //空格dis_buf1[2]=50; //'2'dis_buf1[3]=48; //'0'dis_buf1[4]=year/10+48;dis_buf1[5]=year>10+48;dis_buf1[6]=0x2d;dis_buf1[7]=month/10+48;dis_buf1[8]=month>10+48;dis_buf1[9]=0x2d; //'-'dis_buf1[10]=date/10+48;dis_buf1[11]=date>10+48;dis_buf1[12]=0x20;dis_buf1[13]=dis_week[4*week];dis_buf1[14]=dis_week[4*week+1];dis_buf1[15]=dis_week[4*week+2];dis_buf2[0]=t2[0];dis_buf2[1]=t2[1];dis_buf2[2]=t2[2];dis_buf2[3]=t2[3];dis_buf2[4]=t2[4];dis_buf2[5]=t2[5];dis_buf2[6]=0x20; //空格if (alarm)dis_buf2[7]=0x01; //alarm=1,显示闹钟启用标致(第二个自定义字符)elsedis_buf2[7]=0x20; //alarm=0,不显示闹钟启用标致dis_buf2[8]=dis_h/10+48;dis_buf2[9]=dis_h>10+48;dis_buf2[10]=0x3a; //':'dis_buf2[11]=dis_m/10+48;dis_buf2[12]=dis_m>10+48;dis_buf2[13]=0x3a;dis_buf2[14]=dis_s/10+48;dis_buf2[15]=dis_s>10+48;}//时间和日期处理程序void pro_timedate(){sec++;if(sec > 59){sec = 0;min++;if(min>59){min=0;hour++;if(hour>23){hour=0;date++;if(month==1||month==3||month==5||month==7||month==8||month==10||month== 12)if (date>31) {date=1;month++;} //大月31 天if (month==4||month==6||month==9||month==11)if (date>30) {date=1;month++;} //小月30 天if (month==2){if( leap_year()) //闰年的条件{if (date>29) {date=1;month++;}} //闰年2 月为29 天else{if (date>28) {date=1;month++;}} //平年2 月为28 天}if (month>12) {month=1;year++;}if (year>99) year=0;}}}week_proc();if (sec==armsec &amt;&amt; min==armmin &amt;&amt; hour==armhour) {if (alarm)TR1=1; //闹钟启用时,报警时间到,启动Timer1}}//显示处理程序void pro_display(){ unsigned char i;lcd_pos(0x00);for (i=0;i<=15;i++){lcd_wdat(dis_buf1[i]);}lcd_pos(0x40);for (i=0;i<=15;i++){lcd_wdat(dis_buf2[i]);}}//Timer0 中断处理程序,秒的产生void timer0() interrupt 1{TH0=0xdc; //Timer0 置10ms 定时初值dc00H(2^16=65536D,dc00H=56320D)TL0=0x00; //定时时间=(65536-56320)*(1/11.0592)*12=10ms (f0=11.0592Mhz) sec100++;if(sec100 >= 100) //1 秒时间(100*10ms=1000ms=1s){sec100 = 0;pro_timedate();// 调用时间和日期处理程序}if (sec&amt;0x01) //"XUELIN" 闪一秒,停一秒update_disbuf(0x00," ",hour,min,sec); //0x00 表示显示00 位置的自定义字符elseupdate_disbuf(0x00,"XUELIN",hour,min,sec);pro_display(); //调用显示处理函数}//按键扫描程序unsigned char scan_key(){skey=0x00; //给变量vkey 置初值skey|=PRE; //读取PRE 键的状态skey=skey<<1; //将PRE 键的状态存于skey 的B1 位skey|=SET; //读取SET 键的状态,并存于skey 的B0 位return skey; //返回skey 的键值(即PRE,SET 的状态)}//外部中断INT0 中断处理程序void int0() interrupt 0{TR0=0; //禁止Timer0IE=0; //禁止中断lcd_wcmd(0x0e); //显示光标"_", 整个光标不闪烁alarm=1;update_disbuf(0x50,"alarm:",armhour,armmin,armsec); // 更新显示数据,0x50 表示要显示"P"pro_display(); //调用显示处理程序lcd_pos(0x47); //使光标位于第一个调整项下flag=0;vkey=0x03;while(flag^0x0a){skey = scan_key(); //扫描按键状态if (skey^vkey) //若skey 与vkey 相同,跳出循环,相异执行循环体{ delay(10); //去按键抖动skey = scan_key(); //转回扫描按键状态if (skey^vkey) //若skey 与vkey 相同,跳出循环,相异执行循环体{ vkey=skey; //将skey 的值付给vkeyif (skey==0x01) //PRE 键按下{ flag++; //调整标志位加1switch (flag) //将光标置于相应调整位置{case 1: lcd_pos(0x49);break; //光标置小时报警设置位置case 2: lcd_pos(0x4c);break; // 光标置分钟报警设置位置case 3: lcd_pos(0x4f);break; // 光标置秒时报警设置位置case 4: update_disbuf(0x50,"time: ",hour,min,sec);pro_display();lcd_pos(0x05);break; // 光标置年调整位置case 5: lcd_pos(0x08);break; // 光标置月调整位置case 6: lcd_pos(0x0b);break; // 光标置日调整位置case 7: lcd_pos(0x49);break; //光标置时调整位置case 8: lcd_pos(0x4c);break; // 光标置分调整位置case 9: lcd_pos(0x4f);break; // 光标置秒调整位置default:break;}}if (skey==0x02) //SET 键按下{ pro_key(); //转设置按键处理程序}}} }lcd_wcmd(0x0c); //设置LCD 开显示及光标不闪烁,不显示"-"lcd_wcmd(0x01);IE=0x8f;TR0=1;//清除LCD 的显示内容//CPU 开中断,INT0,INT1, 开中断//Timer0 启动}//主程序,初始化及初值设定void main(){lcd_init(); //初始化LCDlcd_sef_chr(); //写入自定义字符号hour=0;min=0;sec=0; //开机时的时,分,秒显示armhour=0;armmin=0;armsec=0; //开机时的时,分,秒报警初值year= 5; month=1;date=1; //开机时的年,月,日,星期显示week_proc();alarm=1; //初始开机,启用闹钟IE = 0x8f; //CPU 开中断,INT0,INT1,Timer0,Timer1 开中断IP = 0x04; //设置INT0 为中断最高优先级IT0=0;IT1=0; //外部INT0,INT1 设置为电平触发方式(注意,触发不要选边沿方式,)TMOD = 0x11; //Timer0,Timer1 工作于模式1, 16 位定时方式TH0 = 0xdc;TL0 = 0x00; //Timer0 置10ms 定时初值TH1 = 0xff;TL1 = 0x00; //Timer1 置初值TR0 = 1; //Timer0 启动TR1 = 0;while(1);}//设置按键处理程序void pro_key(){switch (flag){case 0:alarm=!alarm; //启用或关闭闹钟(alarm=1: 启用,alarm=0: 关闭)update_disbuf(0x50,"alarm:",armhour,armmin,armsec); // 更新显示数据pro_display(); //调用显示处理lcd_pos(0x47);break; //光标回到原调整位置case 1:armhour++;if (armhour>23) armhour=0;update_disbuf(0x50,"alarm:",armhour,armmin,armsec); // 更新显示数据pro_display(); //调用显示处理lcd_pos(0x49);break; //光标回到原调整位置if (armmin>59) armmin=0;update_disbuf(0x50,"alarm:",armhour,armmin,armsec);pro_display();lcd_pos(0x4c);break;case 3:armsec++;if (armsec>59) armsec=0;update_disbuf(0x50,"alarm:",armhour,armmin,armsec);pro_display();lcd_pos(0x4f);break;case 4:year++;if (year> 99) year= 0;week_proc(); //星期自动运算update_disbuf(0x50,"time: ",hour,min,sec);pro_display();lcd_pos(0x05);break;case 5:month++;if (month>12) month=1;week_proc(); //星期自动运算update_disbuf(0x50,"time: ",hour,min,sec);pro_display();lcd_pos(0x08);break;case 6:date++;if(month==1||month==3||month==5||month==7||month==8||month==10||month== 12)if (date>31) date=1; //大月31 天if (month==4||month==6||month==9||month==11)if (date>30) date=1; //小月30 天if (month==2){if(leap_year()) //闰年的条件{if (date>29) date=1;} //闰年2 月为29 天else{if (date>28) date=1;}} //平年2 月为28 天week_proc(); //星期自动运算update_disbuf(0x50,"time: ",hour,min,sec);pro_display();lcd_pos(0x0b);break;if (hour>23) hour=0;update_disbuf(0x50,"time: ",hour,min,sec); pro_display();lcd_pos(0x49);break;case 8:min++;if (min>59) min=0;update_disbuf(0x50,"time: ",hour,min,sec); pro_display();lcd_pos(0x4c);break;case 9:sec++;if (sec>59) sec=0;update_disbuf(0x50,"time: ",hour,min,sec); pro_display();lcd_pos(0x4f);break;default: break ;}}//Timer1 中断处理程序,产生报警的声音void timer1() interrupt 3{TH1=0xff;TL1=0x00;SPK=~SPK;}//外部中断INT1 中断处理程序,停止报警声音void int1() interrupt 2{if(TR1)TR1=0;}。
基于stc51单片机的LCD1602显示时间的电子万年历(显示

1 课设所需软件简介1.1 Keil uVision4的简要介绍2009年2月发布Keil μVision4,Keil μVision4引入灵活的窗口管理系统,使开发人员能够使用多台监视器,并提供了视觉上的表面对窗口位置的完全控制的任何地方。
新的用户界面可以更好地利用屏幕空间和更有效地组织多个窗口,提供一个整洁,高效的环境来开发应用程序。
新版本支持更多最新的ARM芯片,还添加了一些其他新功能。
2011年3月ARM公司发布最新集成开发环境RealView MDK开发工具中集成了最新版本的Keil uVision4,其编译器、调试工具实现与ARM器件的最完美匹配。
Keil C51开发系统基本知识Keil C51开发系统基本知识1. 系统概述Keil C51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。
另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到Keil C51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。
在开发大型软件时更能体现高级语言的优势。
下面详细介绍Keil C51开发系统各部分功能和使用。
2. Keil C51单片机软件开发系统的整体结构C51工具包的整体结构,uVision与Ishell分别是C51 for Windows和for Dos 的集成开发环境(IDE),可以完成编辑、编译、连接、调试、仿真等整个开发流程。
开发人员可用IDE本身或其它编辑器编辑C或汇编源文件。
然后分别由C51及C51编译器编译生成目标文件(.OBJ)。
目标文件可由LIB51创建生成库文件,也可以与库文件一起经L51连接定位生成绝对目标文件(.ABS)。
ABS文件由OH51转换成标准的Hex文件,以供调试器dScope51或tScope51使用进行源代码级调试,也可由仿真器使用直接对目标板进行调试,也可以直接写入程序存贮器如EPROM中。
使用独立的Keil仿真器时,注意事项:* 仿真器标配11.0592MHz的晶振,但用户可以在仿真器上的晶振插孔中换插其他频率的晶振。
lcd万年历显示及数字温度计

绵阳职业技术信息工程系课程实训报告课程名称:《单片机应用技术》实训题目:lcd万年历显示及数字温度计起止时间: 2010-12-5---2010-12-15 专业班级:学生姓名:小组成员:学号:指导教师:绵阳职业技术学院信息工程系2010年12月15日摘要电子万年历是实现对年,月,日,时,分,秒数字显示的计时装置,广泛用于个人家庭,车站,码头,办公室,银行大厅等场所,成为人们日常生活中的必需品。
数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度远远超过老式钟表。
钟表的数字化给人们生产生活带来了极大的方便,在此基础上完成的万年历精度高,功能易于扩展。
可扩展成为诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、定时开关烘箱、通断动力设备、甚至各种定时电气的自动启用等电路。
所有这些,都是以钟表数字化为基础的。
因此,研究数字时钟及扩大其应用有着非常现实的意义。
本设计就是数字时钟简单的扩展应用并且在现实万年历的同时采用8 个数字温度传感器DS18B20 采集温度信息,通过AT89S52单片机统一发送初始化、写命令等控制信号来操作传感器,并逐一从传感器中读取温度,最后,在LCD 中循环显示温度信息;该系统还可通过键盘来设定温度的限定参数和选定特殊的显示方式,具有良好的人机界面。
实验证明,该温度检测系统具有结构简单、稳定性好、精度高等优点,值得推广。
关键词: AT89S52 单片机;万年历;蜂鸣器;数字温度检测系统;DS18B20 数字温度传感器目录第1章绪论 (3)1.1课题背景及研究意义 (3)1.2国内外现状 (3)1.3课题的设计目的 (4)1.4课题的主要工作 (4)1.5本文研究内容 (4)第二章设计要求和方案论证 (6)2.1 设计要求 (6)2.2 单片机芯片的选择方案和论证 (6)2.3 显示模块选择方案和论证 (6)2.4时钟的选择方案和论证 (7)2.5温度传感器的选择方案与论证 (7)2.6 DS18B20温度传感器与单片机的接口电路 (8)2.7 电路设计最终方案决定 (9)第三章系统的硬件设计与实现 (10)3.1 电路设计框图 (10)3.2 系统硬件概述 (10)3.3 主要单元电路的设计 (10)3.3.1 AT89S52单片机简介 (10)3.3.2 单片机主控制模块的设计 (11)3.3.4温度传感器电路设计 (13)3.3.5独立式键盘设计 (16)3.3.6液晶模块简介 (17)3.3.7液晶显示部分与AT89s52的接口 (19)3.3.8本章小结 (20)第四章系统的软件设计与实现 (28)4.1.1 系统总流程图 (21)4.1.2 温度程序流程图 (22)4.1.3 LCD显示程序流程图 (24)4.2.液晶显示程序 (28)4.3本章小结 (29)第五章仿真与调试 (30)51软件简介 (30)5.1.1 Keil软件简介 (30)5.1.2 Proteus ISIS简介 (31)5.2 Keil软件调试流程 (32)5.3 Proteus软件运行流程 (35)5.4 万年历的功能仿真 (36)5.5 硬件调试结果 (39)5.6本章小结 (40)附录 (41)附录一: (41)源程序代码: (41)附录二: (55)任务书一、设计目的、步骤及要求1、设计目的以单片机为核心,设计单片机最小系统,构成数字式温度计,能够实现实时温度的显示巩固所学知识、加强综合能力、提高软、硬件设计调试方面的能力、启发创新思维,使将相关专业课程知识综合起来,融会贯通,形成系统的概念,从而实现理论与实践相结合提高设计能力、电子线路的组装调试能力和创新能力,通过查阅资料、选定方案、设计电路、调试软件并下载到芯片中、写出完整的报告等过程,2、设计步骤内容:设计一个具有温度实时检测和动态显示功能的温度检测系统,和led动态显示图文字符的系统电路:1.LCD用于实时时钟(时、分、秒)等广告标语的显示;并能用按键进行实时调试2、利用数字温度传感器DS18B20测量温度信号,计算后在LCD上显示相应的温度值。
lcd数显温度万年历电波钟

外观尺寸:29cm(宽)*18.5cm(高)可挂可摆,背面有挂孔,可挂在墙上,也可以安装随机配送的支架摆放在台面上。
电子说明书地址:/item.htm?spm=a1z09.5.0.4 0&id=16362908718功能特点:1、时间显示:时:分:秒,12/24小时制可选2、日历显示:日/月3、星期显示:英文简写4、温度显示:摄氏或华摄,范围:0℃-50℃(32℉-122℉),分辨率:0.1℃。
5、闹铃功能:可设置1个闹铃时间。
6、特殊日期提醒功能:可设置三个特殊日期提醒。
使用电源:两节AA电池(不配送电池),超省电,两节电池可使用一年以上。
使用说明:一、信号自动同步:当时钟正确装上电池后,稍等几秒,自动开始接收日本发射的无线电校时信号,接收过程中屏幕右上角显示一个闪动的信号接收塔标识。
当接收到正确的时间信号后,接收塔标识停止闪动并自动同步时间和日历信息,时钟每天会定时进行接收,无须人工干预。
如果接收不成功,时钟仍可以作为一个高精度石英钟使用。
时钟在接收信号的过程(接收塔标识闪动)中无法进行其他功能的操作,如果需要进行其它设置或取消接收,须按下‘+’键退出接收状态。
为了达到最好的接收效果,应将时钟远离其它用电器至少在1-2米以上,并可以适当转动时钟位置以获取最佳接收效果。
二、信号手动同步:在正常的时钟显示模式,长按‘+’键,强制进入信号接收状态,此时收塔标识闪动,接收过程与自动同步一样。
三、手动设定时钟、日历:在正常的时钟显示模式,长按‘CLK/CAL’键,进入时间日历设置界面,当前设置项目闪动,通过短按‘+,-’键调整数值,再短按‘CLK/CAL’确认并进入下一设置项目。
设置项目顺序:12/24时制—小时—分钟—年—月—日—时区。
四、每日闹钟设置:在正常的时钟显示模式,长按‘ALARM’键,进入闹铃设置界面,通过短按按‘+,-’键输入每天的闹铃时间,最后按‘ALARM’键确认。
在正常的时钟显示模式,短按‘-’键可以开启和关闭闹铃功能,当闹铃响时,按任意键都可以关闭闹铃。
基于液晶显示的万年历

毕业设计(论文)报告题目基于液晶显示的万年历系别专业班级学生姓名学号指导教师2013年4 月基于液晶显示的万年历摘要:本设计应用AT89S52芯片作为核心,采用C语言进行编程,实现以下功能:小时、分、秒、年、月、日、星期的显示和实时温度检测。
该设计的电子时钟系统由时钟电路、LCD显示电路、按键调整电路和温度检测电路四部分组成。
使用时钟芯片DS1302完成时钟日期的功能,以LCD1602为显示器,同时利用温度传感器DS18B20测量周围环境温度,并且可以依靠按键随时对日期时间进行调整。
我们共设计四个按键,一个模式键,也就是我们用来选定被修改的数字的,两个调整键,一个“加”键和一个“减”键,当按下模式键,选定要调整的数字的时候,“加”、“减”可以帮我们调到所需的状态,还有一个复位键,显示精度为1秒。
设计还提供三位实时温度检测并显示,其显示精度为0.1℃。
关键词:AT89S52、时钟日历芯片DS1302、温度传感器DS18B20、LCD1602目录前言 (1)第一章方案选择与万年历研究情况 (2)1.1 方案选择 (2)1.1.1时钟芯片选择 (2)1.1.2键盘选择 (3)1.1.3显示模块选择 (3)1.2电子万年历的研究情况 (4)第二章主要硬件描述 (5)2.1 AT89S52 (5)2.1.1主要性能 (5)2.1.2引脚说明 (5)2.2 LCM1602 (8)2.2.1工作原理 (8)2.2.2端口引脚第二功能 (9)2.2.3管脚功能 (10)2.3 芯片DS1302 (11)2.3.1工作原理 (11)2.3.2引脚功能及结构 (12)2.4 数字温度传感器DS18B20 (12)2.4.1DS18B20工作原理 (12)2.4.2DS18B20 引脚定义 (13)第三章硬件设计与实现 (14)3.1 单片机最小系统的设计 (14)3.2 时钟电路的设计 (15)3.3 温度采集模块的设计 (15)3.4 LCDM1602显示模块设计 (16)第四章系统软件设计与实现 (17)4.1主程序设计 (17)4.2实时时钟日历子程序设计 (17)4.3环境温度采集子程序设计 (18)4.4按键子程序设计 (20)第五章测试结果分析与结果 (21)5.1 测试结果分析 (21)5.2 测试总结 (21)结束语 (22)致谢 (23)参考文献 (24)附录一:原理图 (25)附录二:源程序 (26)前言万年历,就是记录一定时间范围内(比如100年或更多)的具体阳历与阴历的日期的年历, 方便有需要的人查询使用.万年只是一种象征,表示时间跨度大.这次设计通过对万年历系统的设计, 详细介绍AT89S52单片机应用中的按键处理,数码管显示原理,动态和静态显示原理,定时中断,A/D转换等原理.该系统能够显示年,月,日,小时,分钟,秒,星期,农历,温度,通过按键可以修改时间等功能.此系统结构简单,功能齐全,具有一定的推广价值。
电子时钟+万年历(LCD1602)

基于AT89S52的lcd1602显示电子时钟+万年历/**********************************************名称:基于AT89S52的lcd1602显示电子时钟+万年历编写:李松泽时间:2013.07.30**********************************************/#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar code table[]=" 2013-07-30 WED ";uchar code table1[]=" 21:14:55";uchar code table2[]=" 579259 ";uchar code table3[]="Made by Lisongze";uchar code table4[]="MONTUEWEDTHUFRISATSUN"; uchar count,s1num;char miao,fen,shi,ri,yue;uint nian;sbit lcd_rs = P0^5;sbit lcd_rw = P0^6;sbit lcd_en = P0^7;sbit s1=P3^7;sbit s2=P3^6;sbit s3=P3^5;sbit g=P3^0;void delay(uint z)//延时子函数{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(uchar com)//写命令函数{lcd_rs = 0;P2= com;delay(5);lcd_en=1;delay(5);lcd_en=0;}void write_date(uchar date)//写数据函数{lcd_rs = 1;P2= date;delay(5);lcd_en=1;delay(5);lcd_en=0;}void init()//初始化函数{int num;shi=21;fen=14;miao=55;ri=30;yue=7;nian=2013;lcd_en=0;lcd_rw=0;write_com(0x38);//显示设置模式write_com(0x0c);//00001100开显示,不显示光标,光标不闪烁write_com(0x06);//00000110地址指针加一,整屏不移动write_com(0x01);//清屏write_com(0x80);for(num=0;num<16;num++)//显示数字579259{write_date(table2[num]);delay(300);}write_com(0x80+0x40);for(num=0;num<16;num++)//显示made by lisongze{write_date(table3[num]);delay(300);}delay(5000);write_com(0x01);write_com(0x80);for(num=0;num<16;num++)//显示日期{write_date(table[num]);delay(5);}write_com(0x80+0x40);for(num=0;num<12;num++)//显示时间{write_date(table1[num]);delay(5);}TMOD=0x01;//启动定时器中断TH0=(65535-50000)/256;TL0=(65535-50000)%256;EA=1;ET0=1;TR0=1;//打开定时器}void write_sfm(uchar add,uchar date)//写时分秒函数{uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);}void write_nyr(uint add,uint date)//写年月日函数,此处若用uchar范围只有0-255 { //不够,改用uint(0-65535) uint qian,bai,shi,ge;qian=date/1000;bai=date%1000/100;shi=date%100/10;ge=date%10;write_com(0x80+add);write_date(0x30+qian);write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge);}void write_yr(uchar add,uchar date)//写月日函数{uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+add);write_date(0x30+shi);write_date(0x30+ge);}void keyscan()//按键扫描函数{int m,n;g=0;//将矩阵键盘当做独立键盘使用if(s1==0){delay(5);if(s1==0)//按键1光标移位扫描{s1num++;if(s1num==1){ while(!s1);//等待按键松手write_com(0x80+0x40+10);TR0=0;//关闭定时器write_com(0x0f);}if(s1num==2){while(!s1);write_com(0x80+0x40+7);}if(s1num==3){while(!s1);write_com(0x80+0x40+4);}if(s1num==4){while(!s1);write_com(0x80+3);}if(s1num==5){while(!s1);write_com(0x80+6);}if(s1num==6){while(!s1);write_com(0x80+9);}if(s1num==7){while(!s1)write_com(0x80+13);}if(s1num==8){while(!s1);s1num=0;write_com(0x0c);TR0=1;//开定时器}}}if(s1num!=0){if(s2==0)//按键2加功能{delay(5);if(s2==0){while(!s2);if(s1num==1)//秒加{miao++;if(miao==60){miao=0;}write_sfm(10,miao);write_com(0x80+0x40+10);}if(s1num==2)//分加{fen++;if(fen==60){fen=0;}write_sfm(7,fen);write_com(0x80+0x40+7);}if(s1num==3)//时加{shi++;if(shi==24){shi=0;}write_sfm(4,shi);write_com(0x80+0x40+4);}if(s1num==4)//年加{nian++;if(nian==10000){nian=2000;}write_nyr(1,nian);write_com(0x80+3);}if(s1num==5)//月份加{yue++;if(yue==13){yue=1;}write_yr(6,yue);write_com(0x80+6);}if(s1num==6)//日期加{ri++;if(ri==29&&yue==2&&!((nian%4==0&&nian%100!=0)||nian%400==0)){ri=1;//平年}if(ri==30&&yue==2&&((nian%4==0&&nian%100!=0||nian%400==0))){ri=1;//闰年}if(ri==31&&(yue==4||yue==6||yue==9||yue==11)){ri=1;}if(ri==32){ri=1;}write_yr(9,ri);write_com(0x80+9);}if(s1num==7)//星期加{m=m+3;if(m==21)m=0;write_com(0x80+12);for(n=m;n<m+3;n++){write_date(table4[n]);delay(5);}write_com(0x80+13);}}}if(s3==0)//按键3减功能{delay(5);if(s3==0){while(!s3);if(s1num==1)//秒减{miao--;if(miao==-1){miao=59;}write_sfm(10,miao);write_com(0x80+0x40+10);}if(s1num==2)//分减{fen--;if(fen==-1)fen=59;write_sfm(7,fen);write_com(0x80+0x40+7);}if(s1num==3)//时减{shi--;if(shi==-1)shi=23;write_sfm(4,shi);write_com(0x80+0x40+4);}if(s1num==4)//年减{nian--;if(nian==1999)nian=2000;write_nyr(1,nian);write_com(0x80+3);if(s1num==5)//月份减{yue--;if(yue==0)yue=12;write_yr(6,yue);write_com(0x80+6);}if(s1num==6)//日减{ri--;if(ri==0){if(yue==2&&!((nian%4==0&&nian%100!=0)||nian%400==0)){ri=28;//平年}if(yue==2&&((nian%4==0&&nian%100!=0||nian%400==0))){ri=29;//闰年}if(yue==4||yue==6||yue==9||yue==11){ri=30;}if(yue==1||yue==3||yue==5||yue==7||yue==9||yue==11)ri=31;}write_yr(9,ri);write_com(0x80+9);}if(s1num==7)//星期减{m=m-3;if(m==0)m=21;write_com(0x80+12);for(n=m;n-3<m;n++){write_date(table4[n-3]);delay(5);}write_com(0x80+13);}}}}void main(){int i,j;init();while(1){keyscan();if(count==18){count=0;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;ri++;j=j+3;if(j==21)j=0;write_com(0x80+12);for(i=j;i<j+3;i++){write_date(table4[i]);delay(5);}if(ri==29&&yue==2&&!((nian%4==0&&nian%100!=0)||nian%400==0)){ri=1;yue++;//平年}if(ri==30&&yue==2&&((nian%4==0&&nian%100!=0||nian%400==0))){ri=1;yue++;//闰年}if(ri==31&&(yue==4||yue==6||yue==9||yue==11)){ri=1;yue++;}if(ri==32){ri=1;yue++;}if(yue==13){yue=1;nian++;if(nian==10000){nian=2000;}write_nyr(1,nian);}write_yr(6,yue);}write_yr(9,ri);write_sfm(4,shi);}write_sfm(7,fen);}write_sfm(10,miao);}}}void timer() interrupt 1{TH0=(65535-50000)/256;TL0=(65535-50000)%256;count++;}说明:单片机最小系统在这里就不用给图了,对于单片机学习者就不用提了,仅仅给个lcd1602连接图就够了,对了,要说明一点,笔者的最小系统上独立键盘不够,所以就暂且用矩阵键盘代替独立键盘,程序更要说明是在郭天祥视频讲解的基础上加上自己的思想(实现万年历的功能),程序基本上没有问题,就是偶尔调时完,走时有点迟钝,希望能够和大家共同交流!QQ:782373034电子群:257584167。
液晶万年历

液晶万年历作品简介本款作品基于AT89S51主控芯片和DS18B20时钟芯片,采用液晶显示屏1602显示,使用温度传感器采集周围环境温度实现功能:显示年月日时分秒温度准确显示可通过按键进行校时操作定时响铃作品特点:采用双电源供电,停电时可自动切换到电池供电:工作稳定,低功耗,寿命长,外形简洁大方,方便携带、摆放。
1.本设计的主要设计思想是两方面:1、通过设计硬件控制电路和软件控制程序,从而实现能够正确地显示某年某月某日某时某分某秒,万年历应具有校时功能、定时功能、报时功能。
可能除了上边的功能还有其他的功能,如果需要还可以不断的向上加功能。
在万年历电子表的上面还有调整时间和定时用的几个功能键(复位键、选择位键、各个位数值的增大和减小两个键等)硬件控制电路主要用了AT89S51芯片处理器、LCD1602液晶显示器、DS1302时钟芯片等。
根据各自芯片的功能互相连接成万年历电子表的控制电路。
2、软件控制程序主要有主控程序、万年历电子表的时间控制程序。
主控程序中对整个程序进行控制,进行了初始化程序及计数器、还有键盘功能程序、以及显示程序等工作,时间控制程序是万年历电子表中比较重要的部分。
时间控制程序体现了年、月、日、小时、分钟、秒及星期的计算方法。
设计中使用的时钟芯片是美国DALLAS公司推出的与MC146818兼容,寄存器存取速度快,在主机掉电时可用来保存重要数据的实时时钟芯片DS1302,采用DS1302作为主要计时芯片,可做到计时准确。
对它的控制,主要是对其的初始化和对其数据的读取。
采用连续工作制,一般无需每次都初始化,即使系统复位也是如此。
但初始化时,首先应禁止芯片内部的更新周期操作。
所以,应先将它状态寄存器B中的SET位置1,然后初始化。
DS1302处于正常工作状态时,每秒即产生一个更新周期。
在该周期内,微处理器不能读时标寄存器中的内容,否则将得不到确定数据。
为了采样时标寄存器中的数据,采用两种避开在更新周期内访问时标寄存器的方法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
DS18B20温度检测流程图
时间调整部分程序设计
液晶LCD1602显示部分程序设计流程图
实物照片
总结
此次毕业设计的制作,让我明白了:知识无 止境,在做东西的过程中我们会不断补充自 己的知识,让自己受益良多。 我的经验和知识有限,在开发中存在许多不 足之处,请各位老师批评指正.
致谢
此次毕业设计的制作,凝聚了我的心血,也注入了 老师和同学的无私帮助和热情奉献。在此,我要特 别感谢我的指导老师—何培忠老师,感谢老师给予 我的大力支持。从毕业设计的选题、资料的收集、 参考书目的推荐到实物的调试和完成直到最后的论 文定稿,何老师总是循循善诱的给我指出不足并给 出中肯改善的意见;在我进行程序编写的时候,何 老师耐心的帮助我调试程序,所以我要特别的感谢 他对我的帮助。同时,还有那些在我毕业设计制作 过程中帮助和关心过我的同学,他们也倾注了很多 的精力给予我真诚的帮助,在此,我对所有关心和 帮助过我的家人、同学、老师们表示衷心感谢!
DS1302日期时间数据读取显示 流程图
对于时钟芯片DS1302, 对于时钟芯片DS1302, DS1302 公历日期时间显示只需从 DS1302各寄存器读出年 各寄存器读出年、 DS1302各寄存器读出年、月、 星期, 日、时、分、秒、星期,再 加处理即可。 加处理即可。在首次对 DS1302进行操作之前 进行操作之前, DS1302进行操作之前,必须 进行初始化, 进行初始化,然后从中读出 数据,经过处理后, 数据,经过处理后,送给显 示缓冲单元。 示缓冲单元。
系统进行过相关的初始化指 令之后即开始执行万年历部 分的程序:读取DS1302的 分的程序:读取 的 日期时间数据信息、 日期时间数据信息、根据现 时日期进行农历更新、 时日期进行农历更新、查询 有无功能键按下。若有, 有无功能键按下。若有,则 根据相应的按键进行对应的 处理;若无,则显示。 处理;若无,则显示。
系统构成框图
整个系统由主控模块和 显示模块两大模块组成, 显示模块两大模块组成, 主控模块包括主控芯片、 主控模块包括主控芯片、 温度检测、 温度检测、实时时钟电路 及键盘接口电路, 及键盘接口电路,系统构 成框图如左图所示。 成框图如左图所示。
本设计所用主要芯片
主控模块硬件电路
主程序流程图
基于单片机的LCD显示电子万年历 显示电子万年历 基于单片机的
物理与电子工程学院 04物41 物 顾法令 钟芯片DS1302, , 本文设计了一种基于实时时钟芯片 单片机为核心、 以AT89S52单片机为核心、LCD显示的电子万年 单片机为核心 显示的电子万年 并加入了温度实时显示功能,温度误差 温度误差<0.5摄 历,并加入了温度实时显示功能 温度误差 摄 氏度.主要介绍温度传感器 主要介绍温度传感器DS18B20的时序读写 氏度 主要介绍温度传感器 的时序读写 的数据操作原理, 和时钟芯片 DS1302的数据操作原理,通过万年 的数据操作原理 历硬件和软件的设计,实现了公历年、 历硬件和软件的设计,实现了公历年、月、日、 时、分、秒、星期的调整功能 ,温度为实时显示 温度为实时显示 (不可调 不可调). 不可调