DS1802HE LCD1602实现万年历和温度显示(不用时间芯片)

合集下载

C语言Lcd1602万年历闹钟Proteus仿真单片机毕业课程电子设计

C语言Lcd1602万年历闹钟Proteus仿真单片机毕业课程电子设计

C语言Lcd1602万年历闹钟Proteus仿真单片机毕业课程电子设计
C语言Lcd1602万年历闹钟Proteus仿真单片机设计
AT89C51+Lcd1602+DS1302+独立按键+蜂鸣器
Lcd1602万年历闹钟。

时间信息来自DS1302,显示采用
Lcd1602,蜂鸣器提供闹音和按键提示音。

液晶上面显示年月日时分秒星期以及闹钟时间。

有时间调节和闹钟调节,可以调节年月日时分秒星期信息以及闹钟时间。

具体介绍如下。

1.做好的仿真图,如下图所示。

2.启动仿真后,先在液晶屏显示系统信息,然后在第二屏显示需要的万年历闹钟信息。

如下图所示!
3.通过单片机右侧的三个按键,即可设置闹钟。

如下图所示。

4.通过单片机左侧的四个按键,来设置年月日时分秒星期的值。

设置时,参数闪烁,同时会有按键提示音。

5.本设计默认套餐1,具体套餐详情请看下面的发货清单。

如需要其它套餐,请联系客服询问。

详情请:点击此处。

LCD1602_显示时间_温度

LCD1602_显示时间_温度

#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define LCDIO P2sbit DQ=P1^3;//ds18b20与单片机连接口sbit rs=P1^0;sbit rd=P1^1;sbit lcden=P1^2;sbit acc0=ACC^0; //移位时的第0位sbit acc7=ACC^7; //移位时用的第7位uchar second,minute,hour,day,month,year,week,count=0; uchar ReadValue,num,time;uint tvalue;//温度值uchar tflag;uchar code table[]={" 2010-11-29 MON"};uchar code table1[]={" 15:45:00 000.0C"};uchar code table2[]= "THUFRISATSUNMONTUEWES";uchar data disdata[5];sbit DATA=P0^1; //时钟数据接口sbit RST=P0^2;sbit SCLK=P0^0;sbit menu=P3^5; //菜单sbit add=P3^6; //加一sbit dec=P3^7; //减一void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--); }void delay1(uint z){for(;z>0;z--);}void write_com(uchar com) {rs=0;rd=0;lcden=0;P2=com;delay(5);lcden=1;delay(5);lcden=0;}void write_date(uchar date) {rs=1;lcden=0;P2=date;delay(5);lcden=1;delay(5);lcden=0;}void init(){uchar num;lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);delay(5);write_com(0x80);for(num=0;num<15;num++){write_date(table[num]);delay(5);write_com(0x80+0x40);for(num=0;num<15;num++){write_date(table1[num]);delay(5);}}void Write1302(uchar dat){uchar i;SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备delay1(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续写8个二进制位数据{DATA=dat&0x01; //取出dat的第0位数据写入1302delay(2); //稍微等待,使硬件做好准备SCLK=1; //上升沿写入数据delay1(2); //稍微等待,使硬件做好准备SCLK=0; //重新拉低SCLK,形成脉冲dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位 }}void WriteSet1302(uchar Cmd,uchar dat){RST=0; //禁止数据传递SCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输delay1(2); //稍微等待,使硬件做好准备Write1302(Cmd); //写入命令字Write1302(dat); //写数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递}uchar Read1302(void){uchar i,dat;delay(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续读8个二进制位数据{dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位 if(DATA==1) //如果读出的数据是1dat|=0x80; //将1取出,写在dat的最高位SCLK=1; //将SCLK置于高电平,为下降沿读出delay1(2); //稍微等待SCLK=0; //拉低SCLK,形成脉冲下降沿delay1(2); //稍微等待}return dat; //将读出的数据返回}uchar ReadSet1302(uchar Cmd){uchar dat;RST=0; //拉低RSTSCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输Write1302(Cmd); //写入命令字dat=Read1302(); //读出数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递return dat; //将读出的数据返回}void Init_DS1302(void){WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令WriteSet1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值 WriteSet1302(0x82,((45/10)<<4|(45%10))); //根据写分寄存器命令字,写入分的初始值WriteSet1302(0x84,((15/10)<<4|(15%10))); //根据写小时寄存器命令字,写入小时的初始值WriteSet1302(0x86,((29/10)<<4|(29%10))); //根据写日寄存器命令字,写入日的初始值 WriteSet1302(0x88,((11/10)<<4|(11%10))); //根据写月寄存器命令字,写入月的初始值 WriteSet1302(0x8c,((10/10)<<4|(10%10))); //nianWriteSet1302(0x8a,((4/10)<<4|(4%10)));}void DisplaySecond(uchar x){uchar i,j;i=x/10;j=x%10;write_com(0xc7);write_date(0x30+i);write_date(0x30+j);}void DisplayMinute(uchar x){uchar i,j;i=x/10;j=x%10;write_com(0xc4);write_date(0x30+i);write_date(0x30+j);}void DisplayHour(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0xc1);write_date(0x30+i);write_date(0x30+j); }void DisplayDay(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x89);write_date(0x30+i);write_date(0x30+j); }void DisplayMonth(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x86);write_date(0x30+i);write_date(0x30+j); }void DisplayYear(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x83);write_date(0x30+i);write_date(0x30+j); }void DisplayWeek(uchar x) { uchar i;x=x*3;write_com(0x8c);for(i=0;i<3;i++){write_date(table2[x]);x++;}}void read_date(void){ReadValue = ReadSet1302(0x81);second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x83);minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x85);hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x87);day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x89);month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x8d);year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue=ReadSet1302(0x8b); //读星期 week=ReadValue&0x07;DisplaySecond(second);DisplayMinute(minute);DisplayHour(hour);DisplayDay(day);DisplayMonth(month);DisplayYear(year);DisplayWeek(week);}void turn_val(char newval,uchar flag,uchar newaddr,uchar s1num){newval=ReadSet1302(newaddr); //读取当前时间newval=((newval&0x70)>>4)*10+(newval&0x0f); //将bcd码转换成十进制if(flag) //判断是加一还是减一{newval++;switch(s1num){ case 1: if(newval>99) newval=0;DisplayYear(newval);break;case 2: if(newval>12) newval=1;DisplayMonth(newval);break;case 3: if(newval>31) newval=1;DisplayDay(newval);break;case 4: if(newval>6) newval=0;DisplayWeek(newval);break;case 5: if(newval>23) newval=0;DisplayHour(newval);case 6: if(newval>59) newval=0;DisplayMinute(newval);break;case 7: if(newval>59) newval=0;DisplaySecond(newval);break;default:break;}}else{newval--;switch(s1num){ case 1: if(newval==0) newval=99;DisplayYear(newval);break;case 2: if(newval==0) newval=12;DisplayMonth(newval);break;case 3: if(newval==0) newval=31;DisplayDay(newval);break;case 4: if(newval<0) newval=6;DisplayWeek(newval);case 5: if(newval<0) newval=23;DisplayHour(newval);break;case 6: if(newval<0) newval=59;DisplayMinute(newval);break;case 7: if(newval<0) newval=59;DisplaySecond(newval);break;default:break;}}WriteSet1302((newaddr-1),((newval/10)<<4)|(newval%10)); //将新数据写入寄存器}//键盘扫描程序//*******************************************void key_scan(void){ uchar miao,s1num=0;if(menu==0){delay(5);if(menu==0){while(!menu);s1num++;while(1){if(menu==0){delay(5);if(menu==0){while(!menu);s1num++;}}rd=0;miao=ReadSet1302(0x81);second=miao;WriteSet1302(0x80,miao|0x80);write_com(0x0f);//光标闪射if(s1num==1){ year=ReadSet1302(0x8d);write_com(0x80+4); //年光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(year,1,0x8d,1);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(year,0,0x8d,1);}}}if(s1num==2){month=ReadSet1302(0x89);write_com(0x80+7); //月光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(month,1,0x89,2); }}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(month,0,0x89,2); }}}if(s1num==3){ day=ReadSet1302(0x87);write_com(0x80+10);//日光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(day,1,0x87,3);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(day,0,0x87,3); //写入日寄存器 }}}if(s1num==4){ week=ReadSet1302(0x8b);write_com(0x80+14); //星期光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(week,1,0x8b,4);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(week,0,0x8b,4);}}}if(s1num==5){ hour=ReadSet1302(0x85);write_com(0x80+0x40+2); //时光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(hour,1,0x85,5);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(hour,0,0x85,5);}}}if(s1num==6)//调时间分{ minute=ReadSet1302(0x83);write_com(0x80+0x40+5);if(add==0){delay(5);if(add==0){ while(!add);turn_val(minute,1,0x83,6); //写入分寄存器 }}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(minute,0,0x83,6); //写入分寄存器 }}}if(s1num==7)//调时间秒{ second=ReadSet1302(0x81);write_com(0x80+0x40+8);//秒光标if(add==0){delay(3);if(add==0){ while(!add);if(second==0x60)second=0x00;turn_val(second,1,0x81,7);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(second,0,0x81,7);}}}if(s1num==8){ miao=ReadSet1302(0x81);second=miao;WriteSet1302(0x80,second&0x7f);s1num=0;//s1num清零//write_com(0x0c);//光标不闪烁//break;}}}}}void delay_18B20(unsigned int i)//延时1微秒{while(i--);}void ds1820rst()/*ds1820复位*/{ unsigned char x=0;DQ = 1; //DQ复位delay_18B20(4); //延时DQ = 0; //DQ拉低delay_18B20(100); //精确延时大于480usDQ = 1; //拉高delay_18B20(40);}uchar ds1820rd()/*读数据*/{ unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){ DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80;delay_18B20(10);}return(dat);}void ds1820wr(uchar wdata)/*写数据*/ {unsigned char i=0;for (i=8; i>0; i--){ DQ = 0;DQ = wdata&0x01;delay_18B20(10);DQ = 1;wdata>>=1;}}read_temp()/*读取温度值并转换*/{uchar a,b;ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0x44);//*启动温度转换*/ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0xbe);//*读取温度*/a=ds1820rd();b=ds1820rd();tvalue=b;tvalue<<=8;tvalue=tvalue|a;if(tvalue<0x0fff)tflag=0;else{tvalue=~tvalue+1;tflag=1;}tvalue=tvalue*(0.425);//温度值扩大10倍,精确到1位小数return(tvalue);}void ds1820disp()//温度值显示{ uchar flagdat;disdata[0]=tvalue/1000+0x30;//百位数disdata[1]=tvalue%1000/100+0x30;//十位数disdata[2]=tvalue%100/10+0x30;//个位数disdata[3]=tvalue%10+0x30;//小数位if(tflag==0)flagdat=0x20;//正温度不显示符号elseflagdat=0x2d;//负温度显示负号:-if(disdata[0]==0x30){disdata[0]=0x20;//如果百位为0,不显示if(disdata[1]==0x30){disdata[1]=0x20;//如果百位为0,十位为0也不显示}}write_com(0xc9);write_date(flagdat);//显示符号位write_com(0xca);write_date(disdata[0]);//显示百位write_com(0xcb);write_date(disdata[1]);//显示十位write_com(0xcc);write_date(disdata[2]);//显示个位write_com(0xcd);write_date(0x2e);//显示小数点write_com(0xce);write_date(disdata[3]);//显示小数位write_com(0xcf);write_date('C');}void main(){init();Init_DS1302(); //将1302初始化read_temp();//读取温度ds1820disp();//显示while(1){read_date();key_scan();read_temp();//读取温度ds1820disp();//显示}}完。

液晶万年历的显示

液晶万年历的显示

毕业设计(论文)设计(论文)题目:液晶万年历的显示指导教师:学生专业:班级:学生姓教研室主任:信息工程学院二〇一〇年 11 月 10 日摘要随着电子技术的迅速发展,特别是大规模集成电路的出现,人类生活发生了根本性的变化。

