多功能电子钟设计说明书.doc_第1页
多功能电子钟设计说明书.doc_第2页
多功能电子钟设计说明书.doc_第3页
多功能电子钟设计说明书.doc_第4页
多功能电子钟设计说明书.doc_第5页
已阅读5页,还剩17页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

多功能电子钟设计说明书一 作品硬件原理图22三、程序流程图四程序源代码1.头文件代码#ifndef _dianz_H_#define _dianz_H_sbit SD = P10;/串行数据输入sbit ST_CK = P11;/存储寄存器时钟输入sbit SH_CK = P12;/移位寄存器时钟输入unsigned char code tab=0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f; /列扫描unsigned char code digittab78= /字模取模方式 阴码 逆向 逐列式0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00,/*S,0*/0x00,0x00,0x00,0x48,0x7A,0x40,0x00,0x00,/*i,1*/0x00,0x78,0x08,0x08,0x78,0x08,0x78,0x00,/*m,2*/0x00,0xF8,0x48,0x48,0x48,0x48,0x30,0x00,/*p,3*/0x00,0x00,0x00,0x3E,0x40,0x20,0x00,0x00,/*l,4*/0x00,0x38,0x54,0x54,0x54,0x58,0x00,0x00,/*e,5*/0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,;unsigned char outwork8=0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00;/屏显unsigned char i,j,k,num;/变量unsigned char cnta,cntb; void Ser_IN(unsigned char Data)/将8位二进制输入锁存器unsigned char i;for(i = 0; i 8; i+)SH_CK = 0;/CLOCK_MAX=100MHzSD = Data & 0x80;Data = 1;SH_CK = 1;void Par_OUT(void)/将锁存器中的数值输出显示在点阵上ST_CK = 0;ST_CK = 1;void Go_dianzhen() if(cnta7) / if(cntb8) /for(i=0;i50;i+) for(j=0;j8;j+) Ser_IN(tabj); Ser_IN(outworkj); Par_OUT(); /end for(j) /end for(i)Ser_IN(0x00);Ser_IN(0x00);Par_OUT();for(j=0;j7;j+)outworkj=outworkj+1;outwork7=digittabcntacntb; cntb+;/end for(cnta) if(cntb=8) cntb=0; cnta+; /end for(cntb) if(cnta=7)cnta=0;/end while() #endif2.头文件代码#include reg52.hsbit P1_3=P16;unsigned char code TABLE=0x82,0x01,0x81,0x94,0x84,0xB4,0xA4,0x04, 0x82,0x01,0x81,0x94,0x84,0xC4,0xB4,0x04, 0x82,0x01,0x81,0xF4,0xD4,0xB4,0xA4,0x94, 0xE2,0x01,0xE1,0xD4,0xB4,0xC4,0xB4,0x04, 0x82,0x01,0x81,0x94,0x84,0xB4,0xA4,0x04, 0x82,0x01,0x81,0x94,0x84,0xC4,0xB4,0x04, 0x82,0x01,0x81,0xF4,0xD4,0xB4,0xA4,0x94, 0xE2,0x01,0xE1,0xD4,0xB4,0xC4,0xB4,0x04,0;unsigned int code TABLE1=64260,64400,64524,64580,64684,64777,64820,64898, 64968,65030,65058,65110,65157,65178,65217 ; unsigned char th0_temp,tl0_temp;void SING(unsigned char hi);void DELAY(unsigned char lo);void mainsing()unsigned char i,hi,lo,coute;TMOD=0X01; ET0=1; EA=1; TR0=1;P1_3=1;coute=0;while(TABLEcoute!=0)i=TABLEcoute;coute+;lo=i&0x0f;hi=(i&0xf0)4;if(hi0)SING(hi);else TR0=0;P1_3=1;DELAY(lo);P1_3=1;void SING(unsigned char hi)th0_temp=(TABLE1hi-1/256);TH0=th0_temp;tl0_temp=(TABLE1hi-1%256);TL0=tl0_temp;TR0=1;void DELAY(unsigned char lo)unsigned char temp1,temp2;dofor(temp1=0;temp1150;temp1+)for(temp2=0;temp2200;temp2+);while(lo-);void INTT0() interrupt 1TH0=th0_temp;TL0=tl0_temp;P1_3=P1_3;3.主函数代码#include#include#include#include#define uint unsigned int#define uchar unsigned charuchar time,flag,tltemp;uchar stop,setnum;uchar second,minute,hour,day,month,year; /分别储存苗、分、小时,日,月,年uchar dz_ms;sbit RS=P24; /位定义液晶的寄存器选择位 sbit RW=P25; /位定义液晶的读写选择位sbit E=P26; /位定义液晶的使能信号位 sbit BF=P07; /位定义液晶的忙碌标志位sbit SCLK=P20; /位定义DS1302芯片时钟输出端口 sbit DATA=P21; /位定义DS1302芯片数据输出端口sbit RST=P22; /位定义DS1302芯片复位端口sbit DQ=P33; /为定义DS18B20的数据端 uchar code wendu=0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00; /自定义字符 uchar code digit10=0123456789; /显示日历、时间要用到的数字uchar code enjoy1 = Happy Birthday!;uchar code enjoy2 = Enjoy Yourself!;void delayms(uchar i);void delayus(uchar i);bit Test_busy();void Write_instruction(uchar instruction);void Write_address(unsigned char address);void Write_data(uchar dat);void Initiate_LCD();void Display_second(uchar second);void Display_minute(uchar minute);void Display_hour(uchar hour);void Display_day(uchar day);void Display_month(uchar month);void Display_year(uchar year);void Write_DS1302(uchar dat);void Write_handle(uchar order,uchar dat);uchar Read_DS1302();uchar Read_handle(uchar order);void Initiate_DS1302();bit Initiate_DS18B20();uchar ReadOneChar();void WriteOneChar(uchar dat);void display_temp1(uchar x);void display_temp2(uchar x);void ReadyReadTemp();void Key_check();void Set_second();void Set_minute();void Set_hour();void Set_day();void Set_month();void Set_year();void beep();void main() uchar temp; /暂时储存从1302读取的数据 uchar i; uchar TL; /储存暂存器的温度低位 uchar TH; /储存暂存器的温度高位 uchar TN; /储存温度的整数部分 uchar TD; /储存温度的小数部分 uchar count=0; /用来控制唱歌的蜂鸣器响起来的时间 /EA=1; /开放总中断 /EX0=1; /允许使用外中断 /IT0=1; /选择负跳变来触发外中断 TMOD = 0x10; TL1 =0XC0; TH1 =0X63; EA =1; ET1 =1; TR1 =1; Initiate_LCD(); /将液晶初始化 Initiate_DS1302(); /将1302初始化 while(1) count+; temp = Read_handle(0x81); /从秒寄存器读数据 second = (temp&0x70)4)*10 + (temp&0x0F);/将读出数据转化为压缩BCD码 Display_second(second); /显示秒 temp = Read_handle(0x83); /从分寄存器读 minute=(temp&0x70)4)*10 + (temp&0x0F); /将读出数据转化为压缩BCD码 Display_minute(minute); /显示分 temp = Read_handle(0x85); /从分寄存器读 hour=(temp&0x70)4)*10 + (temp&0x0F); /将读出数据转化为压缩BCD码 Display_hour(hour); /显示小时 temp = Read_handle(0x87); /从分寄存器读 day=(temp&0x70)4)*10 + (temp&0x0F); /将读出数据转化为压缩BCD码 Display_day(day); /显示日 temp = Read_handle(0x89); /从分寄存器读 month=(temp&0x70)4)*10 + (temp&0x0F); /将读出数据转化为压缩BCD码 Display_month(month); /显示月 temp = Read_handle(0x8d); /从分寄存器读 year=(temp&0xf0)4)*10 + (temp&0x0F); /将读出数据转化为压缩BCD码 Display_year(year); /显示年 if(count = 8) count=0; Write_instruction(0x01); delayms(5); Write_address(0x00); delayms(5); while(enjoy1i!=0) Write_data(enjoy1i+); delayms(100); Write_address(0x40); i=0; while(enjoy2i!=0) Write_data(enjoy2i+); delayms(100); delayms(100);TR1=0;mainsing();Initiate_LCD(); /将液晶初始化TR1 = 1; flag=0;ReadyReadTemp(); /读温度准备 TL=ReadOneChar(); /先读的是温度值低位TH=ReadOneChar(); /接着读的是温度值高位if(TH&0xf8)!=0x00)/判断高五位 得到温度正负标志flag=1;TL=TL; /取反TH=TH; /取反tltemp=TL+1; /低位加1TL=tltemp;if(tltemp255) TH+; /如果低8位大于255,向高8位进1 TN=TH*16+TL/16; /实际温度值=(TH*256+TL)/16,即:TH*16+TL/16 /这样得出的是温度的整数部分,小数部分被丢弃了 TD=(TL%16)*10/16; /计算温度的小数部分,将余数乘以10再除以16取整,TN=TH*16+TL/16; /实际温度值=(TH*256+TL)/16,即:TH*16+TL/16 /这样得出的是温度的整数部分,小数部分被丢弃了 TD=(TL%16)*10/16; /计算温度的小数部分,将余数乘以10再除以16取整, /这样得到的是温度小数部分的第一位数字(保留1位小数) display_temp1(TN); /显示温度的整数部分 display_temp2(TD); /显示温度的小数部分 delayms(10); /函数功能:延迟i秒void delayms(uchar i) uchar j; while(i-) for(j=0;j115;j+);/延迟i微妙void delayus(uchar i) uchar j; while(i-) for(j=0;j3;j+);/函数功能:判断液晶模块的忙碌状态bit Test_busy() bit result; RW=1; RS=0; /让RS为低电平,RW为高电平时,可以读状态 E=1; /让E=1,才允许读写 _nop_(); /空操作四个机器周期,给硬件反应时间 _nop_(); _nop_(); _nop_(); result=BF; /将忙碌标志电平赋给result E=0; /将E恢复低电平 return result; /函数功能:向液晶写入指令void Write_instruction(uchar instruction) while(Test_busy()=1); /要先确定液晶处于不忙的状态,太可以向液晶写入指令RW=0; /当RS和R/W同时为低电平时,可以写入指令RS=0; E=0; _nop_(); /给硬件反应时间_nop_(); P0=instruction; /将指令送入P0口,即写入指令 _nop_(); _nop_(); _nop_(); _nop_(); /空操作四个机器周期,给硬件反应时间 E=1; /E置高电平,开始写入指令 _nop_(); /空操作四个机器周期,给硬件反应时间 _nop_(); _nop_(); _nop_(); E=0; /当E由高电平跳变成低电平时,开始写入指令 /函数功能:指定字符在液晶中显示的实际地址void Write_address(unsigned char address) Write_instruction(address|0x80); /显示位置规定为80H+地址码 /函数功能:向液晶中写入要显示的字符 void Write_data(uchar dat) while(Test_busy()=1); RS=1; /当RS为高电平,RW为低电平时,可以写入数据 RW=0; E=0; P0=dat; /将数据送入P0口 _nop_(); /空操作四个机器周期,给硬件反应时间 _nop_(); _nop_(); _nop_(); E=1; /E置高电平 _nop_();/空操作四个机器周期,给硬件反应时间 _nop_(); _nop_(); _nop_(); E=0; /当E由高电平跳变成低电平时,液晶模块开始执行命令 /函数功能:对液晶进行初始化设置void Initiate_LCD() uchar i,j;delayms(15); /延时15ms,首次写指令时应给LCD一段较长的反应时间for(i=0;i3;i+) /连续进行三次模式设置,确保初始化成功 Write_instruction(0x38); /显示模式设置:162显示,57点阵,8位数据接口delayms(5); /延时5ms,给硬件一点反应时间 Write_instruction(0x0c); /显示模式设置:显示开,无光标,光标不闪烁delayms(5); /延时5ms,给硬件一点反应时间Write_instruction(0x06); /显示模式设置:光标右移,字符不移delayms(5); /延时5ms,给硬件一点反应时间Write_instruction(0x01); /清屏幕指令,将以前的显示内容清除delayms(5); /延时5ms,给硬件一点反应时间 Write_address(0x04); /在液晶中显示一些必要的字符,包括日历中的连杆,时间中的冒号 ,温度中的小数点和摄氏度符号Write_data(-); Write_address(0x07);Write_data(-);Write_address(0x42);Write_data(:);Write_address(0x45);Write_data(:); Write_address(0x4c);Write_data(.);Write_address(0x04);Write_data(-);Write_address(0x00);Write_data(2);delayms(5);Write_data(0);delayms(10);Write_instruction(0x40); /设定CGRAM地址delayms(5);for(j=0;j8;j+ )Write_data(wenduj);/写入自定义图形 Write_address(0x4e);/设定屏幕上的显示位置delayms(5); Write_data(0x00); /从CGRAM里取出自定义图形显示 /函数功能:将从DS1302读出的秒数显示在液晶上 void Display_second(uchar second) uchar ge,shi; /shi、ge分别储存十位和个位shi=second/10; /取十位ge=second%10; /取个位 Write_address(0x46); /写显示地址,将在第2行第7列开始显示Write_data(digitshi); /将十位数字的字符常量写入LCDWrite_data(digitge); /将个位数字的字符常量写入LCDdelayms(50); /延时50ms给硬件一点反应时间 /函数功能:将从DS1302读出的分数显示在液晶上void Display_minute(uchar minute) uchar ge,shi; /shi、ge分别储存十位和个位shi=minute/10; /取十位ge=minute%10; /取个位 Write_address(0x43); /写显示地址,将在第2行第7列开始显示Write_data(digitshi); /将十位数字的字符常量写入LCDWrite_data(digitge); /将个位数字的字符常量写入LCDdelayms(50); /延时50ms给硬件一点反应时间 /函数功能:将从DS1302读出的时数显示在液晶上void Display_hour(uchar hour) uchar ge,shi; /shi、ge分别储存十位和个位shi=hour/10; /取十位ge=hour%10; /取个位 Write_address(0x40); /写显示地址,将在第2行第7列开始显示Write_data(digitshi); /将十位数字的字符常量写入LCDWrite_data(digitge); /将个位数字的字符常量写入LCDdelayms(50); /延时50ms给硬件一点反应时间 /函数功能:将从DS1302读出的日数显示在液晶上void Display_day(uchar day) uchar ge,shi; /shi、ge分别储存十位和个位shi=day/10; /取十位ge=day%10; /取个位 Write_address(0x08); /写显示地址,将在第2行第7列开始显示Write_data(digitshi); /将十位数字的字符常量写入LCDWrite_data(digitge); /将个位数字的字符常量写入LCDdelayms(50); /延时50ms给硬件一点反应时间 /函数功能:将从DS1302读出的时数显示在液晶上void Display_month(uchar month) uchar ge,shi; /shi、ge分别储存十位和个位shi=month/10; /取十位ge=month%10; /取个位 Write_address(0x05); /写显示地址,将在第2行第7列开始显示Write_data(digitshi); /将十位数字的字符常量写入LCDWrite_data(digitge); /将个位数字的字符常量写入LCDdelayms(50); /延时50ms给硬件一点反应时间 /函数功能:将从DS1302读出的年数显示在液晶上void Display_year(uchar year) uchar ge,shi; /shi、ge分别储存十位和个位shi=year/10; /取十位ge=year%10; /取个位 Write_address(0x02); /写显示地址,将在第2行第7列开始显示Write_data(digitshi); /将十位数字的字符常量写入LCDWrite_data(digitge); /将个位数字的字符常量写入LCDdelayms(50); /延时50ms给硬件一点反应时间 /函数功能:向时钟芯片DS1302写入一个字节的数据void Write_DS1302(uchar dat) uchar i; SCLK=0; /拉低SCLK,为脉冲上升沿写入数据做好准备 delayus(2); /稍微等待,使硬件做好准备 for(i=0;i=1; /将dat的各数据位右移1位,准备写入下一个数据位 /函数功能:对时钟芯片DS1302进行一次写操作void Write_handle(uchar order,uchar dat) RST=0; /禁止数据传递 SCLK=0; /确保写数居前SCLK被拉低 RST=1; /启动数据传输 delayus(2); /稍微等待,使硬件做好准备 Write_DS1302(order); /写入命令字 Write_DS1302(dat); /写数据 SCLK=1; /将时钟电平置于高电平状态 RST=0; /禁止数据传递 /从DS1302中读出一个字节的数据uchar Read_DS1302() uchar i,dat; delayus(2); /稍微等待,使硬件做好准备for(i=0;i= 1; if(DATA=1) /如果读出的数据是1 dat|=0x80; /将1取出,写在dat的最高位 SCLK=1; /将SCLK置于高电平,为下降沿读出 delayus(2); /稍微等待 SCLK=0; /拉低SCLK,形成脉冲下降沿 delayus(2); /稍微等待 return dat; /将读出的数据返回 /函数功能:对DS1302进行一次读操作uchar Read_handle(uchar order) uchar dat; RST=0; /拉低RST SCLK=0; /确保写数居前SCLK被拉低 RST=1; /启动数据传输 Write_DS1302(order); /写入命令字 dat = Read_DS1302(); /读出数据 SCLK=1; /将时钟电平置于已知状态 RST=0; /禁止数据传递 return dat; /将读出的数据返回/函数功能:对DS1302进行初始化设置void Initiate_DS1302() uchar stop; stop= Read_handle(0x81); /读出秒寄存器81h的第八位,即时钟暂停标志位if(stop&0x80) /当stop为1时,时钟芯片时钟芯片DS1302关闭 Write_handle(0x8E,0x00); /根据写状态寄存器命令字,写入不保护指令 Write_handle(0x80,(0/10)4|(0%10); /根据写秒寄存器命令字,写入秒的初始值Write_handle(0x82,(0/10)4|(0%10); /根据写分寄存器命令字,写入分的初始值Write_handle(0x84,(19/10)4|(19%10); /根据写小时寄存器命令字,写入小时的初始值Write_handle(0x86,(14/10)4|(14%10); /根据写日寄存器命令字,写入日的初始值Write_handle(0x88,(5/10)4|(5%10); /根据写月寄存器命令字,写入月的初始值Write_handle(0x8c,(10/10)4|(10%10); /根据写年寄存器命令字,写入年的初始值Write_handle(0x90,0xa5); /打开充电功能 选择2K电阻充电方式Write_handle(0x8E,0x80); /根据写状态寄存器命令字,写入保护指令 /初始化DS18B20传感器bit Initiate_DS18B20(void) bit exit; /储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在 DQ = 1; /先将数据线拉高 for(time=0;time2;time+) /略微延时约6微秒 ; DQ = 0; /再将数据线从高拉低,要求保持480960us for(time=0;time200;time+) /略微延时约600微秒 ; /以向DS18B20发出一持续480960us的低电平复位脉冲 DQ = 1; /释放数据线(将数据线拉高) for(time=0;time10;time+) ; /延时约30us(释放总线后需等待1560us让DS18B20输出存在脉冲) exit=DQ; /让单片机检测是否输出了存在脉冲(DQ=0表示存在) for(time=0;time200;time+) /延时足够长时间,等待存在脉冲输出完毕 ; return (exit); /返回检测成功标志/函数功能:从DS18B20读取一个字节数据 uchar ReadOneChar() uchar i=0;uchar dat; /储存读出的一个字节数据for (i=0;i8;i+) DQ =1; / 先将数据线拉高 _nop_(); /等待一个机器周期 DQ = 0; /单片机从DS18B20读书据时,将数据线从高拉低即启动读时序 _nop_(); /等待一个机器周期 DQ = 1; /将数据线人为拉高,为单片机检测DS18B20的输出电平作准备 for(time=0;time=1; if(DQ=1) dat|=0x80; /如果读到的数据是1,则将1存入datelsedat|=0x00;/如果读到的数据是0,则将0存入dat /将单片机检测到的电平信号DQ存入ri for(time=0;time8;time+); /延时3us,两个读时序之间必须有大于1us的恢复期 return(dat); /返回读出的十六进制数据/函数功能:向DS18B20写入一个字节数据void WriteOneChar(uchar dat)uchar i=0;for (i=0; i8; i+) DQ =1; / 先将数据线拉高 _nop_(); /等待一个机器周期 DQ=0; /将数据线从高拉低时即启动写时序 DQ=dat&0x01; /利用与运算取出要写的某位

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论