单片机万年历课程设计报告_第1页
单片机万年历课程设计报告_第2页
单片机万年历课程设计报告_第3页
单片机万年历课程设计报告_第4页
单片机万年历课程设计报告_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

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

文档简介

1、单片机万年历设计报告 班级:xxx 姓名:xxx 学号:xxx 指导老师:xxx 时间:xxx摘要:本文介绍了单片机的一些比较基础的,比较常用的一些资源的应用,同时也对单片机所涉及的一些简单硬件有一定的介绍,基于单片机的原理设计电路,在了解硬件的基础上完成程序设计,使自己掌握对一个系统的初步规划和设计,提高自己分析问题的能力。一、设计内容及要求利用at89c51单片机芯片实现电子钟系统设计,其硬件原理框图如图1所示,其中显示采用液晶lcd1602,温度测量采用ds18b20。闹铃电路at89c51按键控制液晶显示器 硬件原理框图各部分功能实现:(1) 单片机发送的信号通过程序控制最终在液晶显示

2、器上显示出来。(2) 单片机通过输出各种电脉冲信号来驱动控制各部分正常工作。(3) 为使时钟走时与标准时间一致,校时电路是必不可少的,按键用来校正液晶显示器上显示的时间。(4) 单片机通过控制闹铃电路来完成 准点报时的功能。系统的主要工作和流程 此电子钟系统的设计,为实现其多方面的功能,需要收集芯片元件的资料和芯片的数据手册,理解芯片的工作原理,时钟芯片,温度芯片, lcd1602芯片的显示原理。设计中最为关键的是对整个系统设计原理的理解。 系统的主要工作是进行整个电子钟系统的程序设计,主要是对时间算法,lcd显示设计,温度读取的程序设计。由于电子万年设计的功能较多,所编写的代码量较大,编程中

3、更是用到了大量的算法,所以此次的软件设计使用c语言编程而没有使用汇编语言。软件的设计主要将程序分为主程序和各个子程序模块。系统工作的流程为:在完成了程序的设计调试之后,便可将编译生产的文件下载到at89c51单片机芯片运行,再不断进行调试改进。 二、系统工作原理设计的电路主要由主控模块、液晶显示模块、温度模块、按键模块和闹钟模块共5个模块组成。本设计采用语言程序设计,使单片机控制液晶显示器时、分、秒,当秒计数计满60时就向分进位,分计数器计满60后向时计数器进位,小时计数器按“23翻0”规律计数。时、分、秒的计数结果经过数据处理可直接送显示器显示。当计时发生误差的时候可以用校时电路进行校正。设

4、计采用的是时、分、秒显示,单片机对数据进行处理同时在液晶显示器上显示。主控模块:本系统主控模块采用的单片机at89c51,外接12mhz晶振。at89c51具有40个引脚,1288位内部ram ,32可编程i/o线 ,两个16位定时器/计数器,5个中断源。可编程串行通道,低功耗的闲置和掉电模式, 片内振荡器和时钟电路也是其主要特性。液晶显示模块:lcd1602采用标准的16脚接口,其中: 第1脚:gnd为地电源 第2脚:vcc接5v正电源 第3脚:v0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比最高,对比度过高时会产生“鬼影”,使用时可以通过一个10k的电位器调整对比度 第4

5、脚:rs为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。第5脚:rw为读写信号线,高电平时进行读操作,低电平时进行写操作。当rsrw共同为低电平时可以写入指令或者显示地址,当rs为低电平rw为高电平时可读忙信号,当rs为高电平rw为低电平时可以写入数据.第6脚:e端为使能端,当e端由高电平跳变成低电平时,液晶模块执行命令。第714脚:db0db7为8位双向数据线。第1516脚:空脚。温度模块:ds18b20温度传感器是美国dallas半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现位的数字值读

