单片机课程设计实验报告 基于单片机的数字时钟 含完整实验代码.docx

上传人:b****7 文档编号:25689554 上传时间:2023-06-11 格式:DOCX 页数:34 大小:829.20KB
下载 相关 举报
单片机课程设计实验报告 基于单片机的数字时钟 含完整实验代码.docx_第1页
第1页 / 共34页
单片机课程设计实验报告 基于单片机的数字时钟 含完整实验代码.docx_第2页
第2页 / 共34页
单片机课程设计实验报告 基于单片机的数字时钟 含完整实验代码.docx_第3页
第3页 / 共34页
单片机课程设计实验报告 基于单片机的数字时钟 含完整实验代码.docx_第4页
第4页 / 共34页
单片机课程设计实验报告 基于单片机的数字时钟 含完整实验代码.docx_第5页
第5页 / 共34页
点击查看更多>>
下载资源
资源描述

单片机课程设计实验报告 基于单片机的数字时钟 含完整实验代码.docx

《单片机课程设计实验报告 基于单片机的数字时钟 含完整实验代码.docx》由会员分享,可在线阅读,更多相关《单片机课程设计实验报告 基于单片机的数字时钟 含完整实验代码.docx(34页珍藏版)》请在冰豆网上搜索。

单片机课程设计实验报告 基于单片机的数字时钟 含完整实验代码.docx

单片机课程设计实验报告基于单片机的数字时钟含完整实验代码

单片机课程设计报告

基于单片机的数字时钟

 

姓名:

班级:

学号:

一、前言

利用实验板上的4个LED数码管,设计带有闹铃、秒表功能的数字时钟。

功能要求:

a)计时并显示(LED)。

由于实验板上只有4位数码管,可设计成显示“时分”和显示“分秒”并可切换。

b)时间调整功能。

利用4个独立按钮,实现时钟调整功能。

这4个按钮的功能为工作模式切换按钮(MODE),数字加(INC),数字减(DEC)和数字移位(SHITF)。

c)定闹功能。

利用4个独立按钮设定闹钟时间,时间到以蜂鸣器响、继电器动作作为闹铃。

d)秒表功能。

最小时间单位0.01秒。

二、硬件原理分析

1.电源部分

电源部份采用两种输入接口(如上图)。

a)外电源供电,采用2.1电源座,可接入电源DC5V,经单向保护D1接入开关S1。

b)USB供电,USB供电口输入电源也经D1单向保护,送到开关S1。

注:

两路电源输入是并连的,因此只选择一路就可以了,以免出问题。

S1为板子工作电源开关,按下后接通电源,提供VCC给板子各功能电路。

电路采用两个滤波电容,给板子一个更加稳定的工作电源。

LED为电源的指示灯,通电后LED灯亮。

2.蜂鸣器

蜂鸣器分为有源和无源两种,有源即两引脚有一个直流电源就可以长鸣,无源则需要一个1K左右的脉冲才可以蜂鸣,因此对于按键的提示音及报警蜂鸣使用有源来得方便。

有源也可以当无源使用,而无源则不能当有源使用,当然用有源蜂鸣器作音乐发声会失真厉害。

如上图:

单片机P15输出高低电平经R21连接三极管B极,控制三极管的导通与截止,从而控制蜂鸣器的工作。

低电平时三极管导通,蜂鸣器得电蜂鸣,高电平时三极管截止,蜂鸣器失电关闭蜂鸣。

3.

数码管

电路使用一个四位共阳型数码管,四个公共阳级由三极管放大电流来驱动,三极管由P10-P13控制开与关。

数码管的阴级由P0口经过电阻限流连接。

例如,要十位的数码管工作,P12输出0,使三极管Q12导通,8脚得电,当P0口相应位有输出0时,点亮相应的LED灯组合各种字符数字。

4.独立键盘

如上图,由六个按键组成,每个按键的一端连接IO口,另一端直接连接GND(0电位)。

六个按键分别接入P37-P32,只要按下按键,相应位的IO口位将被拉为低电平(0),程序可以判断相应位是否为0来确认按键己按下。

 

5.动态显示

动态显示驱动电路是单片机应用中最常用的显示方式。

动态显示接口电路是把所有显示器的8个笔划段的同名段连在一起,而每一个显示器的公共极COM是各自独立地受I/O线控制。

