北京交通大学单片机实验报告电子时钟Word下载.docx

上传人:b****3 文档编号:6939676 上传时间:2023-05-07 格式:DOCX 页数:24 大小:778.22KB
下载 相关 举报
北京交通大学单片机实验报告电子时钟Word下载.docx_第1页
第1页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第2页
第2页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第3页
第3页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第4页
第4页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第5页
第5页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第6页
第6页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第7页
第7页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第8页
第8页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第9页
第9页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第10页
第10页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第11页
第11页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第12页
第12页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第13页
第13页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第14页
第14页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第15页
第15页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第16页
第16页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第17页
第17页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第18页
第18页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第19页
第19页 / 共24页
北京交通大学单片机实验报告电子时钟Word下载.docx_第20页
第20页 / 共24页
亲,该文档总共24页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

北京交通大学单片机实验报告电子时钟Word下载.docx

《北京交通大学单片机实验报告电子时钟Word下载.docx》由会员分享,可在线阅读,更多相关《北京交通大学单片机实验报告电子时钟Word下载.docx(24页珍藏版)》请在冰点文库上搜索。

北京交通大学单片机实验报告电子时钟Word下载.docx

按键的闭合与否,反映在电压上就是呈现出高电平或低电平。

由于机械触点的弹性作用,在闭合及断开的瞬间,电压信号伴随有一定时间的抖动,抖动时间与按键的机械特性有关,一般是5~10ms。

为了保证CPU确认一次按键动作,既不重复也不遗漏,必须消除抖动的影响。

通过软件消除抖动的方法为:

在程序执行过程中检测到有按键按下时,调用一段延时(约10ms)子程序,然后判断该按键的电平是否仍然保持在闭合状态,如果是,则确认有键按下。

按键判断流程图如下:

 

按键处理流程图如下:

4.音乐响铃模块音乐闹铃程序:

单片机演奏一个音符,是通过引脚,周期性的输出一个特定频率的方波。

这就需要单片机,在半个周期内输出低电平、另外半个周期输出高电平,周而复始。

众所周知,周期为频率的倒数,可以通过音符的频率计算出周期;

演奏时,要根据音符的不同,把对应的半个周期的定时时间初始值,送入定时器,再由定时器按时输出高低电平。

另外,音乐的节拍是由延时实现的。

我所使用的单片机音乐演奏程序中,包括了两个数据表,其中存放了事先算好的各种音符频率所对应的半周期的定时时间初始值。

有了这些数据,单片机就可以演奏低音、中音、高音,三个八度共21个音符。

演奏乐曲时,就根据音符的不同数值,从表中找到定时时间初始值,送入定时器即可控制音调。

通过调用延迟来实现节拍数。

乐曲的数据,也要写个数据表:

表中每三个数字,说明了一个音符,它们分别代表:

第一个数字是音符的数值;

第二个数字是123之一,代表低音、中音、高音;

第三个数字是时间长度,以半拍为单位。

乐曲数据表的结尾是三个0。

音节与频率的关系如下表所示

音调

X

低音1

F921

中音1

FC8F

高音1

FE47

低音2

F9E1

中音2

FCEE

高音2

FE77

低音3

FA8C

中音3

FD44

高音3

FEA2

低音4

FAD8

中音4

FD6B

高音4

FEB6

低音5

FB68

中音5

FDB4

高音5

FEDA

低音6

FBE9

中音6

FDF4

高音6

FEFA

低音7

FC5B

中音7

FE2D

高音7

FF16

程序流程图如下:

五、程序清单

#include<

reg52.h>

#defineucharunsignedchar

#defineuintunsignedint

ucharcodesegcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//共阳数码管0~9

ucharcodeselect[]={0x0e,0x0d,0x0b,0x07};

/正/常显示时

数码管位选

code

uchar

select1[]={0x0f,0x0d,0x0b,0x07};

/高/两位屏蔽

时的位选(第2位只显示dp)

ucharcodeselect2[]={0x0e,0x0d,0x0f,0x0f};

/低/两位屏蔽时的位选

ucharbuffer[]={0,0,0,0};

//用来存放时间

uinthour,min,sec;

uintalarmhour,alarmmin;

uintstatus=0;

//模式值

sbitmusic=P1^0;

//闹铃

sbitled=P1^1;

//秒驱动LED闪烁

bitringoff=1;

//闹铃停止

uintcount=0;

//定时器计数

ucharkeyinput;

ucharbuf=0xff;

//用来存放按键值

uchartimer1h,timer1l,time;

//time为节拍(延迟时间),timer1l、timer1h为计数器1初值

ucharcodefreqh[]={0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,//低音1~7第一个八度

0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,//中音1~7第二个八度

0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF};

//高音1~7第三个八度

ucharcodefreql[]={0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,//低音1234567

0x8F,0xEE,0x44,0x6B,0xB4,0xF4,0x2D,//中音1234567

0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16};

//高音1234567

