华侨大学单片机课设实验报告文档格式.docx
《华侨大学单片机课设实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《华侨大学单片机课设实验报告文档格式.docx(29页珍藏版)》请在冰豆网上搜索。
对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:
RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:
R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:
D0~D7为8位双向数据线。
第15脚:
LEDA为背光接5V正电源。
第16脚:
LEDK为背光地电源。
1.2LCDI602控制指令
如表1所示,LCD1602的读写操作、屏幕和光标的操作都是通过指令编程来实现的。
·
指令1:
清显示。
指令码01H,光标复位到地址00H位置。
指令2:
光标复位。
光标返回到地址00H。
指令3:
光标和显示模式设置,I/D:
光标移动方向,高电平右移,低电平左移;
S:
屏幕上所有文字是否左移或者右移。
高电平表示有效,低电平则无效。
指令4:
显示开关控制。
D:
控制整体显示的开与关,高电平表示开显示,低电平表示关显示C:
控制光标的开与关,高电平表示有光标,低电平表示无光标B:
控制光标是否闪烁,高电平闪烁,低电平不闪烁
指令5:
光标或显示移位。
S/C:
高电平时移动显示的文字,低电平时移动光标。
指令6:
功能设置命令。
DL:
高电平时为4位总线,低电平时为8位总线;
N:
低电平时为单行显示,高电平时双行显示;
F:
低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。
指令7:
字符发生器RAM地址设置。
指令8:
DDRAM地址设置。
指令9:
读忙信号和光标地址。
BF:
为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。
指令10:
写数据。
指令11:
读数据。
指令
RSR/WD7D6D5D4D3D2D1D0
1清显示
2光标返回
3置输入模式
4显示开/关控制
5光标或字符移位
6置功能
7置字符发生存储器地址
8置数据存储器地址
9读忙标志或地址
10写数CGRAM或DDRAM
11从CGRAM或DDRAM读数
0000000001
000000001*
00000001I/DS
0000001DCB
000001S/CR/L**
00001DLNF**
0001字符发生存储器地址
001显示数据存储器地址
01BF计数器地址
10要写的数
11读出的数据
表1LCD1602的控制指令表
1.3LCDI602读写控制时序
LCD1602的读写控制时序如表2所示,使用LCD1602显示时要严格按照时序要求,否则LCD1602显示会出现问题。
表2LCD1602的读写控制时序表
RSR/WE功能
00下降沿写指令代码
01高电平读忙标志和AC码
10下降沿写数据
11高电平读数据
1.4LCDI602与单片机接口电路
2、DS1302模块设计
DS1302通过三根口线实现与单片机的通信,因DS1302功耗很小,即使电源掉电后通过3V的纽扣电池仍能维持DS1302精确走时。
(1)DS1302特性介绍
DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。
实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。
工作电压宽达2.5~5.5V。
采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后备电源进行涓细电流充电的能力。
(2)DS1302引脚介绍
各引脚的功能为:
8、Vcc1:
备用电池端;
1、Vcc2:
5V电源。
当Vcc2>
Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2<
Vcc1时,由Vcc1向DS1302供电。
7、SCLK:
串行时钟,输入;
6、I/O:
数据输入输出口;
5、CE/RST:
复位脚
23、X1、X2是外接晶振脚(32.768KHZ的晶振)
4、地(GND)
(4)DS1302有关日历、时间的寄存器
寄存器的说明如下:
1、秒寄存器(81h、80h)的位7定义为时钟暂停标志(CH)。
当初始上电时该位置为1,
时钟振荡器停止,DS1302处于低功耗状态;
只有将秒寄存器的该位置改写为0时,时钟才能开
始运行。
2、小时寄存器(85h、84h)的位7用于定义DS1302是运行于12小时模式还是24小时模式。
当为
高时,选择12小时模式。
在12小时模式时,位5是,当为1时,表示PM。
在24小时模式时,
位5是第二个10小时位
3、控制寄存器(8Fh、8Eh)的位7是写保护位(WP),其它7位均置为0。
在对任何的时钟和
RAM的写操作之前,WP位必须为0。
当WP位为1时,写保护位防止对任一寄存器的写操作。
也就是说在电路上电的初始态WP是1,这时是不能改写上面任何一个时间寄存器的,
只有首先将WP改写为0,才能进行其它寄存器的写操作。
(5)DS1302控制字介绍
控制字的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入到DS1302中。
位6:
如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;
位5至位1(A4~A0):
指示操作单元的地址;
位0(最低有效位):
如为0,表示要进行写操作,为1表示进行读操作。
读数据:
读数据时在紧跟8位的控制字指令后的下一个SCLK脉冲的下降沿,读出DS1302的数据,
读出的数据是从最低位到最高位。
写数据:
控制字总是从最低位开始输出。
在控制字指令输入后的下一个SCLK时钟的上升沿时,
数据被写入DS1302,数据输入也是从最低位(0位)开始。
为1表示进行读操作。
如为0,表示要进行写操作,
控制字后SCLK下降沿读数据SCLK上升沿写数据
(6)DS1302单字节读写时序介绍
DS1302的数据读写是通过I/O串行进行的。
当进行一次读写操作时最少得读写两个字节,第一个字节是控制字节,就是一个命令,告诉DS1302是读还是写操作,是对RAM还是对CLOK寄存器操作,以及操作的址。
第二个字节就是要读或写的数据了。
我们先看
单字节写:
在进行操作之前先得将CE(也可说是RST)置高电平,然后单片机将控制字的位0放到I/O上,当I/O的数据稳定后,将SCLK置高电平,DS1302检测到SCLK的上升沿后就将I/O上的数据读取,然后单片机将SCLK置为低电平,再将控制字的位1放到I/O上,如此反复,将一个字节控制字的8个位传给DS1302。
接下来就是传一个字节的数据给DS1302,当传完数据后,单片机将CE置为低电平,操作结束。
单字节读操作的一开始写控制字的过程和上面的单字节写操作是一样,但是单字节读操作在写控制字的最后一个位,SCLK还在高电平时,DS1302就将数据放到I/O上,单片机将SCLK置为低电平后数据锁存,
单机机就可以读取I/O上的数据。
如此反复,将一个字节的数据读入单片机。
读与写操作的不同就在于,写操作是在SCLK低电平时单片机将数据放到IO上,当SCLK上升沿时,DS1302读取。
而读操作是在SCLK高电平时DS1302放数据到IO上,将SCLK置为低电平后,单片机就可从IO上读取数据。
(7)DS1302操作指令介绍
操作说明:
1首先要通过8EH将写保护去掉,将日期,时间的初值写时各个寄存器。
2然后就可以对80H、82H、84H、86H、88H、8AH、8CH进行初值的写入。
同时也通过秒寄存器将位7的CH值改成0,这样DS1302就开始走时运了。
3将写保护寄存器再写为80H,防止误改写寄存器的值。
4不断读取80H-8CH的值,将它们格式化后显示到1602LCD液晶上
(8)DS1302与单片机接口电路
3、键盘模块设计
按键在单片机系统中是一个很重要的部件。
为了输入数据、查询和控制系统的工作状态,都要用到按键。
本实验用到按键进行时间设置与调整作用。
4、闹铃模块设计
系统采用蜂鸣器作为闹铃输出。
闹铃电路连接如图所示。
系统软件设计
软件设计是本设计的关键,软件程序编写的好坏直接影响着系统运行情况的良好。
因本程序涉及的模块较多,所以程序编写也采用模块化设计,C语言具有编写灵活、移植方便、便于模块化设计的特点,所以本系统的软件采用C51编写。
程序框图如下:
程序如下:
#include<
reg52.h>
#include"
define.h"
voiddelay(uintz)//毫秒级延时函数。
{
uintx,y;
for(x=z;
x>
0;
x--)
for(y=110;
y>
y--);
}
voiddi()//蜂鸣器发声函数。
beep=0;
delay(100);
beep=1;
voidwritecom(ucharcom)//液晶写命令函数。
lcdrs=0;
//置为写入命令
lcddata=com;
//送入数据
delay
(1);
lcden=1;
//拉高使能端
lcden=0;
//完成高脉冲
voidwritedata(uchardat)//液晶写数据函数。
lcdrs=1;
//置为写入数据
lcddata=dat;
voidwritetime(ucharadd,uchardat)//液晶刷新时分秒。
{//4为时的开始位置,7为分,10为秒。
ucharshi,ge;
shi=dat/10;
ge=dat%10;
writecom(0x80+0x40+add);
writedata(0x30+shi);
writedata(0x30+ge);
voidwritenyr(ucharadd,uchardat)//液晶刷新日期。
{//3为年,6为月,9为日。
writecom(0x80+add);
voidwriteweek(ucharweek)//液晶星期几显示函数。
writecom(0x80+12);
//从第一行隔十二个字符后开始写星期
switch(week)
{
case1:
writedata('
M'
);
writedata('
O'
N'
break;
case2:
T'
U'
E'
case3:
W'
D'
case4:
H'
case5:
F'
R'
I'
case6:
S'
A'
case7:
}
voidkeyscan()//键盘扫描函数。
key=0;
if(flagalarm==1)//如果闹钟在响,任意键停止闹钟响。
if((kmenu==0)||(kup==0)||(kdown==0)||(kalarm==0))
{
delay(5);
if((kmenu==0)||(kup==0)||(kdown==0)||(kalarm==0))
{
while(!
(kmenu&
&
kup&
kdown&
kalarm));
di();
flagalarm=0;
//清除闹钟标志。
}
}
}
if(kmenu==0)//检测功能键。
delay(5);
if(kmenu==0)
kmenunum++;
//记录功能键按下次数。
if(flagseta==1)//检测是否在进行闹钟设置。
if(kmenunum==4)kmenunum=1;
//因为进行闹钟设置时,只调节
//时分秒,所以,kmenunum只能等于1,2,3。
flagset=1;
//设置标志位,表示在进行各种时间设置。
while(!
kmenu);
di();
switch(kmenunum)//定位光标闪烁点。
case1:
writecom(0x80+0x40+11);
//秒闪烁。
writecom(0x0f);
//开光标闪烁。
break;
case2:
writecom(0x80+0x40+8);
//分闪烁。
case3:
writecom(0x80+0x40+5);
//时闪烁。
case4:
writecom(0x80+14);
//星期闪烁.
case5:
writecom(0x80+10);
//日闪烁.
case6:
writecom(0x80+7);
//月闪烁.
case7:
writecom(0x80+4);
//年闪烁.
case8:
kmenunum=0;
writecom(0x0c);
//取消光标闪烁。
flagset=0;
//取消时间调节标志。
dswrite(0x8e,0x00);
/*允许写操作*/
dswrite(0x80,second/10*16+second%10);
//退出时间设置功能时,往DS1302
dswrite(0x82,minute/10*16+minute%10);
//中保存所有时间变量的值。
dswrite(0x84,hour/10*16+hour%10);
dswrite(0x8a,week/10*16+week%10);
dswrite(0x86,day/10*16+day%10);
dswrite(0x88,month/10*16+month%10);
dswrite(0x8c,year/10*16+year%10);
dswrite(0x8e,0x80);
/*禁止写操作*/
}
if(kmenunum!
=0)//只有当功能键按下时,才检测增大,减小键.
if(kup==0)
if(kup==0)
kup);
switch(kmenunum)//根据功能键被按下的次数,调节相应数值。
{
case1:
second++;
if(second==60)
second=0;
writetime(10,second);
writecom(0x80+0x40+11);
//因为,上面送液晶显示
break;
//一次,光标后移一位,所以要将光标复位.
case2:
minute++;
if(minute==60)
minute=0;
writetime(7,minute);
writecom(0x80+0x40+8);
case3:
hour++;
if(hour==24)
hour=0;
writetime(4,hour);
writecom(0x80+0x40+5);
case4:
week++;
if(week==8)
week=1;
writeweek(week);
writecom(0x80+14);
case5:
day++;
if(day==32)
day=1;
writenyr(9,day);
writecom(0x80+10);
case6:
month++;
if(month==13)
month=1;
writenyr(6,month);
writecom(0x80+7);
case7:
year++;
if(year==100)
year=0;
writenyr(3,year);
writecom(0x80+4);
}
if(kdown==0)
if(kdown==0)
kdown);
switch(kmenunum)//根据功能键被按次数调节相应数值.
second--;
if(second==-1)
second=59;
minute--;
if(minute==-1)
minute=59;
hour--;
if(hour==-1)
hour=23;
week--;
if(week==0)
week=7;
day--;
if(day==0)
day=31;
month--;
if(month==0)
month=12;
year--;
if(year==-1)
year=99;
writenyr(3,year)