本科毕业设计单片机课程设计报告电子日历时钟.docx
《本科毕业设计单片机课程设计报告电子日历时钟.docx》由会员分享,可在线阅读,更多相关《本科毕业设计单片机课程设计报告电子日历时钟.docx(26页珍藏版)》请在冰点文库上搜索。
本科毕业设计单片机课程设计报告电子日历时钟
1题目设计要求
通过串行日历时钟芯片DS1302生成当前日期和是时间,通过IO口传输到AT89c52芯片中,然后再将AT89c52接收到的数据输出到LCD上。
要求LCD上显示的日期和时间与当前系统时间保持一致。
2系统的器件功能和作用
2.1MCSC51单片机AT89C51
AT89C51是一种带4K字节FLASH存储器(FPEROM—FlashProgrammableandErasableReadOnlyMemory)的低电压、高性能CMOS8位微处理器,俗称单片机。
AT89C2051是一种带2K字节闪存可编程可擦除只读存储器的单片机。
单片机的可擦除只读存储器可以反复擦除1000次。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器。
AT89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
AT89S51系列单片机中有PDIP,PLCC,TQFP多种封装形式。
本设计采用的是PDIP封装40管脚的单片机。
图2.1主控制模块AT89C52
●并行I/O接口P0、P1、P2、P3它们是特殊功能寄存器,既可以做输入又可以做输出
●串行I/O接口是全双工可编程的端口
●两个16位定时/计数器实现计数功能
●两个优先级别的中断源
●片内带振荡器,频率范围为1.2-12MHZ
2.2复位电路
复位是单片机的初始化操作。
单片机启运运行时,都需要先复位,其作用是使CPU和系统中其他部件处于一个确定的初始状态,并从这个状态开始工作。
因而,复位是一个很重要的操作方式。
但单片机本身是不能自动进行复位的,必须配合相应的外部电路才能实现。
复位电路的基本功能是:
系统上电时提供复位信号,直至系统电源稳定后,撤销复位信号。
为可靠起见,电源稳定后还要经一定的延时才撤销复位信号,以防电源开关或电源插头分-合过程中引起的抖动而影响复位。
图2.2复位电路
2.3DS1302时钟模块
DS1302是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。
DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。
DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。
2.3.1引脚功能及结构
图2.3DS1302引脚图
DS1302有8个引脚:
●X1、X2:
32.768kHz晶振介入引脚。
●GND:
地。
●RST:
复位引脚,低电平有效。
●I/O:
数据输入/输出引脚,具有三态功能。
●SCLK:
串行时钟输入引脚。
●Vcc1:
工作电源引脚。
●Vcc2:
备用电源引脚。
DS1302有一个控制寄存器,12个日历,时钟寄存器和31个RAM。
DS1302由Vcc1或Vcc2两者中的较大者供电。
当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。
当Vcc2小于Vcc1时,DS1302由Vcc1供电。
RST输入有两种功能:
首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。
当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。
如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。
上电运行时,在Vcc>2.0V之前,RST必须保持低电平。
只有在SCLK为低电平时,才能将RST置为高电平。
2.3.2DS1302的控制字节
DS1302的控制字节。
控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。
2.3.3DS1302的寄存器
DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器及其控制字见表1。
此外,DS1302还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。
时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。
DS1302与RAM相关的寄存器分为两类:
一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。
图2.4时钟芯片外部电路图
2.3.4数据输入输出(I/O)
在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。
同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
2.4晶振电路
图2.5晶振电路
晶体振荡器电路给数字钟提供一个频率稳定准确的32768Hz的方波信号,可保证数字钟的走时准确及稳定。
其中晶振电路的振荡频率为12MHZ。
2.5液晶显示LCD1602
2.5.1LCD1602的引脚功能及结构
1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。
它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM,显示效果也不好)。
1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
图2.6LCD1602引脚图
RT-1602采用表中的16脚接口:
●第1脚:
Vss,电源地。
●第2脚:
VDD,+5V电源。
●第3脚:
VL,液晶显示偏压信号。
●第4脚:
RS,数据/命令选择端,高电平时选择数据寄存器,低电平时选择指令寄存器。
●第5脚:
R/W,读/写选择端。
●第6脚:
E,使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
●第7—14脚:
D0~D7,为8位双向数据线。
●第15脚:
BLA,背光源正极。
●第16脚:
BLK,背光源负极。
2.5.2控制寄存器
控制寄存器用于存放DS1302的控制命令字,DS1302的RST引脚回到高电平后写入的第一个字就为控制命令。
它用于对DS1302读写过程进行控制,它的格式如下:
表2.1控制寄存器的格式
D7D6D5D4D3D2D1D0
1
RAM/CK
A4
A3
A2
A1
A0
RD/W
各项功能说明如下。
●D7:
固定为1
●D6:
RAM/CK位,片内RAM或日历、时钟寄存器选择位,当RAM/CK=1时,对片内RAM进行读写,当RAM/CK=0时,对日历、时钟寄存器进行读写。
●D5~D1:
地址位,用于选择进行读写的日历、时钟寄存器或片内RAM。
对日历、时钟寄存器或片内RAM的选择。
●D0:
读写位,当RD/W=1时,对日历、时钟寄存器或片内RAM进行读操作,当RD/W=0时,对日历、时钟寄存器或片内RAM进行写操作。
说明:
1)数据都以BCD码形式表示。
2)小时寄存器的D7位为12小时制/24小时制的选择位,当为1时选择12小时制,当为0时选24小时制。
当12小时制时,D5位为1是上午,D5位为0是下午,D4位小时的十位。
当24小时制时,D5、D4位为小时的十位。
3)秒寄存器中的CH位为时钟暂停位,当为1时,时钟暂停,为0时,时钟开始启动。
4)写保护寄存器中的WP为写保护位,WP=1时,写保护,当WP=0时,未写保护,当对日历、时钟寄存器或片内RAM进行写时,WP应清零,当对日历、时钟寄存器或片内RAM进行读时,WP一般置1.
5)慢充电寄存器的TCS位为控制慢充电的选择,当它为1010时才能是慢充电工作。
DS为二极管选择位。
DS为01选择一个二极管,DS为10选择两个二极管,DS为11或00充电器被禁止,与TCS无关。
RS用于选择连接在Vcc2与Vcc1之间的电阻,RS为00,充电器被禁止,与TCS无关。
3设计方案
3.1设计原理
电子日历时钟是采用单片机最小系统,用DS1302时钟芯片和LCD1602液晶显示器分别进行寄存相关信息与显示年、月、日、时、分和秒的显示。
每一秒刷新液晶屏的秒数值,每60秒刷新液晶屏分值,以此类推,组成电子日历时钟显示器。
3.2设计内容
通过串行日历时钟芯片DS1302生成当前日期和是时间,通过IO口传输到AT89c52芯片中,然后再将AT89c52接收到的数据输出到LCD上。
3.3系统组成
系统由复位电路、晶振电路、LCD1602液晶显示器、单片机AT89C52、串行时钟日历片DS1302、数据输入输出I/O组成。
DS1302的CLOCK与AT89C52的P1.6相连,RST与P1.5相连,IO与P1.7相连。
LCD1602的D0~D7与AT89C51的P0.0~P.7相连,并接上拉电阻,RS与P2.0相连,RW与P2.1相连,E与P2.2相连。
4系统硬件设计
图4.1电子日历时钟电路原理图
本电路是由AT89C52单片机为控制中心。
时钟电路由DS1302提供,它是一种高性能、低功耗的实时时钟电路。
它可以对年、月、日、时、分、秒进行计时。
显示器部分由LCD1602构成。
5系统软件设计
5.1源代码
#include//包含单片机寄存器的头文件
#include//包含_nop_()函数定义的头文件
/***********************************************************************
以下是DS1302芯片的操作程序
************************************************************************/
unsignedcharcodedigit[10]={"0123456789"};//定义字符数组显示数字
sbitDATA=P1^7;//位定义1302芯片的接口,数据输出端定义在P1.7引脚
sbitRST=P1^5;//位定义1302芯片的接口,复位端口定义在P1.5引脚
sbitSCLK=P1^6;//位定义1302芯片的接口,时钟输出端口定义在P1.6引脚
/*****************************************************
函数功能:
延时若干微秒
入口参数:
n
***************************************************/
voiddelaynus(unsignedcharn)
{
unsignedchari;
for(i=0;i}
/*****************************************************
函数功能:
向1302写一个字节数据
入口参数:
x
***************************************************/
voidWrite1302(unsignedchardat)
{
unsignedchari;
SCLK=0;//拉低SCLK,为脉冲上升沿写入数据做好准备
delaynus
(2);//稍微等待,使硬件做好准备
for(i=0;i<8;i++)//连续写8个二进制位数据
{
DATA=dat&0x01;//取出dat的第0位数据写入1302
delaynus
(2);//稍微等待,使硬件做好准备
SCLK=1;//上升沿写入数据
delaynus
(2);//稍微等待,使硬件做好准备
SCLK=0;//重新拉低SCLK,形成脉冲
dat>>=1;//将dat的各数据位右移1位,准备写入下一个数据位
}
}
/*****************************************************
函数功能:
根据命令字,向1302写一个字节数据
入口参数:
Cmd,储存命令字;dat,储存待写的数据
***************************************************/
voidWriteSet1302(unsignedcharCmd,unsignedchardat)
{
RST=0;//禁止数据传递
SCLK=0;//确保写数居前SCLK被拉低
RST=1;//启动数据传输
delaynus
(2);//稍微等待,使硬件做好准备
Write1302(Cmd);//写入命令字
Write1302(dat);//写数据
SCLK=1;//将时钟电平置于已知状态
RST=0;//禁止数据传递
}
/*****************************************************
函数功能:
从1302读一个字节数据
入口参数:
x
***************************************************/
unsignedcharRead1302(void)
{
unsignedchari,dat;
delaynus
(2);//稍微等待,使硬件做好准备
for(i=0;i<8;i++)//连续读8个二进制位数据
{
dat>>=1;//将dat的各数据位右移1位,因为先读出的是字节的最低位
if(DATA==1)//如果读出的数据是1
dat|=0x80;//将1取出,写在dat的最高位
SCLK=1;//将SCLK置于高电平,为下降沿读出
delaynus
(2);//稍微等待
SCLK=0;//拉低SCLK,形成脉冲下降沿
delaynus
(2);//稍微等待
}
returndat;//将读出的数据返回
}
/*****************************************************
函数功能:
根据命令字,从1302读取一个字节数据
入口参数:
Cmd
***************************************************/
unsignedcharReadSet1302(unsignedcharCmd)
{
unsignedchardat;
RST=0;//拉低RST
SCLK=0;//确保写数居前SCLK被拉低
RST=1;//启动数据传输
Write1302(Cmd);//写入命令字
dat=Read1302();//读出数据
SCLK=1;//将时钟电平置于已知状态
RST=0;//禁止数据传递
returndat;//将读出的数据返回
}
/*******************************************************************************
以下是对液晶模块的操作程序
*******************************************************************************/
sbitRS=P2^0;//寄存器选择位,将RS位定义为P2.0引脚
sbitRW=P2^1;//读写选择位,将RW位定义为P2.1引脚
sbitE=P2^2;//使能信号位,将E位定义为P2.2引脚
sbitBF=P0^7;//忙碌标志位,,将BF位定义为P0.7引脚
/*****************************************************
函数功能:
延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
voiddelay1ms()
{
unsignedchari,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
;
}
/*****************************************************
函数功能:
延时若干毫秒
入口参数:
n
***************************************************/
voiddelaynms(unsignedcharn)
{
unsignedchari;
for(i=0;idelay1ms();
}
/*****************************************************
函数功能:
判断液晶模块的忙碌状态
返回值:
result。
result=1,忙碌;result=0,不忙
***************************************************/
bitBusyTest(void)
{
bitresult;
RS=0;//根据规定,RS为低电平,RW为高电平时,可以读状态
RW=1;
E=1;//E=1,才允许读写
_nop_();//空操作
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
result=BF;//将忙碌标志电平赋给result
E=0;//将E恢复低电平
returnresult;
}
/*****************************************************
函数功能:
将模式设置指令或显示地址写入液晶模块
入口参数:
dictate
***************************************************/
voidWriteInstruction(unsignedchardictate)
{
while(BusyTest()==1);//如果忙就等待
RS=0;//根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
E=0;//E置低电平
//就是让E从0到1发生正跳变,所以应先置"0"
_nop_();
_nop_();//空操作两个机器周期,给硬件反应时间
P0=dictate;//将数据送入P0口,即写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=1;//E置高电平
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:
指定字符显示的实际地址
入口参数:
x
***************************************************/
voidWriteAddress(unsignedcharx)
{
WriteInstruction(x|0x80);//显示位置的确定方法规定为"80H+地址码x"
}
/*****************************************************
函数功能:
将数据(字符的标准ASCII码)写入液晶模块
入口参数:
y(为字符常量)
***************************************************/
voidWriteData(unsignedchary)
{
while(BusyTest()==1);
RS=1;//RS为高电平,RW为低电平时,可以写入数据
RW=0;
E=0;
//就是让E从0到1发生正跳变,所以应先置"0"
P0=y;//将数据送入P0口,即将数据写入液晶模块
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=1;//E置高电平
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:
对LCD的显示模式进行初始化设置
***************************************************/
voidLcdInitiate(void)
{
delaynms(15);//延时15ms,首次写指令时应给LCD一段较长的反应时间
WriteInstruction(0x38);//显示模式设置:
16×2显示,5×7点阵,8位数据接口
delaynms(5);//延时5ms ,给硬件一点反应时间
WriteInstruction(0x38);
delaynms(5);//延时5ms ,给硬件一点反应时间
WriteInstruction(0x38);//连续三次,确保初始化成功
delaynms(5);//延时5ms ,给硬件一点反应时间
WriteInstruction(0x0c);//显示模式设置:
显示开,无光标,光标不闪烁
delaynms(5);//延时5ms ,给硬件一点反应时间
WriteInstruction(0x06);//显示模式设置:
光标右移,字符不移
delaynms(5);//延时5ms ,给硬件一点反应时间
WriteInstruction(0x01);//清屏幕指令,将以前的显示内容清除
delaynms(5);//延时5ms ,给硬件一点反应时间
}
/**************************************************************
以下是1302数据的显示程序
***************************