/*ucharcodesong[]={3,2,2,3,2,2,4,2,2,5,2,2,5,2,2,4,2,2,3,2,2,2,2,2,1,2,2,1,2,2,2,2,2,3,2,2,3,2,3,2,2,1,2,2,4,

3,2,2,3,2,2,4,2,2,5,2,2,5,2,2,4,2,2,3,2,2,2,2,2

1,2,2,1,2,2,2,2,2,3,2,2,2,2,3,1,2,1,1,2,4,

2,2,2,2,2,2,3,2,2,1,2,2,2,2,2,3,1,2,2,2,2,2,3,2,1,4,2,1,3,2,2,2,2,2,

1,2,2,2,2,2,5,1,2,3,2,2,3,2,2,3,5,2,2,4,2,2,3,2,2,4,2,1,2,2,1,1,2,2,1,2,2,

2,2,2,3,2,2,2,2,3,1,2,1,1,2,4,2,1,2,2,2,2,2,3,2,1,4,2,1,3,2,2,1,2,2,2,2,2,

3,2,1,4,2,1,3,2,2,2,2,2,1,2,2,2,3,2,2,3,2,2,4,2,2,5,2,2,5,2,2,4,2,2,3,2,2,

4,2,1,2,2,1,1,2,2,1,2,2,2,2,2,3,1,2,4,0,0,0};

//欢乐颂*/

ucharcodesong[]={5,3,2,3,3,1,4,3,1,5,3,2,3,3,1,4,3,1,5,3,1,5,2,1,6,2,1,7,2,1,1,3,1,2,3,1,3,3,1,4,3,1,3,3,2,1,3,1,2,3,1,3,3,2,

3,2,1,4,2,1,5,2,1,6,2,1,5,2,1,4,4,2,1,5,2,1,4,2,2,6,2,1,5,2,1,4,2,2,3,2,1,2,2,1,3,2,

1,2,2,1,1,2,1,2,2,1,

3,2,1,4,2,1,5,2,1,6,2,1,4,2,2,6,7,2,1,1,3,1,5,2,1,6,2,1,7,2,1,1,3,1,2,3,1,3,3,1,4,3,

1,5,3,1,3,3,2,1,3,1,2,3,1,

3,3,2,2,3,1,1,3,1,2,3,1,7,2,1,1,3,1,2,3,1,3,3,1

2,3,1,1,3,1,7,2,1,1,3,2,6,2,1,7,2,1,1,3,2,1,2,1,2,2,

1,

3,2,1,4,2,1,3,2,1,2,2,1,3,2,1,1,3,1,7,2,1,1,3,1

6,2,2,1,3,2,7,2,1,6,2,2,5,2,1,4,2,1,5,2,1,4,2,1,3,2,

1,4,2,1,5,2,1,6,2,1,7,2,1,1,2,1,

6,2,2,1,3,1,7,2,1,1,3,2,7,2,1,6,2,1,7,2,1,1,3,1

2,3,1,1,3,1,7,2,1,1,3,1,6,2,1,7,2,1,0,0,0};

//卡农

//一个音符有三个数字。

前为音节、中为第几个八度、后为时长(以半拍为单位)。

延迟tms程序

voiddelay1ms(uintt)

{

uinti;

}

while(t--)for(i=0;

i<

123;

i++);

按键处理程序

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