CPU向字段输出口送出字形码时,所有显示器接收到相同的字形码,但究竟是哪个显示器亮,则取决于COM端。

在轮流点亮扫描过程中,每位显示器的点亮时间是极为短暂的(约1ms),但由于人眼的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位显示器并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感。

动态扫描显示必须由CPU不断地调用显示程序,才能保证持续不断的显示。

在实际工作中,当然不可能只显示,这样在两次调用显示程序之间的时间间隔就不一定了,如果时间间隔比较长,就会使显示不连续。

三、

软件设计

●主程序

将按键1设定为功能选择键,每按一次按键1,进入相应的功能模式。

 

●分秒显示

分秒显示模式下,数码管显示时钟时间的分和秒。

当按键1按下后,进入下一模式。

 

●时分显示

时分显示模式下,数码管显示时钟时间的时和分。

当按键1按下后,进入下一模式。

时间调整

时间调整模式下,仅调整时钟的时、分。

数码管闪烁的为当前调整的位子,按键2为加,按键3为减,按键4为移位键。

闹钟

闹钟模式下,可设置闹钟的时、分。

数码管闪烁的为当前调整的位子,按键2为加,按键3为减,按键4为移位键。

当闹钟时间调整完毕之后,按下按键5,确认闹钟时间。

随后等待时钟时间到达闹钟时间。

时钟时间到达闹钟时间后,蜂鸣器工作。

●秒表

秒表模式下,按下按键4,秒表开始计时;再次按下按键4,秒表暂停。

按下按键2或按键3,秒表清零。

 

四、

软件调试

在软件调试过程中碰到了很多问题。

其中比较重要的几个问题如下:

1、时钟调整子程序中,时、分的十位数、个位数加减不符合常识。

比如在加减时,小时可以达到27、28等数值,而这是不符合常识的。

在查看代码后发现,可以在加、减过程中设置if函数判断当前所处位置,调整当前数值所能达到的最大值或最小值。

修改后代码如下:

elseif(keyval==0xbf)//按键2加

{

if(pos==0)

{

dispbuf[pos]++;

if(dispbuf[pos]==3)

{

dispbuf[pos]=0;

}

}

elseif(pos==1)

{

if(dispbuf[0]==0||dispbuf[0]==1)

{

dispbuf[pos]++;

dispbuf[pos]=dispbuf[pos]%10;

}

if(dispbuf[0]==2)

{

dispbuf[pos]++;

if(dispbuf[pos]>=4)

{

dispbuf[pos]=0;

}

}

}

elseif(pos==2)

{

dispbuf[pos]++;

if(dispbuf[pos]==6)

{

dispbuf[pos]=0;

}

}

elseif(pos==3)

{

dispbuf[pos]++;

dispbuf[pos]=dispbuf[pos]%10;

}

}

elseif(keyval==0xdf)//按键3减

{

if(pos==0)

{

if(dispbuf[pos]==0)dispbuf[pos]=2;

elsedispbuf[pos]--;

}

elseif(pos==1)

{

if(dispbuf[0]==0||dispbuf[0]==1)

{

if(dispbuf[pos]==0)dispbuf[pos]=9;

elsedispbuf[pos]--;

}

if(dispbuf[0]==2)

{

if(dispbuf[pos]>=4&&dispbuf[pos]<=9)

{

dispbuf[pos]=3;

}

elseif(dispbuf[pos]==0)

{

dispbuf[pos]=3;

}

else

{

dispbuf[pos]--;

}

}

}

elseif(pos==2)

{

if(dispbuf[pos]==0)dispbuf[pos]=5;

elsedispbuf[pos]--;

}

elseif(pos==3)

{

if(dispbuf[pos]==0)dispbuf[pos]=9;

elsedispbuf[pos]--;

}

}

2、秒表模式下,无法很好地区分当前计时所达到的具体数值。

在秒的个位数位子设置一个小数点,使秒表的显示更加直观。

修改后代码如下:

在程序开始处,添加如下代码:

unsignedcharcodesegtab_dot[]=

