《功多能旋转电子钟课程设计大学论文.doc》由会员分享,可在线阅读,更多相关《功多能旋转电子钟课程设计大学论文.doc(32页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、目录1 工作原理31.1 功能说明31.2 工作原理31.2.1 60个发光二极管驱动原理41.2.2 时、分、年、月、日、星期显示部件驱动原理42 电路图53 程序流程图73.1 时钟LED显示函数程序流程图73.2 电子钟数显示日期函数程序流程图83.3 电子钟显示时间函数程序流程图113.4 电子钟显示星期函数程序流程图134 仿真图165 总结186 参考文献197 致谢208 附录一:器件清单219 附录二:源代码221 工作原理1.1 功能说明1. 本旋转LED电子钟采用STC89C52单片机作为控制芯片,DS1302时钟芯片为走时根据,确保了走时的精确度。24小时制走时,60个发
2、光二极管模拟石英钟的秒针走时,一秒亮一个,60秒走完一圈,走完一圈则分钟位数数码管加1,时时同步。主数码管为4位时钟数码管,显示时、分,结合功能按键,可显示闹钟时间和实时温度(需加装18B20);3个2位数码管分别显示年、月、日;1个1位数码管显示星期。2. 整点报时功能,每天720点整点报时,报时时蜂鸣器响,同时秒灯高速旋转。3. 有一路闹钟功能,开机闹钟默认关闭。S3位闹钟的开关键。默认闹钟时间为6:35。闹钟响时为30秒钟。4. 掉电继续走时,数码管不显示。来电时间继续走时,不用调整。5. S1键为调整按键。开机显示时分00:08。首次使用一定要启动时钟芯片走时,不然时钟一直为00:08
3、,不走时。按S1键一次,时位数码管闪烁,这时按S2数值加1,按S3数值就会减1。再按一次S1键,分位数码管闪烁,同理按S2、S3键来进行调整分的时间。调整完后数码管还在闪烁,同理在按S1(S2,S3),分别调整年、月、日、星期,调整完后再按S1一次(或等待5秒),进入走时状态。6. S2键为时间、闹钟、温度(安装18B20)切换键。正常显示时间模式下,按S2一次则可显示闹钟时间,按二次显示当前温度(如29.6),按第三次则显示正常显示模式(即走时时间)。在显示闹钟时,按S1键一次则闹钟的时位数码管会闪烁,这时可以按S2键和S3键进行调整。按S1键二次则闹钟的分位数码管会闪烁,同理可按S2和S3
4、键进行闹钟时间调整。7. S3为闹钟的开关键。正常显示时间模式下,按S3一次则打开闹钟,同时红色指示灯(D73)点亮,按二次则关闭闹钟,同时关闭红色指示灯(D73)。1.2 工作原理1.2.1 60个发光二极管驱动原理采用了两片CD4017进行六十进制计数译码,实现60个发光二极管的驱动。CD4017芯片是十进制计数时序译码器,共有10个译码输出Q0Q9;每个译码输出一般处于低电平,且在时钟脉冲由低到高的上升沿输出高电平;每个高电平输出维持一个时钟周期;每输入10个时钟脉冲,输出一个进位脉冲,因此进位输出信号可作为下一级计数器的时钟信号。在清零输入端(R)加高电平或正脉冲时,只有输出端Q0为高
5、电平,其余为低电平。为实现对应的发光二极管点亮,应将每一个译码输出口对应的接一个发光二极管,每10个一组接限流电阻后接地。当译码端口Q0Q9中任一端口为高电平,则对应的发光二极管点亮。在这次多功能旋转电子钟我们采用了两片CD4017来实现60个发光二级管的旋转点亮。1.2.2 时、分、年、月、日、星期显示部件驱动原理LED数码管通常由7段译码集成电路组成,完成从数字到显示码的译码驱动。本系统中采用的是软件译码,可以减少该实物的体积,降低成本和功耗,比硬件译码有更大的灵活性。软件译码就是从数字到显示码的转换全由单片机完成。从LED数码管的原理和结构可知,为了显示字符,要为LED显示数码管提供显示
6、段码,组成一个“8”字形字符的7段,再加上1个小数点位,共计8段,因此提供给LED显示数码管的显示段码为一个字节。 系统的时、分显示部件由1个4只7段共阳LED数码管组成,前两只显示时,后两只用于分的显示;年、月、日的显示部件由3个2只7段共阳LED数码管组成;星期的显示部件由1个1只7段共阳LED 数码管组成。2 电路图3 程序流程图3.1 时钟LED显示函数程序流程图图3.1.1主程序流程图3.2 电子钟数显示日期函数程序流程图开始按键是否按下 所设定的值加1所设定的值是否上限清零结束延时10ms按键是否按下等待按键释放将新值写入DS1302中图3.2.1按键检测程序流程图开始将需写入的数
7、据从低到高位送入DS302中将写地址指令从低到高位送入DS302中结束将RST置零, SCLK置零, RST置一图3.2.2写数据函数开始将数据由低到高位从DS1302中读出将读地址指令从低到高位送入DS302中结束将RST置零, SCLK置零, RST置一图3.2.3读数据函数开始将年、月、日从DS1302中读出结束图3.2.4读时间函数开始分别将年、月、日的初始值写入DS1302写保护,相当于缓冲结束图3.2.5初始化函数开始数码管的段选显示需显示的数字数码管的位选控制数码管显示结束数码管的段选口全置高延时图3.2.6数码管显示函数开始读时间函数初始化时间按键扫描程序数码管显示年、月、日图
8、3.2.7主函数3.3 电子钟显示时间函数程序流程图开始RST先置0,SCLK值1,再将RST置1从低到高按位送入所写地址结束从低到高按位送入所写数据图3.3.1写数据和地址函数开始RST先置0,SCLK值1,再将RST置1从低到高按位送入读地址指令结束从低到高按位读出所写数据图3.3.2读地址函数图3.3.3初始化时和分函数图3.3.4读取时和分函数开始检验按键1是否按下结束延时消抖确认按键1按下后未超过设定上限值则时加1检验按键2是否按下延时消抖确认按键2按下后未超过设定上限值分加1图3.3.5按键扫描函数开始数码管段选置高消隐结束位选控制显示段选控制所显示数字图3.3.6显示函数开始初始
9、化函数时间函数结束按键扫描函数读取时和分函数图3.3.7主函数3.4 电子钟显示星期函数程序流程图图3.4.1主函数图3.4.2写函数图3.4.3读函数图3.4.4初始化时间函数图3.4.5按键扫描函数流4 仿真图图4.1时钟LED显示图4.2数码管日期显示图4.3数码管时间显示图4.4数码管星期显示5 总结经过这次的嵌入式课程设计,基本上完成了课题的要求,功能基本完善:时钟显示,整点报时,闹钟功能。时钟显示功能其精确度基本可以满足要求,调时功能方便快捷,报时闹钟准确。硬件设施符合要求,软件设计可以配合硬件实现要求功能。此次课程设计使我更进一步地熟悉了STC89C52芯片的结构及掌握了芯片的工
10、作原理和其具体的使用方法。也锻炼了自己独立思考问题的能力和通过查看相关资料来解决问题的习惯。设计中遇到了很多意想不到的问题,从一开始的通过Protel设计原理图,到Proteus仿真与编写程序,最后是PCB板子的焊接,一直都是在发现问题和解决问题中度过。还好自己一路坚持了下来,把问题一一解决。其实这些都不是问题,只要有耐心,够细心,都可以把它们解决。此次课程设计中出现的主要问题有如下几个: 在用Protel画电路图之前完全没有看懂图纸。后面通过王文虎老师给我们讲述才能大概理解电路图每个模块的功能。 用Proteus仿真时不能出现正确的结果,比如所有的发光二极管都不能点亮、某些数码管显示不了时间
11、等等。后面更据王老师的建议分块仿真解决了这些问题。 在PCB板子焊接的时候,错放了元器件电阻,幸运的是即使从新焊接过正确的器件。总的来说,通过这次课程设计我了解了课程设计的一般步骤,和设计中应注意的问题。设计本身并不是有很重要的意义,而是在于个人对待问题时的态度和处理事情的能力。6 参考文献1曾屹.单片机原理与应用(第二版)M.长沙:中南大学出版社,20092周润景.基于Proteus的电路及单片机系统设计与仿真M.北京:北京航空航天大学出版社,20063周润景.Proteus入门实用教程M.北京:机械工业出版社,20074林立等.单片机原理及应用基于Proteus和Keil CM.北京:电子
12、工业出版社,20125孙育才等.Atmel新型AT89S52系列单片机及其应用M.北京:清华大学出版社,20056 7 7 致谢时光飞逝,转眼间大学生活即将过去,大学生活中有苦、有乐。我想这将是我以后最值得回念的一段时光。此次课程设计能够顺利的完成,还得感谢父母、老师和同学的帮助。首先,我要感谢的是养育了我20年的父母,是他们给予了我生命,给了我美好的人生开端,现在让我有机会进入大学,开拓视野,增长见识。为了供养我读书,他们每天起早贪黑,辛勤劳作,在生活上非常节俭。每次回家,当我还在睡梦中的时候,他们已经出去上班了,而且经常需要上晚班,工作很辛苦。对我来说父亲是位睿智的良师,在我小时候他就教诲
13、我“得意时淡然、失意时坦然”。母亲对我来说是位难得的益友,她会在我不开心的时候,听我述说烦恼,并鼓励我继续向前。对此我非常感谢他们对我的理解与支持。最后,我再次对所有帮助我、关心我和支持我的老师、家人、同学、朋友致以最崇高的敬意!谢谢大家!8 附录一:器件清单序号代号名称型号或规格数量备注1PCB板15.6X15.61硬板2DS1数码管4位13DS2、3、4数码管2位34DS5数码管1位15U1单片机STC89C5216U1插座DIP4017U2时钟芯片DS1302,SSOP818U4、U5计数器CD4017,DIP1629D5,D10,D15,D20D25,D30,D35D40,D45,D5
14、0,D55D60发光二极管方形、绿色1210D61D72发光二极管方形、红色1211D14,D69,D11D14,D16D19,D21D24,D26D29,D31D34,D3639,D41D44,D46D49,D51D54,D56D59发光二极管5、绿色4812D73发光二极管3、红色113Q0二极管IN4148114Q1Q13三极管S85501315Q14Q19三极管S8050616BELL蜂鸣器5V117Y1晶振11.0592MHz118Y2晶振32. 768 kHz119C3,C4瓷片电容6p220C1,C2瓷片电容30p221C8瓷片电容104222C5电解电容10F/25V123C6
15、,C7电解电容220F/16V124S1,S2,S3按键4脚按键325R1R19,R21R33电阻3k/0.25W3726R34R39电阻510/0.25W627R20电阻62/0.25W1短接28BTi电池3V129BTi电池座CR2032-2130DC5V电源插座5.52.1131DS1电源线USB接头,80cm19 附录二:源代码1. 时钟LED显示函数 #include #define uint unsigned int #define uchar unsigned char sbit clk=P14; uchar num; void main() TMOD=0x01;/设置定时器0为
16、工作方式1 TH0=(65536-45872)/256;/装初值11.0592M晶振定时50ms为45872 TL0=(65536-45872)%256; EA=1;/开总中断 ET0=1;/开定时器0中断 TR0=1;/启动定时器0 while(1)if(num=10)num=0;clk=clk; void T0_time() interrupt 1 /中断函数 TH0=(65536-45872)/256; TL0=(65536-45872)%256; num+; 2. 数码管显示日期#include#define uchar unsigned char#define uint unsign
17、ed intsbit SCLK=P12;sbit SDA=P11; sbit RST=P10;/ DS1302复位sbit set1=P13;/定义按键端口sbit set2=P14;sbit set3=P15;uint nian=16,yue=6,ri=19,xingqi,fen,shi,miao;uchar code JD=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;/共阳极数码管显示0-9数字16进制编码 void write(uchar add,uchar date);void key();void init_time();voi
18、d delay(unsigned char i);void get_time();void display();void delayms(uint xms); /延时xms函数void main() /主函数 init_time(); while(1) key(); get_time(); display(); void write(uchar add,uchar date)uchar temp,t; RST=0; SCLK=0; RST=1; temp=add;for(t=0;t1;temp=date;for(t=8;t0;t-) /写数据 if(temp&0x01)=1) SDA=1; e
19、lse SDA=0; SCLK=1; delay(5); SCLK=0; temp=temp1;uchar read(uchar add)uchar temp,t; RST=0; SCLK=0; RST=1; temp=add;for(t=0;t=1;temp=0; for(t=0;t=1; /传送一个字节需要16个时钟return temp/16*10+temp%16;/将BCD码转换成10进制码 void init_time()write(0x8e,0x00);/写保护,相当于初始化或者缓冲write(0x86,(ri/104)|(ri%10); /写日write(0x88,(yue/10
20、4)|(yue%10);/写月write(0x8c,(nian/104)|(nian%10);/写年 /显示时间void get_time()nian=read(0x8d);/读出时间 年yue=read(0x89);/读出时间 月ri=read(0x87);/读出时间 日 void key() if(set1=0) delayms(20); if(set1=0) nian+; if(nian=100) nian=0; while(set1=0); write(0x8c,(nian/104)|(nian%10); if(set2=0) delayms(20); if(set2=0) yue+;
21、 if(yue=13) yue=0; while(set2=0); write(0x88,(yue/104)|(yue%10); if(set3=0) delayms(20); if(set3=0) ri+; if(ri=32) ri=0; while(set3=0); write(0x86,(ri/100;i-) for(j=110;j0;j-); void delay(unsigned char i) while(i-=0); void display() P3=0x00; /将P36和P37值低电平 P0=0xff; / ./P2=0x08; / 第一个数码管显示为0/P0=JDnian
22、/10; /./delayms(6); /延时6msP0=0xff; /将P0口置高电平,消影P2=0x04; / ./P0=JDnian%10; / 第二个数码管显示为1/ delayms(6); /./ P0=0xff;P2=0x02; / ./P0=JDyue/10; / 第三个数码管显示为2/ delayms(6); / ./P0=0xff;P2=0x01; / ./P0=JDyue%10; / 第四个数码管显示为3/ delayms(6); / ./P2=0x00; P0=0xff; / ./P3=0x80; / 第五个数码管显示为4/P0=JDri/10; / ./ delayms
23、(6); P0=0xff; / ./P3=0x40; / 第六个数码管显示为5/P0=JDri%10; / ./ delayms(6);3. 数码管显示时间#include#define uchar unsigned char#define uint unsigned intsbit SCLK=P12;sbit SDA=P11; sbit RST=P10;sbit key1=P14;sbit key2=P15;uint fen,shi;uchar code table=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;/共阳极数码管显示0-9码
24、表 void delayms(uint x) /延时ms函数 uint i,j; for(i=x;i0;i-) for(j=110;j0;j-); void write(uchar add,uchar date) /写数据和地址uchar temp,t; RST=0; SCLK=0; RST=1; temp=add;for(t=0;t1;temp=date;for(t=8;t0;t-) /写数据 if(temp&0x01)=1) SDA=1; else SDA=0; SCLK=1; delayms(1); SCLK=0; temp=temp1;uchar read(uchar add)/读地址
25、uchar temp,t; RST=0; SCLK=0; RST=1; temp=add;for(t=0;t=1;temp=0; for(t=0;t=1; return temp/16*10+temp%16;/将16进制转换成10进制 void init_time()/初始化时和分write(0x8e,0x00);/写保护,相当于初始化或者缓冲write(0x82,0x00);/写分write(0x84,0x12); /写时 void get_time()/读取显示时间shi=read(0x85);/读出时间 时fen=read(0x83);/读出时间 分void key() /按键扫描函数
26、if(key1=0) delayms(10); if(key1=0) shi+; if(shi=24) shi=0; while(key1=0); write(0x84,(shi/104)|(shi%10);/写时 if(key2=0) delayms(10); if(key2=0) fen+; if(fen=60) fen=0; while(key2=0);write(0x82,(fen/104)|(fen%10);/写分 void display()/数码管显示函数 P0=0xff; P2=0x80; P0=tableshi/10;/ 第一个数码管显示小时的十位delayms(6);/延时
27、6msP0=0xff;/将P0口置高电平,消影P2=0x40; P0=tableshi%10;/ 第二个数码管显示小时的个位 delayms(6); P0=0xff;P2=0x20;P0=tablefen/10; / 第三个数码管显示分钟的十位 delayms(6);P0=0xff;P2=0x10;P0=tablefen%10; / 第四个数码管显示分钟的个位 delayms(6); void main() /主函数 init_time(); while(1) key(); get_time(); display();4. 数码管显示星期#include#define uchar unsign
28、ed char#define uint unsigned intsbit RST=P10;sbit IO=P11;sbit SCLK=P12; sbit key=P30;sbit a=P35;uchar tian ;uchar code table=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8; void write(uchar add,uchar date);void keyscan();void init_time();void delay(uchar i);void get_time();void delayms(uint xms); void main
29、() init_time(); while(1) keyscan();get_time(); a=0; if(tian=8)tian=0; P0=tabletian; delayms(100); void write(uchar add,uchar date)uchar temp,t; RST=0; SCLK=0; RST=1; temp=add;for(t=0;t1;temp=date;for(t=8;t0;t-) /写数据if(temp&0x01)=1)IO=1;elseIO=0;SCLK=1;delay(5);SCLK=0;temp=temp1;uchar read(uchar add)
30、uchar temp,t; RST=0; SCLK=0; RST=1; temp=add;for(t=0;t=1;temp=0; for(t=0;t=1; return temp/16*10+temp%16;/将BCD码转换成10进制码 void init_time()write(0x8e,0x00); /开写保护 write(0x8a,(tian/104)|(tian%10); /写星期 write(0x8e,0x80); /关写保护void get_time()tian=read(0x8b);/读星期 void keyscan() if(key=0) delayms(10); if(key=0) tian+; if(tian=8) tian=0;while(key=0); write(0x8e,0x00); /开写保护 write(0x8a,(tian/100;i-) for(j=110;j0;j-); void delay(uchar i) while(i-=0);