6、数方式。 其引脚功能描述见表1。表1ds18b20详细引脚功能描述序号名称引脚功能描述1gnd地信号2dq数据输入/输出引脚。开漏单总线接口引脚。当被用着在寄生电源下,也可以向器件提供电源。3vdd可选择的vdd引脚。当工作于寄生电源时,此引脚必须接地。闹钟模块:闹铃模块为单片机开发箱的蜂鸣器,当闹钟时间到后,蜂鸣器发声,直到过了闹钟时间后停止。按键模块:本设计总共用了5个独立按键,其中一个是设置键,两个是调整项增加、减少的键,一个是闹钟设置键,一个是显示模式设置键。三、系统的软件设计软件的总体设计系统是由at89c51单片机控制,系统分为主函数部分和各模块子函数部分2个部分。系统主函数部分主

7、要是调用各个模块的子函数。本系统的时间是通过软件进行设置,使用定时器使电子钟运行,并将值送入主控芯片,通过液晶显示器lcd1602来显示,时间、日期的修改通过按键来控制的。所以要对定时器、液晶显示器进行初始化。而其他模块的初始化在各模块函数中初始化。各模块的子函数包括lcd1602显示模块、ds18b20测温模块、时钟模块、按键扫描模块。闹钟设置模块包含在时钟模块和按键扫描模块中。主程序通过调用其他函数来实现系统的总体功能,其工作流程如下:(1) 系统启动后,进行定时器和lcd显示初始化。(2) lcd1602显示日期、时间、温度。开始定时器及中断定时器初始化执行时钟闹铃设定程序是否设定参数执

8、行显示程序ny(3) 可以通过按键进行显示模式设置,调整日期、时间、还可以进行万年历查询。图3-1 主程序流程图液晶显示模块于本系统是采用lcd1602显示的,系统的软件设计通过p0口输出数据,数据命令选择端p2.6,读写选择端是p2.5,使能信号选择端为p2.7。程序主要进行lcd1602的初始化设定,及根据时序图编写lcd1602的写指令、写字符函数。此外还需编写显示字符串函数等。测温模块温度检测相关函数包括:ds18b20的初始化函数, ds18b20的温度读取函数等。 由于ds18b20是单总线的时序工作方式,其每次工作前需要初始化。首先由总线拉低480-960us,而后释放总线60-

9、120us,此后会有ds18b20自己拉地60-240us,然后释放总线。这样就完成了ds18b20的初始化过程。如果在有ds18b20自动拉低部分,读取总线其没被拉低,则表示ds18b20不存在。函数编写上由于只对一条总线进行编程,所以十分简单。总线拉低时向dq送0,总线释放向dq送1即可。延时时间通过延时函数调整。温度读取函数的程序流程为首先初始化ds18b20,然后通过ds18b20写字节函数写命令字cc(跳过rom匹配),再写命令字44(温度转换)。然后再初始化ds18b20,写命令字cc,写命令字be(读暂存),通过ds18b20字节读取函数读取暂存的前2字节(0,1字节为温度字节)

10、存入a与b两个变量中,a为温度值低位,b为温度值高位。 ds18b20工作过程:sbit dq = p33; / 定义dq引脚为p3.3/* 延时函数 * 功能:在11.059mhz的晶振条件下调用本函数需要24s ,然后每次计数需16s */void ds18_delay(int useconds) int s;for (s=0; suseconds;s+);/* 复位函数 * 功能:完成单总线的复位操作。* 复位时间为480s,因此延时时间为(480-24)/16 = 28.5,取29s。* 经过70s之后检测存在脉冲,因此延时时间为(70-24)/16 = 2.875,取3s。*/uns

11、igned char ow_reset(void) unsigned char presence;dq = 0; / 将 dq 线拉低ds18_delay(29); / 保持 480sdq = 1; / dq返回高电平ds18_delay(3); / 等待存在脉冲presence = dq; / 获得存在信号ds18_delay(25); / 等待时间隙结束return(presence); / 返回存在信号,0 = 器件存在, 1 = 无器件/* 位写入函数 * 功能:向单总线写入1位值:bitval*/void write_bit(char bitval) dq = 0; / 将dq 拉低

