《大连理工大学单片机课程设计.docx》由会员分享,可在线阅读,更多相关《大连理工大学单片机课程设计.docx(31页珍藏版)》请在三一办公上搜索。
1、1、设计内容及要求2.1.1、设计内容21. 么设计要求21.&撰写设计报告2.2、总体方案设计2.2.1、方案图22. 么面板布置图22.&方案讨论32.4、明晰任务.43、电路原理图44、程序框图5.4.1、显示子程序流程图54.么实时时钟芯片1302读/写数据流程图65、编程序66、调试66.1、软件调试66. 么仿真调试77、自我感想.78、参考书目89、附录:C语言编程源程序81. 设计内容及要求1. 1、设计内容:以AT89C51单片机为核心,制作一个LCD显示的智能电子钟。1.2、设计要求:(1) 计时:秒、分、时、天、周、月、年。(2) 闰年自动判别。(3) 时间、月、日交替显
2、示。(5) 自定任意时刻自动开/关屏。(6) 计时精度:误差W 1秒/月(具有微调设置)。1.3、撰写设计报告单片机课程设计是以课题或项目设计方式开展的一门课程,具有较强的综合 性、实践性,是工科、工程类院校或职业类院校电类专业在校生的必修课,是将 单片机原理与应用课程的理论知识转变为应用技术的重要教学环节。这一环节不 但能加深对单片机原理的理解,而且还能培养学生的实践动手能力,开发学生的 分析、解决问题的能力。单片机课程设计环节的训练能够让学生知道单片机工程 项目的制作过程,使学生尽早了解单片机系统的开发流程。2. 总体方案设计2.1、方案图2.2、面板布置图2.3、方案讨论方案一:采用实时
3、时钟芯片实时时钟芯片具备年、月、日、时、分、秒计时功能和多点计时功能,计时 数据的更新每秒自动进行一次,不需程序干预。计算机可通过中断或查询方式读 取计时数据进行显示,因此计时功能的实现无需占用CPU的时间,程序简单。此 外,实时时钟芯片多数带有锂电池做后备电源,具备永不停止的计时功能;具有 可编程方波输出功能,可用做实时测控系统的采样信号等;有的实时时钟芯片内 部还带有非易失性RAM,可用来存放需长期保存但有时也需变更的数据,由于功 能完善,精度高,软件程序设计相对简单,且计时不占用CPU时间,因此,在工 业实时测控系统中多采用这一类专用芯片来实现实时时钟功能。方案二:软件控制利用单片机内部
4、的定时/计数器进行中断定时,配合软件延时实现时、分、 秒的计时及秒表计时。该方案节省硬件成本,且能使设计者对单片机的指令系统 能有更深入的了解,从而掌握单片机应用技术MCS-51汇编语言程序设计方法, 因此,本系统设计采用此种软件控制方法来实现计时。而由于 Atmel公司的 AT89C51是一种自带4KB Flash存储器的低电压、高性能的CMOS 8位微处理 器。该器件采用Atmel高密度非易失存储器制造技术制造,与工业标准的 MCS-51指令集和输出引脚相兼容。AT89C51将多功能8位CPU和闪存集成在 单个芯片中,是一种高效的微控制器,使用也更方便,寿命更长,可以反复 擦除1000次。
5、形成了功能强大、使用灵活和具有较高性能价格比的微控制器。 它的功能强大,而且也比较容易购买,故本设计中所选的单片机为AT89C51单 片机。2.4、明晰任务采用AT89C51单片机作为系统的控制核心。时钟数据通过市场上流行的时钟 芯片DS1302来获取。DS1302是DALLAS公司推出的涓流充电时钟芯片,内含一 个实时时钟/日历和31字节静态RAM,可以通过串行接口与计算机进行通信,使 得管脚数量减少。实时时钟/日历电路能够计算2100年之前的秒、分、时、日、 星期、月、年的,具有闰年自动判断调整的能力。定时电路能够实现自定任意 时刻自动开/关屏,采用LCD LM016L显示年、月、周、天、
6、时、分、秒。通过 按键开关实现微调,确保计时精度:误差W 1秒/月。DS1302时钟芯片的主要功能特性:(1) 能计算2100年之前的年、月、日、星期、时、分、秒的信息;每月的天数 和闰年的天数可自动调整;时钟可设置为24或12小时格式。(2) 31B的8位暂存数据存储RAM。(3) 串行I/O 口方式使得引脚数量最少。(4) DS1302与单片机之间能简单地采用同步串行的方式进行通信,仅需3根线。(5) 宽范围工作电压2.0-5.5V。(6) 工作电流为2.0A时,小于300nA。(7) 功耗很低,保持数据和时钟信息时功率小于1mW。3. 电路原理图4. 程序框图4.1、显示子程序流程图4.
7、2、实时时钟芯片1302读/写数据流程图5. 编程序源程序见附录部分6. 调试6.1、软件调试目前设计过程中容易造成元件和仪器仪表的损坏,而借助Keil和Proteus 进行单片机系统的开发,可以节省设计成本,提高设计速度。Keil软件包是一个功能强大的开发平台,它包括项目管理器、CX51编译器、 AX51宏汇编器、BL51/LX51连接定位器、RTX51实时操作系统、Simulator软件 模拟器及Monitor51硬件目标调试器。它是一种集成化程度高的文件管理编译环 境,主要功能为编译C语言源程序,汇编程序或混合语言源程序,连接和定位目 标文件和库,创建HEX文件,调试目标程序等。Keil
8、是目前最好的51单片机开 发工具之一。Keil支持软件模拟仿真(Simulator)和用户目标调试(Monitor51) 两种工作模式。前者不需要任何单片机硬件即可完成用户程序仿真、调试,后者 利用硬件目标板中的监控程序可以直接调试目标硬件系统。Proteus是一个完整的嵌入式系统软件、硬件设计仿真平台,它包括原理图 输入系统ISIS、带扩展的Prospice混合模型仿真器、动态元件库、高级图形分 析模块和处理器虚拟系统仿真模型VSMO ISIS是Proteus系统的中心,具有超强 的控制原理设计环境。ProteusVSM最重要的特点是能把微处理器软件作用在处 理器上,并和该处理器的任何模拟和
9、数字元件协同仿真,仿真执行目标码就像在 真正的单片机系统上运行一样,VSMCPU模型能完整仿真I/O接口、中断、定时 器、通用外部设备口及其他与CPU有关的外部设备,甚至能仿真多个处理器。6.2、仿真调试Keil仿真:Proteus 仿真:MlClack-U3 回Til*: date? 23*11-11LS护一 LW _ iTT-TT -pn-ihirD.v.R.ii+Pn-4-vb4EShfiPD.H.13.彰一:|云寺芸务_口Fl-tfrfElDll 11-JJT16:25:137自我感想经历过这么多天不间断的课程设计,我们有挺多感触的,从最基本上说我们 看到了,也意识到了自己的不足,对于
10、不断克服的各种阻碍也让我们体会到了课 程设计的意义所在。对于只接触课本只动笔杆的我们,面临实际的设计尺寸,让我们很是尴尬, 都说理论联系实际,真正到联系的时候才发现挺困难的,不过正是理论知识的各 种补充才让我们能最终完成任务,然后深深地体会到理论对现实的指导作用。我 们现在最缺乏的就是实际工作经验,而理论联系实践并不像我们想象的那么简单, 他需要坚实的理论基础和实际工作经验。坚实的理论基础决定了我必须坚持学习 新的知识新的理论,完善了自己的知识结构,才能在以后的实际中轻松面对,才 能设计出更好的更有益于人们生活与工作的机械,才能跟上时代的步伐,不被淘 汰。在这个一边忙着复习忙着考试又要准备课程
11、设计的日子里,真真正正的体会 到了时间的宝贵,有点像高中忙忙碌碌的生活,不过能按时完成课程设计对我们 来说也是一个莫大的安慰。严谨和细心是做机械设计的必要态度,要想做好一件事,就必须一丝不苟、 态度认真。俗话说:“失之毫厘,谬之千里。”在机械设计上尤其应该注意。在以 后的工作中,你的很小的一个疏忽将会造成一个公司很大的损失,甚至给用户带 去生命危险,而自己也会为自己的不负责任行为付出代价。再者就是设计中要严谨和细心,对于机械是不能出差错的,任何的微小误差 都可能产生不可预计的后果,当然对于我们来说就是设计中要走一些弯路,而且 在这个严重缺少时间又惦记回家问题的我们来说也是一个很严重的后果。不过
12、,困难虽是难免的,但我们有信心就能并且已经战胜了困难,完成了这 个无比揪心的课程设计。因为时间等各种关系设计中难免有些不足还请老师助教给予批评和帮助。8. 参考书目单片机原理及其应用教程张元良主编MCS-51系列单片机原理及应用孙涵芳主编新概念51单片机C语言教程郭天祥 主编51单片机课程设计周向红 主编9. 附录:C语言编程源程序#include#include/#define uint unsigned int#define uchar unsigned char/*ucharcodetable=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf 8, 0x80,
13、0x98,0x88,0x83,0xc6,0xa1,0x86,0x8e;/ 共 阳极数码管代码 */ ucharcodexingqi8 = 0x00,0x07,0x01,0x02,0x03,0x04,0x05, 0x06);/星期显示代码ucharmiao,shi,fen,date,month,day,year,year10,set,mun,set_shi,set_fen,timeflag;/全局定义uint year_data,t;/sbit SCLK=P35; /DS1302 通讯线定义sbit DIO=P3”6;sbit RST=P3”7;sbit speak=P0”0;sbit DS=P
14、20; /595 通讯线定义sbit SH_CP=P2”1;sbit ST_CP1=P2”2;sbit ST_CP2=P2”3;sbit ST_CP3=P2”4;sbit ST_CP4=P2”5;sbit ST_CP5=P2”6;sbit ST_CP6=P2”7;sbit ST_CP7=P3”0;sbit ST_CP8=P3”1;sbit OE1=P0;sbit OE2=P1;sbit OE3=P2;sbit OE4=P3;sbit OE5=P4;sbit OE6=P5;sbit OE7=P6;sbit OE8=P7;sbit K1=P32;/按键接口定义sbit K2=P3”3;sbit K
15、3=P3”4;sbit K4=P0”1;sbit K5=P0”2;/void write_595(uchar temp) /写 74HC595 一个字节(uchar temp_595,i;temp_595=temp;for(i=0;i8;i+)(SH_CP=0;_nop_();_nop_();_nop_();if(temp_595&0x80)(DS=1;else(DS=0;_nop_();_nop_();_nop_();SH_CP=1;temp_5950;x-)for(y=112;y0;y-);/void delaynus(uint z) /ums 延时(uint x,y;for(x=z;x0
16、;x-)for(y=10;y0;y-);/void write(uchar date) /写入 DS1302 一个字节(uchar temp,i;RST=1;SCLK=0;temp二date;for(i=0;i=1;/uchar read() /读出 DS1302 一个字节(uchar a,temp;RST=1;for(a=8;a0;a-)(temp=1;SCLK=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();SCLK=0;if(DIO)(temp二temp|0x80;else(temp二temp|0x00;return (
17、temp);/void write_1302(uchar add,uchar dat) /写 DS1302 数据(RST=0;SCLK=0;RST=1;write(add);write(dat);SCLK=1;RST=0;/uchar read_1302(uchar add) / 读 DS1302 数据(uchar temp;RST=0;SCLK=0;RST=1;write(add);temp二read();SCLK=1;RST=0;return(temp);/void display() /显示子程序(miao=read_1302(0x81); 读秒fen=read_1302(0x83);
18、/读分shi=read_1302(0x85)&0x3f;/读时date=read_1302(0x87); 读日month=read_1302(0x89); /读月year=read_1302(0x8d); 读年day=read_1302(0x8B); /读星期write_595(miao); /显示秒ST_CP1=0;ST_CP1=1;ST_CP1=0;delaynus(10);write_595(fen); /显示分ST_CP2=0;ST_CP2=1;ST_CP2=0;delaynus(10);write_595(shi); /显示时ST_CP3=0;ST_CP3=1;ST_CP3=0;de
19、laynus(10);write_595(date); /显示日ST_CP4=0;ST_CP4=1;ST_CP4=0;delaynus(10);write_595(month); 显示月 读ST_CP5=0;ST_CP5=1;ST_CP5=0;delaynus(10);write_595(year); /显示年ST_CP6=0;ST_CP6=1;ST_CP6=0;delaynus(10);write_595(xingqiday); /显示星期ST_CP7=0;ST_CP7=1;ST_CP7=0;delaynus(10);/void ds1302_init() /1302 初始化(RST=0;S
20、CLK=0;/*write_1302(0x80,0x00);/设置初始值 SECwrite_1302(0x82,0x00);/设置初始值 MINwrite_1302(0x84,0x00);/设置初始值 HRwrite_1302(0x86,0x00);/设置初始值 DATEwrite_1302(0x88,0x00);/设置初始值 MONTHwrite_1302(0x8A,0x00);/设置初始值 DAY*/write_1302 (0x8C,0x10);/设置初始值 YEAR/void PORT_INIT() /端口初始化(P0=0XFE;P1=0X00;P2=0X00;P3=0XFC;void
21、time_init() /定时器初始化(TMOD=0x11; /设置定时器01都为工作方式1TH0=(65536-50000)/256; /装入初值TL0=(65536-50000)%256;TH1=(65536-10000)/256; /装入初值TL1=(65536-10000)%256;PT0=1; /T0定时器优先级最高EA=1 ;/开总中断ET0=1;/开定时器0中断ET1=1;/开定时器1中断TR0=1;/启动定时器0TR1=1; /启动定时器1/void main(void) 主程序(PORT_INIT();ds1302_init();time_init();year=read_1
22、302(0x8d); 读年数据year_data=0x2000|year;write_595(year_data8); /显示 2010 年的 20 字样ST_CP8=0;ST_CP8=1;ST_CP8=0;set_shi=0x09; 闹钟初始值设定set_fen=0x39;time_flag=0; /标志位set=0;while(1)(switch(set)(case 0: /设置秒(display(); /显示子程序if(shi=set_shi)&(fen=set_fen)&(time_flag=0) 闹钟设定 只设定 小时和分钟(speak=speak;if(K2=0)&(time_fl
23、ag=0) 按键 K2 停 止闹钟响(P0&=0XFE;time_flag=1;delay(10);break;if (fen=set_fen+1) /当不按下闹钟停止按键,一分钟后自动停止闹钟(P0&=0XFE; time_flag=0;/void time0()interrupt 1 / 定时器 0 中断(TR0=0;TH0=(65536-50000)/256;TL0=(65536-50000)%256;mun+;if(mun=15)(mun=0;switch(set)(case 1: /设置秒闪烁(OE1=1;delay(300);OE1=0;break;case 2: /设置分闪烁(O
24、E2=1;delay(300);OE2=0;break;case 3: /设置时闪烁(OE3=1;delay(300);OE3=0;break;case 4: /设置日闪烁(OE4=1;delay(300);OE4=0; break;case 5: /设置月闪烁(delay(300);OE5=0;break;case 6: 设置年闪烁(OE6=1;OE8=1;delay(300);OE6=0;OE8=0;break;case 7: /设置星期闪烁(OE7=1;delay(200);OE7=0;break;case 8: /设置闹钟闪烁(OE2=1;OE3=1;delay(200);OE2=0;
25、OE3=0;break;TR0=1;/void time1()interrupt 3 / 定时器 1 中断(TR1=0; /先关定时器TH1=(65536-20000)/256;TL1=(65536-20000)%256;/if(K1=0)(delay(10);if(K1=0)(set+;if(set=9)(set=0;write_1302(0x80,miao); /设置初始值 SECwrite_1302(0x82,fen); 设置初始值 MINwrite_1302(0x84,shi); 设置初始值 HRwrite_1302(0x86,date); /设置初始值 DATEwrite_1302(
26、0x88,month); / 设置初始值 MONTHwrite_1302(0x8A,day); 设置初始值 DAYwrite_1302(0x8C,year_data); 设置初始值 YEARt=50000;while(!K1)&t)( t-;/if(K2=0)(delay(10);if(K2=0)(switch(set)(case 1:(miao+;if(miao&0x0f)0x09)(miao+=0x10;miao&=0xf0;if(miao=0x60)(miao=0x00;write_595(miao);ST_CP1=0;ST_CP1=1;ST_CP1=0;break;case 2:(fe
27、n+;if(fen&0x0f)0x09)(fen+=0x10;fen&=0xf0;if (fen=0x60)(fen=0x00;ST_CP2=0;ST_CP2=1;ST_CP2=0; break;case 3:(if(read_1302(0x85)&0x80)=0x00)(shi+;if(shi&0x0f)0x09)(shi+=0x10;shi&=0xf0;if(shi=0x24) /24 小时制(shi=0x00;else(shi=(shi|0x80)+1;if(shi&0x0f)0x09)(shi+=0x10;shi&=0xf0;if(shi=0x12) /12 小时制(shi=0X80;
28、一write_595(shi); /显示时ST_CP3=0;ST_CP3=1;ST_CP3=0; break;case 4:(date+;if(date&0x0f)0x09)(date+=0x10;date&=0xf0;if(date=0x32)&(month=0x01)|(month=0x03)|(month=0x05)|(month=0x07)|(month=0x08)|(month=0x10)|(month=0x12)(date=0x01;elseif(date=0x31)&(month=0x04)|(month=0x06)|(month=0x09)|(month=0x11)(date=
29、0x01;elseif(date=0x29)&(month=0x02)&(year_data|read_1302(0x8d)%100!=0)&(year_data|read_1302(0x8d)%400!=0)(date=0x01;elseif(date=0x30)&(month=0x02)&(year_data|read_1302(0x8d)%100=0)&(year_data|read_1302(0x8d)%400=0)(date=0x01;write_595(date);ST_CP4=0;ST_CP4=1;ST_CP4=0; break;case 5:(month+;if(month&0
30、x0f)0x09)(month+=0x10;month&=0xf0;if(month=0x13)(month=0x01;write_595(month);ST_CP5=0;ST_CP5=1;ST_CP5=0; break;case 6:(year_data+;if(year_data&0x000f)=0x0a)(year_data+=0x0010;year_data&=0xfff0;if(year_data&0x00ff)=0xa0)(year_data+=0x0100; /向前进 1year_data&=0xff00; 后面尾数归 0write_595(year_data);ST_CP6=0
31、;ST_CP6=1;ST_CP6=0;write_595(year_data8);ST_CP8=0;ST_CP8=1;ST_CP8=0; break;case 7:(day+;if(day&0x0f)=0x08)(day=0x01;write_595(xingqiday);ST_CP7=0;ST_CP7=1;ST_CP7=0; break;t=50000;while(!K2)&t)(t-;/if(K3=0)(delay(10);if(K3=0)(switch(set)(case 1:(miao-;if(miao&0x0f)=0x0F)(miao&=0xf9; 减到0后,再减一次就归0,if(m
32、iao=0xF9) /当全部减到00时,再减一次就为59(miao=0x59;write_595(miao);ST_CP1=0;ST_CP1=1;ST_CP1=0; break;case 2:(fen-;if(fen&0x0f)=0x0F)(fen&=0xf9;if(fen=0xF9)(fen=0x59;write_595(fen);ST_CP2=0;ST_CP2=1;ST_CP2=0; break;case 3:(if(read_1302(0x85)&0x80)=0x00)(shi-;if(shi&0x0f)=0x0F)(shi&=0xf9;if(shi=0xF9) /24 小时制(shi=
33、0x23;else(shi=(shi|0x80)-1;if(shi&0x0f)=0x0F)(shi&=0xf9;if(shi=0xF9) /12 小时制(shi=0X12;write_595(shi);/显示时ST_CP3=0;ST_CP3=1;ST_CP3=0;break;case 4:(date-;if(date&0x0f)=0x0F)(date&=0xf9;if(date=0x00)&(month=0x01)|(month=0x03)|(month=0x05)|(month=0x07)|(month=0x08)|(month=0x10)|(month=0x12)(date=0x31;el
34、seif(date=0x00)&(month=0x04)|(month=0x06)|(month=0x09)|(month=0x11)(date=0x30;elseif(date=0x00)&(month=0x02)&(year_data|read_1302(0x8d)%100!=0)&(year_data|read_1302(0x8d)%400!=0)(date=0x28; elseif(date=0x00)&(month=0x02)&(year_data|read_1302(0x8d)%100=0)&(year_data|read_1302(0x8d)%400=0)(date=0x29;w
35、rite_595(date);ST_CP4=0;ST_CP4=1;ST_CP4=0;break;case 5:(month-;if(month&0x0f)=0x0F)(month&=0xf9;if(month=0x00)(month=0x12;write_595(month);ST_CP5=0;ST_CP5=1;ST_CP5=0;break;case 6:(year_data-;if(year_data&0x000f)=0x0F)(year_data&=0xfff9;if(year_data&0x00f0)=0xF0)(year_data&=0xf999;write_595(year_data
36、);ST_CP6=0;ST_CP6=1;ST_CP6=0;write_595(year_data8);ST_CP8=0;ST_CP8=1;ST_CP8=0; break;case 7:(day-;if(day&0x0f)=0x00)(day=0x07;write_595(xingqiday);ST_CP7=0;ST_CP7=1;ST_CP7=0; break;t=50000;while(!K3)&t) /松手检测(t-;/switch(set)(case 8:(if(K4=0)(delay(10);if(K4=0)(if(read_1302(0x85)&0x80)=0x00)(set_shi+
37、;if(set_shi&0x0f)0x09)(set_shi+=0x10;set_shi&=0xf0;if(set_shi=0x24) /24 小时制(set_shi=0x00;else(set_shi=(set_shi|0x80)+1;if(set_shi&0x0f)0x09)(set_shi+=0x10;set_shi&=0xf0;if(set_shi=0x12) /12 小时制(set_shi=0X80;write_595(set_shi); / 显示闹钟的时 ST_CP3=0;ST_CP3=1;ST_CP3=0;t=50000;while(!K4)&t)(t-;/if(K5=0)(de
38、lay(10);if(K5=0)(set_fen+;if(set_fen&0x0f)0x09)(set_fen+=0x10;set_fen&=0xf0;if(set_fen=0x60)(set_fen=0x00;write_595(set_fen);ST_CP2=0;ST_CP2=1;ST_CP2=0;t=50000;while(!K5)&t)(t-;/if(K4=0)|(K5=0)&(set=0)(delay(10);if(K4=0)|(K5=0)&(set=0)(一write_595(set_shi); /显示闹钟的时ST_CP3=0;ST_CP3=1;ST_CP3=0;write_595(set_fen);ST_CP2=0;ST_CP2=1;ST_CP2=0;P1=0XF9;while(!K4)|(!K5);P1=0X00;/TR1=1; /退出时开定时器/