voidkeyprocess(ucharkey){

switch(key)

case0xe0:

status++i;

f(status>

=5)status=0;

break;

//第一个键被按下,模式值+1

case0xd0:

//第

二个键被按下

switch(status)

case0x01:

if(hour<

23)hour++;

elsehour=0;

//模式1小时+1,到24变成0

case0x02:

if(min<

59)min++;

elsemin=0;

//模式2分钟+1

case0x03:

if(alarmhour<

23)alarmhour++;

elsealarmhour=0;

//模式3闹铃小时+1

case0x04:

if(alarmmin<

59)alarmmin++;

elsealarmmin=0;

//模式4闹铃分钟+1

case0xb0:

//第三个键被按下

if(hour>

0)hour--;

elsehour=23;

if(min>

0)min--;

elsemin=59;

if(alarmhour>

0)

alarmhour--;

elsealarmhour=23;

if(alarmmin>

alarmmin--;

elsealarmmin=59;

case0x70:

ringoff=~ringoff;

break;

//第四个键按下,闹铃开关。

default:

正常走时时数码管

/******************显示程序*************/

voiddisplay()

if(status==3||status==4)//闹铃时间

buffer[0]=alarmhour/10;

buffer[1]=alarmhour%10;

buffer[2]=alarmmin/10;

buffer[3]=alarmmin%10;

else//正常时间

buffer[0]=hour/10;

buffer[1]=hour%10;

buffer[2]=min/10;

buffer[3]=min%10;

for(i=0;

4;

i++)

if(i==1)

P0=segcode[buffer[i]]-0x80;

//第二个数码管显示dp

P2=select[i];

delay1ms

(1);

//否则数码管上无

显示

P2=0xff;

//否则乱码

else

P0=segcode[buffer[i]];

//查找段码值

//查找位选

//否则数码管上无显示

/********************高两位屏蔽时的显示程序*************/

voiddisplay1()

if(status==1)

buffer[1]=hour%10;

buffer[2]=min/10;

buffer[3]=min%10;

else//status==3时

buffer[1]=alarmhour%10;

buffer[2]=alarmmin/10;

buffer[3]=alarmmin%10;

P0=0x7f;

//只显示小数点

P2=select1[i];

/*****************低两位屏蔽时的显

voiddisplay2()

if(status==2)

else//status==4时

//

第2个数码管显示dp

P2=select2[i];

数码管抖动延迟

voiddelaydd(uintp)

uintk;

for(k=p;

k!

=0;

k--)display();

//延迟时也显示,避免数码管闪烁

判断按键程序

voidpress()

keyinput=P1&

0xf0;

//取按键状态if(keyinput!

=0xf0)//有按键按下?

{

delaydd(20);

//利用数码管显示来

达到延迟的效果。

防止有键按下是数码管闪

if(keyinput!

=0xf0)//开关仍在处于闭合状态

buf=keyinput;

//将按键值赋给buf

keyprocess(buf);

buf=0xff;

/当/松开按键时(无键按下)才进行按键处理

定时器T0中断

voidt0()interrupt1

TH0=(65536-1000)/256;

TL0=(65536-1000)%256;

//重新装入计数初值

count++;

//正常计时

if(count==550)//定时0.5S到,以下为时钟的正常走钟逻辑。

理论上应为500

led=~led;

//LED灯亮0.5s,灭0.5s。

达到秒显示的效果

count=0;

if(led==0)//达到1s

sec++;

if(sec>

=60)

sec=0;

min++;

min=0;

hour++;

=24)

hour=0;

/**********定时器T1中断。

用来产生不同频率方波********/

voidt1()interrupt3

TR1=0;

//先关中断

music=~music;

//产生方波

TH1=timer1h;

TL1=timer1l;

//重新装入初值

TR1=1;

//在开始计数

延迟半节拍数

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

voiddelay(uchart)

uchart1;

unsignedlongt2;

for(t1=0;

t1<

10*t;

t1++){

display();

//防止响音乐时数码管无

press();

for(t2=0;

t2<

200;

t2++);

//一个音符发送完后关计数

产生音乐程序

voidsend()

delay(time);

//根据节拍数调用延迟

函数

*******************voidmain(){

uinth=0;

uinti,k;

music=1;

TMOD=0x11;

//1ms计数初值

EA=1;

ET0=1;

//开中断

ET1=1;

P3=0xff;

while

(1){

if(status==1||status==2)TR0=0;

//当调整时间时,秒不走。

elseTR0=1;

//开始计数

if(status==0)P3=0xff;

if(status==1||status==2)P3=0xfe;

//调整时间指示灯

if(status==3||status==4)P3=0xfd;

//调整闹铃指示灯

//判断是否有键按下并

处理

if(hour==alarmhour&

&

min==alarmmin)//闹铃时间到

i=0;

time=1;

while(!

ringoff)

k=song[i]+7*song[i+1]-8;

//找到相应音符的计数初值

timer1h=freqh[k];

timer1l=freql[k];

//装入计数初值

time=song[i+2];

i=i+3;

if(time!

=0)send();

//播放音符elsei=0;

//循环播放

music=1;

if(status==0)//给显示加

上一些效果

elseif(status==1||status==3)//高两

位闪烁

if(h<

75){display();

h++;

}else

display1();

if(h==150)h=0;

else//低两位闪烁

h++;

display2();

if(h==150)h=0;

六、

1.

2.

3.

实验遇到的问题及解决方法

问题:

数码管上无显示解决方法:

用三极管来驱动数码管的位选端,否则数码管发光微弱。

数码管显示出现乱码解决方法:

动态显示时,需要确定LED各位显示的保持时间。

在某一位显示结束后,应将P2口置为0xff。

按下按键时,数码管上的数字跳跃式变化。

解决方法:

按键处理程序调用的位置错误。

当有键按下时,将按键值赋给buf,松开按键时,才对buf中的数据进行按键处理,并重新将buf置为0xff。

若在键按下时进行处理,会导致数字跳跃式变化。

=0xf0)

//有键按下时赋给buf}else{

/当/松开按键时(无键按下)才进行按键处理

4.问题:

按下按键时,数码管的显示闪烁一次解决方法:

在程序执行过程中检测到有按键按下时,会调用一段延时(约10ms)子程序来消抖。

若通过执行空操作来实现延时10ms,则会使动态扫描的时间间隔变长,数码管亮度变暗。

因此我通过调用数码管显示程序来实现延时10ms,即如下:

voiddelaydd(uintp)

//延迟时也显示,避免数码管闪烁

5.问题:

在放音乐过程中,数码管上无显示解决方法:

音乐的节拍是由延时实现的。

当放音乐时,一直在调用延时程序,因此在延时程序中调用数码管显示程序,问题即可得到解决。

如下:

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

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2