12、开始写时间隙if(bitval=1) dq =1; / 如果写1,dq 返回高电平ds18_delay(5); / 在时间隙内保持电平值,dq = 1; / ds18_delay函数每次循环延时16s,因此ds18_delay(5) = 104s/* 字节写入函数 * 功能:向单总线写入一个字节值:val*/void ds18write_byte(char val) unsigned char i;unsigned char temp;for (i=0; ii; temp &= 0x01; write_bit(temp); ds18_delay(5);/* 位读取函数 * 功能:从单总线上读取

13、一位信号,所需延时时间为15s,因此无法调用前面定义* 的ds18_delay()函数,而采用一个for()循环来实现延时。* */unsigned char read_bit(void) unsigned char i;dq = 0; /将dq 拉低开始读时间隙dq = 1; / then return highfor (i=0; i3; i+); / 延时15sreturn(dq); / 返回 dq 线上的电平值/* 字节读取函数 * 功能:从单总线读取一个字节的值*/unsigned char dsread_byte(void) unsigned char i;unsigned char

14、 value = 0;for (i=0;i8;i+) / 读取字节,每次读取一个字节if(read_bit() value|=0x01i; / 然后将其左移ds18_delay(6); return(value);/* 读取温度函数 * 功能:如果单总线节点上只有一个器件则可以直接掉用本函数。如果节点上有多个器* 件,为了避免数据冲突,应使用match rom函数来选中特定器件。* 注: 本函数是根据ds1820的温度数据格式编写的,若用于ds18b20,必须根据* ds18b20的温度数据格式作适当修改。*/unsigned int readtemperature(void) unsigne

15、d char get10;unsigned char temp_lsb,temp_msb;unsigned int t;unsigned char k;ow_reset();ds18write_byte(0xcc); / 跳过 romds18write_byte(0x44); / 启动温度转换ds18_delay(5);ow_reset();ds18write_byte(0xcc); / 跳过 romds18write_byte(0xbe); / 读暂存器for (k=0;k2;k+)getk=dsread_byte();temp_msb = get1; / sign byte + lsbit

16、temp_lsb = get0; / temp data plus lsbt=temp_msb*256+temp_lsb;t=t&0x0ff0;if(t0xf0)t=(-1)*t;return t4;/temp_f = (int)temp_c)* 9)/5 + 32; / 输出华氏温度值时钟函数时钟函数包括年、月、日、时、分、秒、星期的计算方法。时间控制程序主要是定时器0计时中断程序每隔17ms中断一次当作一个计数,每中断一次则计数加1,当计数60次时,则表示1秒到了,秒变量加1,同理再判断是否1分钟到了,再判断是否1小时到了,再判断是否1天到了,再判断是否1月到了,再判断是否1年到了,若计数

17、到了则相关变量清除0。月份算法:先给出一般年份的每月天数。如果是闰年,第二个月天数不为28天,而是29天。星期算法:算出当前时间距2000年1月1日(星期六)的天数,通过公式week=(6+sum%7)%7计算当前显示日期是星期几。闰年的判断规则为,如果该年份是4或100的整数倍或者是400的整数倍,则为闰年;否则为非闰年。当电子钟运行的时间与所设定的时间相同时,蜂鸣器响,直到过了设置时间后不响。按键扫描函数本系统的时间、日期设置、闹钟设置、万年历判断是通过5个按键进行设置,分别为key_1、key_2、key_3、key_4、key_5按键。系统启动后按key_1进入设置程序,对当前项进行设

18、置,调整顺序依次为:年、月、日、时、分、秒。设置时时钟停止运行,按key_1对各个设置项进行切换,第7项为设置完成,时钟开始运行。key_1键为功能键,key_2键为加1,key_3为减一,key_4为显示模式设置按键,key_5为闹钟设置按键。四、仿真1、仿真:打开软件,输入所编写的源程序并对程序进行编译,在软件的帮助下检查其中的错误并进行反复修改,知道编译正确后运行,确保没有错误以后对正确的源程序进行保存,保存时给其命名,以便将来载入程序时容易找到。2、打开proteus软件,并出画单片机电子万年历具体运行电路图。3、检查所画电路运行图,确保没有错误以后,在proteus下对原理图进行加载