以单片机技术为核心的产品已走进了千家万户,数字万年历的出现更是给人们的生活带来诸多方便,本文就实现了基于AT89C52单片机的多功能数字万年历的设计。

本设计以AT89C52单片机技术为核心,以各种硬件电路为基础,软件采用C语言进行编写,为了便于扩展和更改,采用模块化的程序设计方法,使程序设计的逻辑关系更加简洁明了,系统升级更加简单方便。

系统以LCD1602液晶模块为载体显示数据,所以具有人性化的操作界面和美观的页面效果;可以显示公历日期、时间、农历日期、星期、温度。

用户可以通过按键调节系统时间、设定时间。

左后完成了组装与调试。

关键词:AT89C52 LCD1602AbstractWith the rapid development of electronic technology, especially the emergence of large-scale integrated circuits, human life there has been a fundamental change. The products have entered tens of thousands of household whose core is single-chip technology, the emergence of digital calendar is to bring a lot of people’s lives easy, This article worked out a design of multi-functional digital calendar based on the single chip AT89S52.The design of single-chip AT89S52 technology as the core, based on a variety of hardware circuitry and used assembly language for the preparation of software, In order to facilitate the expansion and changes to the design ,procedures for the used of modular design method so that the logic of the relationship between program design more concise, the system more simple and convenient to upgrade. System use dot-matrix LCD Module 1602 font display as the data ,time ,Chinese data, week ,temperature, and has alarm functions. User can adjust the system time or set the alarm time through the button . I completed the assembly and commissioning finally.Keywords:AT89C51chip LCD1602目录第一章绪论 (1)1.1单片机的发展 (1)1.2设计任务 (1)1.3设计意义 (1)1.4设计方案思路: (2)1.5系统原理 (2)第二章硬件电路设计 (3)2.1芯片DS1302: (3)2.1.1、D S1302简介: (3)2.1.2、D S1302工作原理: (4)2.2温度传感器: (4)2.2.1、温度传感器(DS18B20芯片)简介: (4)2.2.2、DS18B20的主要特征: (5)2.2.3、引脚定义: (5)2.2.4、DS18B20工作原理及应用: (6)2.3液晶显示器 (6)2.3.1引脚说明: (6)2.3.2液晶显示器的工作原理: (8)2.4AT89C52主控模块: (8)2.4.1㈠引脚功能特性: (9)2.4.2AT89S52的总线结构 (10)2.4.3AT89C51的功能描述 (11)2.5硬件原理框图 (11)2.5.1系统硬件概述 (12)2.5.2主要单元电路 (12)第三章系统软件设计 (14)3.1软件开发流程 (14)3.1.1系统的程序流程图 (14)3.1.2时钟设定模块设计流程图 (15)3.1.3温度设定模块设计流程图: (22)第四章设计调试 (27)4.1开发环境介绍: (27)4.2 PROTEUS调试与仿真 (27)致谢 (30)附录: (31)液晶显示部分子程序: (31)按键部分子程序: (34)第一章绪论1.1单片机的发展单片机是单片微型计算机的简称,也就是把微处理器(CPU)、一定容量的程序存储器(ROM)和数据存储器(RAM)、输入/输出接口(I/O)、时钟及其他一些计算机外围电路,通过总线连接在一起并集成在一个芯片上构成的微型计算机系统。

1602显示温度+万年历

1602显示温度+万年历

程序功能:1602显示温度、时间(简称万年历)废话不多说,先上图希望大家多多捧场#include<reg51.h>#include<lcd1602.h>//#include<keyscan.h>#include<ds1302.h>#define uchar unsigned char#define uint unsigned intuchar init_time[]={21,50,30,11,12,31,6}; //23:59:30 11-12-31 6 uchar current_time[]={0,0,0,0,0,0,0};uchar num=0;sbit up=P1^1;sbit donw=P1^2;sbit set=P1^3;void read_current_time() //读取当前时间{current_time[2]=read_1302(0x81);current_time[1]=read_1302(0x83);current_time[0]=read_1302(0x85);current_time[3]=read_1302(0x8d);current_time[4]=read_1302(0x89);current_time[5]=read_1302(0x87);}void write_hour_min_sec(uchar add,uchar date) //时分秒{uchar s,g;s=date/16;g=date%16;lcd_wcom(0x80+0x40+add);lcd_wdat(0x30+s);lcd_wdat(0x30+g);}void write_yea_mon_dat(uchar add,uchar date) //年月日{uchar s,g;s=date/16;g=date%16;lcd_wcom(0x80+add);lcd_wdat(0x30+s);lcd_wdat(0x30+g);}void dis_dat_1602() //显示{lcd_wcom(0x80);lcd_wdat('2');lcd_wdat('0');write_yea_mon_dat(2,current_time[3]);lcd_wdat('-');write_yea_mon_dat(5,current_time[4]);lcd_wdat('-');write_yea_mon_dat(8,current_time[5]);lcd_wcom(0x80+11);lcd_wdat('W');lcd_wdat('e');lcd_wdat('e');lcd_wdat('k');write_hour_min_sec(0,current_time[0]);lcd_wdat(':');write_hour_min_sec(3,current_time[1]);lcd_wdat(':');write_hour_min_sec(6,current_time[2]);}void delay(uint z) //延时函数{uint x,y;for(x = z;x>0;x--)for(y = 124;y>0;y--);}void keyscan(){if(set==0) //判断按键是否按下{delay(5); //消除抖动if(set==0){num++;if(num==7){num=0;current_time[2]=0;write_1302(0x8e,0x00);write_1302(0x80,current_time[2]);write_1302(0x8e,0x80);}}if(up==0){delay(5);if(up==0){while(!up); //一直检测,直到up=1if(num==1){// lcd_wcom(0x80+0x44);// lcd_wcom(0x0e); //光标闪烁// lcd_wdat(current_time[1]);current_time[1]=read_1302(0x83);current_time[1]++;if(current_time[1]&0x0f>9)current_time[1]=current_time[1]+6;if(current_time[1]>=60)current_time[1]=0x00;write_1302(0x8e,0x80);write_1302(0x82,current_time[1]);write_1302(0x8e,0x80);}}}}}void main(){uchar i,d;TMOD=0x01;TH0=0xfc;TL0=0x18;EA=1;ET0=1;TR0=1;for(i=0;i<7;i++) //十进制转BCD码{d=init_time[i]/10;init_time[i]=init_time[i]%10;init_time[i]=init_time[i]+d*16;}write_1302(0x8e,0x00);write_1302(0x80,init_time[2]);write_1302(0x82,init_time[1]);write_1302(0x84,init_time[0]);write_1302(0x86,init_time[5]);write_1302(0x88,init_time[4]);write_1302(0x8a,init_time[6]);write_1302(0x8c,init_time[3]);write_1302(0x8e,0x80);lcd_init();while(1){dis_dat_1602();read_current_time();}}void timer0() interrupt 1{TH0=0xfc;TL0=0x18;keyscan();}#ifndef __lcd1602_H__#define __lcd1602_H__#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit rs=P2^6;sbit rw=P2^5;sbit en=P2^7;void delayled(int n){int x,y;for(x=n;x>0;x--){for(y=110;y>0;y--);}}void lcd_wcom(uchar com){rs=0;rw=0;P0=com;delayled(5);en=1;en=0;}void lcd_wdat(uchar dat){rs=1;rw=0;P0=dat;delayled(5);en=1;en=0;}void lcd_init(){lcd_wcom(0x38);lcd_wcom(0x0c);lcd_wcom(0x06);lcd_wcom(0x01);}#endif#ifndef __ds1302_H__#define __ds1302_H__#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit rst=P3^5;sbit sclk=P3^6;sbit io=P3^4;//写入一个字节到DS1302void write_byte_1302(uchar temp){uchar i;for(i=0;i<8;i++){sclk=0;io=temp&0x01;temp>>=1;sclk=1;}}//写入到DS1302void write_1302(uchar address,uchar dat) {rst=0;sclk=0;rst=1;write_byte_1302(address);write_byte_1302(dat);rst=0;sclk=0;sclk=1;io=1;}//读出ds1302数据uchar read_1302(uchar address){uchar i,temp;rst=0;sclk=0;rst=1;write_byte_1302(address);for(i=0;i<8;i++){sclk=0;temp>>=1;if(io==1)temp|=0x80;sclk=1;}rst=0;sclk=0;sclk=1;io=0;io=1;return temp;}#endif#ifndef __keyscan_H__#define __keyscan_H__#include<reg51.h>#include<ds1302.h>#include<lcd1602.h>#define uchar unsigned char#define uint unsigned intuchar current_time[]={0,0,0,0,0,0,0};void delay(uint z) //延时函数{uint x,y;for(x = z;x>0;x--)for(y = 124;y>0;y--);}void keyscan(){uchar num;if(set==0) //判断按键是否按下{delay(5); //消除抖动if(set==0){num++;if(num==7){num==0;current_time[2]=0;write_1302(0x8e,0x00);write_1302(0x80,current_time[2]);write_1302(0x8e,0x80);}}if(up==0){delay(5);if(up==0){while(!up); //一直检测,直到up=1if(num==1){lcd_wcom(0x80+0x44);lcd_wcom(0x0e); //光标闪烁lcd_wdat(current_time[1]);current_time[1]=read_1302(0x83);current_time[1]++;if(current_time[1]&0x0f>9)current_time[1]=current_time[1]+6;if(current_time[1]>=60)current_time[1]=0x00;write_1302(0x8e,0x80);write_1302(0x82,current_time[1]);write_1302(0x8e,0x80);}}}}}#endif。

简析基于DS1302和LCD1602的万年历系统设计论文

简析基于DS1302和LCD1602的万年历系统设计论文

简析基于DS1302和LCD1602的万年历系统设计论文简析基于DS1302和LCD1602的万年历系统设计论文0引言在日常生活中,无论哪一行业,哪一领域,时间授时都是不可或缺的。

从古老的钟表到现代的电子设备都提供时间授时的功能。

因此,对于单片机学习者来说,设计并实现一款低成本的,有操作性的,提供年,月,日,小时,分,秒,星期等基本计时功能的万年历系统,显得特别实用,特别有意义。

1总体设计及原理图万年历的基本功能一是要提供年月日等基本时间项的授时;二是可以修改时间项。

基于以上两个功能,我们万年历总体设计方案。

万年历有时钟计时模块,显示模块,调整时钟模块和控制器4部分组成。

接下来的任务就是对以上模块进行选型。

低成本,可操作是选型的标准。

对于控制器,选择最常用的C51系列单片机STC89C52。

STC89C52是由宏品科技生产的是一种低功耗8位基于经典C51内核的微处理器,具有8 KhyteFLASH存储器,512 byte RAM , 4 KByte EEPROM , 32位通用IO接口,可以直接用串口下载程序。

时钟模块选择由dallas公司生产的时钟芯片DS1302,DS1302是一款支持年月日,小时分秒,星期,闰年补偿的实时时钟芯片;其简单三线结构可以很方便地与单片机通用IO相连,进行串行总线读写传输。

显示模块选择16x2的字符点阵模块LCD 16020LC D 1602的控制器以Hitachi公司生产的HD44780芯片最为常见。

LC D 1602引脚主要包括3类,第1类是电源。

第2类是8位数据I/0通道,用于读写LC D 1602。

第3类是3根控制线,RS,R/W和E,其中,RS和R/W是用于实现LCD不同操作的。

E是作为读写的启动信号,有点类似一个时钟信号,数据要写人LC D 1602或从LCD 1602读出数据均需要首先置E信号为高至少1 s,然后置低。

调整时钟模块设计了4个轻触开关,用于设定和修改时间项。

DSHELCD实现万年历和温度显示(不用时间芯片)

DSHELCD实现万年历和温度显示(不用时间芯片)

#include<reg52.h>#include<intrins.h>#include <math.h>#define uchar unsigned char#define uint unsigned intuchar code table[]="--Figo"。

//uchar code table1[]=""。

sbit lcden=P3^4。

sbit lcdrs=P3^5。

sbit dula=P2^6。

sbit wela=P2^7。

