实时时钟设计报告.docx
《实时时钟设计报告.docx》由会员分享,可在线阅读,更多相关《实时时钟设计报告.docx(15页珍藏版)》请在冰豆网上搜索。
![实时时钟设计报告.docx](https://file1.bdocx.com/fileroot1/2023-1/23/fdf38d43-4512-4727-8a41-271b2abc535b/fdf38d43-4512-4727-8a41-271b2abc535b1.gif)
实时时钟设计报告
《单片机系统设计》(课程设计)
实验报告
题目:
实时时钟
组号:
任课教师:
组长:
成员:
联系方式:
年月日
一、实施方案1
1.1设计要求1
1.2实现功能1
1.3设计方案1
二、原理简述2
2.1主控模块2
2.2时钟电路3
2.3显示电路5
2.4键盘输入电路7
2.5蜂鸣器电路8
三、调试过程9
3.1硬件调试9
3.2软件调试9
四、主要程序10
五、心得体会12
一、实施方案
1.设计要求
通过对DS1302编程,实现实时时钟功能,用数码管显示时、分,用小数点作秒闪。
可用键盘设置时间。
2.实现功能
本组的课程设计成果最终将实现如下功能:
(1)实现实时时钟功能,四位数码管前两位显示时、后两位显示分,小数点作秒闪;
(2)按下S8键,可实现对小时的加1设置;
(3)按下S7键,可实现对分钟的加1设置;
(4)按下S1键,可实现小时的单独显示;
(5)实现整点蜂鸣器报时功能。
3.设计方案
根据系统设计的功能的要求,初步确定设计系统由主控模块、时钟电路、显示电路、键盘输入电路与蜂鸣器电路组成。
电路系统框图如图1所示。
图1系统设计框图
其中,主控芯片使用51系列AT89C52单片机,时钟芯片使用DS1302,晶振为11.0592MHz,显示电路由四位共阳LED数码管完成,键盘采用线性连接,使用查询法实现调整功能,蜂鸣器电路由有源蜂鸣器完成。
二、原理简述
1.主控模块
图2AT89C52管脚图
AT89C52是低功耗、高性能的CMOS8位单片机。
片内带有8KB的Flash存储器,且允许在系统内改写或用编程器编程。
另外,AT89C52的指令系统和引脚与80C52完全兼容。
管脚功能如下:
VCC:
供电电压;GND:
接地;P0口:
P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。
;P1口:
P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流;P2口:
P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。
并因此作为输入时,P2口的管脚被外部拉低,将输出电流;P3口:
P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。
当P3口写入“1”后,它们被内部上拉为高电平,并用作输入;P3口管脚功能:
P3.0是RXD(串行输入口);P3.1是TXD(串行输出口);P3.2是/INT0(外部中断0);P3.3是/INT1(外部中断1);P3.4是T0(记时器0外部输入);P3.5是T1(记时器1外部输入);P3.6是/WR(外部数据存储器写选通);P3.7是/RD(外部数据存储器读选通);P3口同时为闪烁编程和编程校验接收一些控制信号。
RST:
复位输入。
当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:
当访问外部存储器时,地址锁存允许输出电平用于锁存地址的地位字节。
/PSEN:
外部程序存储器的选通信号。
在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。
但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:
当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。
XTAL1:
反向振荡放大器的输入与内部时钟工作电路的输入。
XTAL2:
来自反向振荡器的输出。
2.时钟电路
图3硬件时钟DS1302电路
DS1302时钟芯片包括实时时钟/日历和31字节的静态RAM。
它经过一个简单的串行接口与微处理器通信。
实时时钟/日历提供秒、分、时、日、周、月和年等信息。
对于小于31天的月和月末的日期自动进行调整,还包括闰年校正的功能。
时钟的运行可以采用24h或带AM(上午)/PM(下午)的12h格式。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多字节的时钟信号或RAM数据。
DS1302在任何数据传送时必须先初始化,把RST脚置为高电平,然后把8位地址和命令字装入移位寄存器,数据在SCLK的上升沿被输入。
无论是读周期还是写周期,开始8位指定40个寄存器中哪个被访问到。
在开始8个时钟周期,把命令装入移位寄存器之后,另外的时钟周期在读操作时输出数据,在写操作时写入数据。
时钟脉冲在单字节方式下为8加8,在多字节方式下为8加字节数,最大可达248个字节数。
如果在传送过程中置RST脚为低电平,则会中止本次数据传送,并且I/O引脚变为高阻态。
相关代码如下:
/***********************ds1302与at89s52引脚连接******************/
sbitT_RST=P3^6;//RST脚接P3^6
sbitT_CLK=P3^4;//CLK脚接P3^4
sbitT_IO=P3^5;//IO脚接P3^5
sbitACC0=ACC^0;//定义标志位
sbitACC7=ACC^7;
/**********************DS1302:
写入操作(上升沿)*******************/
voidwrite_byte(unsignedcharda)
{
unsignedchari;
ACC=da;
for(i=8;i>0;i--)
{
T_IO=ACC0;
T_CLK=0;
T_CLK=1;
ACC=ACC>>1;
}
}
/**********************DS1302:
读取操作(下降沿)*****************/
unsignedcharread_byte(void)
{
unsignedchari;
for(i=0;i<8;i++)
{
ACC=ACC>>1;
T_CLK=1;
T_CLK=0;
ACC7=T_IO;
}
return(ACC);
}
/***************DS1302:
写入数据(先送地址,再写数据)***************/
voidwrite_1302(unsignedcharaddr,unsignedcharda)
{
T_RST=0;//停止工作
T_CLK=0;
T_RST=1;//重新工作
write_byte(addr);//写入地址
write_byte(da);
T_RST=0;
T_CLK=1;
}
/******************DS1302:
读取数据(先送地址,再读数据)************/
unsignedcharread_1302(unsignedcharaddr)
{
unsignedchartemp;
T_RST=0;//停止工作
T_CLK=0;
T_RST=1;//重新工作
write_byte(addr);//写入地址
temp=read_byte();
T_RST=0;
T_CLK=1;//停止工作
return(temp);
}
3.显示电路
图4四位共阳数码管电路
显示部分采用普通的共阳数码管显示,使用动态扫描,以便减少硬件电路。
LED数码管里面有8只发光二极管,与实验板P0端口所接的二极管是相同的。
分别记作a﹑b﹑c﹑d﹑e﹑f﹑g﹑dp,其中dp为小数点,每一只发光二极管都有一根电极引到外部引脚上,而另外一只引脚就连接在一起同样也引到外部引脚上。
该数码管为共阳极,且通过P0=P2直接把按键状态给到LED上,并没有中间变量,通过按键控制数码管的各管脚的高低电平接入情况。
当数码管里面的发光二极管的阳极接在一起作为公共引脚,在正常使用时此引脚接电源正极。
发光二极管的阴极接低电平时,发光二极管被点亮,从而相应的数码段显示数字。
LED接到单片机的P0口,若为低电平,可使LED亮起。
发光二极管的亮、灭由内部程序控制,因为流水灯与数码管同时接在P0端口,所以流水灯的8个LED发光二极管与LED数码管亮暗相同。
相关程序如下:
/*****************************定义数码管显示引脚*****************************/
sbitLED_0=P1^4;//数码管8个控制引脚定义
sbitLED_1=P1^5;
sbitLED_2=P1^0;
sbitLED_3=P1^1;
sbitLED_4=P1^2;
sbitLED_5=P1^3;
sbitLED_6=P1^6;
sbitLED_7=P1^7;
unsignedcharseg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~~9段码
/*********************************显示程序************************************/
/*动态扫描条件(单个LED在1秒内):
count>=50次//点亮次数*/
/*time>=2ms//持续时间*/
/*DS1302秒,分,时寄存器是BCD码形式:
用16求商和余进行"高4位"和"低4位"分离*/
/****************************************************************************/
voidled_disp(unsignedchar*poi)
{
P0=seg[*(poi+1)%16];//第1个数码管:
显示分(个位);
LED_5=0;
delay(3);
LED_5=1;
P0=seg[*(poi+1)/16];//第2个数码管:
显示分(十位);
LED_4=0;
delay(3);
LED_4=1;
P0=seg[*(poi+2)%16]-(((*poi%16)%2)<<7);//第3个数码管:
显示时(个位);
LED_3=0;
delay(3);
LED_3=1;
P0=seg[*(poi+2)/16];//第4个数码管:
显示时(十位);
LED_2=0;
delay(3);
LED_2=1;
}
voidled_disp1(unsignedchar*poi)
{
P0=seg[*(poi+2)%16]-(((*poi%16)%2)<<7);//第1个数码管:
显示时(个位);
LED_5=0;
delay(3);
LED_5=1;
P0=seg[*(poi+2)/16];//第2个数码管:
显示时(十位);
LED_4=0;
delay(3);
LED_4=1;
}
4.键盘输入电路
图58路独立按键电路
单片机的按键各自独立,按下归零,抬起置一。
相关程序如下:
sbitsw0=P2^7;//按键8
sbitsw1=P2^6;//按键7
sbitsw2=P2^0;//按键1
5.蜂鸣器电路
图6有源蜂鸣器电路
蜂鸣器发声原理是电流通过电磁线圈,使电磁线圈产生磁场来驱动振动膜发声的。
因此需要一定的电流才能驱动它,单片机I/O口输出的电流较小,其TTL电平基本上驱动不了蜂鸣器,因此需要增加一个电流放大的电路。
程序中通过改变单片机对应I/O口输出波形的频率,就可以调整控制蜂鸣器音调,产生各种不同音色、音调的声音。
另外,改变其占空比,也可以控制蜂鸣器的声音大小。
可以有两种驱动方式,即用PNP或NPN三极管电流放大电路驱动。
本电路通过一个PNP三极管9012来放大驱动蜂鸣器,当输出高电平时,三极管Q1截止,没有电流流过线圈,蜂鸣器不发声;当输出低电平时,三极管导通,这样蜂鸣器的电流形成回路,发出声音。
因此,我们可以通过程序控制I/O口输出的电平来使蜂鸣器发出声音和关闭,从而实现各种可能音响的产生。
相关程序如下:
#include//包含头文件
sbitbuz=P3^7;//定义蜂鸣器引脚是P33
voidDelay(unsignedinti)//最常用的延时函数,已经反复使用过
{
while(i--);
}
voidmain(void)//主函数开始
{
for(;;)
{
//以下实现buzzer和relay以一定频率改变状态
buz=0;//蜂鸣器响继电器开
Delay(60000);//延时
buz=1;//蜂鸣器不响继电器关
Delay(60000);//延时
}
}
三、调试过程
1.硬件调试
使用烙铁、焊锡、镊子等工具,根据原理图,将各种电子元件正确装配到电阻板上。
焊接过程中注意电路板与原理图连接一致,分清电解电容、二极管、芯片、排阻、蜂鸣器、单片机I/O接口等元件的引脚正反,避免虚焊、引脚短路现象。
为了避免较低的元件焊接不便,焊接时元件需要从低往高焊,较低的元件如电阻、单排圆孔、排阻、晶振等,普通高度元件有瓷片电容、按键、LED、芯片座、USB头、数码管、柱状晶振等,较高的元件有串口头、排针排孔、电源头等。
完成电路板的焊接工作并检查无误后,借助测试程序测试电路板的好坏。
在板子上正确下载DS1302实时时钟测试程序后,经测试电路板能够正确完成程序的功能,说明电路板焊接正确无误,可放心地进行下一步软件调试。
2.软件调试
DS1302实时时钟测试程序可以完成从12:
00开始计时,并在数码管上显示相应时间,在此程序基础上进行修改,即可完成本项目的预期功能。
在完成按键设置时间功能时,发现数码管显示数据出现时而正常,时而乱码该情况。
研究程序代码后发现,由于DS1302中秒、分、时寄存器是BCD码形式的,所以在进行加法运算时需要对BCD码进行修正,当结果大于9时,要进行加6操作,另外时和分的个位满10进一,分满60进一归零,时满24归零的判断分支语句顺序不是任意的,必须遵守一定的顺序。
在修改了上述错误后,发现由于按键消抖动不彻底,也导致了显示时间存在一定问题。
通过修改延迟时间,发现设置为20000时按键不灵活,设置为15000时按键存在抖动。
再通过一定调试后,最终将数值设置为18000。
在完成整点报时功能时,会出现蜂鸣器鸣叫持续一分钟的情况,这与鸣叫次数与小时相同的设计初衷违背。
研究发现是由于蜂鸣器相关语句位置太后,其中参数的值已经改变原有的值的原因,通过反复测试与分析,最终将蜂鸣器代码位置放在修改进位语句后面,从而完成了蜂鸣器整点报时的功能。
四、主要程序
#include//包含头文件
************************************主程序**********************************/
voiddelaysw(unsignedinti)
{
while(i--);
}
voidmain(void)
{
unsignedcharclk_time[3]={0x00,0x00,0x12};//秒,分,时寄存器初始值
unsignedchartemp=0x80;//数组序号
unsignedchari;
delay(300);
write_1302(0x8e,0x00);//WP=0写操作
for(i=0;i<3;i++)
{
write_1302(temp,clk_time[i]);
temp+=2;
//delay(300);
}
write_1302(0x8e,0x80);//WP=1写保护
//delay(300);
while
(1)
{
if(sw0==0)//按键8按下,时加1
{
delaysw(18000);
if(sw0==0)
{
clk_time[2]=read_1302(0x85);
clk_time[2]=clk_time[2]+1;
dflag=1;//标志位置1
}
}
if(sw1==0)//按键7按下,分加1
{
delaysw(18000);
if(sw1==0)
{
clk_time[1]=read_1302(0x83);
clk_time[1]=clk_time[1]+1;
dflag=1;//标志位置1
}
}
if(dflag==1)//标志位为1
{
if(clk_time[1]%16==10)
clk_time[1]=clk_time[1]+6;//分的个位满10,分的十位加1
if(clk_time[1]%96==0)
{
clk_time[1]=0;
clk_time[2]+=1;
}//分满60归零,时加1
if(clk_time[2]%16==10)
clk_time[2]=clk_time[2]+6;//时的个位满10,时的十位加1
if(clk_time[2]%36==0)
clk_time[2]=0;//时满24归零
if(clk_time[1]==0)//整点报时
{
for(i=0;i{
led_disp(clk_time);
buz=0;
delay(60000);
buz=1;
delay(60000);
}
}
temp=0x80;
write_1302(0x8e,0x00);//WP=0写操作
for(i=0;i<3;i++)
{
write_1302(temp,clk_time[i]);
temp+=2;
//delay(300);
}
write_1302(0x8e,0x80);//WP=1写保护
//delay(300);
dflag=0;//标志位置0
}
if(sw2==0)//按键1按下
{
delaysw(18000);
if(sw2==0)
dflag=~dflag;
}
if(dflag==0)//发送时间到数码管显示
led_disp(clk_time);
else
led_disp1(clk_time);
temp=0x81;
for(i=0;i<3;i++)
{
clk_time[i]=read_1302(temp);//实现每秒读时间
temp+=2;
}
}
五、心得体会
本次课程设计是对我们单片机学习的检验与对实际动手能力的又一次提高。
回顾此次单片机课程设计,真是感慨颇多。
期间不仅巩固了以前所学过的知识,还学到了很多在书本上所没有学到过的知识。
在实际设计中才发现,书本上理论性的东西与在实际运用中的还是有一定的出入的,所以有些问题不但要深入地理解,而且要不断地更正以前的错误思维。
一切问题必须要靠自己一点一滴地解决,而在解决的过程当中你会发现自己在飞速地提升。
对于单片机设计,其硬件电路是比较简单的,只要实验板焊接正确就问题不大了,主要的还是解决程序设计中的问题。
而程序设计是一个很灵活的东西,它反映了你解决问题的逻辑思维和创新能力,它才是一个设计的灵魂所在。
因此可以说单片机的设计是软件和硬件的结合,二者是密不可分的。
通过这次课程设计我发现单片机原理应用性极强,只有老师的讲解不行,光看不试也没用,只有自己动手去做才会发现自己确实有太多的不足。
许多的原理、程序看似简单,真正去做之后才会了解专业知识并没有自己想象中的那样扎实,从而明白理论与实际相结合是很重要的。
只有理论知识是远远不够的,只有将所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考能力,树立起对自己工作能力的信心,相信这会对今后的生活有非常重要的影响,而且大大提高了动手的能力,使我们充分体会到了在创造过程中探索的艰难和成功时的喜悦。
当然这次课程设计会提高我们独立思考完成任务的能力,但同组之间遇到实在没有办法解决的问题时,也会相互咨询和讨论,这样加强了大家的合作精神与团结能力,对未来的学习工作也有着极大的帮助。
在本次课程设计中,我们感到过程决定结果,细节决定成败。
整个过程中,从一开始的实验板焊接,到软件编程,再最后到程序调试,每一步我们都相当认真地去对待,每个细节都经过再三地分析确认。
从中我们学会了很多,我们要对自己所正在进行的事情有着充分的耐心,因为程序的编写和调试会经历很多的挫折和困难,如果不够坚持,最终是不会得到预期的项目成果的,同时也了解到了一个项目的设计完成并不是将简单的理论知识的拼凑和组合,是需要将理论和实际有机结合的过程。
在大学的这几年,我们接触到的都是基本的理论知识,极少会有机会在实践中运用这些知识,而本次课程就给我们这样的一次机会。
通过此次课程设计中遇到的问题也让我们认识到了自己知识的欠缺,所以以后的时间要好好利用图书馆、专业网站等途径来学习更多知识武装自己,为以后走上工作岗位打下坚实的基础。
我相信,在以后的单片机学习与使用中,本次课程设计学到的东西将会起着不可代替的作用。
此次设计的顺利如期完成也给了我们很大的信心,让我们在了解专业知识的同时也对本专业的发展前景充满了信心。