19、keil下的源程序。4、加载完成后,单击电路图框下的开始按钮,进行仿真,观察液晶显示器显示情况。调节开关进行时间的调节,调节石英晶体震荡器的频率参数,从而使秒的间隔达到标准。然后检查电路其它问题,并对其的各参数进行调整,使之正确。五、pcb图六、程序#include#includeds18b20_3.h#define uint unsigned int#define uchar unsigned charuchar a,b,miao,shi,fen,ri,yue,nian,week,flag,key1n,temp,miao1,shi1=12,fen1=1,miao1=0,clock=0 ;/f

20、lag用于读取头文件中的温度值,和显示温度值#define yh 0x80 /lcd第一行的初始位置,因为lcd1602字符地址首位d7恒定为1(100000000=80)#define er 0x80+0x40 /lcd第二行初始位置(因为第二行第一个字符位置地址是0x40)/液晶屏的与c51之间的引脚连接定义(显示数据线接c51的p0口)sbit rs=p20;sbit en=p22;sbit rw=p21; /如果硬件上rw接地,就不用写这句和后面的rw=0了sbit led=p26; /lcd背光开关/ds1302时钟芯片与c51之间的引脚连接定义sbit io=p11;sbit sc

21、lk=p10;sbit rst=p12;sbit clo=p14;sbit acc0=acc0;sbit acc7=acc7;/*acc累加器=aacc.0=e0hacc.0就是acc的第0位。acc可以位寻址。累加器acc是一个8位的存储单元,是用来放数据的。但是,这个存储单元有其特殊的地位,是单片机中一个非常关键的单元,很多运算都要通过acc来进行。以后在学习指令时,常用a来表示累加器。但有一些地方例外,比如在push指令中,就必须用acc这样的名字。一般的说法,a代表了累加器中的内容、而acc代表的是累加器的地址。*/校时按键与c51的引脚连接定义sbit key1=p15; /设置键s

22、bit key2=p16; /加键sbit key3=p17; /减键sbit buzzer=p13;/蜂鸣器,通过三极管9012驱动,端口低电平响/*/uchar code tab1=20 - - ; /年显示的固定字符uchar code tab2= : : ;/时间显示的固定字符uchar code tab3= hello welcome;/开机动画/延时函数,后面经常调用void delay(uint xms)/延时函数,有参函数uint x,y;for(x=xms;x0;x-) for(y=110;y0;y-);void delay1ms(int i)/1毫秒延时 int j,k;

23、while(i-) for(j=76;j1;j-); for(k=29;k1;k-); /*液晶写入指令函数与写入数据函数,以后可调用*/*在这个程序中,液晶写入有关函数会在ds1302的函数中调用,所以液晶程序要放在前面*/write_1602com(uchar com)/*液晶写入指令函数*rs=0;/数据/指令选择置为指令rw=0; /读写选择置为写p0=com;/送入数据delay(1);en=1;/拉高使能端,为制造有效的下降沿做准备delay(1);en=0;/en由高变低,产生下降沿,液晶执行命令write_1602dat(uchar dat)/*液晶写入数据函数*rs=1;/数

24、据/指令选择置为数据rw=0; /读写选择置为写p0=dat;/送入数据delay(1);en=1; /en置高电平,为制造下降沿做准备delay(1);en=0; /en由高变低,产生下降沿,液晶执行命令lcd_init()/*液晶初始化函数* uchar j; write_1602com(0x0f|0x08);for(a=0;a17;a+) write_1602dat(tab3a); j=17;while(j-)write_1602com(0x1c);/循环左移delay(700);write_1602com(0x01);delay(10);write_1602com(0x38);/设置液

25、晶工作模式,意思:16*2行显示,5*7点阵,8位数据write_1602com(0x0c);/开显示不显示光标write_1602com(0x06);/整屏不移动,光标自动右移write_1602com(0x01);/清显示/*开机动画显示hello welcome dianzizhong*/write_1602com(yh+1);/日历显示固定符号从第一行第1个位置之后开始显示for(a=0;a14;a+)write_1602dat(tab1a);/向液晶屏写日历显示的固定符号部分/delay(3);write_1602com(er+2);/时间显示固定符号写入位置,从第2个位置后开始显示

