电子万年历课程设计报告.doc_第1页
电子万年历课程设计报告.doc_第2页
电子万年历课程设计报告.doc_第3页
电子万年历课程设计报告.doc_第4页
电子万年历课程设计报告.doc_第5页
免费预览已结束,剩余36页可下载查看

下载本文档

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

文档简介

机电信息工程学院单片机系统课程设计报告系 别:专 业:班 级:设计题目:学生姓名:指导教师:完成日期: 一、设计任务与性能指标1.1设计任务设计一个带有年月日、时分秒及星期显示的电子日历。要求用Altium 6.0 画出系统的电路原理图,印刷电路板,绘出程序流程图,并给出程序清单。1.2性能指标 电子日历的主要功能是给人们提供时间和日期信息,无论其形式如何,从外部都可分为显示和校准两部分。为使电子日历协调工作,整个系统从功能上可分为实时时钟、显示和键盘三个模块,分别完成时间和日期的计算以及人机交互的管理。带有时钟(时分秒)和日期(年月日)和星期的显示。可进行时间及日期的校正及报时点设置。1.3系统要求带有时钟(时分秒)和日期(年月日)和星期的显示。可进行时间及日期的校正及报时点设置。二、方案选择2.1硬件方案2.1.1实时时钟方案选择实时时钟(RTC:Real Time Clock)是系统的核心,其运行精度直接影响产品质量。实时时钟的实现有两种方案可选,一是利用单片机系统时钟和中断完成时间和日期的计算;二是利用专用时钟芯片。前者不用附加芯片,系统简单,但是累计误差较大,只有短时计时才可使用。长时间计时一般都采用后者。后者采用32.768KHz晶体振荡器振作为脉冲源,内部的15位计数器刚好产生标准秒脉冲。该类芯片除时钟计时外,还有年月日和星期的计算功能,并且还可计算闰年。芯片初始化后可脱离CPU自动运行,有些芯片内部带有电池,出厂时芯片即开始运行。专用时钟芯片的种类很多,与CPU的通信方式有并行,也有串行。常见的芯片有DALLAS 公司生产的DS1302和DS12887,前者为串行,需要外加后备电池;后者为并行,芯片内置锂电池和晶体振荡器,无外加电源的情况下可运行10年。本实验采用的是第二种方案,而且用的是DS1302。2.1.2显示方案选择简单的数据显示常采用液晶显示或数码管显示。液晶显示有耗电低、外形美观的优点,并且,点阵液晶可显示较复杂的字符或图案。其缺点是通用液晶显示器的显示方案构建不够灵活,在较暗的环境下液晶需要背光,而且,液晶显示成本较高。相对液晶显示器来讲,由于数码管种类繁多,其显示方案构建灵活,成本较低。由于本身即是发光体,所以,数码管显示无需额外光源。数码管的缺点是功耗较大,字符较多时,必须交流供电,而且,数码管不能显示复杂字型。考虑到本实验的设计要求,选择的则是液晶显示。系统框图如图1所示:单片机显示系统RTC键盘 图1电子万年历的系统框图2.2软件方案系统软件可分为键盘管理、显示管理、报时管理和RTC管理三部分。软件可由汇编语言完成,也可由C语言完成。本实验采用的则是C语言。三、硬件电路的设计与分析 图2 单片机模块原理图3.1单片机模块本实验CPU采用的是STC89C52,单片机模块主要包括晶振电路,复位电路,单片机芯片,P0口作为输出连接液晶模块,P1口连接实时时钟部分,P3口用来扫描键盘使用,如图2所示。3.2实时时钟模块实时时钟采用DS1302,其中Vcc1为后备电源,VCC2为主电源。在主电源关闭的情况下,也能保持时钟的连续运行。DS1302由Vcc1或Vcc2两者中的较大者供电。当Vcc2大于Vcc10.2V时,Vcc2给DS1302供电。当Vcc2小于Vcc1时,DS1302由Vcc1供电。X1和X2是振荡源,外接32.768kHz晶振。RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。上电运行时,在Vcc2.5V之前,RST必须保持低电平。只有在SCLK为低电平时,才能将RST置为高电平。I/O为串行数据输入输出端(双向),SCLK始终是输入端。DS1302与P1口连接。如图3所示: 图3实时时钟模块原理图3.3 按键模块 实时系统的按键共有4个:确定键,加一键,减一键,返回键。与P2口连接。如图4所示: 图4按键模块原理图3.4显示模块 显示模块用的是液晶显示器1602,1602采用标准的16脚接口。第1脚:VSS为地电源。第2脚:VDD接5V正电源。第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。第714脚:D0D7为8位双向数据线。第1516脚:背光。DS1602的控制端与P3口连接,而数据端与P0口连接。如图5所示: 图5液晶显示模块3.5报时模块报时模块采用的蜂鸣器,具有整点报时的功能。例如:1点钟响1声,12点钟响12声。如图6所示: 图6 报时模块电路图3.6测温模块测温模块主要采用的则是18B20,18B20是一个三脚的温度芯片,一脚接电源,一脚接地,另一个脚是一跟信号线。18B20是一款仅使用一跟信号线与单片机通信的温度测量芯片,这跟信号线既要包含时间信息,又要包含数据信息,因此与单片机的硬件连接(物理层)比较简单。如图7所示: 图7 测温模块电路图四、系统软件设计4.1主程序设计程序软件部分流程图如图8所示:YN内存变量初始化:报时点、显示缓冲区等系统硬件初始化:显示器、RCT芯片等系统硬件初始化:显示器、RCT芯片等扫描键盘键盘分析处理显示管理开始上电复位Y图8 主程序流程图4.2 时钟芯片DS1302子程序设计表1 DS1302的控制字节定义DS1302的控制字节定义如表1所示。控制字节的最高有效位(位7)必须是逻辑1,如果为0,则不能把数按位写入DS1302中。位6为0,表示存取日历时钟数据;为1,表示存取RAM数据。位5至位1指示操作单元的地址,最低有交往位(位0)为0,表示要执行写操作;为1,表示执行读操作,控制字节总是从最低位开始输出。 7 6 5 4 3 2 1 01RAM _ CKA4A3A2A1A0RAM _KDS1302共有12个寄存器,其中有7个与日历、时钟有关,存放的数据为BCD码,其日历、时间寄存器及其控制字如表2所示。表2 DS1302 各寄存器及控制字寄存器名命令字取值范围各位内容写操作读操作76543210秒寄存器80H81H0059CH10SECSEC分寄存器82H83H0059010MINMIN时寄存器84H85H0012或002312/24010/APHRHR日寄存器86H87H0128,29,30,310010DATEDATE月寄存器88H89H011200010MMONTH周寄存器8AH8BH010700000DAY年寄存器8CH8DH009910YEARYEAR图9 DS1302流程图 4.3 液晶显示芯片1602子程序设计 1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,如表3所示 液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,表4是DM-162的内部显示地址.表3 CGROM和CGRAM中字符代码与字符图形对应关系高位低位 00000010001101000101011001111010101111001101111011110000CGRAM(1)0Pp p0001(2)!1AQaq。 aq0010(3)“2BRbr 0011(4)#3CScs 0100(5)$4DTds、0101(6)%5EUeu0110(7)&6FVfv 0111(8)7GWgw g 1000(1)(8HXhx _1001(2))9IYiy y1010(3)“JZgz j 千1011(4)+Kk 万1100(5)L¥l| 1101(6)一Mm %1110(7)Nn n1111(8)Oo 表4 DM-162的内部显示地址1234567891011121314151600 0102030405060708090A0B0C0D0E0F第一行404142434445464748494A4B4C4D4E4F第二行 图10 1602液晶显示子程序流程图4.4 温度传感芯片18B20子程序设计18B20可以测量-55度到125度之间的温度,测量精度为0.5度。在DS1820 中温度是以1/2 度LSB (最低有效位)形式表示时产生以下9位格式MSB(最高位) (最低有效位) LSB1.11001110最高有效(符号)位被复制到存储器内两字节的温度寄存器中较高MSB 的所有位这种符号扩展产生了如表5 所示的16 位温度读数。 表5 温度 / 数据关系温度数字输出/(二进制)安息字输出(十六进制)+12500000000 1111101000FAh+2500000000 001100100032h+1/200000000 00000001 0001h00000000 00000000 0000h11111111 11111111 FFFFh11111111 11001110 FFCEh11111111 10010010 FF92h 图11 18B20温度传感子程序流程图五、调试及性能分析5.1调试步骤1)硬件调试主要是检测硬件电路是否有短路、断路、虚焊等。具体步骤及测试结果如下所示:由于在PCB图设计中按键封装选择有误,导致起初电路无任何反应,后经万用表测试,发现了错误原因,通过割线、飞线加以改正了电路的错误连接,实现了预期功能。2)软件调试因为网上相似的万年历案例很多,基本相似的也不少,我们小组参照相关程序进行调试,基本没遇到很困难的问题。5.2性能分析单片机上电复位后,我们已经给1302赋了初值,按下控制键进入时间调整状态,此时在我们调整哪一位时哪一位就会处于闪烁状态,按下加1键被调整的那一位就会加1,按减一也会减1,然后我们把时间调到当时的时间,屏幕也很稳定,温度也自动的显示出来,但经过我们仔细的观察之后,时钟走的好像不是很稳定,可能会有一定的误差,所以我们的日历在性能上还有不完善的地方,在以后的学习当中,我们将尽力把这些功能也完善好。六、心得体会经过这次的课程设计,我们对单片机、PCB其相关芯片的资料和运用有了深刻的了解。同时,理论同实践相联系,使我们对这些知识的应用更加清楚。我们此次的设计产品为电子万年历,基本功能包括时间,日期,星期和温度已经实现,报时功能因软件问题,未能实现。在调试过程中,起初无论如何复位,烧录的程序都未见任何现象,后来,在用万用表测试串口模块硬件的过程中,发现按键全都短路了,经查看PCB图才发现按键的封装反了,应该是横向短路、纵向开关,我们误把横向设计成开关、纵向短路了。经过仔细校对、割线、飞线,才开始出现预定的现象。本次课程设计时间不算长,但是收获很大,包括对单片机的认识,对Altium Designer 6软件使用的巩固和加深,对DS1302的工作原理的了解等。同时也培养了我们面对问题,要耐心冷静处理的态度。这次课程设计对我们今后的影响会非常大。当然,非常感谢老师和同学们在我们遇到问题时的热情帮助。 课程设计是一次很好的理论联系实践的动手机会,增了我们的动手能力,使我们的理论知识得以应用,今后我们会注重实践能力的锻炼,注重动手能力的培养。参考文献1 徐维祥、刘旭敏。 单片微型机原理及应用。 大连理工大学出版社,19962杨将新、李华军、刘东骏。 单片机程序设计及应用。 电子工业出版社,20063刘文涛。 单片机语言C51典型应用设计。 人民邮电出版社,20054 楼然苗、李光飞. 51系列单片机设计实例. 北京航空航天大学出版社,2003附录1系统硬件电路图附录2程序清单#include #include /#include LCD1602.h/#include DS1302.h#define uint unsigned int#define uchar unsigned charsbit DS1302_CLK = P14; /实时时钟时钟线引脚 sbit DS1302_IO = P13; /实时时钟数据线引脚 sbit DS1302_RST = P12; /实时时钟复位线引脚sbit wireless_1 = P30;sbit wireless_2 = P31;sbit wireless_3 = P32;sbit wireless_4 = P33;sbit ACC0 = ACC0;sbit ACC7 = ACC7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; /秒,分,时到日,月,年位闪的计数sbit Set = P20; /模式切换键sbit Up = P21; /加法按钮sbit Down = P22; /减法按钮sbit out = P23; /立刻跳出调整模式按钮sbit DQ = P10; /温度传送数据IO口char done,count,temp,flag,up_flag,down_flag;uchar temp_value; /温度值uchar TempBuffer5,week_value2;void show_time(); /液晶显示程序/*1602液晶显示部分子程序*/Port Definitions*sbit LcdRs= P25;sbit LcdRw= P26;sbit LcdEn = P27;sfr DBPort = 0x80;/P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口/内部等待函数*unsigned char LCD_Wait(void)LcdRs=0;LcdRw=1;_nop_();LcdEn=1;_nop_(); LcdEn=0;return DBPort;/向LCD写入命令或数据*#define LCD_COMMAND0 / Command#define LCD_DATA1 / Data#define LCD_CLEAR_SCREEN0x01 / 清屏#define LCD_HOMING 0x02 / 光标返回原点void LCD_Write(bit style, unsigned char input)LcdEn=0;LcdRs=style;LcdRw=0;_nop_();DBPort=input;_nop_();/注意顺序LcdEn=1;_nop_();/注意顺序LcdEn=0;_nop_();LCD_Wait();/设置显示模式*#define LCD_SHOW0x04 /显示开#define LCD_HIDE0x00 /显示关 #define LCD_CURSOR0x02 /显示光标#define LCD_NO_CURSOR0x00 /无光标 #define LCD_FLASH0x01 /光标闪动#define LCD_NO_FLASH0x00 /光标不闪动void LCD_SetDisplay(unsigned char DisplayMode)LCD_Write(LCD_COMMAND, 0x08|DisplayMode);/设置输入模式*#define LCD_AC_UP0x02#define LCD_AC_DOWN0x00 / default#define LCD_MOVE0x01 / 画面可平移#define LCD_NO_MOVE0x00 /defaultvoid LCD_SetInput(unsigned char InputMode)LCD_Write(LCD_COMMAND, 0x04|InputMode);/初始化LCD*void LCD_Initial()LcdEn=0;LCD_Write(LCD_COMMAND,0x38); /8位数据端口,2行显示,5*7点阵LCD_Write(LCD_COMMAND,0x38);LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); /开启显示, 无光标LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); /清屏LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); /AC递增, 画面不动/液晶字符输入的位置*void GotoXY(unsigned char x, unsigned char y)if(y=0)LCD_Write(LCD_COMMAND,0x80|x);if(y=1)LCD_Write(LCD_COMMAND,0x80|(x-0x40);/将字符输出到液晶显示void Print(unsigned char *str)while(*str!=0)LCD_Write(LCD_DATA,*str);str+;/*DS1302时钟部分子程序*/typedef struct _SYSTEMTIME_unsigned char Second;unsigned char Minute;unsigned char Hour;unsigned char Week;unsigned char Day;unsigned char Month;unsigned char Year;unsigned char DateString11;unsigned char TimeString9;SYSTEMTIME;/定义的时间类型SYSTEMTIME CurrentTime;#define AM(X)X#define PM(X)(X+12) / 转成24小时制#define DS1302_SECOND0x80 /时钟芯片的寄存器位置,存放时间#define DS1302_MINUTE0x82#define DS1302_HOUR0x84 #define DS1302_WEEK0x8A#define DS1302_DAY0x86#define DS1302_MONTH0x88#define DS1302_YEAR0x8C void DS1302InputByte(unsigned char d) /实时时钟写入一字节(内部函数) unsigned char i; ACC = d; for(i=8; i0; i-) DS1302_IO = ACC0; /相当于汇编中的 RRC DS1302_CLK = 1; DS1302_CLK = 0; ACC = ACC 1; unsigned char DS1302OutputByte(void) /实时时钟读取一字节(内部函数) unsigned char i; for(i=8; i0; i-) ACC = ACC 1; /相当于汇编中的 RRC ACC7 = DS1302_IO; DS1302_CLK = 1; DS1302_CLK = 0; return(ACC); void Write1302(unsigned char ucAddr, unsigned char ucDa)/ucAddr: DS1302地址, ucData: 要写的数据 DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr); / 地址,命令 DS1302InputByte(ucDa); / 写1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; unsigned char Read1302(unsigned char ucAddr)/读取DS1302某地址的数据 unsigned char ucData; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr|0x01); / 地址,命令 ucData = DS1302OutputByte(); / 读1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; return(ucData);void DS1302_GetTime(SYSTEMTIME *Time) /获取时钟芯片的时钟数据到自定义的结构型数组unsigned char ReadValue;ReadValue = Read1302(DS1302_SECOND);Time-Second = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_MINUTE);Time-Minute = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_HOUR);Time-Hour = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_DAY);Time-Day = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_WEEK);Time-Week = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_MONTH);Time-Month = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_YEAR);Time-Year = (ReadValue&0x70)4)*10 + (ReadValue&0x0F);void DateToStr(SYSTEMTIME *Time) /将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString if(hide_year2) /这里的if,else语句都是判断位闪烁,2就不显示,输出字符串为 2007/07/22 Time-DateString0 = 2; Time-DateString1 = 0; Time-DateString2 = Time-Year/10 + 0; Time-DateString3 = Time-Year%10 + 0; else Time-DateString0 = ; Time-DateString1 = ; Time-DateString2 = ; Time-DateString3 = ;Time-DateString4 = /;if(hide_monthDateString5 = Time-Month/10 + 0; Time-DateString6 = Time-Month%10 + 0; else Time-DateString5 = ; Time-DateString6 = ; Time-DateString7 = /;if(hide_dayDateString8 = Time-Day/10 + 0; Time-DateString9 = Time-Day%10 + 0; else Time-DateString8 = ; Time-DateString9 = ; if(hide_weekWeek%10 + 0; /星期的数据另外放到 week_value数组里,跟年,月,日的分开存放,因为等一下要在最后显示 else week_value0 = ; week_value1 = 0;Time-DateString10 = 0; /字符串末尾加 0 ,判断结束字符void TimeToStr(SYSTEMTIME *Time) /将时,分,秒数据转换成液晶显示字符放到数组 TimeString; if(hide_hourTimeString0 = Time-Hour/10 + 0; Time-TimeString1 = Time-Hour%10 + 0; else Time-TimeString0 = ; Time-TimeString1 = ;Time-TimeString2 = :; if(hide_minTimeString3 = Time-Minute/10 + 0; Time-TimeString4 = Time-Minute%10 + 0; else Time-TimeString3 = ; Time-TimeString4 = ; Time-TimeString5 = :; if(hide_secTimeString6 = Time-Second/10 + 0; Time-TimeString7 = Time-Second%10 + 0; else Time-TimeString6 = ; Time-TimeString7 = ; Time-DateString8 = 0;void Initial_DS1302(void) /时钟芯片初始化 unsigned char Second=Read1302(DS1302_SECOND);if(Second&0x80) /判断时钟芯片是否关闭 Write1302(0x8e,0x00); /写入允许Write1302(0x8c,0x07); /以下写入初始化时间 日期:07/07/25.星期: 3. 时间: 23:59:55Write1302(0x88,0x07);Write1302(0x86,0x25);Write1302(0x8a,0x07);Write1302(0x84,0x23);Write1302(0x82,0x59);Write1302(0x80,0x55);Write1302(0x8e,0x80); /禁止写入/*ds18b20子程序*/*ds18b20延迟子函数(晶振12MHz )*/ void delay_18B20(unsigned int i)while(i-);/*ds18b20初始化函数*/void Init_DS18B20(void) unsigned char x=0; DQ = 1; /DQ复位 delay_18B20(8); /稍做延时 DQ = 0; /单片机将DQ拉低 delay_18B20(80); /精确延时 大于 480us DQ = 1; /拉高总线 delay_18B20(14); x=DQ; /稍做延时后 如果x=0则初始化成功 x=1则初始化失败 delay_18B20(20);/*ds18b20读一个字节*/ unsigned char ReadOneChar(void)uchar i=0;uchar dat = 0;for (i=8;i0;i-) DQ = 0; / 给脉冲信号 dat=1; DQ = 1; / 给脉冲信号 if(DQ) dat|=0x80; delay_18B20(4); return(dat);/*ds18b20写一个字节*/ void WriteOneChar(uchar dat) unsigned char i=0; for (i=8; i0; i-) DQ = 0; DQ = dat&0x01; delay_18B20(5); DQ = 1; dat=1; /*读取ds18b20当前温度*/void ReadTemp(void)unsigned char a=0;unsigned char b=0;un

温馨提示

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

最新文档

评论

0/150

提交评论