sbit ds=P1^7。

sbit key1=P1^0。

sbit key2=P1^1。

sbit key3=P1^2。

sbit key4=P1^3。

int tempValue。

int s_1=1000。

unsigned char FunKeyFlag=6,keypress。

#define key_vaule1 0x01#define key_vaule2 0x02#define key_vaule3 0x03#define key_vaule4 0x04uchar num。

int ms_10=10。

int flag=0。

int s_1_1=1000。

uint sec=55。

uint min=9。

uint hour=22。

uint nian=2014。

uint yue=8。

uint ri=20。

uint xingqi=3。

//延时函数, 对于11.0592MHz时钟, 例i=10,则大概延时10ms. void delay_wendu(unsigned int i){unsigned int j。

while(i--){for(j = 0。

j < 125。

j++)。

}}//初始化DS18B20//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动void dsInit(){//对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于?usunsigned int i。

LCD1602液晶显示带汉字的万年历程序51单片机

LCD1602液晶显示带汉字的万年历程序51单片机

LCD1602液晶显示带汉字的万年历程序(51单片机)#include &quot;reg51.h&quot;#define uint unsigned int#define uchar unsigned char#define port P0uchar table[]=&quot;I love you!&quot;; uchar table1[]=&quot;Shang Hong Rui!&quot;;uchar table2[]=&quot;LI ZHEN WEI!&quot; ;uchar table3[]=&quot;>; >; >; >; >; >; >; >; &quot;; uchar num;sbit rs=P2^0;sbit rw=P2^1;sbit e=P2^2;/********************************************1ms 为基本单位的延时函数********************************************/ void delay(uint z){uint x,y;for(x=z;x>;0;x--)for(y=110;y>;0;y--);}/******************************************** 读取lcd1602状态********************************************/ read(){uchar temp ;port=0xff;rs=0;rw=1;e=1;temp=port;e=0;return temp;}/******************************************** 检测lcd是否忙碌小卒整天没事********************************************/ void busy(){uchar temp;do{temp=read();}while((temp&0x80)==0x80);}/********************************************向 lcd 里写命令********************************************/ void write_com(uchar com){busy();//delay(2);port=com;//busy();rs=0;rw=0;e=1;e=0;}/******************************************** 向 lcd 里写数据********************************************/ void write_data(uchar dat){busy();//delay(2);port=dat;//busy();rs=1;rw=0;e=1;e=0;}/******************************************** 初始化lcd********************************************/ void init(){write_com(0x06) ;//显示地址递增,即写一个数据后,显示位置右移一位write_com(0x0e) ;//开显示,有光标,光标不闪write_com(0x38) ;//8位数据,双列,5*7字形write_com(0x01) ;//清屏}/********************************************** 主程序实现显示***********************************************/ main(){init();write_com(0x80+0x02);for(num=0;num; 0xff*****0** /5*80x40*****0**0x40 ---->; I*****0**0x40 ---->;*****0**0x40*****0**0x40***000000x1f添加自己的自定义字符***********************************/code uchar ziku[]={0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00, //汉字&ldquo;日&rdquo;0x0F,0x09,0x0F,0x09,0x0F,0x09,0x11,0x00, //汉字&ldquo;月&rdquo;0x01,0x02,0x03,0x05,0x09,0x03,0x00,0x00, //汉字&ldquo;年&rdquo;左半部0x00,0x00,0x1e,0x08,0x08,0x1e,0x08,0x08 //汉字&ldquo;年&rdquo;右半部};/*******************************读取lcd1602状态*******************************/uchar lcd_readcom(){uchar temp;e=0;port=0xff;rs=0;rw=1;e=1;temp=port;e=0;return temp;}/***************************************检测 lcd 是否忙碌小卒整天没事***************************************/ check_busy(){uchar temp;do{temp=lcd_readcom();}while((temp&0x80)==0x80);}/*****************************************向lcd里写命令*****************************************/ void lcd_writecom(uchar dat){check_busy();e=0;port=dat;rs=0;rw=0;e=1;e=0;}/*************************************** 读取lcd对应地址数据*****************************************/ uchar lcd_readdat(){uchar temp;check_busy();e=0;port=0xff;rs=1;rw=1;e=1;temp=port;e=0;return temp;}/**************************************** 向lcd里写数据****************************************/ void lcd_writedat(uchar dat){check_busy();e=0;port=dat;rs=1;rw=0;e=1;e=0;}/****************************************向lcd写字符串*****************************************/ void lcd_gets(char *dat){while(*dat!=0){lcd_writedat(*dat);dat++;}}/*****************************************确定要写的位子即x y 坐标******************************************/void lcd_xy(uchar x,uchar y){switch(y){case 0:lcd_writecom(0x80+x);break;//第一行第X个位置case1:lcd_writecom(0xc0+x);break;//0xc0==0x80+0x50 第二行第X个位置case 2:lcd_writecom(0x94+x);break;//case 3:lcd_writecom(0xd4+x);break;//4*20}}/************************************************ ****单行显示才有5*10 其他5*8 MODE=1 5*8 MODE=0 5*10 ****************************************************/add_custom_word(uchar *dat,uchar len,uchar mode) {uchar n,m;for(n=0;n;0;x--)for(y=110;y>;0;y--)for(a=1;a>;0;a--) ;}/********************************************** 主程序实现显示***********************************************/ main(){lcd_init();//lcd_xy(0,0);//lcd_gets(&quot; I LOVE YOU&quot;);//lcd_xy(0,1);//lcd_gets(&quot;Shang Hong Rui&quot;);lcd_xy(2,0) ;lcd_gets(&quot;2011&quot;);lcd_xy(6,0) ;lcd_writedat(2);lcd_writedat(3);lcd_xy(8,0) ;lcd_gets(&quot;03&quot;); lcd_xy(10,0);lcd_writedat(1);lcd_xy(11,0) ;lcd_gets(&quot;06&quot;); lcd_xy(13,0);lcd_writedat(0);lcd_xy(3,1) ;lcd_gets(&quot;0&quot;); lcd_xy(4,1) ;lcd_gets(&quot;0&quot;); lcd_xy(5,1) ;lcd_gets(&quot;:&quot;); lcd_xy(6,1) ;lcd_gets(&quot;0&quot;); lcd_xy(7,1) ;lcd_gets(&quot;0&quot;); lcd_xy(8,1) ;lcd_gets(&quot;:&quot;);lcd_gets(&quot;0&quot;);lcd_xy(10,1) ;lcd_gets(&quot;0&quot;);while(1){//for(m=0;m<10;m++)lcd_xy(10,1);lcd_writedat(table[miaog]);//秒个位delay(1000);miaog++;if(miaog==10){miaog=0;lcd_xy(9,1);lcd_writedat(table[miaos]); //秒十位miaos++;if(miaos==6){miaos=0;lcd_xy(7,1);lcd_writedat(table[feng]); //分个位 feng++;if(feng==10){feng=0;lcd_xy(6,1);lcd_writedat(table[fens]); //分十位 fens++;if(fens==6){fens=0;lcd_xy(4,1);lcd_writedat(table[shig]); //时个位 shig++;if(shig==10){shig=0;lcd_xy(3,1);lcd_writedat(table[shis]);//时十位shis++;if(shis==6){shis=0;}}}}}}}//lcd_xy(0,0);//lcd_writedat(0);//自定义字符使用,0表示第一个字,1表示第二个字,依此类推//lcd_xy(15,0);//lcd_writedat(3); //自定义字符使用}第二段程序为借用别人的,呵呵。

DS18B20温度计 c程序 lcd1602显示

DS18B20温度计 c程序 lcd1602显示

2007-12-14 19:05温度值精确到0.1度,lcd1602显示仿真电路图如下c程序如下:#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit DQ=P3^7;//ds18b20与单片机连接口sbit RS=P3^0;sbit RW=P3^1;sbit EN=P3^2;unsigned char code str1[]={"temperature: "};unsigned char code str2[]={" "};uchar data disdata[5];uint tvalue;//温度值uchar tflag;//温度正负标志/*************************lcd1602程序**************************/ void delay1ms(unsigned int ms)//延时1毫秒(不够精确的){unsigned int i,j;for(i=0;i<ms;i++)for(j=0;j<100;j++);}void wr_com(unsigned char com)//写指令//{ delay1ms(1);RS=0;RW=0;EN=0;P2=com;delay1ms(1);EN=1;delay1ms(1);EN=0;}void wr_dat(unsigned char dat)//写数据//{ delay1ms(1);;RS=1;RW=0;EN=0;P2=dat;delay1ms(1);EN=1;delay1ms(1);EN=0;}void lcd_init()//初始化设置//{delay1ms(15);wr_com(0x38);delay1ms(5);wr_com(0x08);delay1ms(5);wr_com(0x01);delay1ms(5);wr_com(0x06);delay1ms(5);wr_com(0x0c);delay1ms(5);}void display(unsigned char *p)//显示//{while(*p!='\0'){wr_dat(*p);p++;delay1ms(1);}}init_play()//初始化显示{ lcd_init();wr_com(0x80);display(str1);wr_com(0xc0);display(str2);}/******************************ds1820程序***************************************/ void delay_18B20(unsigned int i)//延时1微秒{while(i--);}void ds1820rst()/*ds1820复位*/{ unsigned char x=0;DQ = 1; //DQ复位delay_18B20(4); //延时DQ = 0; //DQ拉低delay_18B20(100); //精确延时大于480usDQ = 1; //拉高delay_18B20(40);}uchar ds1820rd()/*读数据*/{ unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){ DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80;delay_18B20(10);}return(dat);}void ds1820wr(uchar wdata)/*写数据*/{unsigned char i=0;for (i=8; i>0; i--){ DQ = 0;DQ = wdata&0x01;delay_18B20(10);DQ = 1;wdata>>=1;}}read_temp()/*读取温度值并转换*/{uchar a,b;ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0x44);//*启动温度转换*/ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0xbe);//*读取温度*/a=ds1820rd();b=ds1820rd();tvalue=b;tvalue<<=8;tvalue=tvalue|a;if(tvalue<0x0fff)tflag=0;else{tvalue=~tvalue+1;tflag=1;}tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数return(tvalue);}/*******************************************************************/ void ds1820disp()//温度值显示{ uchar flagdat;disdata[0]=tvalue/1000+0x30;//百位数disdata[1]=tvalue%1000/100+0x30;//十位数disdata[2]=tvalue%100/10+0x30;//个位数disdata[3]=tvalue%10+0x30;//小数位if(tflag==0)flagdat=0x20;//正温度不显示符号elseflagdat=0x2d;//负温度显示负号:-if(disdata[0]==0x30){disdata[0]=0x20;//如果百位为0,不显示if(disdata[1]==0x30){disdata[1]=0x20;//如果百位为0,十位为0也不显示}}wr_com(0xc0);wr_dat(flagdat);//显示符号位wr_com(0xc1);wr_dat(disdata[0]);//显示百位wr_com(0xc2);wr_dat(disdata[1]);//显示十位wr_com(0xc3);wr_dat(disdata[2]);//显示个位wr_com(0xc4);wr_dat(0x2e);//显示小数点wr_com(0xc5);wr_dat(disdata[3]);//显示小数位}/********************主程序***********************************/void main(){ init_play();//初始化显示while(1){read_temp();//读取温度ds1820disp();//显示}}。

DS18B20与LCD1602结合显示温度汇总(可编辑修改word版)