26、for(a=0;a0;a-)io=acc0;sclk=0;sclk=1;acc=acc1;uchar read_byte()/读一个字节rst=1;for(a=8;a0;a-)acc7=io;sclk=1;sclk=0;acc=acc1;return (acc);/-void write_1302(uchar add,uchar dat)/向1302芯片写函数,指定写入地址,数据rst=0;sclk=0;rst=1;write_byte(add);write_byte(dat);sclk=1;rst=0;uchar read_1302(uchar add)/从1302读数据函数,指定读取数据来

27、源地址uchar temp;rst=0;sclk=0;rst=1;write_byte(add);temp=read_byte();sclk=1;rst=0;return(temp);uchar bcd_decimal(uchar bcd)/bcd码转十进制函数,输入bcd,返回十进制 uchar decimal; decimal=bcd4; return(decimal=decimal*10+(bcd&=0x0f);/-void ds1302_init() /1302芯片初始化子函数(2010-01-07,12:00:00,week4)rst=0;sclk=0;write_1302(0x8e

28、,0x00); /允许写,禁止写保护write_1302(0x80,0x00); /向ds1302内写秒寄存器80h写入初始秒数据00write_1302(0x82,0x00);/向ds1302内写分寄存器82h写入初始分数据00write_1302(0x84,0x12);/向ds1302内写小时寄存器84h写入初始小时数据12write_1302(0x8a,0x01);/向ds1302内写周寄存器8ah写入初始周数据4write_1302(0x86,0x08);/向ds1302内写日期寄存器86h写入初始日期数据07write_1302(0x88,0x07);/向ds1302内写月份寄存器8

29、8h写入初始月份数据01write_1302(0x8c,0x10);/向ds1302内写年份寄存器8ch写入初始年份数据10write_1302(0x8e,0x80); /打开写保护/-/温度显示子函数void write_temp(uchar add,uchar dat)/向lcd写温度数据,并指定显示位置uchar gw,sw,bw;if(dat=0&dat31) ri=1; break; case 2:if(nian%4=0|nian%400=0) if(ri29) ri=1; else if(ri28) ri=1; break; case 4:case 6:case 9:case 11

30、: ri+; if(ri30) ri=1; break; write_nyr(9,ri);/令lcd在正确的位置显示加设定好的日期数据temp=(ri)/10*16+(ri)%10;/十进制转换成ds1302要求的dcb码 write_1302(0x8e,0x00);/允许写,禁止写保护 write_1302(0x86,temp);/向ds1302内写日期寄存器86h写入调整后的日期数据bcd码 write_1302(0x8e,0x80);/打开写保护write_1602com(yh+10);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 6:yue+;i

31、f(yue=13)yue=1;write_nyr(6,yue);/令lcd在正确的位置显示加设定好的月份数据temp=(yue)/10*16+(yue)%10;/十进制转换成ds1302要求的dcb码 write_1302(0x8e,0x00);/允许写,禁止写保护 write_1302(0x88,temp);/向ds1302内写月份寄存器88h写入调整后的月份数据bcd码 write_1302(0x8e,0x80);/打开写保护write_1602com(yh+7);/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位break;case 7:nian+; if(nian=100)nian=0;write_nyr(3,nian);/令lcd在正确的位置显示加设定好的年份数据 temp=(nian)/10*16+(nian)%10;/十进制转换成ds1302要求的dcb码 write_1302(0x8e,0x00);/允许写,禁止写保护 write_1302(0x8c,temp);/向ds1302内写年份寄存器8ch写入调整后的年份数据bcd码 write_1302(0x8e,0x80);

温馨提示

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

评论

0/150

提交评论