单片机电子琴设计
作者:s51 来源:不详 点击数:7010 更新时间:2007年05月16日 【字体: 】 |
1. 实验任务 |
(1. 由4X4组成16个按钮矩阵,设计成16个音。
(2. 可随意弹奏想要表达的音乐。
2.电路原理图 |
|
图4.22.1 | |
3.系统板硬件连线 | |
(1. | 把“单片机系统”区域中的P1.0端口用导线连接到“音频放大模块”区域中的SPK IN |
端口上;
(2. 把“单片机系统“区域中的P3.0-P3.7端口用8芯排线连接到“4X4行列式键盘”区域中的C1-C4R1-R4端口上;
4. 相关程序内容
(1. 4X4行列式键盘识别;
(2. 音乐产生的方法;
一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。现在以单片机12MHZ晶振为例,例出高中低音符与
单片机计数T0相关的计数值如下表所示 | |||||||
音符 | 频率(HZ) | 简谱码(T 值) | 音符 | 频率(HZ) | 简谱码(T 值) | ||
低1 DO | 262 | 63628 | | 860 | |||
#1 DO# | 277 | 63731 | 8 | ||||
| |||||||
低 4 FA | 349 | 103 | 中 7 SI | 988 | 65030 | ||
# 4 FA# | 370 | 185 | 高 1 DO | 1046 | 65058 | ||
低 5 SO | 392 | 260 | # 1 DO# | 1109 | 65085 | ||
# 5 SO# | 415 | 331 | 高 2 RE | 1175 | 65110 | ||
低 6 LA | 440 | 400 | # 2 RE# | 1245 | 65134 | ||
# 6 | 466 | 463 | 高 3 M | 1318 | 65157 | ||
低 7 SI | 494 | 524 | 高 4 FA | 1397 | 65178 | ||
中 1 DO | 523 | 580 | # 4 FA# | 1480 | 65198 | ||
# 1 DO# | 554 | 633 | 高 5 SO | 1568 | 65217 | ||
中 2 RE | 587 | 684 | # 5 SO# | 1661 | 65235 | ||
# 2 RE# | 622 | 732 | 高 6 LA | 1760 | |||
中 3 M | 659 | 777 | # 6 | 1865 | 65268 |
中 4 FA | 698 | 820 | 高 7 SI | 1967 | 65283 |
下面我们要为这个音符建立一个表格,有助于单片机通过查表的方式来获得相应的数据低音0-19之间,中音在20-39之间,高音在40-59之间
TABLE: DW 0,63628,63835,021,103,260,400,524,0,0
DW 0,63731,63928,0,185,331,463,0,0,0
DW 0,580,684,777,820,8,968,65030,0,0 DW 0,633,732,0,860,934,994,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 | | 62ms |
调3/4 | 187ms | 94ms | |
| |||
在这个程序中用到了两个定时/计数器来完成的。其中T0用来产生音符频率,T1用来产生音拍。
5.程序框图 |
|
|
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 | |
WAIT: |
MOVP3,#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 | |
| |
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 | |
MOV DPTR,#TABLE |
MOVCA,@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 | |
| |
ANL A,#0FH
XRL A,#0FH
JNZ DK1A
CLR TR0
NOKEY1:
MOV P3,#0FFH
CLR P3.5
MOV A,P3
ANL A,#0FH | |
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
NK8: NOP
DK2:
MOV A,KEYBUF
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,KEYBUF
MOV B,#2 | |
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
DK2A: MOV A,P3
ANL A,#0FH
XRL A,#0FH | |
JNZ DK2A | |
NOKEY2: | |
MOV A,P3 |
ANLA,#0FH
XRL A,#0FH
JZ NOKEY3
LCALL DELY10MS
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY3 | |
CJNE A,#0EH,NK9 |
MOV KEYBUF,#8
LJMP DK3
NK9: CJNE A,#0DH,NK10
MOV KEYBUF,#9
LJMP DK3
NK10: CJNE A,#0BH,NK11
MOV KEYBUF,#10
LJMP DK3
NK11: CJNE A,#07H,NK12
MOV KEYBUF,#11
LJMP DK3
NK12: NOP | ||
DK3: | MOV A,KEYBUF | |
| ||
MOVA,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 STL0,A |
MOV TL0,A
SETB TR0
DK3A: MOV A,P3
ANL A,#0FH
XRL A,#0FH
JNZ DK3A
CLR TR0
NOKEY3:
MOV P3,#0FFH
CLR P3.7
MOV A,P3
ANL A,#0FH | |
XRL A,#0FH | |
| |
XRL A,#0FH
JZ NOKEY4
MOV A,P3
ANL A,#0FH
CJNE A,#0EH,NK13
MOV KEYBUF,#12
LJMP DK4
NK13: CJNE A,#0DH,NK14
MOV KEYBUF,#13 LJMP DK4 | |
MOV KEYBUF,#14 |
LJMP DK4
NK15: CJNE A,#07H,NK16
MOV KEYBUF,#15
LJMP DK4
NK16: NOP
DK4:
MOV A,KEYBUF
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,KEYBUF
MOV B,#2 | |
MUL AB | |
| |
MOV TH0,A
INC TEMP
MOV A,TEMP
MOVC A,@A+DPTR
MOV STL0,A
MOV TL0,A
SETB TR0
DK4A: MOV A,P3
ANL A,#0FH | |
CLR TR0 |
NOKEY4:
LJMP WAIT
DELY10MS:
MOV R6,#10
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
INT_T0:
MOV TH0,STH0
MOV TL0,STL0
CPL P1.0 |
DW 820,8,968,65030
DW 65058,65110,65157,65178
END
7. C语言源程序
#include<ATX51.H>
unsignedchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
unsigned char temp; | 0x39,0x5e,0x79,0x71}; | |
unsigned char key; | ||
|
unsigned char i,j; |
unsignedchar STH0;
unsignedchar STL0;
unsignedint code tab[]={021,103,260,400,
524,580,684,777,
820,8,968,65030,
65058,65110,65157,65178};
voidmain(void)
{
TMOD=0x01;
ET0=1;
EA=1;
while(1) | |
{ | |
| |
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; | |
{ |
case0x0e:
key=0;
break;
case 0x0d:
key=1;
break;
case 0x0b:
key=2;
break;
case 0x07:
key=3;
break; | |
} | |
| |
STL0=tab[key]%6;
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; |
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]%6;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
TR0=0; | ||
} | } | |
| ||
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)
{ | |
switch(temp) |
{
case 0x0e:
key=8;
break;
case 0x0d:
key=9;
break;
case 0x0b:
key=10;
break;
case 0x07:
key=11; | ||
} | break; | |
| ||
STH0=tab[key]/256;
STL0=tab[key]%6;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
} | |
} |
P3=0xff;
P3_7=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)
{ |
key=12;
break;
case 0x0d:
key=13;
break;
case 0x0b:
key=14;
break;
case 0x07: | |
} |
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%6;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
} | } | |
TR0=0; | | |
| ||
voidt0(void) interrupt 1 using 0
{
TH0=STH0;
TL0=STL0;
P1_0=~P1_0;
} |