DS18B20与LCD1602结合显示温度汇总(可编辑修改word版)
其他字节保留用,不需要看。 三、关于单总线系统
单总线系统包括一个总线控制器和一个或多个从机。DS18B20 总是充当从机。当只有 一只从机挂在总线上时,系统被称为“单点”系统;如果由多只从机挂在总线上,系统被 称为“多点”。 所有的数据和指令的传递都是从最低有效位开始通过单总线。单总线需要 一个约 5KΩ 的外部上拉电阻;单总线的空闲状态是高电平。无论任何理由需要暂停某一 执行过程时,如果还想恢复执行的话,总线必须停留在空闲状态。在恢复期间,如果单总 线处于非活动(高电平)状态,位与位间的恢复时间可以无限长。如果总线停留在低电平 超过 480us,总线上的所有器件都将被复位。 四、操作流程 1.DS18B20 复位。 2.执行 ROM 指令。就是访问,搜索,匹配每个 DS18B20 独有的 64 位序列号。实验板上只 连有一个 DS18B20,故不需识别,也就是不需读出此序列号,写代码时直接写命令 0xcc 跳过。 3.执行 DS18B20 功能指令(RAM 指令,就是读写暂存器指令)。
一个身份证号),这是出厂时被光刻好的。最前面 8 位是单线系列编码:28h。接着的 48 位
是一个唯一的序列号。最后 8 位是以上 56 位的 CRC 编码。64-位的光刻 ROM 又包括 5 个
ROM 的功能命令:读 ROM,匹配 ROM,跳跃 ROM,查找 ROM 和报警查找。ROM 的作
用是使每个 DS18B20 各不相同,这样就8B20 一、DS18B20 的外形及其与单片机的连接图
(a)
(b)
图1
DS18B20 是 Dallas 公司生产的 1-Wire 接口数字温度传感器,其外形如图 1(a)所示,有
三个引脚,分别为:电源地 1(GND); 数字信号输入/输出端 2(DQ);外接供电电源输入端

用DS1302与LCD1602设计可调数字万年历课程设计

用DS1302与LCD1602设计可调数字万年历课程设计

数字开发与实践课程设计题目:用DS1302与LCD1602设计可调式电子日历时钟班级:姓名:学号:学院:年月日用DS1302与LCD1602设计的可调式电子日历时钟一、总体设计1.1、设计目的为巩固所学的单片机知识,把所学理论运用到实践中,用LCD1602与DS1302 设计可调式电子日历时钟。

1.2、设计要求(1)显示:年、月、日、时、分、秒和星期;(2)设置年、月、日、时、分、秒和星期的初始状态;(3)能够用4个按键调整日历时钟的年、月、日、时、分、秒和星期;完成可调式电子日历时钟的硬件和软件的设计,包括单片机的相关内容;日历时钟模块的设计,液晶显示模块的设计,按键模块的设计。

控制程序的编写等。

备注:本程序另外添加了每到上午8:10和下午2:10的闹钟提醒功能。

1.3、系统基本方案选择和论证1.3.1、单片机芯片的选择方案方案一:采用89C51芯片作为硬件核心,采用Flash ROM,内部具有4KB ROM 存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容。

方案二:采用STC12C5A60S2系列单片机是宏晶科技生产的单时钟/机器周期(1T)的单片机,是高速/低功耗/超强抗干扰的新一代8051单片机,指令代码完全兼容传统8051,但速度快8-12倍。

内部集成MAX810专用复位电路,2路PWM,8路高速10位A/D转换(250K/S),针对电机控制,强干扰场合。

但造价较高。

1.3.2 、显示模块选择方案和论证:方案一:采用点阵式数码管显示,点阵式数码管是由八行八列的发光二极管组成,对于显示文字比较适合,如采用显示数字显得太浪费,且价格也相对较高。

所以不用此种作为显示。

方案二:采用LED数码管动态扫描,虽然LED数码管价格适中,但要显示多个数字所需要的个数偏多,功耗较大,显示出来的只是拼音,而不是汉字。

所以也不用此种作为显示。

方案三:采用LCD液晶显示屏,液晶显示屏的显示功能强大,可显示大量字符,且视觉效果较好,外形美观。

带温度显示的数字万年历设计

带温度显示的数字万年历设计
1.2万年历的使用现状及设计目的
如今万年历已经在人们生活中广泛的使用,它不仅是记录日期和时间的工具,而且 也成为了一种装饰品。现在的万年历可以说是多种多样,外观精美。放在家里既可以计 时也可作为风景壁画,因此越来越受到大众消费者的喜爱。
本次课程设计通过利用STC89C52单片机和DS1302芯片以及外围的按键和LCD显示器 等部件,设计一个基于单片机的电子时钟。设计的电子时钟通过液晶显示器显示,并能 通过按键对时间以及闹钟进行设置。目的来模拟真实产品中万年历的工作原理,具有很 强的实用性。
2.2方案选择和论证 2.2.1、显示模块选择方案和论证
方案一:
采用点阵式数码管显示。点阵式数码管是由八行八列的发光二极管组成,对于显示文字 比较适合,如采用在显示数字显得太浪费,且难度也相对较高,所以不用此种作为显示。 方案二:
采用LED数码管动态扫描。LED数码管价格便宜,对于显示数字最合适,但功耗较大, 且显示容量不够,所以也不用此种方案。 方案三:
1
方案二:
采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、 时、日、周、月、年以及闰年补偿的年进行计数,而且精度高,工作电压2.5V~5.5V范围 内,2.5V时耗电小于300nA.
2.2.4温度Leabharlann 集模块方案选择(宋体四号,加粗)DS18B20数字温度传感器接线方便,独特的单线接口方式,DS18B20在与微处理器连接时 仅需要一条口线即可实现微处理器与DS18B20的双向通讯。封装后的DS18B20可用于电缆 沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测 温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭 小空间设备数字测温和控制领域。因此DS18B20完全满足设计要求。

单片机的LCM1602液晶显示温度与万年历显控制

单片机的LCM1602液晶显示温度与万年历显控制

毕业设计报告(论文)报告(论文)题目:基于单片机的LCM1602液晶控制——温度与万年历显示设计作者所在系部:电子工程系作者所在专业:作者所在班级:作者姓名:作者学号:指导教师姓名:完成时间: 2011年 6 月 9 日院教务处制电子工程系毕业设计(论文)任务书指导教师:教研室主任:系主任:摘要论文的研究工作是以液晶屏显示技术为背景展开的,并且详细介绍了通过MCS-51单片机控制LCM1602液晶的显示情况,以软件形式对系统进行控制,使得系统控制更具灵活与方便。

本文在深入分析LCD显示技术的基础上,重点解析了LCM显示的单片机控制技术,以及LCD显示在各种电子显示中的优势,同时阐述了其在日常显示系统中的应用;并且以Proteus与Keil uVision4软件为基础,编写了MCS-51单片机对LCM1602显示控制的软件,绘制其原理图,并使用Proteus软件与Keil uVision4软件建立联合仿真。

论文主要论述了原理图各个模块的作用,控制软件的各个模块的编程。

关键词液晶显示技术LCM1602 MCS-51单片机Proteus Keil uVision4目录第1章绪论 (1)1.1课题背景及主要技术国内外研究概况 (1)1.2LCM1602显示控制系统简介 (2)1.3课题的建立以及本文完成的主要工作 (3)第2章开发工具软件简介 (4)2.1K EIL U V ISION4软件简介 (4)2.2P ROTEUS软件简介 (4)2.3K EIL U V ISION4与P ROTEUS软件联合仿真 (5)2.4小结 (5)第3章 LCD显示控制技术 (6)3.1LCD显示技术的发展 (6)3.2LCM1602显示控制技术及其体系结构 (7)3.2.1 LCM1602模块简介 (8)3.2.2 LCM1602模块内部结构 (9)3.2.3 LCM1602控制指令 (10)3.3小结 (12)第4章系统硬件概况 (13)4.1系统概况 (13)4.2功能模块 (13)4.2.1 MCS-51单片机最小系统模块 (14)4.2.2 温度采集模块 (14)4.2.3 蜂鸣器报警模块 (15)4.2.4 万年历调节设置模块 (16)4.2.5 LCM1602显示模块 (16)4.2.6 电源模块 (17)3.3小结 (17)第5章软件控制系统概况 (18)5.1程序流程概况 (18)5.2万年历显示控制模块 (18)5.2.1 流程图 (18)5.2.2 源程序代码 (19)5.3温度显示控制模块 (19)5.3.1 程序流程 (19)5.3.2 源程序代码 (19)5.3.3 主程序 (19)5.4小结 (20)第6章课题特点 (21)6.1LCM模块的应用 (21)6.2程序结构化与模块化设计 (21)6.3抗干扰技术 (21)第7章结论 (23)7.1调试联合仿真 (23)7.2仿真结果 (23)7.3小结 (23)致谢 (24)参考文献 (25)附录 (26)基于单片机的LCM1602液晶控制——温度与万年历显示设计第1章绪论1.1 课题背景及主要技术国内外研究概况自20世纪80年代起,显示设备经历着传统工艺的改良、新工艺的发展、成熟的优胜劣汰。

51单片机的18B20、1302和LCM1602液晶显示温度与万年历显控制

51单片机的18B20、1302和LCM1602液晶显示温度与万年历显控制

摘要本设计以数字集成电路技术为基础,单片机技术为核心。

软件设计采用模块化结构,C语言编程。

系统通过LCD显示数据,可以显示日期(年、月、日、时、分、秒)以及温度。

在内容安排上首先描述系统硬件工作原理,着重介绍了各硬件接口技术和各个接口模块的功能;其次,详细的阐述了程序的各个模块和实现过程。

前言电子时钟是实现对年,月,日,时,分,秒数字显示的计时装置,广泛用于个人家庭,车站,码头,办公室,银行大厅等场所,成为人们日常生活中的必需品。

数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度远远超过老式钟表。

钟表的数字化给人们生产生活带来了极大的方便,在此基础上完成的电子时钟精度高,功能易于扩展。

可扩展成为诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、定时开关烘箱、通断动力设备、甚至各种定时电气的自动启用等电路。

所有这些,都是以钟表数字化为基础的。

因此,研究数字时钟及扩大其应用有着非常现实的意义。

本设计就是数字时钟简单的扩展应用。

1.1设计目标:利用单片机技术,以及模拟电子技术和数字电子技术的理论知识,设计实现MCS-51单片机对LCM1602液晶输出显示控制的这一基本要求。

1.2设计要求:本设计利用DS1302;DS18B20;LCD1602实现以下功能:(1) 显示日期功能(年、月、日、时、分、秒以及星期)(2) 可通过按键切换年、月、日及时、分、秒的显示状态(3) 可随时调校年、月、日或时、分、秒(4) 可每次增减一进行时间调节(5) 可动态完整显示年份,实现真正的万年历显示(6) 可显示温度2 设计方案2.1 控制器硬件控制电路主要用了AT89C52芯片处理器、LCD显示器等。

根据各自芯片的功能互相连接成电子万年历的控制电路。

软件控制程序主要有主控程序、电子万年历的时间控制程序、时间显示及星期显示和温度采集程序等组成。

主控程序中对整个程序进行控制,进行了初始化程序及计数器、还有键盘功能程序、以及显示程序等工作,时间控制程序是电子万年历中比较重要的部分。

利用LCD1602显示的数字温度计毕业设计

利用LCD1602显示的数字温度计毕业设计

(单片机原理及接口技术)利用LCD1602显示的数字温度计一.课程设计的目的1.进一步熟悉和掌握单片机的结构及工作原理。

2.掌握单片机的接口技术及相关外围芯片的外特性,控制方法。

3.通过课程设计,掌握以单片机核心的电路设计的基本方法和技术。

4.通过实际程序设计和调试,逐步掌握模块化程序设计方法和调试技术。

5.通过完成一个包括电路设计和程序开发的完整过程,了解开发一单片机应用系统的全过程,为今后从事相应开发打下基础。

二.课程设计的基本要求1.认真认识设计的意义,掌握设计工作程序,学会使用工具书和技术参考资料,并培养科学的设计思想和良好的设计作风。

2.提高模型建立和设计能力,学会应用相关设计资料进行设计计算的方法。

3.提高独立分析、解决问题的能力,逐步增强实际应用训练。

4.课程设计的说明书要求简洁、通顺,计算正确,图纸表达内容完整、清楚、规范。

5.课程设计说明书封面格式要求见《天津城市建设学院课程设计教学工作规范》附表1。

三.课程设计具体要求a) 要求每位同学独立完成设计任务。

b) 原理图设计1.原理图设计要符合项目的工作原理,连线要正确。

