共2条
1/1 1 跳转至页
求音乐编程方法,各位大侠帮忙
问
现在做了一个项目,需要音乐蜂鸣,我已经有了一张乐谱,但是实在不知道,1,2,3,4,5,6,7的频率是多少,还有什么重音在软件上怎么处理(频率加倍?)还有什么大括号,双划线等等都不知道怎么处理。还望哪位大侠可以指点在下,假如可以提供学习的链接网站的话,也不胜感激,谢谢
答 1:
还不如直接用音乐片!
答 2:
这是本人一个产品中的音乐单元,很完整,供参考.这是本人一个产品中的音乐单元,单音演奏的,多重和音不宜用这方法,一般用硬件的音源加单片机控制方法完成,有兴趣可去合泰网站http://www.holtek.com.cn/docum/consumer/8950.htm看看.ht8950提供了一个产生乐音包络用的硬件平台(a/d,d/a等),用软波表数据来完成音阶及包络,单片机只是进行控制,以前8bit声卡中ym3812与此差不多功能.
中央C的A音为440Hz,半音价之间关系为2开12次方(12√2=1.05946)
中央C的#A音为440Hz*1.05946=466.163Hz
中央C的B音为440Hz*1.05946*1.05946=493.883Hz
用定时器来模拟这个频率,精度取决于时钟快慢,一般小数点后保留一位,音准已可忍受了,生日快乐芯片是小数点前一位的,耳朵容易听坏的拉.
ORG 0000H
AJMP CSH ;主程序进入点
ORG 000BH
LJMP TIM0 ;定时中断T0入口
;
;**********
;* 初始化 *
;**********
;
ORG 0020H
CSH: MOV R0,#7FH ;内部RAM(00H~7FH)清零
CSH1: MOV @R0,#00H
DJNZ R0,CSH1
MOV SP,#60H ;堆栈60H~7FH,【使用89C51】
MOV TMOD,#01H ;TMOD=11H,T0作16位计数器(4M晶振)
CLR TCON.4 ;T0禁止动作
SETB IE.1 ;T0允许中断
SETB PT0 ;T0中断优先
SETB IE.7 ;系统允许中断
;
;**********
;* 主程序 *
;**********
;
MAIN: MOV 5CH,#00 ;取简码谱指针
LCALL MUSIC
MOV 5CH,#49 ;取简码谱指针
LCALL MUSIC
MOV 5CH,#66 ;取简码谱指针
LCALL MUSIC
MOV 5CH,#100 ;取简码谱指针
LCALL MUSIC
MOV 5CH,#108 ;取简码谱指针
LCALL MUSIC
MOV 5CH,#136 ;取简码谱指针
LCALL MUSIC
MOV 5CH,#174 ;取简码谱指针
LCALL MUSIC
AJMP MAIN
;
;*************************
;* 音乐子程序 MUSIC *
;* 入口: 5CH←简码谱指针 *
;*************************
;
MUSIC: MOV A,5CH ;简码谱指针装入A
MOV DPTR,#TABLE ;至TABLE取简码
MOVC A,@A+DPTR
MOV R2,A ;取到的简码暂存于R2
JZ END1 ;是否取到00(结束码)?
ANL A,#0FH ;不是,则取低四位(节拍码)
MOV R6,A ;将节拍码存入R6
MOV A,R2 ;将取到的简码再装入R2
SWAP A ;高低四位交换
ANL A,#0FH ;取低四位(音符码)
JNZ SING ;取到的音符码是否为0?
CLR TR0 ;是,则不发音
AJMP D1 ;跳到D1
;
SING: DEC A ;取到的音符码减1
MOV 4BH,A ;存入(4BH)
RL A ;乘2
MOV DPTR,#TABLE1 ;至TABLE1取相对的高字节计数值
MOVC A,@A+DPTR
MOV TH0,A ;取到的高字节存入TH0
MOV 4AH,A ;取到的高字节存入(4AH)
MOV A,4BH ;再装入取到的音符码
RL A ;乘2
INC A ;加1
MOVC A,@A+DPTR ;至TABLE1取相对的低位
MOV TL0,A ;取到的低字节存入TL0
MOV 49H,A ;取到的低字节存入(49H)
SETB TR0 ;启动TIMER0
D1: CALL DELAY ;基本单位时间1/4拍187毫秒
INC 5CH ;取简码谱指针加1
AJMP MUSIC ;取下一个码
DD1: RET
;
STOP: NOP
; JB P3.7,STOP1 ;在软件延时中掺插做其他动作
; SETB P2.7 ;P2.7←"1"
NOP
NOP
STOP0: NOP
RET
STOP1: NOP
; JB P3.6,STOP0 ;在软件延时中掺插做其他动作
; SETB P2.6 ;P2.6←"1"
RET
;
END1: CLR TR0 ;停止TIMER0
RET
;
TIM0: PUSH A ;将A的值暂存于堆栈区
PUSH PSW ;将PSW的值暂存于堆栈区
MOV TL0,49H ;重设计数值
MOV TH0,4AH
CPL P1.7 ;将输出端P1.1取反(P1.7接至无源蜂鸣器)
POP PSW ;至堆栈区取回PSW的值
POP A ;至堆栈区取回A的值
RETI ;返回主程序
;
DELAY: MOV R7,#02 ;187毫秒
D2: MOV R4,#24
D3: MOV R3,#48
DJNZ R3,$
ACALL STOP ;在软件延时中掺插做其他动作
DJNZ R4,D3
DJNZ R7,D2
DJNZ R6,DELAY ;决定节拍
RET
; .5 .6 .7 1
TABLE1: DW 65111,65150,65199,65217 ;4M晶振时的定时中断时间常数
; 2 3 4 5 ;若采用其它频率,则要根据乐音的
DW 65252,65283,65297,65323 ;频率计算,例中央C的A音为440Hz,
; 6 7 1` 2` ;440Hz=2.273ms,把T0设置为2.273ms
DW 65347,65367,65377,65394 ;中断即可发出A音.
; 3` 4` #6
DW 65410,65417,65357
;
;***************************************************************
;* 音符代码 1 2 3 4 5 6 7 8 9 A B C D E F 0 *
;* 音高 .5 .6 .7 1 2 3 4 5 6 7 1` 2` 3` 4` 5` 休止 *
;*-------------------------------------------------------------*
;* 节拍代码 1 2 3 4 5 6 8 A C F *
;* 节拍 1/4 2/4 3/4 1 1(1/4) 1(1/2) 2 2(1/2) 3 3(3/4) *
;*-------------------------------------------------------------*
;* 结束代码 00H *
;*-------------------------------------------------------------*
;* 乐谱格式 每字节的高字节为音符代码,低字节为节拍代码 *
;*-------------------------------------------------------------*
;* 例子: ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ *
;* DB A4H,02H,84H,02H,A4H,02H,84H,02H,D8H,04H,00H *
;* ⑴ A→唱"7" , 4→ 1 拍 *
;* ⑵ 0→休止 , 2→2/4拍 *
;* ⑶ 8→唱"5" , 4→ 1 拍 *
;* ⑷ 0→休止 , 2→2/4拍 *
;* ⑸ A→唱"7" , 4→ 1 拍 *
;* ⑹ 0→休止 , 2→2/4拍 *
;* ⑺ 8→唱"5" , 4→ 1 拍 *
;* ⑻ 0→休止 , 2→2/4拍 *
;* ⑼ D→唱"3`", 8→ 2 拍 *
;* ⑽ 0→休止 , 4→ 1 拍 *
;* ⑾ 00H→乐曲结束 *
;***************************************************************
;
TABLE:
;【00】
DB 98H,02H,B4H,01H,94H,01H,68H,02H,94H,01H
DB 64H,01H,48H,02H,64H,01H,44H,01H,28H,02H
DB 64H,01H,94H,01H,B4H,01H,94H,01H,B4H,01H
DB 94H,01H,B4H,01H,D4H,01H,94H,01H,64H,01H
DB 44H,01H,64H,01H,98H,02H,01H,01H,00H
;【49】
DB A4H,02H,84H,02H,A4H,02H,84H,02H,D8H,04H
DB C8H,01H,01H,01H,01H,01H,00H
;【66】
DB 42H,52H,62H,72H,82H,92H,A2H,B2H,42H,52H
DB 62H,72H,82H,92H,A2H,B2H,00H
;【100】
DB 61H,81H,B1H,D1H,B1H,81H,61H,00H
;【108】
DB 11H,41H,61H,81H,61H,41H,11H,00H
;【136】
DB 24H,04H,34H,04H,44H,04H,54H,04H,64H,04H,44H,04H,64H,04H,94H,04H
DB 83H,01H,93H,01H,83H,01H,63H,01H,46H,02H,66H,02H
DB 91H,21H,91H,21H,91H,21H,91H,21H,94H,00H
;【174】
DB 94H,04H,A4H,04H,B4H,04H,C4H,04H,D4H,04H
DB B4H,04H,D8H,08H,C4H,04H,F4H,04H,CCH,00H
;
END
答 3: 谢谢tyw,程序结构很清楚,太感谢了谢谢,我先study了 答 4: 這年頭還是好人多啊
中央C的A音为440Hz,半音价之间关系为2开12次方(12√2=1.05946)
中央C的#A音为440Hz*1.05946=466.163Hz
中央C的B音为440Hz*1.05946*1.05946=493.883Hz
用定时器来模拟这个频率,精度取决于时钟快慢,一般小数点后保留一位,音准已可忍受了,生日快乐芯片是小数点前一位的,耳朵容易听坏的拉.
ORG 0000H
AJMP CSH ;主程序进入点
ORG 000BH
LJMP TIM0 ;定时中断T0入口
;
;**********
;* 初始化 *
;**********
;
ORG 0020H
CSH: MOV R0,#7FH ;内部RAM(00H~7FH)清零
CSH1: MOV @R0,#00H
DJNZ R0,CSH1
MOV SP,#60H ;堆栈60H~7FH,【使用89C51】
MOV TMOD,#01H ;TMOD=11H,T0作16位计数器(4M晶振)
CLR TCON.4 ;T0禁止动作
SETB IE.1 ;T0允许中断
SETB PT0 ;T0中断优先
SETB IE.7 ;系统允许中断
;
;**********
;* 主程序 *
;**********
;
MAIN: MOV 5CH,#00 ;取简码谱指针
LCALL MUSIC
MOV 5CH,#49 ;取简码谱指针
LCALL MUSIC
MOV 5CH,#66 ;取简码谱指针
LCALL MUSIC
MOV 5CH,#100 ;取简码谱指针
LCALL MUSIC
MOV 5CH,#108 ;取简码谱指针
LCALL MUSIC
MOV 5CH,#136 ;取简码谱指针
LCALL MUSIC
MOV 5CH,#174 ;取简码谱指针
LCALL MUSIC
AJMP MAIN
;
;*************************
;* 音乐子程序 MUSIC *
;* 入口: 5CH←简码谱指针 *
;*************************
;
MUSIC: MOV A,5CH ;简码谱指针装入A
MOV DPTR,#TABLE ;至TABLE取简码
MOVC A,@A+DPTR
MOV R2,A ;取到的简码暂存于R2
JZ END1 ;是否取到00(结束码)?
ANL A,#0FH ;不是,则取低四位(节拍码)
MOV R6,A ;将节拍码存入R6
MOV A,R2 ;将取到的简码再装入R2
SWAP A ;高低四位交换
ANL A,#0FH ;取低四位(音符码)
JNZ SING ;取到的音符码是否为0?
CLR TR0 ;是,则不发音
AJMP D1 ;跳到D1
;
SING: DEC A ;取到的音符码减1
MOV 4BH,A ;存入(4BH)
RL A ;乘2
MOV DPTR,#TABLE1 ;至TABLE1取相对的高字节计数值
MOVC A,@A+DPTR
MOV TH0,A ;取到的高字节存入TH0
MOV 4AH,A ;取到的高字节存入(4AH)
MOV A,4BH ;再装入取到的音符码
RL A ;乘2
INC A ;加1
MOVC A,@A+DPTR ;至TABLE1取相对的低位
MOV TL0,A ;取到的低字节存入TL0
MOV 49H,A ;取到的低字节存入(49H)
SETB TR0 ;启动TIMER0
D1: CALL DELAY ;基本单位时间1/4拍187毫秒
INC 5CH ;取简码谱指针加1
AJMP MUSIC ;取下一个码
DD1: RET
;
STOP: NOP
; JB P3.7,STOP1 ;在软件延时中掺插做其他动作
; SETB P2.7 ;P2.7←"1"
NOP
NOP
STOP0: NOP
RET
STOP1: NOP
; JB P3.6,STOP0 ;在软件延时中掺插做其他动作
; SETB P2.6 ;P2.6←"1"
RET
;
END1: CLR TR0 ;停止TIMER0
RET
;
TIM0: PUSH A ;将A的值暂存于堆栈区
PUSH PSW ;将PSW的值暂存于堆栈区
MOV TL0,49H ;重设计数值
MOV TH0,4AH
CPL P1.7 ;将输出端P1.1取反(P1.7接至无源蜂鸣器)
POP PSW ;至堆栈区取回PSW的值
POP A ;至堆栈区取回A的值
RETI ;返回主程序
;
DELAY: MOV R7,#02 ;187毫秒
D2: MOV R4,#24
D3: MOV R3,#48
DJNZ R3,$
ACALL STOP ;在软件延时中掺插做其他动作
DJNZ R4,D3
DJNZ R7,D2
DJNZ R6,DELAY ;决定节拍
RET
; .5 .6 .7 1
TABLE1: DW 65111,65150,65199,65217 ;4M晶振时的定时中断时间常数
; 2 3 4 5 ;若采用其它频率,则要根据乐音的
DW 65252,65283,65297,65323 ;频率计算,例中央C的A音为440Hz,
; 6 7 1` 2` ;440Hz=2.273ms,把T0设置为2.273ms
DW 65347,65367,65377,65394 ;中断即可发出A音.
; 3` 4` #6
DW 65410,65417,65357
;
;***************************************************************
;* 音符代码 1 2 3 4 5 6 7 8 9 A B C D E F 0 *
;* 音高 .5 .6 .7 1 2 3 4 5 6 7 1` 2` 3` 4` 5` 休止 *
;*-------------------------------------------------------------*
;* 节拍代码 1 2 3 4 5 6 8 A C F *
;* 节拍 1/4 2/4 3/4 1 1(1/4) 1(1/2) 2 2(1/2) 3 3(3/4) *
;*-------------------------------------------------------------*
;* 结束代码 00H *
;*-------------------------------------------------------------*
;* 乐谱格式 每字节的高字节为音符代码,低字节为节拍代码 *
;*-------------------------------------------------------------*
;* 例子: ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ *
;* DB A4H,02H,84H,02H,A4H,02H,84H,02H,D8H,04H,00H *
;* ⑴ A→唱"7" , 4→ 1 拍 *
;* ⑵ 0→休止 , 2→2/4拍 *
;* ⑶ 8→唱"5" , 4→ 1 拍 *
;* ⑷ 0→休止 , 2→2/4拍 *
;* ⑸ A→唱"7" , 4→ 1 拍 *
;* ⑹ 0→休止 , 2→2/4拍 *
;* ⑺ 8→唱"5" , 4→ 1 拍 *
;* ⑻ 0→休止 , 2→2/4拍 *
;* ⑼ D→唱"3`", 8→ 2 拍 *
;* ⑽ 0→休止 , 4→ 1 拍 *
;* ⑾ 00H→乐曲结束 *
;***************************************************************
;
TABLE:
;【00】
DB 98H,02H,B4H,01H,94H,01H,68H,02H,94H,01H
DB 64H,01H,48H,02H,64H,01H,44H,01H,28H,02H
DB 64H,01H,94H,01H,B4H,01H,94H,01H,B4H,01H
DB 94H,01H,B4H,01H,D4H,01H,94H,01H,64H,01H
DB 44H,01H,64H,01H,98H,02H,01H,01H,00H
;【49】
DB A4H,02H,84H,02H,A4H,02H,84H,02H,D8H,04H
DB C8H,01H,01H,01H,01H,01H,00H
;【66】
DB 42H,52H,62H,72H,82H,92H,A2H,B2H,42H,52H
DB 62H,72H,82H,92H,A2H,B2H,00H
;【100】
DB 61H,81H,B1H,D1H,B1H,81H,61H,00H
;【108】
DB 11H,41H,61H,81H,61H,41H,11H,00H
;【136】
DB 24H,04H,34H,04H,44H,04H,54H,04H,64H,04H,44H,04H,64H,04H,94H,04H
DB 83H,01H,93H,01H,83H,01H,63H,01H,46H,02H,66H,02H
DB 91H,21H,91H,21H,91H,21H,91H,21H,94H,00H
;【174】
DB 94H,04H,A4H,04H,B4H,04H,C4H,04H,D4H,04H
DB B4H,04H,D8H,08H,C4H,04H,F4H,04H,CCH,00H
;
END
答 3: 谢谢tyw,程序结构很清楚,太感谢了谢谢,我先study了 答 4: 這年頭還是好人多啊
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图四被打赏50分 | |
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 |