北交单片机课设电子时钟Word格式文档下载.docx
《北交单片机课设电子时钟Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《北交单片机课设电子时钟Word格式文档下载.docx(19页珍藏版)》请在冰豆网上搜索。
![北交单片机课设电子时钟Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2023-1/21/5135f11a-8555-4c12-988f-071827a5e811/5135f11a-8555-4c12-988f-071827a5e8111.gif)
有了这些数据,单片机就可以演奏低音、中音、高音,三个八度共21个音符。
演奏乐曲时,就根据音符的不同数值,从表中找到定时时间初始值,送入定时器即可控制音调。
通过调用延迟来实现节拍数。
乐曲的数据,也要写个数据表:
表中每三个数字,说明了一个音符,它们分别代表:
第一个数字是音符的数值;
第二个数字是123之一,代表低音、中音、高音;
第三个数字是时间长度,以半拍为单位。
乐曲数据表的结尾是三个0。
音节与频率的关系如下表所示
音调
X
低音1
F921
低音2
F9E1
低音3
FA8C
低音4
FAD8
低音5
FB68
低音6
FBE9
低音7
FC5B
中音1
FC8F
中音2
FCEE
中音3
FD44
中音4
FD6B
中音5
FDB4
中音6
FDF4
中音7
FE2D
高音1
FE47
高音2
FE77
高音3
FEA2
高音4
FEB6
高音5
FEDA
高音6
FEFA
高音7
FF16
《欢乐颂》音符表
TONE:
334554321123322
0FDH,0AH,0FDH,0AH,0FDH,34H,0FDH,82H,0FDH,82H,0FDH,34H,0FDH,0AH,0FCH,0AEH,0FCH,44H,0FCH,44H,0FCH,0AEH,0FDH,0AH,0FDH,0AH,0FCH,0AEH,0FCH,0AEH
334554321123211
0FDH,0AH,0FDH,0AH,0FDH,34H,0FDH,82H,0FDH,82H,0FDH,34H,0FDH,0AH,0FCH,0AEH,0FCH,44H,0FCH,44H,0FCH,0AEH,0FDH,0AH,0FCH,0AEH,0FCH,44H,0FCH,44H
223123431234311253
0FCH,0AEH,0FCH,0AEH,0FDH,0AH,0FCH,44H,0FCH,0AEH,0FDH,0AH,0FDH,34H,0FDH,0AH,0FCH,44H,0FCH,0AEH,0FDH,0AH,0FDH,34H,0FDH,0AH,0FCH,44H,0FCH,44H,0FCH,0AEH,0FBH,04H,0FDH,0AH
《欢乐颂》节拍表
RYTH:
08,08,08,08,08,08,08,08,08,08,08,08,12,04,16
08,08,08,08,08,04,04,08,08,08,04,04,08,08,08,08,08,08
程序清单
#include<
reg52.h>
#defineucharunsignedchar
#defineuintunsignedint
ucharcodesegcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//数码管0~9
ucharcodeselect[]={0x0e,0x0d,0x0b,0x07};
//正常显示时数码管位选
ucharcodeselect1[]={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[]={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,2,1,5,2,1,3,2,1,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,2,1,5,2,1,6,2,2,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};
/*uchar
codesong[]={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,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,2,2,5,1,2,3,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,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,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,2,2,5,1,2,3,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,2,2,2,2,3,1,2,1,1,2,4,0,0,0};
voidmain()
{
uinth=0;
uinti,k;
music=1;
TMOD=0x11;
工作方式1
TH0=(65536-1000)/256;
//1ms计数初值
TL0=(65536-1000)%256;
EA=1;
ET0=1;
//开中断
ET1=1;
P3=0xff;
while
(1)
{
if(status==1||status==2)
TR0=0;
elseTR0=1;
//开始计数
if(status==0)
if(status==1||status==2)
P3=0xfe;
if(status==3||status==4)
P3=0xfd;
press();
//按键处理
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)//给显示加上一些效果
display();
elseif(status==1||status==3)//高两位闪烁
{
if(h<
75){display();
h++;
}
else
{
display1();
h++;
if(h==150)h=0;
else//低两位闪烁
h++;
display2();
voiddelay1ms(uintt)
uinti;
while(t--)
for(i=0;
i<
100;
i++);
voidkeyprocess(ucharkey)
switch(key)
case0xe0:
status++;
if(status>
=5)status=0;
break;
case0xd0:
switch(status)
case0x01:
if(hour<
23)hour++;
elsehour=0;
case0x02:
if(min<
59)min++;
elsemin=0;
case0x03:
if(alarmhour<
23)alarmhour++;
elsealarmhour=0;
case0x04:
if(alarmmin<
59)alarmmin++;
elsealarmmin=0;
break;
case0xb0:
switch(status)
if(hour>
0)hour--;
elsehour=23;
if(min>
0)min--;
elsemin=59;
if(alarmhour>
0)alarmhour--;
elsealarmhour=23;
if(alarmmin>
0)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)
else//status==3时
P0=0x7f;
P2=select1[i];
}
/*****************低两位屏蔽时的显示程序************/
voiddisplay2()
if(status==2)
else
//第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;
else
keyprocess(buf);
//当松开按键时才进行按键处理
buf=0xff;
/*******************定时器T0中断*****************/
voidt0()interrupt1
count++;
if(count==500)
led=~led;
count=0;
if(led==0)
sec++;
if(sec>
=60)
sec=0;
min++;
if(min>
min=0;
hour++;
if(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++)
for(t2=0;
t2<
200;
t2++);
//一个音符发送完后关计数
/********************产生音乐程序***************/
voidsend()
delay(time);
作品实物照片:
元件清单:
开关4个
四位一体共阳数码管1个
蜂鸣器1个
三极管4个
发光二级管3个
芯片STC89C521个
12MHZ晶振1个
电容30pF2个
10μF1个
电阻10K6个
1K8个
设计体会:
这次实验的体会特别深刻,这近两个星期的忙碌,有辛酸有欣喜,重要的是我竟然对单片机产生了不少的兴趣。
开始着手设计应该算比较早的,但是设计的过程中遇到了不少的麻烦。
焊接之类的工作由于买到的焊锡丝含锡量较低同时烙铁的氧化比较严重等原因也做的异常的艰难,虽然到了最后板子已经被经过无数次的拆装、原先布好的线因为多次更新路径弄的有些乱,但我还是由衷的感到欣慰,因为我的板子是我亲手焊接出来的,其中凝结着我努力的汗水。
首先是硬件电路的设计,经过了不少曲折的地方花费了不少的时间,复位电路我原先只设