2.图中所使用的元器件要合理选用,电阻、电容等器件的参数要正确标明。

3.原理图要完整,CPU、外围器件、外扩接口、输入/输出装置要一应俱全。

c) 程序调计1.根据要求,将总体功能分解成若干个子功能模块,每个功能模块完成一个特定的功能。

2.根据总体要求及分解的功能模块,确定各功能模块之间的关系,设计出完整的程序流程图。

d) 程序调试1.编写相关程序,并进行仿真。

2.将程序下载到单片机,进行运行调试。

e) 设计说明书1.原理图设计说明简要说明设计目的,原理图中所使用的元器件功能及在图中的作用,各器件的工作过程及顺序。

2.程序设计说明对程序设计总体功能及结构进行说明,对各子模块的功能以及各子模块之间的关系作较详细的描述。

3.画出工作原理图,程序流程图并给出相应的程序清单。

单片机万年历汇编闹钟时间可调程序(LCD1602,DS18B20,DS1302,MAX810L)

单片机万年历汇编闹钟时间可调程序(LCD1602,DS18B20,DS1302,MAX810L)

片机万年历汇编闹钟时间可调程序(LCD1602,DS18B20,DS1302,MAX810L)说明:0该程序全部是用汇编语言编写1.该程序附带有温度显示,并且带有闹铃功能2.正常时间和闹钟时间都可以用键盘设置3.该程序是使用LCD1602显示年月日,格式为TIME XX-XX-XX XX,由于屏幕的关系,所以就不显示周的数据,其中闹铃调整的上界面是“BELLADJUST”4.该程序的时间是由时钟芯片DS1302提供的,据说很精准,目前看起来确实是这样的,刚开始我是使用定时器计时的,但是不怎么精准,可能是我的汇编技术有限才导致,所以本人就把这个版本呈上,希望诸位多多斧正5.该程序的温度是通过DS18B20提取的,这个模块是我从别人那里COPY过来的,O(∩_∩)O~,显示是肯定没问题的6.该程序也有用MAX810l的复位功能,但是好像这一点还没被体现出来7.烧程序我使用的是MAX232外加几个极性电容,还有一个RS232,不幸的是我的PCB板的RS232的封装画错啦!!~~~~(>_<)~~~~8.该万年历是由五个按键控制的,SW5复位,SW1调时间,调年月日时分秒,除秒可以加减调节之外其余的调节都是只能加不能减(自我觉得如果增加减的功能会觉得程序复杂,所以免!), SW4 是用来调节闹钟的时分秒的,和SW1按键不同的是时分秒都能加减,当闹钟设置的时间和正常显示时间的时分秒相同时,闹铃十秒钟,期间你可以按SW4键终止响铃,SW2 和SW3 分别是用来加减时间的!9.说了这么多,最后说说自我认为的缺陷,行家应该都一眼就看出一些破绽了,那就是按键消抖的问题,这个我觉得有点麻烦所以本人就把这个问题留给阅览资料的你吧!10.废话说了这么多,最后把我的程序,ORCAD电路原理图,PADS软件的PCB图,以及一张实物图献上,希望你能喜欢,页脚有我的Email(prettyboy2009@),欢迎随时交流!程序:;*************************************************************** ;***************************************************************RS BIT P2.5RW BIT P2.6E BIT P2.7SU BIT P1.6 ;1302串行口数据端RST BIT P1.5CLK BIT P1.7ALARM BIT P2.3JIAN BIT P2.2 ;减JIA BIT P2.1 ;加MOSHI BIT P2.0 ;模式DQ BIT P1.0SOUND BIT P1.3NIAN EQU 7FHYUE EQU 7DHDAY EQU 7CHHHH EQU 7EHSHI EQU 7BHFEN EQU 7AHMIAO EQU 79HASHI EQU 78HAFEN EQU 77HAMIAO EQU 76HGEW EQU 75HA_BIT EQU 70H ;18B20B_BIT EQU 6FHFLAG EQU 6EHDS1302_ADDR EQU 6DHDS1302_DATA EQU 6CHORG 0000HLJMP STARTORG 0030H ;***************************************************************; 初始化开机时间 &&&&&&& 初始化闹铃时间;***************************************************************START:MOV DPTR,#TABMOV SHI,#16HMOV ASHI,#17MOV FEN,#58HMOV AFEN,#30MOV MIAO,#00HMOV AMIAO,#00MOV NIAN,#11HMOV YUE,#12HMOV DAY,#13HMOV HHH,#00H;***************************************************************; 初始化LCD1602 &&&&&&& 初始化DS1302 ;***************************************************************MOV P0,#01H ; 显示清屏数据指针清零所有显示清零LCALL WR_CODEMOV P0,#02H ; 显示回车数据指针清零LCALL WR_CODEMOV P0,#38H ;设置16*2显示 5*7 点阵 8位数据接口LCALL WR_CODEMOV P0,#06H ; 当写或写一个数据时地址指针自动加一光标自动加一LCALL WR_CODEMOV P0,#0cH ; 开显示不显光标 0fh开显示开光标光标闪烁LCALL WR_CODELCALL XIAN1;***************************************************************; 主函数(这个大家都懂的);*************************************************************** MAIN:lcall RD_DS1302LCALL XIANSHIlcall keyLCALL AKEYLCALL RE_TEMPLCALL CONVERLCALL DISPLAY_INTLJMP BELLRING;***************************************************************; 读1302子程序;***************************************************************RD_DS1302:MOV DS1302_ADDR,#8DH ;读DS1302中的年LCALL READ ;调用读DS1302子程序MOV NIAN, DS1302_DATA ;把读出的年数据存入年寄存器中MOV DS1302_ADDR,#89H ;读DS1302中的月LCALL READMOV YUE, DS1302_DATA ;把读出的月数据存入月寄存器中MOV DS1302_ADDR,#87H ;读DS1302中的天LCALL READMOV DAY, DS1302_DATA ;把读出的天数据存入天寄存器中MOV DS1302_ADDR,#85H ;读DS1302中的小时LCALL READMOV SHI, DS1302_DATA ;把读出的天数据存入小时寄存器中MOV FEN, DS1302_DATA ;把读出的天数据存入分钟寄存器中MOV DS1302_ADDR,#81H ;读DS1302中的秒钟LCALL READMOV MIAO, DS1302_DATA ;把读出的天数据存入秒钟寄存器中RET ;***************************************************************; 写1302子程序;***************************************************************WR_DS1302:MOV DS1302_ADDR, #8EH ;写DS1302控制指令MOV DS1302_DATA, #00H ;写数据到DS1302的8E控制寄存器中,允许对其进行写操作LCALL WRITE ;调用写DS1302子程序MOV DS1302_ADDR,#8CH ;写DS1302中的年MOV DS1302_DATA , NIAN ;把写出的年数据存入年寄存器中LCALL WRITEMOV DS1302_ADDR,#88H ;写DS1302中的月MOV DS1302_DATA ,YUE ;把写出的月数据存入月寄存器中LCALL WRITEMOV DS1302_ADDR,#86H ;写DS1302中的天MOV DS1302_DATA ,DAY ;把写出的天数据存入天寄存器中LCALL WRITEMOV DS1302_ADDR,#84H ;写DS1302中的小时MOV DS1302_DATA , SHI ;把写出的天数据存入小时寄存器中LCALL WRITEMOV DS1302_ADDR,#82H ;写DS1302中的分钟MOV DS1302_DATA , FEN ;把写出的天数据存入分钟寄存器中LCALL WRITEMOV DS1302_ADDR,#80H ;写DS1302中的秒钟MOV DS1302_DATA , MIAO ;把写出的天数据存入秒钟寄存器中LCALL WRITEMOV DS1302_ADDR, #90H ;写DS1302控制指令MOV DS1302_DATA,#0A6H ;写数据到DS1302的90控制寄存器中,对电池涓流充电,充电电流为1.1mARET;***************************************************************; 写1302程序;***************************************************************WRITE:CLR CLKNOPSETB RSTNOPMOV A,DS1302_ADDRMOV R4,#8 WRITE1:RRC A ;送地址给1302NOPNOPCLR CLKNOPNOPNOPMOV SU,CSETB CLK ;送入地址在时钟上升沿有效NOPNOPNOPNOPDJNZ R4,WRITE1CLR CLKNOPMOV A,DS1302_DATAMOV R4,#8 WRITE2:RRC ANOP ;送数据给1302,时钟上升沿,数据输入CLR CLKNOPNOPMOV SU,CNOPNOPNOPSETB CLKDJNZ R4,WRITE2CLR RSTCLR ARET ;***************************************************************; 读1302程序;***************************************************************READ:CLR CLKNOPNOPSETB RSTNOPMOV A,DS1302_ADDRMOV R4,#8 READ1:RRC ANOPMOV SU,CNOPNOPNOPSETB CLK ;送入地址在时钟上升沿有效NOPNOPNOPCLR CLKNOPNOPDJNZ R4,READ1 ;判断8位数据是否传送完?MOV R4,#8 READ2:CLR CLKNOPNOPNOPMOV C,SUNOPNOPNOPNOPNOP ;从ds1302中读取数据,时钟下降沿有效NOPNOPNOPSETB CLKNOPDJNZ R4,READ2 ;判断8位数据是否传送完?MOV DS1302_DATA,ACLR RSTRET;***************************************************************; 固定显示显示TIME ,'-',:;***************************************************************XIAN1:MOV P0,#84HLCALL WR_CODEMOV A,#'-' ;1602有字库可以直接调用不用查表LCALL WR_DATAMOV P0,#87HLCALL WR_CODEMOV A,#'-'LCALL WR_DATAMOV P0,#80HLCALL WR_CODEMOV A,#'2' ;计时100年所以20XX 20是固定的LCALL WR_DATAMOV P0,#81HLCALL WR_CODEMOV A,#'0'LCALL WR_DATAMOV P0,#0C1HLCALL WR_CODEMOV A,#'T'LCALL WR_DATAMOV P0,#0C2HLCALL WR_CODEMOV A,#'I'LCALL WR_DATAMOV P0,#0C3HLCALL WR_CODEMOV A,#'M'LCALL WR_DATAMOV P0,#0C4HLCALL WR_DATAMOV P0,#0CCHLCALL WR_CODEMOV A,#':'LCALL WR_DATAMOV P0,#0C9HLCALL WR_CODEMOV A,#':'LCALL WR_DATAMOV P0,#08EHLCALL WR_CODEMOV A,#0DFHLCALL WR_DATAMOV P0,#08FHLCALL WR_CODEMOV A,#'C'LCALL WR_DATARET;*************************************************************** ; 显示数据时分秒年月日周地址数据都在变化没用循环体;***************************************************************XIANSHI:MOV HHH,MIAOLCALL HEXMOV P0,#0CDHLCALL WR_CODEMOVC A,@A+DPTRLCALL WR_DATAMOV A,BMOV P0,#0CEHLCALL WR_CODEMOVC A,@A+DPTRLCALL WR_DATAMOV HHH,FENLCALL HEXMOV P0,#0CAHLCALL WR_CODEMOVC A,@A+DPTRLCALL WR_DATALCALL WR_CODE MOVC A,@A+DPTR LCALL WR_DATAMOV HHH,SHI LCALL HEXMOV P0,#0C7H LCALL WR_CODE MOVC A,@A+DPTR LCALL WR_DATA MOV A,BMOV P0,#0C8H LCALL WR_CODE MOVC A,@A+DPTR LCALL WR_DATAMOV HHH,DAY LCALL HEXMOV P0,#088H LCALL WR_CODE MOVC A,@A+DPTR LCALL WR_DATA MOV A,BMOV P0,#089H LCALL WR_CODE MOVC A,@A+DPTR LCALL WR_DATAMOV HHH,YUE LCALL HEXMOV P0,#085H LCALL WR_CODE MOVC A,@A+DPTR LCALL WR_DATA MOV A,BMOV P0,#086H LCALL WR_CODE MOVC A,@A+DPTR LCALL WR_DATAMOV HHH,NIAN LCALL HEXMOV P0,#082HMOVC A,@A+DPTRLCALL WR_DATAMOV A,BMOV P0,#083HLCALL WR_CODEMOVC A,@A+DPTRLCALL WR_DATARET;***************************************************************; 判键子程按一次模式键后就一直判断下一次按键是P2.1还是P2.2;判断进入下一模式还是加1(按下模式键第一次加1需要按两次);MO1加分 MO2加时 MO3加月 MO4加日 MO5加年,除秒可以加减调节外,;时间只能通过加分时日月年调节;***************************************************************KEY:JNB MOSHI,MORET MO:JNB MOSHI,$MOV P0,#0DH ; 开显示不显光标 0fh开显示开光标光标闪烁LCALL WR_CODE MO1:MOV P0,#0CBHLCALL WR_CODEJNB JIA,JIAFFJNB JIAN,JIANFFJNB MOSHI,MO11LJMP MO1 MO11:JNB MOSHI,$;MO2:MOV P0,#0C8HLCALL WR_CODEJNB JIA,JIASSJNB MOSHI,MO21LJMP MO2 MO21:JNB MOSHI,$; ;MO4:MOV P0,#089HLCALL WR_CODELJMP MO4 MO41:JNB MOSHI,$MO3:MOV P0,#086HLCALL WR_CODEJNB JIA,JIAMMJNB MOSHI,MO31LJMP MO3 MO31:JNB moshi,$;MO5:MOV P0,#083HLCALL WR_CODEJNB JIA,JIAYYJNB MOSHI,MO51LJMP MO5 MO51:JNB MOSHI,$MOV P0,#0CH ; 开显示不显光标 0fh开显示开光标光标闪烁LCALL WR_CODElcall XIAN1RET;***************************************************************; 跳转出范围中转;***************************************************************JIAFF:LJMP JIAFJIANFF:LJMP JIANFJIADD:LJMP JIADJIAMM:LJMP JIAMJIAYY:LJMP JIAYJIASS:LJMP JIAS;***************************************************************;判断加1 以及跳转到另一模式(模式是指加分还是加时加月等);***************************************************************JIAF:MOV P0,#0CBHLCALL WR_CODEJNB JIAN,JIANFJB JIA,JIAF2JNB JIA,$mov A,FENADD A , #01HDA Amov FEN,ACJNE A , #60H ,JIAF3MOV FEN ,#00H JIAF3:LCALL WR_DS1302LCALL XIANSHILJMP JIAF JIAF1:JNB MOSHI,$LJMP MO11JIANF:MOV P0,#0CBHLCALL WR_CODEJNB MOSHI,JIANF1JNB JIA,JIAFJB JIAN,JIANFJNB JIAN,$MOV A,FENCJNE A,#00,JIANF2MOV FEN,#59HLJMP JIANF3 JIANF2:CLR CSUBB A,#01DA AMOV FEN,A JIANF3:LCALL WR_DS1302LCALL XIANSHILJMP JIANF JIANF1:JNB MOSHI,$LJMP MO11JIAS:MOV P0,#0C8HJIAS2:JNB MOSHI,JIAS1JB JIA,JIAS2JNB JIA,$MOV A,SHIADD A,#01HDA AMOV SHI,ACJNE A,#24H,JIAS3MOV SHI,#00 JIAS3:LCALL WR_DS1302LCALL XIANSHILJMP JIAS JIAS1:JNB MOSHI,$LJMP MO21JIAD:MOV P0,#089HLCALL WR_CODEJIAD2:JNB MOSHI,JIAD1JB JIA,JIAD2JNB JIA,$MOV A,DAYADD A,#01HDA AMOV DAY,AMOV A,YUECJNE A,#01H,SS1LJMP JIAD4 SS1:CJNE A,#03H,SS2 LJMP JIAD4 SS2:CJNE A,#05H,SS3LJMP JIAD4 SS3:CJNE A,#07H,SS4LJMP JIAD4 SS4:SS5:CJNE A,#10H,SS6LJMP JIAD4 SS6:CJNE A,#12H,SSS JIAD4:MOV A,DAYCJNE A,#32H,JIAD3MOV DAY,#01H JIAD3:LCALL WR_DS1302LCALL XIANSHILJMP JIAD JIAD1:JNB MOSHI,$LJMP MO41 SSS:CJNE A,#02H,S30MOV A,NIANANL A,#0FHMOV GEW,AMOV A,NIANANL A,#0F0HSWAP AMOV B,#10MUL ABADD A,GEWMOV B,#04HDIV ABMOV A,BCJNE A,#00H,S29LJMP S28 S30:MOV A,DAYCJNE A,#31H,JIAD3MOV DAY,#01HLJMP JIAD3 S29:MOV A,DAYCJNE A,#29H,JIAD3MOV DAY,#01HLJMP JIAD3 S28:MOV DAY,#01HLJMP JIAD3;***************************************************************;;判断月的天数判断闰年的方法先将年的数据有十六进制BCD码转换成正常的十六进制;再除以4 判断余数是否为0 为零则为闰年不为零不是;***************************************************************JIAM:MOV P0,#086HLCALL WR_CODE JIAM2:JNB MOSHI,JIAM1JB JIA,JIAM2JNB JIA,$MOV A,YUEADD A,#01HDA AMOV YUE,ACJNE A,#13H,JIAM3MOV YUE,#01 JIAM3:LCALL WR_DS1302LCALL XIANSHI JIAM1:JNB MOSHI,$LJMP MO31 JIAY:MOV P0,#083HLCALL WR_CODE JIAY2:JNB MOSHI,JIAY1JB JIA,JIAY2JNB JIA,$MOV A,NIANADD A,#01HDA AMOV NIAN,ACJNE A,#99H,JIAY3MOV NIAN,#00 JIAY3:LCALL WR_DS1302LCALL XIANSHILJMP JIAY;***************************************************************;温度读取;***************************************************************RE_TEMP:SETB DQACALL INIT_18B20JB FLAG, STRET ST:MOV A, #0CCHACALL WRITE_18B20MOV A, #44HACALL WRITE_18B20ACALL INIT_18B20MOV A, #0CCHACALL WRITE_18B20MOV A, #0BEHACALL WRITE_18B20ACALL READ_18B20RET;***************************************************************;初始化DS18B20;***************************************************************INIT_18B20:SETB DQNOPCLR DQMOV R1, #3 DLY:MOV R0, #107DJNZ R0, $DJNZ R1, DLYSETB DQNOPNOPNOPMOV R0, #25H T2:JNB DQ, T3DJNZ R0, T2JMP T4 T3:SETB FLAGJMP T5JMP T7 T5:MOV R0, #117 T6:DJNZ R0, T6 T7:SETB DQRET ;***************************************************************;写DS18B20;***************************************************************WRITE_18B20:MOV R2, #8CLR C WR1:CLR DQMOV R3, #6DJNZ R3, $RRC AMOV DQ, CMOV R3, #23DJNZ R3, $SETB DQNOPDJNZ R2, WR1SETB DQRET;***************************************************************;读DS18B20;***************************************************************READ_18B20:MOV R4, #2MOV R1, #21H RE0:MOV R2, #8 RE1:CLR CSETB DQNOPNOPCLR DQNOPNOPMOV R3, #9 RE2:DJNZ R3, RE2MOV C, DQMOV R3, #23 RE3:DJNZ R3, RE3RRC ADJNZ R2, RE1MOV @R1, ADEC R1DJNZ R4, RE0RET;***************************************************************;温度转换;***************************************************************CONVER:MOV A, 21HMOV C, 20H.0RRC AMOV C, 20H.1RRC AMOV C, 20H.2RRC AMOV C, 20H.3RRC AMOV 21H, ARET;***************************************************************;显示温度整数部分;***************************************************************DISPLAY_INT:MOV A, 21HMOV B, #10DIV ABMOV B_BIT, AMOV A_BIT, BMOV DPTR, #TABMOV P0,#08cHLCALL WR_CODELCALL WR_DATAMOV P0,#08DHLCALL WR_CODEMOV A, A_BITMOVC A, @A+DPTRLCALL WR_DATARET;***************************************************************; 1602的写数据读指令判忙程序;***************************************************************WR_DATA:MOV P0,ASETB RS ;RS=1选择数据寄存器CLR RW ;RW=0 ;准备CLR E ;E=0 ;执行显示命令LCALL BUSY ;判断液晶模块是否忙?SETB E ;E=1 ;显示完成,程序停车RET WR_CODE:CLR RS ;写入控制命令的子程序CLR RWCLR ELCALL BUSYSETB ERET BUSY:MOV P0,#0FFH ;判断液晶显示器是否忙的子程序CLR RSSETB RWCLR ENOP ;nop一定要有SETB EJB P0.7,BUSY ;如果P0.7为高电平表示忙就循环等待RET ;***************************************************************; 判键子程按一次模式键后就一直判断下一次按键是P3.4还是P3.5 判断进入下一模式还是加1(按下模式键第一次加1需要按两次);MO1加分 MO2加时 MO3加月 MO4加日 MO5加年AKEY:JNB ALARM, XIANGUANGRET XIANGUANG:JNB ALARM,$MOV P0,#01H ; 显示清屏数据指针清零所有显示清零LCALL WR_CODEMOV P0,#02H ; 显示回车数据指针清零LCALL WR_CODEMOV P0,#038H ;设置16*2显示 5*7 点阵 8位数据接口LCALL WR_CODEMOV P0,#04H ; 当读或写一个数据时地址指针自动加一光标自动加一LCALL WR_CODEMOV P0,#0DH ; 开显示不显光标 0fh开显示开光标光标闪烁LCALL WR_CODELCALL AXIANLCALL AXIANSHIMOMIAO: MOV P0,#0CBHLCALL WR_CODEJNB JIA,INCMJNB JIAN,DECMJNB ALARM ,BACKMIAOLJMP MOMIAO BACKMIAO:JNB ALARM,$LJMP MOFENINCM:MOV P0,#0CBHLCALL WR_CODE INCM2:JNB ALARM,INCM1JNB JIAN,DECMJB JIA,INCM2JNB JIA,$INC AMIAOMOV A,AMIAOCJNE A,#60,INCM3MOV AMIAO,#00 INCM3:LCALL AXIANSHILJMP INCMINCM1:JNB ALARM ,BACKMIAODECM:MOV P0,#0CBHLCALL WR_CODEJNB ALARM,DECM1JNB JIA,INCMJB JIAN,DECMJNB JIAN,$MOV A,AMIAOCJNE A,#00,DECM2MOV AMIAO,#59LJMP DECM3 DECM2:CLR CSUBB A,#01MOV AMIAO,A DECM3:LCALL AXIANSHILJMP DECM DECM1:JNB ALARM,BACKMIAOMOFEN:MOV P0,#0C8HLCALL WR_CODEJNB JIA,INCFJNB JIAN,DECFJNB ALARM ,BACKFENLJMP MOFEN BACKFEN:JNB ALARM,$LJMP AMOSHIINCF:MOV P0,#0C8HLCALL WR_CODEINCF2:JNB ALARM,INCF1JNB JIAN,DECFJB JIA,INCF2JNB JIA,$INC AFENMOV A,AFENCJNE A,#60,INCF3MOV AFEN,#00INCF3:LCALL AXIANSHILJMP INCFINCF1:JNB ALARM ,BACKFENDECF:MOV P0,#0C8HLCALL WR_CODEJNB ALARM,DECF1JNB JIA,INCFJB JIAN,DECFJNB JIAN,$MOV A,AFENCJNE A,#00,DECF2MOV AFEN,#59LJMP DECF3DECF2:CLR C;DEC ASUBB A,#01;DA AMOV AFEN,ADECF3:LCALL AXIANSHILJMP DECFDECF1:JNB ALARM,BACKFENAMOSHI:MOV P0,#0C5HLCALL WR_CODEJNB JIA,INCSJNB JIAN,DECSJNB ALARM ,BACKSHI LJMP AMOSHIINCS:MOV P0,#0C5HLCALL WR_CODEINCS2:JNB ALARM,INCS1JNB JIAN,DECSJB JIA,INCS2JNB JIA,$INC ASHIMOV A,ASHICJNE A,#24,INCS3MOV ASHI,#00INCS3:LCALL AXIANSHILJMP INCSINCS1:JNB ALARM ,BACKSHIBACKSHI:JNB ALARM,$MOV P0,#01HLCALL WR_CODEMOV P0,#0CHLCALL WR_CODELCALL XIAN1LJMP MAINDECS:MOV P0,#0C5HLCALL WR_CODEJNB ALARM,DECS1JNB JIA,INCSJB JIAN,DECSJNB JIAN,$MOV A,ASHICJNE A,#00,DECS2MOV ASHI,#23LJMP DECS3 DECS2:CLR CSUBB A,#01MOV ASHI,ADECS3:LCALL AXIANSHILJMP DECS DECS1:JNB ALARM,BACKSHI;***************************************************************; 闹钟部分固定显示显示TIME ADJUST;***************************************************************AXIAN:MOV P0,#82HLCALL WR_CODEMOV A,#'B'LCALL WR_DATAMOV P0,#83HLCALL WR_CODEMOV A,#'E'LCALL WR_DATAMOV P0,#84HLCALL WR_CODEMOV A,#'L' ;LCALL WR_DATAMOV P0,#85HLCALL WR_CODEMOV A,#'L'LCALL WR_DATAMOV P0,#088HLCALL WR_CODEMOV A,#'A'LCALL WR_DATAMOV P0,#089HLCALL WR_CODEMOV A,#'D'LCALL WR_DATAMOV P0,#08AHLCALL WR_CODEMOV A,#'J'LCALL WR_DATAMOV P0,#08BHLCALL WR_CODEMOV A,#'U'LCALL WR_DATAMOV P0,#08CHLCALL WR_CODEMOV A,#'S'LCALL WR_DATAMOV P0,#08DHLCALL WR_CODEMOV A,#'T'LCALL WR_DATAMOV P0,#0C6HLCALL WR_CODEMOV A,#':'LCALL WR_DATAMOV P0,#0C9HLCALL WR_CODEMOV A,#':'LCALL WR_DATARET;*************************************************************** ; 显示数据时分秒年月日周地址数据都在变化没用循环体;*************************************************************** AXIANSHI:MOV HHH,AMIAOLCALL AHEXMOV P0,#0CAHLCALL WR_CODEMOVC A,@A+DPTRLCALL WR_DATAMOV A,BMOV P0,#0CBHLCALL WR_CODEMOVC A,@A+DPTRLCALL WR_DATAMOV HHH,AFENLCALL AHEXMOV P0,#0C7HLCALL WR_CODEMOVC A,@A+DPTRLCALL WR_DATAMOV A,BMOV P0,#0C8HLCALL WR_CODEMOVC A,@A+DPTRLCALL WR_DATAMOV HHH,ASHILCALL AHEXMOV P0,#0C4HLCALL WR_CODEMOVC A,@A+DPTRLCALL WR_DATAMOV A,BMOV P0,#0C5HLCALL WR_CODEMOVC A,@A+DPTRLCALL WR_DATARET;***************************************************************; 分离十进制BCD码中的十位和个位;***************************************************************AHEX: MOV A,HHHMOV B,#10DIV ABRET;***************************************************************; 闹钟模块;***************************************************************;==========================条件符合响铃1分钟============================ BELLRING:MOV HHH,SHILCALL HEXMOV R2,BMOV B,#10MUL ABADD A,R2CJNE A ,ASHI, AAAMOV HHH,FENLCALL HEXMOV R2,BMOV B,#10MUL ABADD A,R2CJNE A ,AFEN,AAAMOV HHH,MIAOLCALL HEXMOV R2,BMOV B,#10MUL ABADD A,R2CJNE A ,AMIAO,AAALCALL BELLRAAA:LJMP MAIN;==========================闹钟响铃10秒钟============================BELLR:MOV COUNT,#10ZZZ:SETB SOUNDLCALL DELAY500MSCLR SOUNDLCALL DELAY500MSlcall RD_DS1302LCALL XIANSHIJNB ALARM ,BBBDJNZ COUNT ,ZZZBBB:JNB ALARM ,$SETB SOUNDRET;==========================设置闹铃延时500MS响一次=================== DELAY500MS:MOV R7,#17HDL1:MOV R6,#98HDL0:MOV R5,#46HDJNZ R5,$DJNZ R6,DL0DJNZ R7,DL1RET;*************************************************************** ; 转换成BCD码;*************************************************************** ZHUAN:MOV A,HHHADD A,#00HDA ARET;*************************************************************** ; 分离BCD码中的十位和个位;*************************************************************** HEX:MOV A,HHHMOV B,#16DIV ABRET;*************************************************************** ; 数据查表;*************************************************************** TAB: DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39HENDORCAD电路原理图PADS软件的PCB图实物图。