{0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//带小数点的数码管代码

在voidt0int(void)interrupt1using1之中添加如下代码:

if(mode==4&&P1==0xfd)//秒表处显示小数点的if语句

{

P0=segtab_dot[dispbuf[dispindex]];

}

else

{

P0=segtab[dispbuf[dispindex]];

}

 

3、在秒表运行一遍后,进入其他模式操作完毕,再次进入秒表模式下发现秒表无法清零。

检查代码后发现,在闹钟模式下,进入秒表模式时,未对秒表清零。

修改后代码如下:

if(keyval==0x7f)//1号按键模式进入秒表模式

{

mode=4;

old_ss=0;

old_ms=0;

miaobiao_ss=old_ss;

miaobiao_ms=old_ms;

dispbuf[0]=miaobiao_ss/10;

dispbuf[1]=miaobiao_ss%10;

dispbuf[2]=miaobiao_ms/10;

dispbuf[3]=miaobiao_ms%10;

clocksing=0;

}

 

附完整实验代码:

/***********************************************************************

基于单片机的数字时钟

功能:

时钟、闹钟、秒表

模式0:

时钟显示模式-分、秒

模式0下,数码管显示时钟时间-分、秒。

按键说明:

按键1:

选择下一模式。

模式1:

时钟显示模式-时、分

模式1下,数码管显示时钟时间-时、分。

按键说明:

按键1:

选择下一模式。

模式2:

时钟调整模式

模式2下,调整时钟时间,仅调整时、分时间。

按键说明:

按键1:

选择下一模式。

按键2:

增加选中数码管的数值。

按键3:

减少选中数码管的数值。

按键4:

移位键,按键选择下一数码管。

模式3:

闹钟模式

模式3下,设置闹铃时间之后,等时钟到达相应时间,发出铃声。

按键说明:

按键1:

选择下一模式。

按键2:

增加选中数码管的数值。

按键3:

减少选中数码管的数值。

按键4:

移位键,按键选择下一数码管。

按键5:

设置闹铃时间后,按键确认,数码管显示当前时钟时间。

模式4:

秒表模式

模式4为秒表模式,可记录0-59秒。

最小时间单位为0.01秒。

按键说明:

按键1:

选择下一模式。

按键2:

清除秒表当前数值。

按键3:

清除秒表当前数值。

按键4:

开始、暂停秒表。

***********************************************************************/

#include

unsignedchardispbuf[4]={0,0,0,0};

unsignedcharcodesegtab[]=

{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//不带小数点的数码管代码

unsignedcharcodesegtab_dot[]=

{0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//带小数点的数码管代码

unsignedcharcodebittab[]={0xfe,0xfd,0xfb,0xf7};

unsignedchardispindex;

unsignedcharmode;

unsignedcharpos;

unsignedcharkeyval;

unsignedcharhh,mm,ss;

unsignedcharmiaobiao_ms=0,miaobiao_ss=0;//秒表

unsignedcharold_ms,old_ss;//保存秒表时间

unsignedcharclock_hh,clock_mm;//用于存放所设闹钟时间

unsignedintclock_shanshuo;//用于控制闹钟调整时间时是否闪烁0:

闪烁1:

不闪烁

sbitclocksing=P1^5;//闹钟所用蜂鸣器

unsignedintcnt;//用于10ms转1s计数

unsignedcharcnt1;//用于10ms转0.5s处计数(用于闪烁)

unsignedcharcnt2;//用于秒表处计时

unsignedcharkeyscan(void);

voiddelay(unsignedintt);

voidkeypro(void);

bitflash;

/******************主函数******************/

voidmain(void)

{

TMOD=0x11;

TH0=(0-2000)/256;

TL0=(0-2000)%256;

ET0=1;

TR0=1;

TH1=(0-2000)/256;

TL1=(0-2000)%256;

ET1=1;

TR1=0;//秒表先不开

EA=1;

mode=0;

hh=02;

mm=03;

ss=15;

while

(1)

{

if(mode==3)

{

if(hh==clock_hh)

{

if(mm==clock_mm)

{

clocksing=0;

}

}

else

{

clocksing=1;

}

}

else

{

clocksing=1;

}

if(keyscan()==0xff)continue;

keypro();

}

}

/******************键扫描程序******************/

unsignedcharkeyscan(void)

{

P3=0xff;

keyval=P3;

if(keyval==0xff)

{

return0xff;

}

delay(10000);

if(keyval!

=P3)

{

return0xff;

}

else

{

while(P3!

=0xff);

returnkeyval;

}

}

/******************时钟中断及显示程序******************/

voidt0int(void)interrupt1using1

{

TH0=(0-2000)/256;//2ms

TL0=(0-2000)%256;

P0=0xff;

P1=0xff;

P1=bittab[dispindex];

if(mode==4&&P1==0xfd)//秒表处显示小数点的if语句

{

P0=segtab_dot[dispbuf[dispindex]];

}

else

{

P0=segtab[dispbuf[dispindex]];

}

if((dispindex==pos)&&(flash==1)&&(mode==2||(mode==3&&clock_shanshuo==0)))//闪烁控制程序

{

P0=0xff;

P1=0xf0;

}

dispindex++;

dispindex=dispindex&0x03;

cnt++;

cnt1++;

if(cnt1>=250)//0.5ms闪烁

{

cnt1=0;

flash=~flash;

}

if(cnt>=500)//2ms*500=1s

{

cnt=0;

ss++;

if(ss>=60)

{

ss=0;

mm++;

if(mm>=60)

{

mm=0;

hh++;

if(hh>=24)

{

hh=0;

}

}

}

if(mode==0)

{

dispbuf[0]=mm/10;

dispbuf[1]=mm%10;

dispbuf[2]=ss/10;

dispbuf[3]=ss%10;

}

elseif(mode==1||(mode==3&&clock_shanshuo==1))

{

dispbuf[0]=hh/10;

dispbuf[1]=hh%10;

dispbuf[2]=mm/10;

dispbuf[3]=mm%10;

}

}

}

/******************按键选择,进入不同模式******************/

voidkeypro(void)

{

switch(mode)

{

case0:

//显示分秒

if(keyval==0x7f)

{

mode=1;

dispbuf[0]=hh/10;

dispbuf[1]=hh%10;

dispbuf[2]=mm/10;

dispbuf[3]=mm%10;

}

break;

case1:

//显示时分

if(keyval==0x7f)

{

mode=2;

dispbuf[0]=hh/10;

dispbuf[1]=hh%10;

dispbuf[2]=mm/10;

dispbuf[3]=mm%10;

}

break;

case2:

//时间调整(只调整时分)

if(keyval==0x7f)//按键1调整模式进入闹钟模式

{

mode=3;

clock_hh=0;

clock_mm=0;

clock_shanshuo=0;

hh=dispbuf[0]*10+dispbuf[1];//保存调整后的时间

mm=dispbuf[2]*10+dispbuf[3];

dispbuf[0]=clock_hh/10;//显示闹钟的初始时间

dispbuf[1]=clock_hh%10;

dispbuf[2]=clock_mm/10;

dispbuf[3]=clock_mm%10;

TR0=1;

}

elseif(keyval==0xbf)//按键2加

{

if(pos==0)

{

dispbuf[pos]++;

if(dispbuf[pos]==3)

{

dispbuf[pos]=0;

}

}

elseif(pos==1)

{

if(dispbuf[0]==0||dispbuf[0]==1)

{

dispbuf[pos]++;

dispbuf[pos]=dispbuf[pos]%10;

}

if(dispbuf[0]==2)

{

dispbuf[pos]++;

if(dispbuf[pos]>=4)

{

dispbuf[pos]=0;

}

}

}

elseif(pos==2)

{

dispbuf[pos]++;

if(dispbuf[pos]==6)

{

dispbuf[pos]=0;

}

}

elseif(pos==3)

{

dispbuf[pos]++;

dispbuf[pos]=dispbuf[pos]%10;

}

}

elseif(keyval==0xdf)//按键3减

{

if(pos==0)

{

if(dispbuf[pos]==0)dispbuf[pos]=2;

elsedispbuf[pos]--;

}

elseif(pos==1)

{

if(dispbuf[0]==0||dispbuf[0]==1)

{

if(dispbuf[pos]==0)dispbuf[pos]=9;

elsedispbuf[pos]--;

}

if(dispbuf[0]==2)

{

if(dispbuf[pos]>=4&&dispbuf[pos]<=9)

{

dispbuf[pos]=3;

}

elseif(dispbuf[pos]==0)

{

dispbuf[pos]=3;

}

else

{

dispbuf[pos]--;

}

}

}

elseif(pos==2)

{

if(dispbuf[pos]==0)dispbuf[pos]=5;

elsedispbuf

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1