单片机音乐的编程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单片机音乐的编程
我们知道,声音的频谱范围约在几十到几千赫兹,若能利用程序来控制单处机某个口线的高电平或低电平,则在该口线上就能产生一定频率的矩形波,接上喇叭就能发出一定频率的声音,若再利用延时程序控制“高”“低”电平的持续时间,就能改变输出频率,从而改变音调。
例如,要产生200HZ的音频信号,200HZ音频的变化周期为1/200秒,即5ms。这样,当P2.5的高电平或低电平的持续时间为2.5ms时就能发出200HZ的音调。
乐曲中,每一音符对应着确定的频率,我们将每一音符的时间常数和其相应的节拍常数作为一组,按顺序将乐曲中的所有常数排列成一个表,然后由查表程序依次取出,产生音符并控制节奏,就可以实现演奏效果。
此外,结束符和体止符可以分别用代码00H和0XH来表示,若查表结果为00H,则表示曲子终了;若查表结果为FFH,则产生相应的停顿效果。
定时器T0工作在定时方式1,改变TH0及TL0,产生不同的音频频率。必须考虑到中断响应时间的影响,尤其在高音部分,若忽略中断响应时间,会使音频频率比标准值低几十Hz,相当于1/4音程,很容易听出来,对低音部分影响不
大。一般中断响应时间为3~6个机器周期,经过反复试验取5个机器周期作为校正最为恰当,表1中所给的定时初值就是考虑中断响应后的定时常数。另外,为避免T1中断可能引起杂音,应将定时器T0中断设为高优先级。这样编写出来的程序播放的音与标准音叉进行差频校音,非常准确和谐。本例中单片机晶振频率为6MHz。
现在以单片机12MHZ晶振为例,例出高中低音符与单片机计数T0相关的计数值如下表所示
音符频率(HZ)简谱码音符频率(HZ)简谱码(T值)低1DO 262 63628 # 4 FA# 740 64860
#1DO# 277 63731 中5 SO 784 64898
低2RE 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
DW 64260,64400,64524,64580
DW 64684,64777,64820,64898
DW 64968,65030,65058,65110
DW 65157,65178,65217
下面我们要为这个音符建立一个表格,有助于单片机通过查表的方式来获得相应的数据
低音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调)
拍数为1/8拍(0.10s)~8拍(6.40s)
编写乐曲程序可以分四个步骤:
第一步,为演奏的乐曲定义一个频率表和一个节拍时间表。频率表中的数据可以从表中查到,节拍时间表的数据是延迟时间的倍数;
第二步,分别将两个表中的偏移地址送入两个指针寄存器;
第三步,分别从两个表中取出频率值和音符的持续时间值,送入相应的寄存器中,供调用通用发声程序使用;
第四步,调用通用发声程序发出音调。
我们知道,声音的频谱范围约在几十到几千赫兹,若能利用程序来控制单处机某个口线的高电平或低电平,则在该口线上就能产生一定频率的矩形波,接上喇叭就能发出一定频率的声音,若再利用延时程序控制“高”“低”电平的持续时间,就能改变输出频率,从而改变音调。
为了产生手弹的节奏感,在某些音符(例如两个相同音符)音插入一个时间单位的频率略有不同的音符。
ORG 0000H
AJMP MAIN
ORG 000BH
JMP TIM0
ORG 0030H
MAIN: ;主程序
MOV TMOD,#01H ;设定时方式
MOV IE,#82H ;开中断
START0: MOV 30H,#00H ;
NEXT: MOV A,30H
MOV DPTR,#TABLE ;节拍表格,
MOVC A,@A+DPTR ;查表取音调和节拍
MOV R2,A ;
JZ END0 ;为零,不进行处理.
ANL A,#0FH ;分离高低位
MOV R5,A ;将节拍存入R5
MOV A,R2 ;分离高低位
SWAP A ;分离高低位
ANL A,#0FH ;分离高低位
JNZ SING ;根据音调决定是否演奏.
CLR TR0
JMP D1
SING:DEC A ;a中放的是音阶位置.
MOV 22H,A ;将音调存入22H.
RL A ;乘2操作指向高字节
MOV DPTR,#TABLE1
MOVC A,@A+DPTR ;根据音调决定定时器初值.
MOV TH0,A ;放入TH0
MOV 21H,A
MOV A,22H
RL A
INC A ;乘2后加一操作指向低字节
MOVC A,@A+DPTR
MOV TL0,A ;放入TL0
MOV 20H,A
SETB TR0 ;启动定时
D1: CALL DELAY
INC 30H
JMP NEXT
END0: CLR TR0
JMP START0
TIM0: PUSH ACC ;定时器中断服务程序PUSH PSW