DS18B20温度传感器和1602液晶制作温度和时间同时显示

DS18B20温度传感器和1602液晶制作温度和时间同时显示

用DS18B20温度传感器和1602液晶制作温度和时间同时显示【含原理图】2009年11月26日星期四22:43C程序如下:/*功能:温度采集显示和可调时钟显示,时钟用中断法实现s1:选择要调节的时、分、秒位s2:时、分、秒加一s3:时、分、秒减一*/#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar num,s1num,count;uchar shi,fen,miao;sbit rs=P2^0;sbit e=P2^1;sbit s1=P3^0;sbit s2=P3^1;sbit s3=P3^2; //按键定义sbit DQ =P2^2; //定义通信端口bit flag;uchar code table1[]="Time: 00:00:00";uchar code table2[]="Temperature: 'C";//1602初始化字符void delay(uint z)//延时子函数{uint x,y;for(x=z; x>0; x--)for(y=110;y>0;y--);}#include<1602.h>#include<18b20.h>#include<clock_set.h>void main(){uchar temp;init_1602();while(1){ delay(500); //去除0秒和1秒之间显示间隔跟正常1秒间隔相差过大if(miao==0) //每分钟进行温度采集一次{TR0=0; //进入温度采集后,关闭定时器flag=1; //flag=1,标志进入温度采集模式write_com(0x80+0x40+13);write_dat(0x30+1); //消除不显示数字1temp=ReadTemperature(); //读取DS18B20的温度值write_1602(12,temp); //向1602中写入温度值TR0=1; //温度采集完成后,打开定时器delay(100);//等待miao不等零,跳出循环}flag=0; //flag=0,标志在时钟显示模式下keyscan(); //调用键盘扫描子程序,用以调整时间}}void timer0() interrupt 1//定时器1的中断服务程序,并向1602中写时分秒显示时间{TH0=(65535-50000)/256;TL0=(65535-50000)%256;count++;if (count==18){count=0;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;}if(flag==0) //flag=0,标志在时钟显示模式下,然后才显示时间write_1602(6,shi);}if(flag==0)write_1602(9,fen);}if(flag==0)write_1602(12,miao);}}"1602.h"void write_com(uchar com)//向1602液晶写命令函数{rs=0;e=0;P0=com;delay(5);e=1;delay(5);e=0;}void write_dat(uchar dat)//向1602液晶写入数据{rs=1;e=0;P0=dat;delay(5);e=1;delay(5);e=0;}void init_1602()//1602液晶的初始化{uchar i;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);TMOD=0x01;TH0=(65535-50000)/256;TL0=(65535-50000)%256;EA=1;ET0=1;TR0=1;write_com(0x80); //第一行字符的初始化for(i=0;i<16;i++){write_dat(table2[i]);delay(5);}write_com(0x80+0x40); //第二行字符的初始化for(i=0;i<14;i++){write_dat(table1[i]);delay(5);}}void write_1602(uchar address,uchar temp_dat)//向指定的地址中写入时、分、秒数据{uchar gewei,shiwei;if(flag==0) //若在时钟显示模式下,向第二行写数据{write_com(0x80+0x40+address);}else{write_com(0x80+address); //若在温度采集显示模式下,向第一行写数据}shiwei=temp_dat/10;gewei=temp_dat%10;write_dat(0x30+shiwei); //根据1602字符库做相应转换write_dat(0x30+gewei);}"18B20.h"void delay_18b20(unsigned int i)//延时子函数{while(i--);}//初始化DS18B20子函数Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ复位delay_18b20(8); //稍做延时DQ = 0; //单片机将DQ拉低delay_18b20(80); //精确延时大于480usDQ = 1; //拉高总线delay_18b20(14);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay_18b20(20);}//读一个字节ReadOneChar(void){unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号if(DQ)dat|=0x80;delay_18b20(4);}return(dat);}//写一个字节WriteOneChar(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay_18b20(5);DQ = 1;dat>>=1;}delay_18b20(4);}//读取温度值ReadTemperature(void){uchar a,b,t;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delay(850); //等待温度转换结束,不能过短,否则第一次显示不出实际温度,会显示85 Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=ReadOneChar(); //读取温度值低位b=ReadOneChar(); //读取温度值高位a=a>>4; //低位右移4位,舍弃小数部分t=b<<4; //高位左移4位,舍弃符号位t=t|a;return(t);}"clock_set.h"void keyscan()//键盘扫描程序{if(s1==0)//s1键扫描{delay(5);if(s1==0){TR0=0;s1num++;while(!s1);//等待键的释放switch(s1num)//根据s1的按键次数做相应的处理{case 1:write_com(0x80+0x40+12);write_com(0x0f); break;//按键一次,调整光标的形状及位置case 2:write_com(0x80+0x40+9); break;case 3:write_com(0x80+0x40+6); break;case 4:s1num=0;write_com(0x0c);TR0=1;break;}}}if(s1num)//在s1有被按下的情况下做相应的处理{if(s2==0)//s2按键检测,按下s2键后相应的时、分、秒加1操作{delay(5);if(s2==0){while(!s2);//松手检测switch(s1num){case 1:miao++;if(miao==60) miao=0;write_1602(12,miao);write_com(0x80+0x40+12);break;case 2:fen++;if(fen==60) fen=0;write_1602(9,fen);write_com(0x80+0x40+9);break;case 3:shi++;if(shi==24) shi=0;write_1602(6,shi);write_com(0x80+0x40+6);break;case 4:break;}// delay(500);//把松手检测部分去除后,按下后时间一直增加}}if(s3==0)//s3按键检测,按下s3键后相应的时、分、秒减1操作{delay(5);if(s3==0){while(!s3);//松手检测switch(s1num){case 1:miao--;if(miao==-1) miao=59;write_1602(12,miao);write_com(0x80+0x40+12);break;case 2:fen--;if(fen==-1) fen=59;write_1602(9,fen);write_com(0x80+0x40+9);break;case 3:shi--;if(shi==-1) shi=23;write_1602(6,shi);write_com(0x80+0x40+6);break;case 4:break;}// delay(500);//把松手检测部分去除后,按下后时间一直减小}}}}原理图:。

