《基于单片机和DS1302电子万年历的方案设计书.doc》由会员分享,可在线阅读,更多相关《基于单片机和DS1302电子万年历的方案设计书.doc(26页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、基于单片机和DS1302电子万年历的方案设计书(1) 时钟芯片DS1302的工作原理: DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置 “0”,接着把RST端置“1”,最后才给予SCLK脉冲;读/写时序如下图所示。为DS1302的控制字,此控制字的位7必须置1,若为0则不能把对DS1302进行读写数据。对于位6,若对程序进行读/写时RAM=1,对时间进行读/写时,CK=0。位1至位5指操作单元的地址。位0是读/写操作位,进行读操作时,该位为1;该位为0则表示进行的是写操作。控制字节总是从最低位开始输入/输出的。表6为DS1302的日历、时间寄存器内容:“CH”是时钟暂停标志位
2、,当该位为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位为0时,时钟开始运行。“WP”是写保护位,在任何的对时钟和RAM的写操作之前,WP必须为0。当“WP为1时,写保护位防止对任一寄存器的写操作。(2) DS1302的控制字节DS1302的控制字如表-1所示。控制字节的高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出表-1 DS1302的控制字格式 RAM RD 1 A4 A3
3、A2 A1 A0 / CK /WR(3) 数据输入输出(I/O) 在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始.同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。如下图1所示 图1 DS1302读/写时序图(4) DS1302的寄存器DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器及其控制字见表-2。表-2 DS1302的日历、时间寄存器 写寄存器读寄存器Bit7Bit6Bit5Bit4Bit3Bit2Bit1Bit08
4、0H81HCH10秒秒82H83H10分分84H85H12/010时时/PM86H87H0010日日88H89H00010月月8AH8BH00000星期8CH8DH10 年年8EH8FHWP0000000此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等.时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。 DS1302与RAM相关的寄存器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0HFDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的
5、31个字节,命令控制字为FEH(写)、FFH(读). 2 方案论证与设计2.1控制器部分方案设计硬件控制电路主要用了AT89C52芯片处理器、1602LCD显示器、DS1302实时时钟、DB18B20温度传感器。根据各自芯片的功能互相连接成电子万年历的控制电路。软件控制程序主要有主控程序、电子万年历的时间控制程序、时间显示及温度显示程序等组成.设计框图如图2。1所示AT89C52主控模块1602液晶显示DS1302时钟电路独立键盘电路DS18B20实时环境温度采集电路蜂鸣器图2.1 框图设计2。2 显示部分的方案论证方案一:采用8段数码管虽经济实惠,但操作比液晶显示来说略显繁琐。方案二:液晶显
6、示方式。液晶显示效果出众,可以运用菜单项来方便操作,比较简单,所以,最后选择液晶显示方案。显示电路图如图2.2所示.图2。2 液晶显示电路2。3 实时时钟电路设计 图2。3是 DS1302与单片机的连接,其中Vcc1为后备电源,Vcc2为主电源.在主电源关闭的情况下,也能保持时钟的连续运行。DS1302由Vcc1或Vcc2两者中的较大者供电。当Vcc2大于Vcc1+0。2V时,Vcc2给DS1302供电.当Vcc2小于Vcc1时,DS1302由Vcc1供电.X1和X2是振荡源,外接32。768KHz晶振。图2.3 DS1302时钟电路2。4 温度采集模块设计如图2。4所示,采用数字式温度传感器
7、DS18B20,它是数字式温度传感器,具有测量精度高,电路连接简单特点,此类传感器仅需要一条数据线进行数据传输,使用P3。7与DS18B20的I/O口连接加一个上拉电阻,Vcc接电源,Vss接地。图2.4 DS18B20温度采集模块2.5 功能按钮设计当按钮被按下时,该按钮对应的I/O口被拉为低电平,松开时按钮对应的I/O口由内部的上拉电阻将该I/O拉为高电平,如图2.5所示:图2.5 键盘电路设计2。6 总体电路图3 软件设计流程3.1 系统总流程图 系统总体流程图如图3.1所示,系统流程图设计分析如下:首系统初始化,系统运行,当有设置键按下时进入时间修改模式,无按键按下时读取时间温度等数据
8、送入显示器显示。在时间修改模式下设置时间完成后再将时间送入显示器显示。图3。1 系统流程图3.2 温度程序流程图 温度读取程序流程图如图3。2所示。流程图分析:开始进入初始化DS18B20,就是通过主机拉低单线产生复位脉冲然后释放总线,如果有应答就发起ROM命令,当成功执行操作命令后,就使用温度转换,当温度转换完成后又初始化DS18B20是否有应答脉冲,若有就发起读暂存器和CRC命令,同时读出第一第二字节即温度数据。 图3。2 温度读取程序流程图3。3 DS1302时钟程序流程图 时钟流程图如图3。3所示,流程图分析:DS1302开始计时时,首先进行初始化,当有中断信号时,读取时钟芯片的时间数
9、据送入液晶显示。这时若有设置键按下,进行时间修改,完成后将时间数据送入1302芯片,若没有按键按下,直接送入EPROM中,送入液晶显示.图3.3 时钟程序流程图DS1302时钟部分子程序void write_byte(uchar dat)/写一个字节ACC=dat。RST=1。for(a=8。a0。a-) IO=ACC0。 SCLK=0。 /产生上升沿写入数据,从低位写入 SCLK=1。 ACC=ACC1.uchar read_byte()/读一个字节RST=1。for(a=8.a0。a-) ACC7=IO。 SCLK=1。 /产生下降沿输出数据,先输出低位,保存到ACC中 SCLK=0. A
10、CC=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读数据函数,指定读取数据来源地址uchar temp。RST=0。SCLK=0。RST=1。write_byte(add).temp=read_byte()。SCLK=1。RST=0。return(temp)。uchar BCD_Decimal(uch
11、ar bcd)/BCD码转十进制函数,输入BCD,返回十进制uchar Decimal。Decimal=bcd4。return(Decimal=Decimal10+(bcd=0x0F))。void ds1302_init() /1302芯片初始化子函数(2012-06-18,12:00:00,week7)RST=0。SCLK=0.write_1302(0x8e,0x00)。 /允许写,禁止写保护 write_1302(0x80,0x00)。 /向DS1302内写秒寄存器80H写入初始秒数据00write_1302(0x82,0x00)。/向DS1302内写分寄存器82H写入初始分数据00wri
12、te_1302(0x84,0x12)。/向DS1302内写小时寄存器84H写入初始小时数据12write_1302(0x8a,0x07)./向DS1302内写周寄存器8aH写入初始周数据4write_1302(0x86,0x17)。/向DS1302内写日期寄存器86H写入初始日期数据18write_1302(0x88,0x06)。/向DS1302内写月份寄存器88H写入初始月份数据06write_1302(0x8c,0x12)。/向DS1302内写年份寄存器8cH写入初始年份数据12write_1302(0x8e,0x80)。 /打开写保护3。4 LCD显示程序流程图显示流程图如图3。4所示,
13、流程图分析如下:首先对1602显示屏进行初始化(初始化大约持续10ms),然后检查忙信号,若BF=0,则获得显示RAM地址,写入相应的数据显示.若BF=1,则代表模块正在进行内部操作,不接受任何外部指令和数据,直到BF=0为止。图3.4 LCD显示程序流程图4 万年历的仿真与调试结果上电后的显示 秒调节 功能按键,自上而下功能依次为调节按键、加按键、减按键5 心得体会本次设计是我们遇到过的较大的设计,所以遇到的问题也比较的多,尤其是以前没有接触过如此复杂的硬件电路以及软件编程,在软、硬件设计和调试中遇到了不少的困难,在同学的帮助才逐一克服了难题,学习到了不少的专业知识。在整个设计过程之前,我已
14、经在网上找了相关方面的资料,万事开始难,一开始不知道从哪里下手。后来慢慢学会分析系统,将系统模块化,各个模块可以在软件或者硬件上实现。在确保各个模块的硬件电路和与之相搭配的程序能够正常工作后在把它们组成一个系统.在今后的日子里,我会进一步加强自己的动手能力,丰富自己的知识面。参考文献1 李朝青。单片机原理及接口技术M,北京:北京航天航空大学出版社,20052 李广弟.单片机基础M,北京:北京航空航天大学出版社,20003 万光毅.单片机实验与实践教程M,北京:北京航空航天大学出版社,20034 唐亚平、李移伦。单片机原理实训与学习指导M,长沙:中南大学出版社,20065 刘军。单片机原理与接口
15、技术M,华东理工大学出版社,20066 谢自美.电子线路设计、实验、测试M,武汉:华中理工大学出版社,2000附件万年历源程序includereg51。h#include”DS18B20_3.Hdefine uint unsigned intdefine uchar unsigned charuchar a,miao,shi,fen,ri,yue,nian,week,flag,key1n,temp。/flag用于读取头文件中的温度值,和显示温度值#define yh 0x80 /LCD第一行的初始位置,因为LCD1602字符地址首位D7恒定为1(100000000=80)#define er
16、0x80+0x40 /LCD第二行初始位置(因为第二行第一个字符位置地址是0x40)/液晶屏的与C51之间的引脚连接定义(显示数据线接C51的P0口)sbit rs=P26。 /寄存器选择sbit en=P27. /下降沿使能sbit rw=P25。 /读写信号线/DS1302时钟芯片与C51之间的引脚连接定义sbit IO=P34./数据线sbit SCLK=P36.sbit RST=P35.sbit ACC0=ACC0。sbit ACC7=ACC7。ACC累加器=AACC。0=E0H /校时按键与C51的引脚连接定义sbit key1=P20。 /设置键sbit key2=P21。 /加键
17、sbit key3=P22. /减键sbit buzzer=P15。/蜂鸣器,端口低电平响uchar code tab1=”20 - - ”。 /年显示的固定字符uchar code tab2= : : 。/时间显示的固定字符/延时函数,后面经常调用void delay(uint xms)/延时函数,有参函数uint x,y.for(x=xms.x0。x-) for(y=120。y0。y-)。void write_1602com(uchar com)/*液晶写入指令函数*rs=0./数据/指令选择置为指令rw=0。 /读写选择置为写P0=com。/送入数据delay(1)。en=1。/拉高使能
18、端,为制造有效的下降沿做准备delay(1)。en=0。/en由高变低,产生下降沿,液晶执行命令void write_1602dat(uchar dat)/*液晶写入数据函数*rs=1./数据/指令选择置为数据rw=0。 /读写选择置为写P0=dat./送入数据delay(1).en=1。 /en置高电平,为制造下降沿做准备delay(1).en=0. /en由高变低,产生下降沿,液晶执行命令void lcd_init()/*液晶初始化函数*write_1602com(0x38)。/设置液晶工作模式,意思:16*2行显示,57点阵,8位数据write_1602com(0x0c)。/开显示不显示
19、光标write_1602com(0x06)。/整屏不移动,光标自动右移write_1602com(0x01)./清显示write_1602com(yh+1)。/日历显示固定符号从第一行第1个位置之后开始显示for(a=0。a14。a+)write_1602dat(tab1a)。/向液晶屏写日历显示的固定符号部分/delay(3).write_1602com(er+2)。/时间显示固定符号写入位置,从第2个位置后开始显示for(a=0。a1。uchar read_byte()/读一个字节RST=1.for(a=8.a0。a-) ACC7=IO. SCLK=1。 /产生下降沿输出数据,先输出低位,
20、保存到ACC中 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读数据函数,指定读取数据来源地址uchar temp。RST=0。SCLK=0。RST=1。write_byte(add)。temp=read_byte()。SCLK=1。RST=0。return(temp).ucha
21、r BCD_Decimal(uchar bcd)/BCD码转十进制函数,输入BCD,返回十进制uchar Decimal.Decimal=bcd4.return(Decimal=Decimal10+(bcd&=0x0F)。void ds1302_init() /1302芯片初始化子函数(201206-18,12:00:00,week7)RST=0。SCLK=0。write_1302(0x8e,0x00). /允许写,禁止写保护 write_1302(0x80,0x00)。 /向DS1302内写秒寄存器80H写入初始秒数据00write_1302(0x82,0x00)。/向DS1302内写分寄存
22、器82H写入初始分数据00write_1302(0x84,0x12)。/向DS1302内写小时寄存器84H写入初始小时数据12write_1302(0x8a,0x07)。/向DS1302内写周寄存器8aH写入初始周数据4write_1302(0x86,0x17)。/向DS1302内写日期寄存器86H写入初始日期数据18write_1302(0x88,0x06)./向DS1302内写月份寄存器88H写入初始月份数据06write_1302(0x8c,0x12)./向DS1302内写年份寄存器8cH写入初始年份数据12write_1302(0x8e,0x80)。 /打开写保护/温度显示子函数voi
23、d write_temp(uchar add,uchar dat)/向LCD写温度数据,并指定显示位置uchar gw,sw.gw=dat%10。/取得个位数字sw=dat/10。/取得十位数字write_1602com(er+add)。/er是头文件规定的值0x80+0x40write_1602dat(0x30+sw)。/数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw)。/数字+30得到该数字的LCD1602显示码 write_1602dat(0xdf)。/显示温度的小圆圈符号,0xdf是液晶屏字符库的该符号地址码 write_1602dat(0x43)
24、。 /显示”C符号,0x43是液晶屏字符库里大写C的地址码 /时分秒显示子函数void write_sfm(uchar add,uchar dat)/向LCD写时分秒,有显示位置加、现示数据,两个参数uchar gw,sw。gw=dat%10。/取得个位数字sw=dat/10。/取得十位数字write_1602com(er+add)。/er是头文件规定的值0x80+0x40write_1602dat(0x30+sw)。/数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw)。/数字+30得到该数字的LCD1602显示码 /年月日显示子函数void write_n
25、yr(uchar add,uchar dat)/向LCD写年月日,有显示位置加数、显示数据,两个参数uchar gw,sw。gw=dat%10。/取得个位数字sw=dat/10。/取得十位数字write_1602com(yh+add)。/设定显示位置为第一个位置+addwrite_1602dat(0x30+sw)。/数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw)。/数字+30得到该数字的LCD1602显示码void write_week(uchar week)/写星期函数write_1602com(yh+0x0c)。/星期字符的显示位置switch(we
26、ek) case 1:write_1602dat(M)。/星期数为1时,显示 write_1602dat(O)。 write_1602dat(N). break。 case 2:write_1602dat(T)./星期数据为2时显示 write_1602dat(U)。 write_1602dat(E)。 break。 case 3:write_1602dat(W)./星期数据为3时显示 write_1602dat(E). write_1602dat(D)。 break。 case 4:write_1602dat(T)./星期数据为4是显示 write_1602dat(H). write_160
27、2dat(U). break。 case 5:write_1602dat(F)。/星期数据为5时显示 write_1602dat(R)。 write_1602dat(I). break。 case 6:write_1602dat(S)。/星期数据为6时显示 write_1602dat(T)。 write_1602dat(A)。 break。 case 7:write_1602dat(S)。/星期数据为7时显示 write_1602dat(U)。 write_1602dat(N). break。/*键盘扫描有关函数*void keyscan()if(key1=0)/-key1为功能键(设置键)-
28、delay(9)。/延时,用于消抖动if(key1=0)/延时后再次确认按键按下 buzzer=0。/蜂鸣器短响一次 delay(20)。 buzzer=1。while(!key1)。key1n+。if(key1n=9) key1n=1。/设置按键共有秒、分、时、星期、日、月、年、返回,8个功能循环switch(key1n)case 1: TR0=0./关闭定时器 /TR1=0。 write_1602com(er+0x09)。/设置按键按动一次,秒位置显示光标 write_1602com(0x0f)。/设置光标为闪烁 temp=(miao)/10*16+(miao)10./秒数据写入DS130
29、2 write_1302(0x8e,0x00)。 write_1302(0x80,0x80|temp)。/miao write_1302(0x8e,0x80)。 break.case 2: write_1602com(er+6)。/按2次fen位置显示光标 /write_1602com(0x0f)。 break。case 3: write_1602com(er+3)./按动3次,shi /write_1602com(0x0f). break.case 4: write_1602com(yh+0x0e)。/按动4次,week /write_1602com(0x0f). break.case 5:
30、 write_1602com(yh+0x0a)。/按动5次,ri /write_1602com(0x0f). break.case 6: write_1602com(yh+0x07)。/按动6次,yue /write_1602com(0x0f)。 break。case 7: write_1602com(yh+0x04)。/按动7次,nian /write_1602com(0x0f)。 break。case 8: write_1602com(0x0c)。/按动到第8次,设置光标不闪烁 TR0=1。/打开定时器 temp=(miao)/10*16+(miao)10。 write_1302(0x8e
31、,0x00)。 write_1302(0x80,0x00|temp)./miao数据写入DS1302 write_1302(0x8e,0x80)。 break。 /-加键key2- if(key1n!=0)/当key1按下以下。再按以下键才有效(按键次数不等于零)if(key2=0) /上调键delay(10)。if(key2=0) buzzer=0./蜂鸣器短响一次 delay(20)。 buzzer=1。while(!key2)。switch(key1n)case 1:miao+./设置键按动1次,调秒 if(miao=60) miao=0。/秒超过59,再加1,就归零 write_sfm
32、(0x08,miao)。/令LCD在正确位置显示”加设定好的秒数 temp=(miao)/1016+(miao)%10。/十进制转换成DS1302要求的BCD码 write_1302(0x8e,0x00)。 /允许写,禁止写保护 write_1302(0x80,temp). /向DS1302内写秒寄存器80H写入调整后的秒数据BCD码 write_1302(0x8e,0x80)。 /打开写保护 write_1602com(er+0x09)。/因为设置液晶的模式是写入数据后,光标自动右移,所以要指定返回 /write_1602com(0x0b)。 break。case 2:fen+。 if(fe
33、n=60) fen=0。 write_sfm(0x05,fen)。/令LCD在正确位置显示”加设定好的分数据 temp=(fen)/10*16+(fen)10。/十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00)。/允许写,禁止写保护 write_1302(0x82,temp)。/向DS1302内写分寄存器82H写入调整后的分数据BCD码 write_1302(0x8e,0x80)。/打开写保护 write_1602com(er+6)./因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置 break。case 3:shi+. if(shi=24
34、) shi=0。 write_sfm(2,shi)./令LCD在正确的位置显示加”设定好的小时数据 temp=(shi)/10*16+(shi)%10。/十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00)./允许写,禁止写保护 write_1302(0x84,temp)./向DS1302内写小时寄存器84H写入调整后的小时数据BCD码 write_1302(0x8e,0x80)。/打开写保护 write_1602com(er+3)。/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break。case 4:week+. if(week=8) we
35、ek=1。 write_1602com(yh+0x0C)./指定加后的周数据显示位置 write_week(week)。/指定周数据显示内容 temp=(week)/1016+(week)%10。/十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00)。/允许写,禁止写保护 write_1302(0x8a,temp)。/向DS1302内写周寄存器8aH写入调整后的周数据BCD码 write_1302(0x8e,0x80)。/打开写保护 write_1602com(yh+0x0e)。/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break。case
36、 5:ri+。 if(ri=32) ri=1。 write_nyr(9,ri)./令LCD在正确的位置显示”加”设定好的日期数据 temp=(ri)/1016+(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
37、f(yue=13) yue=1。 write_nyr(6,yue)./令LCD在正确的位置显示”加设定好的月份数据 temp=(yue)/1016+(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(nia
38、n=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)。/打开写保护 write_1602com(yh+4)。/因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位 break。/-减键key3,各句功能参照加键注释
39、-if(key3=0)delay(10)。/调延时,消抖动if(key3=0) buzzer=0./蜂鸣器短响一次 delay(20)。 buzzer=1。while(!key3).switch(key1n) case 1:miao-. if(miao=1) miao=59。/秒数据减到-1时自动变成59 write_sfm(0x08,miao)./在LCD的正确位置显示改变后新的秒数 temp=(miao)/1016+(miao)%10./十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00)。 /允许写,禁止写保护 write_1302(0x80,temp)。
40、/向DS1302内写秒寄存器80H写入调整后的秒数据BCD码 write_1302(0x8e,0x80)。 /打开写保护 write_1602com(er+0x09)。/因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置 /write_1602com(0x0b)。 break。 case 2:fen-。 if(fen=-1) fen=59. write_sfm(5,fen)。 temp=(fen)/10*16+(fen)10./十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00)。/允许写,禁止写保护 write_1302(0x82,temp)。/向DS1302内写分寄存器82H写入调整后的分数据BCD码 write