单片机AT89C51电子琴设计的16位点路图及其C语言编程,送我邮箱里469519583@qq.com 谢谢了 ,收货立马给分

2024-12-20 15:22:51
推荐回答(2个)
回答1:

实验二十一 电子琴模拟实验
一、实验目的
1、了解单片机系统发声原理
2、进一步熟悉定时器编程方法
3、进一步熟悉键盘扫描电路工作原理及编程方法
二、实验说明
1.利用定时器,可以发出不同频率的脉冲,不同频率的脉冲经喇叭驱动电路放大滤波后,就会发出不同的音调。
2.定时器按设置的定时参数产生中断,这一次中断发出脉冲低电平,下一次反转发出脉冲高电平.由于定时参数不同,就发出了不同频率的脉冲. 本实验中当有键按下,会发出连续脉冲,直到按键松开,才停止发音。发完后继续检测键盘,如果键还按下,继续发音。
各音阶标称频率值:
音 阶 1 2 3 4 5 6 7
频率(HZ) 261.1 293.7 329.6 349.2 392.0 440.0 493.9
三、实验步骤
利用实验仪上提供的键盘,使数字键1、2、3、4、5、6、7作为电子琴按键,按下即发出相应的音调。用P3.2 口发出音频脉冲,驱动喇叭。
1、用8P数据线连接单片机最小应用系统1模块的 P1口到查询式键盘模块KEY1-KEY8口,用二号导线连接单片机最小应用系统1模块INT0(P3.2)口到扬声器模块的输入口。
2、用串行数据通信线连接计算机与仿真器,把仿真器插到单片机最小应用系统1模块的锁紧插座中,请注意仿真器的方向:缺口朝上。
3、打开Keil uVision2仿真软件,首先建立本实验的项目文件,接着添加“TH21_电子琴.ASM”源程序,进行编译,直到编译无误。
4、打开模块电源和总电源开关,点击开始调试按钮,点击RUN按钮运行程序。
5、实验现象:按查询式键盘的1~7键,扬声器发出高低不同的声音。
四、实验流程图及源程序
1、源程序:
PULSE EQU 10H ;脉冲
PULSECNT EQU 50H ;脉冲计数
TONEHIGH EQU 40H ;高音调
TONELOW EQU 41H ;低音调
TONE EQU 42H ;音调
KEYBUF EQU 54H
SPEAKER BIT P3.2
ORG 0000H
LJMP START
ORG 000BH
LJMP TIMER0INT
ORG 0030H
TIMER0INT: PUSH PSW ;定时中断
CLR TR0
MOV TH0, TONEHIGH
MOV TL0, TONELOW
SETB TR0
MOV C, PULSE
MOV SPEAKER,C
CPL PULSE
POP PSW
RETI
TONETABLE: DW 64578,64686,64778,64821
DW 64898,64968,65029
TESTKEY: MOV P1, #0FFH
MOV A, P1
CPL A ; 读入键状态
RET
KEYTABLE:DB 0FEH,0FDH,0FBH,0F7H
DB 0EFH,0DFH,0BFH,07FH ; 键码定义
GETKEY: MOV R6, #10
ACALL DELAY
MOV A,P1
CJNE A, #0FFH, K01 ;确有键按下
LJMP MLOOP
K01: MOV R3, #8 ;8个键
MOV R2, #0 ;键码
MOV B, A ;暂存键值
MOV DPTR, #KEYTABLE
K02: MOV A, R2
MOVC A, @A+DPTR ;从键值表中取键值
CJNE A, B, K04 ;键值比较
MOV A, R2 ;得键码
INC A
RET
K04: INC R2 ;不相等,到继续访问键值表
DJNZ R3, K02
MOV A, #0FFH ;键值不在键值中,即多键同时按下
LJMP MLOOP
DELAY: MOV R7, #0
DELAYLOOP: DJNZ R7, DELAYLOOP
DJNZ R6, DELAY
RET
START: MOV SP, #70H
MOV TMOD, #01 ; TIMER
MOV IE, #82H ; EA=1, IT0 = 1
MOV TONE, #0
MLOOP: CALL TESTKEY
JZ MLOOP
CALL GETKEY
MOV B, A
JZ MLOOP ; = 0, < 1
ANL A, #8
JNZ MLOOP ; > 8
DEC B
MOV A, B
RL A ; A = A*2
MOV B, A
MOV DPTR, #TONETABLE
MOVC A, @A+DPTR
MOV TONEHIGH, A
MOV TH0, A
MOV A, B
INC A
MOVC A, @A+DPTR
MOV TONELOW, A
MOV TL0, A
SETB TR0
MOV P1,#0FFH
WAIT: MOV A, P1
CJNE A, #0FFH, WAIT
MOV R6, #10
ACALL DELAY
CLR TR0
LJMP MLOOP
END
2.流程图

五、实验思考题
1、请思考实验是怎样在硬件与软件上实现发声的?
2、本程序中断子程序的调用是怎样进行的?
六、实验电路图
本实验用到单片机最小应用系统1模块,查询式键盘模块, 扬声器模块。单片机最小应用系统1模块电路原理参考附录三,查询式模块电路原理参考实验八图8.1,扬声器模块电路原理参考实验三图3.1。

回答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
音乐的音拍,一个节拍为单位(C调)
曲调值 DELAY 曲调值 DELAY
调4/4 125ms 调4/4 62ms
调3/4 187ms 调3/4 94ms
调2/4 250ms 调2/4 125ms
#include
unsigned char code table[]=;
unsigned char temp;
unsigned char key;
unsigned char i,j;
unsigned char STH0;
unsigned char STL0;
unsigned int code tab[]=;
void main(void)
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)TR0=0;}}P3=0xff;P3_5=0;temp=P3;temp=temp & 0x0f;if (temp!=0x0f)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)TR0=0;}}P3=0xff;P3_6=0;temp=P3;temp=temp & 0x0f;if (temp!=0x0f)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)TR0=0;}}P3=0xff;P3_7=0;temp=P3;temp=temp & 0x0f;if (temp!=0x0f)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)TR0=0;}}}}void t0(void) interrupt 1 using 0