基于51单片机和lcd1602的万年历设计

基于51单片机和lcd1602的万年历设计

基于单片机的万年历设计摘要古人依靠日冕、漏刻记录时间,而随着科技的发展,电子万年历已经成为日渐流行的日常计时工具。

本文研究的万年历系统拟用STC89C52单片机控制,以DS1302时钟芯片计时、DS18B20采集温度、1602液晶屏显示。

系统主要由温度传感器电路,单片机控制电路,显示电路以及校正电路四个模块组成。

本文阐述了系统的硬件工作原理,所应用的各个接口模块的功能以及其工作过程,论证了设计方案理论的可行性。

系统程序采用C语言编写,经Keil软件进行调试后在Proteus软件中进行仿真,可以显示年、月、日、星期、时、分、秒和温度并具有校准功能和与即时时间同步的功能。

实验结果表明此万年历实现后具有读取方便、显示直观、功能多样、电路简洁等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。

关键词:万年历单片机仿真The Calendar of Design based on Single ChipAbstractAncient rely on corona, Louke recording time. The electronic calendar has become the popular tool for the daily timing.as the development of technology.In the calendar system , the STC89C52 is used to control,with the DS1302 clock chip timing, DS18B20 collecting temperature, 1602 LCD Displaying. The system is composed of four modules:the temperature sensor circuit, the MCU control circuit, the display circuit and the correction circuit.This paper describes the hardware works, the functions of each interface module and its working process, demonstrates design theory is Feasibility.. C language is used to program, after debugging in the Keil software,then simulating in the Proteus. The electronic calendar can display year, month, day, week, hours, minutes, seconds, temperature, and has calibration features and functionality with real time synchronization.The results show that this calendar is easy to read, intuitive display, versatile, simple circuits, and many other advantages,The design meets the development trend of electronic instruments and meters, and has broad market prospects.Keywords:Calendar ; MCU ; simulation目录第一章绪论 (1)1.1课题研究的意义 (1)1.2本课题主要的研究工作 (1)1.2.1研究内容 (1)1.2.2论文章节安排 (2)1.3本章小结 (2)第二章单片机的概述 (3)2.1单片机的定义和特点 (3)2.1.1单片机的定义 (3)2.1.2单片机的特点 (3)2.2单片机的发展现状和趋势 (4)2.2.1单片机的发展现状 (4)2.2.2单片机的发展趋势 (5)2.3编程语言的选择 (5)2.4本章小结 (6)第三章设计要求和方案论证 (7)3.1设计要求 (7)3.2单片机芯片的选择方案和论证 (7)3.3显示模块选择方案和论证 (7)3.4时钟芯片的选择方案和论证 (8)3.5温度传感器的选择方案与论证 (8)3.6电路设计最终方案决定 (9)3.7本章小结 (9)第四章系统的硬件设计与实现 (10)4.1电路设计框图 (10)4.2系统硬件概述 (10)4.3主要单元电路的设计 (11)4.3.1 STC89C52单片机简介 (11)4.3.2单片机主控制模块的设计 (13)4.3.3时钟电路模块的设计 (15)4.3.4温度传感器电路设计 (16)4.3.5独立式键盘设计 (19)4.3.6显示模块的设计 (19)4.4本章小结 (21)第五章系统的软件设计 (22)5.1程序流程图 (22)5.1.1系统总流程图 (22)5.1.2温度程序流程图 (23)5.1.3时钟程序流程图 (24)5.1.4液晶显示程序流程图 (25)5.2程序的设计 (26)5.2.1 DS18B20测温程序 (26)5.2.2读写DS1302程序 (27)5.2.3液晶显示程序 (29)5.3本章小结 (29)第六章仿真与调试 (30)6.1软件简介 (30)6.1.1 Keil软件简介 (30)6.1.2 Proteus ISIS简介 (30)6.2 Keil软件调试流程 (31)6.3 Proteus软件运行流程 (33)6.4 万年历的功能仿真 (35)6.5 硬件调试结果 (35)6.6本章小结 (39)第七章总结与展望 (40)参考文献 (41)附录一:系统电路图 (42)附录二:系统PCB板 (43)附录三:系统程序 (44)致谢 (57)第一章绪论1.1课题研究的意义万年历是我国古代传说中最古老的一部太阳历。

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

