|
八级 守卫队长
    
- UID
- 012325
- 积分
- 1763
- 金币
- 0
- 阅读权限
- 80
|
1楼
大 中
小
发表于 2006-8-6 16:57 只看该作者
AT89S51单片机试验及实践教程之电子琴
1. 实验任务
1. 由 4X4 组成 16 个按钮矩阵,设计成 16 个音。
2. 可随意弹奏想要表达的音乐。
2. 电路原理图

3. 系统板硬件连线
1. 把“单片机系统”区域中的 P1.0 端口用导线连接到“音频放大模块”区域中的 SPK IN 端口上;
2. 把“单片机系统“区域中的 P3.0 - P3.7 端口用 8 芯排线连接到“ 4X4 行列式键盘”区域中的 C1 -
C4 R1 - R4 端口上;
4. 相关程序内容
1. 4X4 行列式键盘识别;
2. 音乐产生的方法;
一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时
/ 计数器 T0 来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。现在以单片机 12MHZ 晶振为例,例出高中低音符与单片机计数
T0 相关的计数值如下表所示
|
音符 |
频率( HZ ) |
简谱码( T 值) |
|
音符 |
频率( HZ ) |
简谱码( T 值) |
|
低 1 DO |
262 |
63628 |
# 4 FA# |
740 |
64860 |
|
#1 DO# |
277 |
63731 |
中 5 SO |
784 |
64898 |
|
低 2 RE |
294 |
63835 |
# 5 SO# |
831 |
64934 |
|
#2 RE# |
311 |
63928 |
中 6 LA |
880 |
64968 |
|
低 3 M |
330 |
64021 |
# 6 |
932 |
64994 |
|
低 4 FA |
349 |
|
|
|
|
八级 守卫队长
    
- UID
- 012325
- 积分
- 1763
- 金币
- 0
- 阅读权限
- 80
|
2楼
大 中
小
发表于 2006-8-6 16:58 只看该作者
Re:楼主
低音 0 - 19 之间,中音在 20 - 39 之间,高音在 40 - 59 之间
TABLE: DW 0,63628,63835,64021,64103,64260,64400,64524,0,0
DW 0,63731,63928,0,64185,64331,64463,0,0,0
DW 0,64580,64684,64777,64820,64898,64968,65030,0,0
DW 0,64633,64732,0,64860,64934,64994,0,0,0
DW 0,65058,65110,65157,65178,65217,65252,65283,0,0
DW 0,65085,65134,0,65198,65235,65268,0,0,0
DW 0
2 、音乐的音拍,一个节拍为单位( C 调)
|
曲调值 |
DELAY |
|
曲调值 |
DELAY |
|
调 4/4 |
125ms |
|
调 4/4 |
62ms |
|
调 3/4 |
187ms |
|
调 3/4 |
94ms |
|
调 2/4 |
250ms |
|
调 2/4 |
125ms |
对于不同的曲调我们也可以用单片机的另外一个定时 / 计数器来完成。
下面就用 AT89S51 单片机产生一首“生日快乐”歌曲来说明单片机如何产生的。
在这个程序中用到了两个定时 / 计数器来完成的。其中 T0 用来产生音符频率, T1 用来产生音拍。
|
|
|
|
|
八级 守卫队长
    
- UID
- 012325
- 积分
- 1763
- 金币
- 0
- 阅读权限
- 80
|
3楼
大 中
小
发表于 2006-8-6 16:59 只看该作者
Re:楼主
7. C 语言源程序
#include
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
unsigned char temp;
unsigned char key;
unsigned char i,j;
unsigned char STH0;
unsigned char STL0;
unsigned int code tab[]={64021,64103,64260,64400,
64524,64580,64684,64777,
64820,64898,64968,65030,
65058,65110,65157,65178};
void main(void)
{
TMOD=0x01;
ET0=1;
EA=1;
while(1)
{
P3=0xff;
P3_4=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=0;
break;
case 0x0d:
key=1;
break;
case 0x0b:
key=2;
break;
case 0x07:
key=3;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
TR0=0;
}
}
P3=0xff;
P3_5=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=4;
break;
case 0x0d:
key=5;
break;
case 0x0b:
key=6;
break;
case 0x07:
key=7;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
TR0=0;
}
}
P3=0xff;
P3_6=0;
te
|
|
|
|
|
八级 守卫队长
    
- UID
- 012325
- 积分
- 1763
- 金币
- 0
- 阅读权限
- 80
|
4楼
大 中
小
发表于 2006-8-6 16:59 只看该作者
Re:楼主
5. 程序框图

6. 汇编源程序
KEYBUF EQU 30H
STH0 EQU 31H
STL0 EQU 32H
TEMP EQU 33H
ORG 00H
LJMP START
ORG 0BH
LJMP INT_T0
START: MOV TMOD,#01H
SETB ET0
SETB EA
WAIT:
MOV P3,#0FFH
CLR P3.4
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY1
LCALL DELY10MS
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY1
MOV A,P3
ANL A,#0FH
CJNE A,#0EH,NK1
MOV KEYBUF,#0
LJMP DK1
NK1: CJNE A,#0DH,NK2
MOV KEYBUF,#1
LJMP DK1
NK2: CJNE A,#0BH,NK3
MOV KEYBUF,#2
LJMP DK1
NK3: CJNE A,#07H,NK4
MOV KEYBUF,#3
LJMP DK1
NK4: NOP
DK1:
MOV A,KEYBUF
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,KEYBUF
MOV B,#2
MUL AB
MOV TEMP,A
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
MOV STH0,A
MOV TH0,A
INC TEMP
MOV A,TEMP
MOVC A,@A+DPTR
MOV STL0,A
MOV TL0,A
SETB TR0
DK1A: MOV A,P3
ANL A,#0FH
XRL A,#0FH
JNZ DK1A
CLR TR0
NOKEY1:
MOV P3,#0FFH
CLR P3.5
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY2
LCALL DELY10MS
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY2
MOV A,P3
ANL A,#0FH
CJNE A,#0EH,NK5
MOV KEYBUF,#4
LJMP DK2
NK5: CJNE A,#0DH,NK6
MOV KEYBUF,#5
LJMP DK2
NK6: CJNE A,#0BH,NK7
MOV KEYBUF,#6
LJMP DK2
NK7: CJNE A,#07H,NK8
MOV KEYBUF,#7
LJMP DK2
NK8: NOP
|
|
|
|

统计代码
|