基于单片机的电子时钟设计课程设计.docx
《基于单片机的电子时钟设计课程设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的电子时钟设计课程设计.docx(35页珍藏版)》请在冰点文库上搜索。
基于单片机的电子时钟设计课程设计
目录
第一章电子时钟的相关知识3
1.1电子时钟简介3
1.2电子时钟的工作原理3
1.3电子时钟的应用与优缺点4
第二章课程设计内容与要求分析5
2.1课程设计内容5
2.2设计要求5
2.3控制系统的选择6
第三章系统原理及其工作原理描述6
3.1STC89C51简介6
3.2系统电路组成9
3.3各个模块说明10
第四章控制系统的软件设计12
4.1程序流程图12
4.1.1按键处理程序12
4.1.2按键读取程序13
4.2程序设计14
第五章实验心得25
参考文献27
评语及成绩28
第一章电子时钟的相关知识
1.1电子时钟简介
电子钟亦称数显钟(数字显示钟),是一种用数字电路技术实现时、分、秒计时的装置,与机械时钟相比,直观性为其主要显著特点,且因非机械驱动,具有更长的使用寿命,相较石英钟的石英机芯驱动,更具准确性。
电子钟已成为人们日常生活中必不可少的必需品,广泛用于个人家庭以及车站、码头、剧院、办公室等公共场所,给人们的生活、学习、工作、娱乐带来极大地方便。
相对于其他时钟类型,它的特点可归结为“两强一弱”:
比机械钟强在观时显著,比石英钟强在走时准确,但是它的弱点为显时较为单调。
1.2电子时钟的工作原理
电子钟是一个将“时”,“分”,“秒”显示于人的视觉器官的计时装置。
它的计时周期为24小时,显示满刻度为23时59分59秒,具有校时功能和报时功能。
因此,一个基本的数字钟电路主要由译码显示器、“时”,“分”,“秒”计数器、校时电路、报时电路和振荡器组成。
主电路系统由秒信号发生器、“时、分、秒”计数器、译码器及显示器、校时电路、整点报时电路组成。
秒信号产生器是整个系统的时基信号,它直接决定计时系统的精度,一般用石英晶体振荡器加分频器来实现。
将标准秒信号送入“秒计数器”,“秒计数器”采用60进制计数器,每累计60秒发出一个“分脉冲”信号,该信号将作为“分计数器”的时钟脉冲。
“分计数器”也采用60进制计数器,每累计60分钟,发出一个“时脉冲”信号,该信号将被送到“时计数器”。
“时计数器”采用24进制计时器,可实现对一天24小时的累计。
译码显示电路将“时”、“分”、“秒”计数器的输出状态用七段显示译码器译码,通过七段显示器显示出来。
整点报时电路时根据计时系统的输出状态产生一脉冲信号,然后去触发一音频发生器实现报时。
校时电路时用来对“时”、“分”、“秒”显示数字进行校对调整。
1.3电子时钟的应用与优缺点
应用
目前,在国内,电子钟因LCD数字显示效用直接有效,所以大多运用在城市的主要营业场所,以及车站、码头等公共场所。
在对公共场所的电子钟设定的时候,使用者还可根据周边的气候、温度等对LCD屏进行设置。
同时,因为LCD的显示耗电量很省,所以能够保持持续的工作效果。
夜间在睡觉的时候,床头如果放个带投影功能的电子钟,可以不用起床,直接让时间显示在天花板上,非常直观与有效。
现在生产的大部分汽车中,车内前方仪表盘旁边一般也都自带电子钟功能,采取蓝色背景光板成像效果,非常清晰。
优点
与传统的机械钟先比,电子钟具有更优异的优点。
由于电子钟采用数字集成电路的发展和采用了先进的石英技术,使电子钟具有走时准确、性能稳定、携带方便等优点,电子钟用于定时自动报警、按时自动打铃、时间程序自动控制、定时广播及自动控制等各个领域。
缺点
因为电子钟毕竟是电子产品,电子产品都有辐射,不过电子钟危害极低,对人体够不成任何危害,不象手机的辐射那么大。
第二章课程设计内容与要求分析
2.1课程设计内容
1)以MCS-51系列单片机为核心器件组成电子时钟控制系统;
2)利用提供单元模块构成硬件系统。
3)系统程序编制与调试;
4)电路系统的综合调试;
5)撰写课程设计论文;
6)完成课程设计论文答辩。
2.2设计要求
1)以STC10F04E单片机为控制核心,用单片机内部定时器为时钟源,设计电子时钟,使用4位数码管显示时、分,后两位数码管(分)的闪烁显示秒。
2)显示格式为:
“XXXX
3)用4个功能键操作来进行对时。
可自行定义各键的功能,也可按下述方式定义K1~K4键的功能如下。
K1—功能键,每按下一次对应的LED闪烁。
K2—移位键,每按下一次向后移一位。
K3—加1键。
K4—减1键。
2.3控制系统的选择
通过对多种单片机性能的分析,最终认为89C51是最理想的电子时钟开发芯片。
89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS8位微处理器,器件采用宏晶高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容,并且可是在线编程。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中。
宏晶的STC89C51是一种高效微控制器,而且它与MCS-51兼容,且具有4K字节可编程闪烁存储器和1000写/擦循环,数据保留时间为10年等特点,是最好的选择。
第三章系统原理及其工作原理描述
3.1STC89C51简介
VCC:
电源。
GND:
接地。
P0口:
P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。
当P1口的管脚第一次写1时,被定义为高阻输入。
P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。
在FIASH编程时,P0口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
P1口:
P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。
P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。
在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:
P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。
并因此作为输入时,P2口的管脚被外部拉低,将输出电流。
这是由于内部上拉的缘故。
P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。
在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。
P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:
P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。
当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。
作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
P3口也可作为AT89C51的一些特殊功能口,如下表所示:
口管脚备选功能
P3.0RXD(串行输入口)
P3.1TXD(串行输出口)
P3.2/INT0(外部中断0)
P3.3/INT1(外部中断1)
P3.4T0(记时器0外部输入)
P3.5T1(记时器1外部输入)
P3.6/WR(外部数据存储器写选通)
P3.7/RD(外部数据存储器读选通)
P3口同时为闪烁编程和编程校验接收一些控制信号。
RST:
复位输入。
当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:
当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。
在FLASH编程期间,此引脚用于输入编程脉冲。
在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。
因此它可用作对外部输出的脉冲或用于定时目的。
然而要注意的是:
每当用作外部数据存储器时,将跳过一个ALE脉冲。
如想禁止ALE的输出可在SFR8EH地址上置0。
此时,ALE只有在执行MOVX,MOVC指令是ALE才起作用。
另外,该引脚被略微拉高。
如果微处理器在外部执行状态ALE禁止,置位无效。
图3-189C51单片机
PSEN:
外部程序存储器的选通信号。
在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。
但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
EA/VPP:
当/EA保持低电平时,则在此期间外部程序存储(0000H-FFFFH),不管是否有内部程序存储器。
注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。
在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
3.2系统电路组成
图3-2系统原理图
图3-3系统原理图
3.3各个模块说明
1、显示模块
数码管是一种把多个LED显示段集成在一起的显示设备。
有两种类型,一种是共阳型,一种是共阴型。
共阳型就是把多个LED显示段的阳极接在一起,又称为公共端。
共阴型就是把多个LED显示段的阴极接在一起,即为公共商。
阳极即为二极管的正极,又称为正极,阴极即为二极管的负极,又称为负极。
通常的数码管又分为8段,即8个LED显示段,这是为工程应用方便如设计的,分别为A、B、C、D、E、F、G、DP,其中DP是小数点位段。
而多位数码管,除某一位的公共端会连接在一起,不同位的数码管的相同端也会连接在一起。
即,所有的A段都会连在一起,其它的段也是如此,这是实际最常用的用法。
数码管显示方法可分为静态显示和动态显示两种。
静态显示就是数码管的8段输入及其公共端电平一直有效。
动态显示的原理是,各个数码管的相同段连接在一起,共同占用8位段引管线;每位数码管的阳极连在一起组成公共端。
利用人眼的视觉暂留性,依次给出各个数码管公共端加有效信号,在此同时给出该数码管加有效的数据信号,当全段扫描速度大于视觉暂留速度时,显示就会清晰显示出来。
图3-4数码管
2、按键模块
该设计只用了一个键盘,但实现的功能却是比较完善,减少了硬件资源的损耗,该键盘可以实现小时和分钟的调节以及控制是否进入省电模式。
当按键按下又松开,可以实现屏蔽数码管显示的功能,达到省电的目的;直接按下不松开,则可以通过按键实现分钟的累加,每按一次分钟加一;而连续两次按下按键不放松,则可实现小时的调节,同样每按一次小时加一。
达到时间调节的目的。
图3-5按键
第四章控制系统的软件设计
4.1程序流程图
4.1.1按键处理程序
4.1.2按键读取程序
4.2程序设计
#include"reg51.h"
#include
typedefbitBOOL;//位变量//
typedefunsignedcharUINT8;//无符号8位整型变量//
typedefsignedcharINT8;//有符号8位整型变量//
typedefunsignedintUINT16;//无符号16位整型变量//
typedefsignedintINT16;//有符号16位整型变量//
typedefunsignedlongUINT32;//无符号32位整型变量//
typedefsignedlongINT32;//有符号32位整型变量//
typedeffloatFP32;//单精度浮点数(32位长度)//
typedefdoubleFP64;//双精度浮点数(64位长度)//
sbitKeyFunction=P2^0;
sbitKeyMove=P2^1;
sbitKeyAdd=P2^2;
sbitKeySub=P2^3;
bitSetFinish=0;//设置完成标志
bitSecFlag=0;//秒闪烁标
bitSecFlag1=0;
UINT8KeyfunFlag,MoveFlag,AddFlag,SubFlag,Set1Timer,Set2Timer,Set3Timer,Set4Timer;
UINT8codeLEDVal[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};//0-9
UINT8datanum[5];
UINT8datanum1[5];
UINT16Time,GmsTimer;
UINT8Sec,Min,Hour;
UINT8disp_value;
voidDisp(UINT16disp_value);
voidDisp1(UINT16disp_value);
voidBcd(UINT16bcd_value);
voidDelayMs(UINT16delay);
voidDispSet(UINT16disp_value);
voidKeyScan();
//========================================================
//函数名称:
显示函数
//函数功能:
//入口参数:
//出口参数:
//备注:
//========================================================
voidDisp(UINT16disp_value)
{
UINT8i;
Bcd(disp_value);
for(i=1;i<5;i++)
{
if((SecFlag==1)&&((i==1)|(i==2)))//第几个管闪烁
{
SBUF=0xff;
while(TI==0);
TI=0;
}
else
{
SBUF=LEDVal[num[i]];
while(TI==0);
TI=0;
}
}
}
///////////////////////////////
voidDisp1(UINT16disp_value)
{
{
UINT8i;
Bcd(disp_value);
for(i=1;i<5;i++)
{
if((SecFlag1==1)&&((i==1)|(i==2)))//第几个管闪烁
{
SBUF=0xff;
while(TI==0);
TI=0;
}
else
{
SBUF=LEDVal[num[i]];
while(TI==0);
TI=0;
}
}
}
}
//========================================================
//函数名称:
设置显示函数
//函数功能:
//入口参数:
//出口参数:
//备注:
//========================================================
voidDispSet(UINT16disp_value)
{
UINT8i;
Bcd(disp_value);
for(i=1;i<5;i++)
{
if((MoveFlag==i)&&(SecFlag1==1))
{SBUF=0xff;
while(TI==0);
TI=0;
}
else
{
SBUF=LEDVal[num[i]];
while(TI==0);
TI=0;
}
}
}
//========================================================
//函数名称:
延时函数
//函数功能:
//入口参数:
//出口参数:
//备注:
//========================================================
voidDelayMs(UINT16delay)
{
UINT8j;
while(delay--)
{
for(j=125;j>0;j--)
{;}
}
}
//========================================================
//函数名称:
数据分离函数
//函数功能:
//入口参数:
//出口参数:
//备注:
//========================================================
voidBcd1(UINT16bcd_value)
{
num1[4]=bcd_value/1000;
num1[3]=(bcd_value%1000)/100;
num1[2]=((bcd_value%1000)%100)/10;
num1[1]=((bcd_value%1000)%100)%10;
}
//////////////////////////////////////////////////////////////
voidBcd(UINT16bcd_value)
{
num[4]=bcd_value/1000;
num[3]=(bcd_value%1000)/100;
num[2]=((bcd_value%1000)%100)/10;
num[1]=((bcd_value%1000)%100)%10;
}
//========================================================
//函数名称:
键盘扫描函数
//函数功能:
//入口参数:
//出口参数:
//备注:
//========================================================
voidKeyScan()
{
if(KeyFunction==0)//功能键按下
{
DelayMs(20);
if(KeyFunction==0)
{
while(KeyFunction==0);
KeyfunFlag++;
}
}
//////////////
if(KeyMove==0)//移位键按下
{
DelayMs(20);
if(KeyMove==0)
{
while(KeyMove==0);
MoveFlag++;
if(MoveFlag==5)
{
MoveFlag=1;
}
}
}
//////////////
if(KeyAdd==0)//加一键
{
DelayMs(20);
if(KeyAdd==0)
{
while(KeyAdd==0);
AddFlag=1;
}
}
if(KeySub==0)//减一键
{
DelayMs(20);
if(KeySub==0)
{
while(KeySub==0);
SubFlag=1;
}
}
}
//========================================================
//函数名称:
按键处理
//函数功能:
//入口参数:
//出口参数:
//备注:
//========================================================
voidKeyDeal()
{
if(KeyfunFlag==1)//功能按下一次
{
TR0=0;//关闭定时器
if((MoveFlag==1)&&(AddFlag==1))//设置第一位
{
AddFlag=0;
Set1Timer++;
if(Set1Timer==10)
{
Set1Timer=0;
}
}
if((MoveFlag==1)&&(SubFlag==1))
{
SubFlag=0;
Set1Timer--;
if(Set1Timer==-1)
{
Set1Timer=9;
}
}
if((MoveFlag==2)&&(AddFlag==1))//设置第二位
{
AddFlag=0;
Set2Timer++;
if(Set2Timer==6)
{
Set2Timer=0;
}
}
if((MoveFlag==2)&&(SubFlag==1))
{
SubFlag=0;
Set2Timer--;
if(Set2Timer==-1)
{
Set2Timer=5;
}
}
if((MoveFlag==3)&&(AddFlag==1))//设置第三位
{
AddFlag=0;
Set3Timer++;
if(Set4Timer<2)
{
if(Set3Timer==10)
{
Set3Timer=0;
}
}
if((Set4Timer==2)&&(Set3Timer==4))//时钟十位为2
{
Set3Timer=0;
}
}
if((MoveFlag==3)&&(SubFlag==1))
{
SubFlag=0;
Set3Timer--;
if(Set3Timer==-1)
{
if(Set4Timer<2)
{
Set3Timer=9;
}
if(Set4Timer==2)
{
Set3Timer=3;
}
}
}
if((MoveFlag==4)&&(AddFlag==1))//设置第四位
{
AddFlag=0;
Set4Timer++;
if(Set3Timer>3)
{
if(Set4Timer==2)
{
Set4Timer=0;
}
}
elseif(Set4Timer==3)
{
Set4Timer=0;
}
}
if((MoveFlag==4)&&(SubFlag==1))
{
SubFlag=0;
Set4Timer--;
if(Set4Timer==-1)
{
if(Set3Timer>3)
{
Set4Timer=1;
}
else
{
Set4Timer=2;
}
}
}
}
if(KeyfunFlag