#include<reg52.h>#include<intrins.h>#include <math.h>#define uchar unsigned char#define uint unsigned intuchar code table[]="--Figo";//uchar code table1[]="";sbit lcden=P3^4;sbit lcdrs=P3^5;sbit dula=P2^6;sbit wela=P2^7;sbit ds=P1^7;sbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;sbit key4=P1^3;int tempValue;int s_1=1000;unsigned char FunKeyFlag=6,keypress;#define key_vaule1 0x01#define key_vaule2 0x02#define key_vaule3 0x03#define key_vaule4 0x04uchar num;int ms_10=10;int flag=0;int s_1_1=1000;uint sec=55;uint min=9;uint hour=22;uint nian=2014;uint yue=8;uint ri=20;uint xingqi=3;//延时函数, 对于11.0592MHz时钟, 例i=10,则大概延时10ms. void delay_wendu(unsigned int i){unsigned int j;while(i--){for(j = 0; j < 125; j++);}}//初始化DS18B20//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动void dsInit(){//对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于?us unsigned int i;ds = 0;i = 100; //拉低约800us, 符合协议要求的480us以上while(i>0) i--;ds = 1; //产生一个上升沿, 进入等待应答状态i = 4;while(i>0) i--;}void dsWait(){unsigned int i;while(ds);while(~ds);//检测到应答脉冲i = 4;while(i > 0) i--;}//向DS18B20读取一位数据//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,//之后DS18B20则会输出持续一段时间的一位数据bit readBit(){unsigned int i;bit b;ds = 0;i++;//延时约8us, 符合协议要求至少保持1usds = 1;i++; i++;//延时约16us, 符合协议要求的至少延时15us以上b = ds;i = 8;while(i>0) i--; //延时约64us, 符合读时隙不低于60us要求return b;}//读取一字节数据, 通过调用readBit()来实现unsigned char readByte()unsigned int i;unsigned char j, dat;dat = 0;for(i=0; i<8; i++){j = readBit();//最先读出的是最低位数据dat = (j << 7) | (dat >> 1);}return dat;}//向DS18B20写入一字节数据void writeByte(unsigned char dat){unsigned int i;unsigned char j;bit b;for(j = 0; j < 8; j++){b = dat & 0x01;dat >>= 1;//写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1if(b){ds = 0;i++;i++; //拉低约16us, 符号要求15~60us内ds = 1;i = 8;while(i>0)i--; //延时约64us, 符合写时隙不低于60us要求}else //写"0", 将DQ拉低60us~120usds = 0;i = 8; while(i>0) i--;//拉低约64us, 符号要求ds = 1;i++;i++;//整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了}}//向DS18B20发送温度转换命令void sendChangeCmd()dsInit(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化dsWait(); //等待DS18B20应答delay_wendu(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号writeByte(0xcc); //写入跳过序列号命令字Skip RomwriteByte(0x44); //写入温度转换命令字Convert T}//向DS18B20发送读取数据命令void sendReadCmd(){dsInit();dsWait();delay_wendu(1);writeByte(0xcc); //写入跳过序列号命令字Skip RomwriteByte(0xbe); //写入读取数据令字Read Scratchpad}//获取当前温度值int getTmpValue(){unsigned int tmpvalue;int value; //存放温度数值float t;unsigned char low, high;sendReadCmd();//连续读取两个字节数据low = readByte();high = readByte();//将高低两个字节合成一个整形变量//计算机中对于负数是利用补码来表示的//若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的valuetmpvalue = high;tmpvalue <<= 8;tmpvalue |= low;value = tmpvalue;//使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度t = value * 0.0625;//将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入//如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度//如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5return value;}void HandleKeyPress() ;void KeyScan() //按键扫描{static unsigned char state=0;unsigned char temp;if (key1==0) temp=key_vaule1;else if (key2==0) temp=key_vaule2;else if (key3==0) temp=key_vaule3;else if (key4==0) temp=key_vaule4;else temp=0;switch (state){case 0: if(temp!=0) state=1;break;case 1: state=2; break;case 2: if(temp!=0) {state=3;keypress=temp;} else state=0; break;case 3: if(temp==0) {HandleKeyPress();state=0;} break;}}void HandleKeyPress() //按键功能的设置{ if (keypress==key_vaule1) //功能键的设置{FunKeyFlag=(FunKeyFlag+1)%7;}else if (keypress==key_vaule2) //第二个按键的设置{switch (FunKeyFlag){case 0:hour++;if(hour>23)hour=0;break;case 1:min++;if(min>59)min=0;break;case 2:sec++;if(sec>59)min=0;break;case 3:ri++;xingqi++;if(ri>30)ri=1;if(xingqi>7)xingqi=1;break;case 4:yue++;if(yue>12)yue=1;break;case 5:nian++;break;}}else if (keypress==key_vaule3) //第三个按键的设置{switch (FunKeyFlag){case 0:hour--;if(hour<0)hour=23;break;case 1:min--;if(min<0)min=59;break;case 2:sec--;if(sec<0)sec=59;break;case 3:ri--;xingqi--;if(ri<1)ri=31;if(xingqi<1)xingqi=1;break;case 4:yue--;if(yue<1)yue=12;break;case 5:nian--;break;}}else if (keypress==key_vaule4) //第四个按键的设置{switch (FunKeyFlag){case 0:hour=0;break;case 1:min=0;break;case 2:sec=0;break;case 3:ri=1;xingqi=1;break;case 4:yue=1;break;case 5:nian=2000;break;}}}void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(uchar com){lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar date){lcdrs=1;P0=date;flag=1;delay(5);lcden=1;delay(5);lcden=0;}shijian_show(uchar wei,shijian ){uchar shi,ge;shi=shijian/10;ge=shijian%10;write_com(0x80+0x40+wei);write_data(0x30+shi);write_data(0x30+ge);}rili_show(uchar wei,rili ){uchar shi,ge;shi=rili/10;ge=rili%10;write_com(0x80+wei);write_data(0x30+shi);write_data(0x30+ge);}nian_show(uchar wei,shijian ){uchar shi,ge,qian,bai;qian=shijian/1000;bai=shijian%1000/100;shi=shijian%100/10;ge=shijian%10;write_com(0x80+wei);write_data(0x30+qian);write_data(0x30+bai);write_data(0x30+shi);write_data(0x30+ge);}wendu_show(uchar wei,int wendu ) {uchar shi,ge,qian,bai,xiao;qian=wendu/10000;bai=wendu%10000/1000;shi=wendu%1000/100;ge=wendu%100/10;xiao=wendu%10;write_com(0x80+0x40+wei);write_data(0x30+qian);write_data(0x30+bai);write_data(0x30+shi);// write_com(0x80+0x40+wei+1);write_data(0xdf);write_data(0x30+ge);write_data(0x30+xiao);}void init(){P0=0;dula=0;wela=0;lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);}void week_show() //星期的显示{write_com(0x80+12);switch (xingqi){case 1:{write_data('M');write_data('o');write_data('n');}break;case 2:{write_data('T');write_data('u');write_data('e');}break;case 3:{write_data('W');write_data('e');write_data('d');}break;case 4:{write_data('T');write_data('h');write_data('u');}break;case 5:{write_data('F');write_data('r');write_data('i');}break;case 6:{write_data('S');write_data('a');write_data('t');}break;case 7:{write_data('S');write_data('u');write_data('n');}break;}}void main(){TMOD = 0x01;TH0 = (65536-1000)/256;TL0 = (65536-1000)%256;EA = 1;ET0 = 1;TR0 = 1;init();while(1){nian_show(1,nian);rili_show(6,yue);rili_show(9,ri);shijian_show(0,hour);shijian_show(3,min);shijian_show(6,sec);write_com(0x80+5);write_data(0x2d);write_com(0x80+8);write_data(0x2d);write_com(0x80+0x40+2);write_data(0x3A);write_com(0x80+0x40+5);write_data(0x3A);week_show();wendu_show(10,tempValue);}}void time() interrupt 1{TH0 = (65536-1000)/256;TL0 = (65536-1000)%256;ms_10--;s_1_1--;if(s_1_1<=0){s_1_1=1000; sendChangeCmd();//显示5次tempValue = getTmpValue(); //计算温度}if(ms_10<=0) //按键扫描{ms_10=10;KeyScan();}s_1--;if(s_1<=0){s_1=1000;sec++;if(sec>59){sec=0;min++;if(min>59){min=0;hour++;if(hour>23){hour=0;ri++;xingqi++;if(xingqi>7){xingqi=1;}if((yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)&&ri>31){ri=1;yue++;}else if(yue==2){if(nian%100!=0){if(nian%4==0){if(ri>29){ri=1;yue++;}}else if(nian%4!=0){if(ri>28){ri=1;yue++;}}}else if(nian%100==0){if(nian%400==0){if(ri>29){ri=1;yue++;}}else if(nian%400!=0){if(ri>28){ri=1;yue++;}}}}else if((yue==4||yue==6||yue==9||yue==11)&&ri>30){ri=1;yue++;}if(yue>12){nian++;yue=1;}}}}}}。

相关文档
最新文档