钢琴编程是什么意思啊

钢琴编程是什么意思啊,第1张

是使用计算机语言模拟钢琴d奏的调试程序。

使用汇编语言设计一个d奏程序,程序运行时使PC机成为一架可d奏的“钢琴”。

屏幕显示钢琴图像。

当按下数字1-8时,依次发出1,2,3,4,5,6,7,i八个音调;按下CTRL-C则退出“钢琴”状态。

变调:按下键“U”后,再d奏和演奏时琴键相应的音符频率变高;按下键“D”后,再d奏和演奏时琴键相应的音符频率变低;

22. 电子琴

1. 实验任务

(1. 由4X4组成16个按钮矩阵,设计成16个音。

(2. 可随意d奏想要表达的音乐。

2. 电路原理图

图4.22.1

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 64103 中 7 SI 988 65030

# 4 FA# 370 64185 高 1 DO 1046 65058

低 5 SO 392 64260 # 1 DO# 1109 65085

# 5 SO# 415 64331 高 2 RE 1175 65110

低 6 LA 440 64400 # 2 RE# 1245 65134

# 6 466 64463 高 3 M 1318 65157

低 7 SI 494 64524 高 4 FA 1397 65178

中 1 DO 523 64580 # 4 FA# 1480 65198

# 1 DO# 554 64633 高 5 SO 1568 65217

中 2 RE 587 64684 # 5 SO# 1661 65235

# 2 RE# 622 64732 高 6 LA 1760 65252

中 3 M 659 64777 # 6 1865 65268

中 4 FA 698 64820 高 7 SI 1967 65283

下面我们要为这个音符建立一个表格,有助于单片机通过查表的方式来获得相应的数据

低音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用来产生音拍。

5. 程序框图

图4.22.2

6. 汇编源程序

KEYBUF EQU 30H

STH0 EQU 31H

STL0 EQU 32H

TEMP EQU 33H

ORG 00H

LJMP START

ORG 0BH

LJMP INT_T0 T0中断入口

START: MOV TMOD,#01H T0工作方式1

SETB ET0

SETB EA

WAIT:

MOV P3,#0FFH 输入口置1准备工作

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

DK2:

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

DK2A: MOV A,P3

ANL A,#0FH

XRL A,#0FH

JNZ DK2A

CLR TR0

NOKEY2:

MOV P3,#0FFH

CLR P3.6

MOV A,P3

ANL A,#0FH

XRL A,#0FH

JZ NOKEY3

LCALL DELY10MS

MOV A,P3

ANL A,#0FH

XRL A,#0FH

JZ NOKEY3

MOV A,P3

ANL A,#0FH

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

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

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

JZ NOKEY4

LCALL DELY10MS

MOV A,P3

ANL 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

NK14: CJNE A,#0BH,NK15

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 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

DK4A: MOV A,P3

ANL A,#0FH

XRL A,#0FH

JNZ DK4A

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

RETI

TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H

DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H

TABLE1: DW 64021,64103,64260,64400

DW 64524,64580,64684,64777

DW 64820,64898,64968,65030

DW 65058,65110,65157,65178

END

7. C语言源程序

#include <AT89X51.H>

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=50i>0i--)

for(j=200j>0j--)

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=50i>0i--)

for(j=200j>0j--)

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

temp=P3

temp=temp &0x0f

if (temp!=0x0f)

{

for(i=50i>0i--)

for(j=200j>0j--)

temp=P3

temp=temp &0x0f

if (temp!=0x0f)

{

temp=P3

temp=temp &0x0f

switch(temp)

{

case 0x0e:

key=8

break

case 0x0d:

key=9

break

case 0x0b:

key=10

break

case 0x07:

key=11

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_7=0

temp=P3

temp=temp &0x0f

if (temp!=0x0f)

{

for(i=50i>0i--)

for(j=200j>0j--)

temp=P3

temp=temp &0x0f

if (temp!=0x0f)

{

temp=P3

temp=temp &0x0f

switch(temp)

{

case 0x0e:

key=12

break

case 0x0d:

key=13

break

case 0x0b:

key=14

break

case 0x07:

key=15

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

}

}

}

}

void t0(void) interrupt 1 using 0

{

TH0=STH0

TL0=STL0

P1_0=~P1_0

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11234757.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存