汇编_音乐乐曲演奏程序
- 格式:doc
- 大小:132.50 KB
- 文档页数:19
SETB P3.5CLR P1.4JB P1.0,NEXT_11MOV CMD,#11CALL SENDW AIT_10:JNB P1.0,WAIT_10 JMP LOOPNEXT_11:JB P1.1,NEXT_12 MOV CMD,#06CALL SENDW AIT_11:JNB P1.1,WAIT_11 JMP LOOPNEXT_12:JB P1.2,NEXT_13 MOV CMD,#01CALL SENDW AIT_12:JNB P1.2,WAIT_12 JMP LOOPNEXT_13:JB P1.3,NEXT_14 MOV CMD,#8CALL SENDW AIT_13:JNB P1.3,WAIT_13 JMP LOOPNEXT_14:JB P3.4,NEXT_15 MOV CMD,#50HCALL SENDW AIT_14:JNB P3.4,WAIT_14 JMP LOOPNEXT_15:JB P3.5,TO_1 MOV CMD,#60HCALL SENDW AIT_15:JNB P3.5,WAIT_15 JMP LOOPTO_1:SETB P1.4CLR P1.5JB P1.0,NEXT_21MOV CMD,#80HCALL SENDW AIT_20:JNB P1.0,WAIT_20 JMP LOOPMOV CMD,#07CALL SENDW AIT_21:JNB P1.1,WAIT_21 JMP LOOPNEXT_22:JB P1.2,NEXT_23 MOV CMD,#02CALL SENDW AIT_22:JNB P1.2,WAIT_22 JMP LOOPNEXT_23:JB P1.3,NEXT_24 MOV CMD,#04CALL SENDW AIT_23:JNB P1.3,WAIT_23 JMP LOOPNEXT_24:JB P3.4,NEXT_25 MOV CMD,#90HCALL SENDW AIT_24:JNB P3.4,WAIT_24 JMP LOOPNEXT_25:JB P3.5,TO_2 MOV CMD,#70HCALL SENDW AIT_25:JNB P3.5,WAIT_25 JMP LOOPTO_2:SETB P1.5CLR P1.6JB P1.1,NEXT_31MOV CMD,#09CALL SENDW AIT_30:JNB P1.1,WAIT_30 JMP LOOPNEXT_31:JB P1.2,NEXT_32 MOV CMD,#03CALL SENDW AIT_31:JNB P1.2,WAIT_31 JMP LOOPNEXT_32:JB P1.3,NEXT_33 MOV CMD,#10HCALL SENDJMP LOOPNEXT_33:JB P3.4,NEXT_34MOV CMD,#40HCALL SENDW AIT_33:JNB P3.4,WAIT_33JMP LOOPNEXT_34:JB P3.5,TO_3MOV CMD,#20HCALL SENDW AIT_34:JNB P3.5,WAIT_34JMP LOOPTO_3:SETB P1.6CLR P1.7JB P1.1,NEXT_41MOV CMD,#10CALL SENDW AIT_40:JNB P1.1,WAIT_40JMP LOOPNEXT_41:JB P1.2,NEXT_42MOV CMD,#5CALL SENDW AIT_41:JNB P1.2,WAIT_41JMP LOOPNEXT_42:JB P3.5,OVERMOV CMD,#30HCALL SENDW AIT_42:JNB P3.5,WAIT_42OVER:JMP LOOP;************************************** SEND:MOV A,CMDMOV C,PMOV TB8,CSETB TR0MOV SBUF,ACALL DELAYCALL DELAYRET;*****************定时器0中断服务程序***************INT_T:CPL FLAG_OUTMOV C,FLAG_OUTMOV P3.7,CRETI;*****************串口中断服务程序******************INT_S:PUSH ACLR EACLR TICLR TR0CALL DELAY;等待接收方处理数据SETB EAPOP ARETI;***************延时子程序*********************DELAY:MOV30H,#0FFHD_1:MOV31H,#08HD_2:NOPDJNZ31H,D_2DJNZ30H,D_1RET机器人代码:(外部中断用来接红外传感器的,呵呵,现在没接)ORG0000HJMP INITORG0003HJMP INT_0ORG000BHJMP INT_TORG0023HJMP INT_S;-------------------------------------FLAG_F EQU01H;功能选择,0为播放,1为演奏FLAG_L EQU02H;指示灯选择,0指示灯亮或1亮FLAG_P EQU03H;是否播放标志,0停止,1播放FLAG_CH EQU04H;演奏时是否换音符,1有效FLAG_LAST EQU05H;播放时是否到最后64分音符FLAG_PRESS EQU06H;是否有演奏按键FLAG_GO EQU07H;是否行走标志位(1为行走,0为停止)STAT_0EQU08H;4位行走状态,对应P1.0--P1.3STAT_1EQU09HSTAT_2EQU0AHSTAT_3EQU0BHFLAG_MUTE EQU0CHPERIOD_H EQU30H;音长(定时器高位)PERIOD_L EQU31H;音长(定时器低位)COUNTER EQU32H;定时器计数(设定定时周期的倍数)CU_COUNTER EQU41H;当前定时器计数TONE EQU33H;音高SPEED EQU34H;乐曲速度D_1EQU35HD_2EQU36HP_1EQU37HP_2EQU38HNUM EQU39H;乐曲的位置(第几首)POSITION EQU40H;乐曲中音符的位置TAB_H EQU42H;当前乐曲的音长表首地址高八位TAB_L EQU43H;当前乐曲的音长表首地址低八位TAB_TONE_H EQU44H;当前乐曲的音高表首地址高八位TAB_TONE_L EQU45H;当前乐曲的音高表首地址低八位THIS_NUM EQU46H;存储当前按键号PRE_NUM EQU47H;存储上次按键号COUNTER_1EQU48H;判断是否为最后64分音符用,其值等于COUNTER-1D_L1EQU49HD_L2EQU4AHD_L3EQU4BHP_L1EQU4CHP_L2EQU4DHTAB_1EQU4EH;查表时的高低字节序号存储TAB_2EQU4FHCMD EQU50H;行走命令存储(1:功能选择、2:加速、3:减速、4:原速、5:停止/前进、;(6:左转、7:右转、8:朝前))COUNTER_LOOP EQU51H;定时器循环计数;STATUS EQU52H;行走状态寄存PERIOD_TEMP EQU53H;*****************主程序*************************ORG0030HINIT:;CALL LONGCLR P3.7;SETB P3.7MOV SP,#54HCLR FLAG_F;初始化CLR FLAG_LCLR FLAG_PCLR FLAG_LASTSETB FLAG_CHCLR FLAG_PRESSSETB FLAG_GOCLR FLAG_MUTESETB STAT_0SETB STAT_1SETB STAT_2SETB STAT_3MOV CMD,#00HMOV PERIOD_H,#00HMOV PERIOD_L,#00HMOV TONE,#00HMOV SPEED,#00HMOV COUNTER,#00HMOV NUM,#00HMOV POSITION,#00H;MOV STATUS,#0FFHMOV D_1,#80MOV D_2,#79MOV P_L1,#01HMOV P_L2,#0FFHMOV TMOD,#21H;定时器0为16位计数器定时,1为8位自动装载MOV TH0,#0FFHMOV TL0,#0FFHMOV TH1,#0CCHMOV TL1,#0CCHMOV SCON,#0D0HSETB IT0;设定外部中断0为负跳变触发SETB PX0;外部中断为高优先级SETB PSSETB EASETB ET0SETB EX0;开外部中断SETB ESSETB TR1;CALL DELAY;-------------------------------------------LOOP:JB FLAG_F,PLAY;演奏功能跳转OUT:JNB FLAG_P,LOOP;播放部分MOV A,TONEJZ MUTEJB FLAG_MUTE,MUTE_1SETB P3.7MUTE_1:CJNE A,#1FH,NO_OVERCLR TR0;TONE值等于1FH,乐曲结束,重新赋初值开始CLR P3.7ORL P1,#0FHMOV POSITION,#00HMOV CU_COUNTER,COUNTERCALL LONGMOV TONE,#00MOV COUNTER_LOOP,#0SETB TR0JMP LOOPNO_OVER:MUTE:CALL DELAYCLR P3.7CALL DELAYJMP LOOP;------------------PLAY:JNB FLAG_PRESS,OVERSETB P3.7;演奏部分CALL DELAYCLR P3.7OVER:CALL DELAYJMP LOOP;****************串口中断服务程序******************INT_S:PUSH ACLR RIMOV A,SBUFJB P,R_1R_0:JB RB8,TO_OVERJMP RIGHTR_1:JNB RB8,TO_OVERRIGHT:MOV NUM,A;赋乐曲号ANL A,#0FHJNZ SELECT;选曲跳转MOV A,NUMSWAP AMOV CMD,A;----------------------------CJNE A,#01H,IF_2CLR P3.7CPL FLAG_FORL P1,#0FHJB FLAG_F,PLAY_SETSETB FLAG_GOJMP INT_OVERPLAY_SET:CLR FLAG_PCLR TR0CLR FLAG_GOCLR FLAG_PRESSJMP INT_OVERIF_2:CJNE A,#02H,IF_3MOV A,PERIOD_HADD A,#4MOV NUM,ACLR CSUBB A,#240JC S_UPJMP INT_OVERS_UP:MOV PERIOD_H,NUM JMP INT_OVERIF_3:MOV A,CMDCJNE A,#03H,IF_4MOV A,PERIOD_HSUBB A,#9MOV NUM,ACLR CSUBB A,#100JNC S_DOWNJMP INT_OVERS_DOWN:MOV PERIOD_H,NUM JMP INT_OVERIF_4:MOV A,CMDCJNE A,#04H,IF_5MOV PERIOD_H,PERIOD_TEMP JMP INT_OVERIF_5:CJNE A,#05H,IF_9CPL FLAG_GOJMP INT_OVERIF_9:CJNE A,#09H,CMD_OVERCPL FLAG_MUTECMD_OVER:TO_OVER:JMP INT_OVER;---------------------------SELECT:DEC NUMMOV A,NUMANL A,#0F0HJNZ TO_OVERMOV A,NUMCLR CSUBB A,#11JNC TO_OVERMOV A,NUMRL AMOV T AB_1,AMOV T AB_2,TAB_1INC TAB_2MOV DPTR,#TAB_SPEED;查乐曲速度MOV A,TAB_1MOVC A,@A+DPTRMOV PERIOD_L,AMOV TL0,AMOV A,TAB_2MOVC A,@A+DPTRMOV PERIOD_H,AMOV PERIOD_TEMP,AMOV TH0,AMOV DPTR,#TAB_NUM_T;查音高位置首地址MOV A,TAB_1MOVC A,@A+DPTRMOV TAB_TONE_H,AMOV A,TAB_2MOVC A,@A+DPTRMOV TAB_TONE_L,AMOV DPTR,#TAB_NUM_L;查音长位置首地址MOV A,TAB_1MOVC A,@A+DPTRMOV TAB_H,AMOV A,TAB_2MOVC A,@A+DPTRMOV TAB_L,AHANDLE:JB FLAG_F,PLAY_0;演奏乐曲时跳转SETB FLAG_P;允许播放MOV POSITION,#0H;赋乐曲位置值为0,即从头开始拨出MOV COUNTER,#02HMOV CU_COUNTER,COUNTER;赋当前定时次数和应定时次数值,使之相等,以使定时器工作时就播放,无需等待MOV COUNTER_1,COUNTERDEC COUNTER_1CLR FLAG_LASTMOV COUNTER_LOOP,#0SETB TR0;启动定时器0JMP INT_OVERPLAY_0:CLR P3.7SETB FLAG_PRESSSETB FLAG_CHMOV DPTR,#TAB_TONE;查音高表MOV A,NUMADD A,#07RL A;音高表每组音高有两个延时值MOV TAB_1,AMOVC A,@A+DPTR;查第一个延时值MOV D_1,AMOV A,TAB_1INC AMOVC A,@A+DPTRMOV D_2,AJB FLAG_L,L_0SETB FLAG_LCLR P3.4SETB P3.3JMP INT_OVERL_0:CLR FLAG_LCLR P3.3SETB P3.4INT_OVER:POP ARETI;****************定时器0中断服务程序****************INT_T:PUSH ACLR TR0MOV TH0,PERIOD_HMOV TL0,PERIOD_LMOV A,CU_COUNTERCJNE A,COUNTER_1,GO_ON_1SETB FLAG_LASTJMP READGO_ON_1:CJNE A,COUNTER,GO_ON;音符时间未到跳转CLR FLAG_LASTMOV DPH,TAB_H;读取音长表首地址MOV DPL,TAB_LMOV A,POSITIONMOVC A,@A+DPTRMOV COUNTER,AMOV COUNTER_1,ADEC COUNTER_1READ:MOV DPH,TAB_TONE_H;读取音高表首地址MOV DPL,TAB_TONE_LMOV A,POSITION;查音高值MOVC A,@A+DPTRJNB FLAG_LAST,NO_LASTSUBB A,#07NO_LAST:MOV TONE,AMOV DPTR,#TAB_TONE;查与音高相对印的延时值MOV A,TONE;查第一个延时值SUBB A,#06HRL AMOVC A,@A+DPTRMOV D_1,AMOV A,TONE;查第二个延时值SUBB A,#06HRL AINC AMOVC A,@A+DPTRMOV D_2,AJB FLAG_LAST,GO_ON_INCINC POSITIONMOV CU_COUNTER,#01HMOV A,TONEJZ INT_T_OVERJB FLAG_L,LT_0SETB FLAG_LCLR P3.4SETB P3.3JMP INT_T_OVERLT_0:CLR FLAG_LCLR P3.3SETB P3.4JMP INT_T_OVERGO_ON_INC:MOV A,TONEADD A,#07MOV TONE,AGO_ON:INC CU_COUNTERINT_T_OVER:INC COUNTER_LOOP;行走控制MOV A,COUNTER_LOOPCJNE A,#16,IF_GOORL P1,#0FHJMP RIF_GO:CJNE A,#25,IF_32MOV A,TONE;JZ RMOV A,COUNTERCLR CSUBB A,#64JC YES;音长大于等于64时停止行走MOV A,COUNTERSUBB A,CU_COUNTERCLR CSUBB A,#33JC YESJMP RYES:JB FLAG_GO,GO_1;不允许行走跳转ORL P1,#0FHJMP RGO_1:JB STAT_0,GO_2;行走一步SETB P1.0SETB STAT_0CLR P1.1CLR STAT_1JMP RGO_2:JB STAT_1,GO_3SETB P1.1SETB STAT_1CLR P1.2CLR STAT_2JMP RGO_3:JB STAT_2,GO_4SETB P1.2SETB STAT_2CLR P1.3CLR STAT_3JMP RGO_4:SETB P1.3SETB STAT_3CLR P1.0CLR STAT_0JMP RIF_32:MOV A,COUNTER_LOOPCJNE A,#32,RMOV COUNTER_LOOP,#00HR:SETB TR0POP ARETI;******************外部中断0服务程序*******************INT_0:PUSH APOP ARETI;******************长延时子程序(1S)*******************LONG:MOV D_L1,P_L1DL1:MOV D_L2,P_L2DL2:MOV D_L3,#0FFHDL3:DJNZ D_L3,DL3DJNZ D_L2,DL2DJNZ D_L1,DL1MOV P_L1,#01HRET;*******************延时子程序**********************DELAY:MOV P_1,D_1D1:MOV P_2,D_2D2:DJNZ P_2,D2DJNZ P_1,D1RET;---------------音长表--------------------;以64分音符为一个单位,即1为64分音符、2为32分...TAB_L0:DB32,16,16,32,16,16,32,16,16,24,8,64;《DINGO BELL》DB16,16,32,16,16,32,16,16,16,16,64DB16,16,32,16,16,32,16,16,24,8,64DB16,16,32,16,16,32,16,16,16,16,32,32TAB_L1:DB32,32,32,32,32,32,32,32,32,32,32,32,32,48,16,64;欢乐颂DB32,32,32,32,32,32,32,32,32,32,32,32,48,16,64DB32,32,32,32,32,16,16,32,32,32,16,16,32,32,32,32,32,64DB32,32,32,32,32,32,32,32,32,32,32,32,16,16,64TAB_L2:DB32,32,16,16,16,16,32,32,32,32,16,16,16,16,32,32,32;小步舞曲DB32,16,16,16,16,32,16,16,16,16,32,16,16,16,16,32,64,32DB32,16,16,16,16,32,32,32,32,16,16,16,16,32,32,32TAB_L3:DB32,16,16,32,16,16,32,16,16,16,16,16,16,32;小蜜蜂DB16,16,32,16,16,32,16,16,16,16,64DB16,16,16,16,16,16,32,16,16,16,16,16,16,32DB16,16,32,16,16,32,16,16,16,16,32TAB_L4:DB32,16,16,32,32,32,64,16,16,32,32,32,64;生日快乐DB16,16,32,32,32,32,64,16,16,32,32,32,64TAB_L5:DB32,32,16,16,64,32,32,64,32,16,16,32,16,16,96+32;送别DB32,16,16,48,16,32,32,64,32,16,16,48,16,128DB32,32,64,32,16,16,64,16,16,16,16,16,16,16,16,96+32DB32,16,16,48,16,32,32,64,32,16,16,48,16,96,32TAB_L6:DB32,32,32,64,32,32,64,32,32,32,32,32,16,16,64;樱花DB32,32,32,32,32,16,16,64,32,32,32,32,32,16,16,64DB32,32,32,32,32,16,16,64,32,32,64,32,32,64,DB32,32,16,16,32,96TAB_L7:DB32,32,16,16,32,16,16,16,32,16,64,32,16,16,32,16,16,16,32,16,64;虹彩妹妹DB32,16,16,16,16,16,16,16,32,16,64,32,16,16,32,32,16,32,16,48TAB_L8:DB32,16,16,48,16,16,16,16,32,16,16,16,32,16,16,16,16,16,16,128+32;童年DB16,16,32,16,16,16,16,16,32,16,16,16,32,16,16,16,16,16,16,128DB16,16,16,32,16,16,16,32,16,16,16,16,16,16,32,16,16,16,16,16,16,128DB16,32,16,32,32,16,32,16,16,16,16,16,16,32,16,16,16,16,16,128TAB_L9:DB32,00HTAB_L10:DB32,00H;---------------播放音符表(0表示休止,1FH为结束标志)----------------;从6开始,6——低6,7——低7,8——1,9——2,10——3,11——4,12——5,13——6,14——7,15——高1 ;16——高2,17——高3,18——高4,19——高5,20——高6TAB_TONE0:DB0,10+7,10+7,10+7,10+7,10+7,10+7,10+7,12+7,8+7,9+7,10+7;《DINGO BELL》DB11+7,11+7,11+7,11+7,10+7,10+7,10+7,9+7,9+7,10+7,9+7DB10+7,10+7,10+7,10+7,10+7,10+7,10+7,12+7,8+7,9+7,10+7DB11+7,11+7,11+7,11+7,10+7,10+7,12+7,12+7,11+7,9+7,8+7DB1FHTAB_TONE1:DB0,17,17,18,19,19,18,17,16,15,15,16,17,17,16,16;欢乐颂DB17,17,18,19,19,18,17,16,15,15,16,17,16,15,15DB16,16,17,15,16,17,18,17,15,16,17,18,17,16,15,16,12,17DB17,18,19,19,18,17,16,15,15,16,17,16,12,15,15DB1FHTAB_TONE2:DB0,19,15,16,17,18,19,15,15,20,18,19,20,21,22,15,15;小步舞曲DB19,15,16,17,18,19,15,15,20,18,19,20,21,22,15,15DB18,19,18,17,16,17,18,17,16,15,16,17,16,15,14,15DB1FHTAB_TONE3:DB0,19,17,17,18,16,16,15,16,17,18,19,19,19;小蜜蜂DB19,17,17,18,16,16,15,16,17,19,17DB16,16,16,16,16,17,18,17,17,17,17,17,18,19DB19,17,17,18,16,16,15,16,17,19,15DB1FHTAB_TONE4:DB0,12,12,13,12,15,14,12,12,13,12,16,15;生日快乐DB12,12,19,17,15,14,13,18,18,17,15,16,15DB1FHTAB_TONE5:DB0,19,17,19,22,20,22,19,19,15,16,17,16,15,16;送别DB19,17,19,22,21,20,22,19,19,16,17,18,14,15DB20,22,22,21,20,21,22,20,21,22,20,20,19,17,15,16DB19,17,19,22,21,20,22,19,19,16,17,18,14,15DB1FH;从6开始,6——低6,7——低7,8——1,9——2,10——3,11——4,12——5,13——6,14——7,15——高1 ;16——高2,17——高3,18——高4,19——高5,20——高6TAB_TONE6:DB0,20,20,21,20,20,21,20,21,22,21,20,21,20,18;樱花DB17,15,17,18,17,17,15,14,20,21,22,21,20,21,20,18DB17,15,17,18,17,17,15,14,20,20,21,20,20,21DB17,18,21,20,18,17DB1FHTAB_TONE7:DB0,20,19,17,20,19,17,20,20,19,20,20,19,17,20,19,17,16,16,15,16;虹彩妹妹DB17,17,19,20,22,20,19,17,17,19,15,17,17,17,17,17,13,13,12,13DB1FHTAB_TONE8:DB0,10,12,12,10,13,13,14,13,13,13,12,15,15,15,15,13,15,13,12DB10,12,12,12,10,13,13,14,13,13,13,12,15,15,15,15,13,13,15,16DB19,19,19,19,19,17,16,15,15,15,13,15,13,15,16,16,16,16,15,17,16,16DB17,17,17,17,16,15,15,15,16,15,13,12,12,12,12,13,12,16,17,15DB1FHTAB_TONE9:DB0,00HDB1FHTAB_TONE10:DB0,00HDB1FH;-------(实际音高表,每个音高包括两个延时值)-----------------;第一个音符为6,7。
音乐演奏1 总体要求与分析1.1设计要求本文主要编写一段音乐程序,该程序可以进行如下操作:按大写字母“A”,奏一首歌曲;按大写字母“B”;奏另一首歌曲,曲目自选,可重复操作。
按Q 退出程序。
1.2设计思路分析在IBM-PC/XT机中都带有8253-5定时/计数器,IBM-PC/AT中带有8254定时/计数器,这两种芯片功能十分类似。
本文通过对8253-5定时/计数器芯片的操作实现音乐演奏。
该声音接口通过汇编语言对8253-5的端口直接进行操作,可以不必要过多的使用BIOS的调用和DOS的调用。
计数器芯片有3个通道,各自具有专用功能。
通道0时系统的始终节拍计时器,通道1专用于产生动态RAM的定时刷新信号,通道2用来控制计算机的扬声器的声音频率。
该音乐演奏主要用到通道2的功能,使通道2工作在“方波发生器”方式,产生相应频率的音调送至喇叭驱动电路,使喇叭发出不同音调的声音。
使用8255A的PB0控制通道2的计数,PB1控制通道2的输出对扬声器产生控制的时间。
人机交互包括屏幕显示提示语以及人工输入相应参数,主要应用到BIOS的10H号中断调用以及DOS的21H号中断调用。
BIOS的10H号中断调用用于显示器驱动,设置显示模式和光标位置;DOS的21H号中断调用用于单字符输入以及多字符输出显示。
音乐演奏实现的一个主要步骤是乐谱编程。
通过相应的频率表将乐谱中对应的音符转化为计数器的计数初值,节奏通过延时程序转化为对喇叭发音时间的控制,从而实现音符和节拍的数字化。
2 方案设计音乐的实现主要是对乐谱中的单音符按照一定的音符频率表转化为计数器的计数频率以及喇叭发声的控制时间,通过计数产生相应的控制动作。
由此可以有两种方案比较和选择。
2.1 方案一通过编程使用软件来实现计数和喇叭发声的时间设置,控制8255A并行I/O 接口驱动喇叭发声。
CPU每执行一条指令需要耗费一定的时间,这样可以通过循环的方式设置好循环次数,实现软件计数,然后输出相应的高低电平,驱动喇叭发出对应频率和节拍的声音。
ORG 0000HAJMP LOOOOP //绝对转移指令。
ORG 000BHAJMP TIM0ORG 001BHRETI //中断返回指令ORG 0023HLOOOOP: MOV A,#01HLOOOP: MOV P1,#3FHMOV P2,ARL A //A左移MOV R2,#0FFHDELAY0: MOV R3,#0FFHDJNZ R3,$ //$在某些51的汇编语言里表示本条指令的地址DJNZ R3,$ 意思是 R3减一,不为零跳转到本条指令(为零执行下一条指令)MOV R4,#0FFHDJNZ R4,$DJNZ R2,DELAY0JNB P3.3,START //直接寻址位不为1转LJMP LOOOP //长调用指令START: MOV P1,#06HMOV R5,#00H /初始化MOV TMOD,#00010001BMOV IE,#10101010BMOV DPTR,#TAB2 //装第一首歌MOV 30H,DPL //DPTR低8位送30H暂存MOV 31H,DPH //DPTR高8位送31H暂存START1: INC R4 寄存器内容加1//产生8位随机数 MOV A,#01010101BMOV B,R4MUL ABMOV P2,AMOV DPL,30HMOV DPH,31HMOV A,#00HMOVC A,@A+DPTR //查表MOV R0,A //音符数据送R0暂存MOV A,#00HINC DPTR //DPTR的内容加1MOVC A,@A+DPTR //查表MOV R1,A //节拍数据送R1暂存INC DPTRMOV 30H,DPLMOV 31H,DPHCJNE A,#01H,ELECT//立即数与A相比不相等则转移/一首歌没结束转ELECTINC R5LJMP KEYWORK //结束歌曲计数器加1ELECT: JZ START //所有歌曲结束转START循环(累加器内容为0转移)MOV A,R0JNZ SING (累加器内容不为0转移)CLR TR0 //累加器内容清0SETB P3.7 //置位直接位LOOP1: ACALL DELAY //绝对调用(调用延时子程序)DJNZ R1,LOOP1SJMP START1 //相对转移SING: MOV DPTR,#TAB1 //音符表首地址送DPTRDEC R0 //R0内容减1(计算音符)MOV A,R0MOV B,#02HMUL AB //A乘以BMOV R0,AMOVC A,@A+DPTRMOV 21H,AINC DPTR //数据之指针加1MOV A,R0MOVC A,@A+DPTRMOV 20H,AMOV TL0,20HMOV TH0,21HSETB TR0 开T0定时器LOOP2: ACALL DELAYDJNZ R1,LOOP2AJMP START1TIM0: MOV TL0,20HMOV TH0,21HCPL P3.7RETI 中断返回DELAY: MOV R2,#70DELAY1: MOV R3,#252DJNZ R3,$JNB P3.3,AGAIN 重复正播放的曲子JNB P3.4,FORM //上一曲开关按下转FORM JNB P3.5,NEXT //下一曲开关按下转NEXT DJNZ R2,DELAY1RETAGAIN: JNB P3.3,$ 等待键释放LJMP KEYWORKFORM: CLR EA 关中断JNB P3.4,$ 等待键释放CJNE R5,#00H,ZERO 不是第一首歌曲转ZER0MOV R5,#04H//是第一首将最后一首歌曲装入歌曲计数器 SJMP KEYWORKZERO: DEC R5 歌曲向上进一首SJMP KEYWORKNEXT: CLR EAJNB P3.5,$CJNE R5,#04H,LASTMOV R5,#00HLJMP KEYWORKLAST: INC R5 歌曲下翻一首LJMP KEYWORKKEYWORK: MOV DPTR,#TAB//将歌曲排列表装入DPTRMOV A,R5//将R5的内容送ARL A //A左移SETB EA //开中断JMP @A+DPTR // 根据A的内容转向不同歌曲TAB: AJMP MUSIC2AJMP MUSIC3AJMP MUSIC4AJMP MUSIC5MUSIC2: MOV DPTR,#TAB2 //第二首歌曲送DPTRMOV P1,#06HGONG: MOV 30H,DPLMOV 31H,DPHAJMP START1MUSIC3: MOV DPTR,#TAB3MOV P1,#5BHSJMP GONGMUSIC4: MOV DPTR,#TAB4MOV P1,#4FHSJMP GONGMUSIC5: MOV DPTR,#TAB5MOV P1,#66HSJMP GONG********************(音符表)**********************; TAB1:DW 64021,64185,64331,64400,64524,64632,64732DW 64777,64860,64934,64968,65030,65085,65134DW 65157,65198,65235,65252,65283,65310,65335 ;**********************(因为爱情)*************************;TAB2:DW 0910H,0A08H,0C08H,0C08H,0A18H,0010H,0C08H,0A08HDW 0908H,0C08H,0C20H,0D08H,0E08H,0F08H,0F08H,0F08HDW 0E08H,0F18H,0E04H,0E08H,0E08H,0C08H,0A08H,0A20HDW 0C08H,0A08H,0C08H,0D08H,0D18H,0C08H,0D08H,0C08HDW 0C08H,0808H,0820H,0608H,0808H,0A08H,0908H,0608HDW 0A08H,0908H,0608H,0A08H,0908H,0608H,0D10H,0C20HDW 0001H ;*********************(兰花草)***********************;TAB3:DW 0608H,0A08H,0A08H,0A08H,0A18H,0908H,0808H,0908HDW 0808H,0708H,0620H,0D08H,0D08H,0D08H,0D08H,0D18HDW 0C08H,0A08H,0C08H,0C08H,0B08H,0A20H,0A08H,0D08HDW 0D08H,0C08H,0A18H,0908H,0808H,0908H,0808H,0708HDW 0610H,0310H,0308H,0808H,0808H,0708H,0618H,0A08HDW 0908H,0808H,0708H,0508H,0620H,0908H,0808H,0708HDW 0508H,0640H,0001H ;*********************(我只在乎你)*****************************;TAB4: DW 0A08H,0A08H,0A08H,0908H,0A10H,0C08H,0C08H,0C2 0HDW 0D08H,0D08H,0D08H,0C08H,0A10H,0D08H,0C08H,0C20HDW 0F08H,0F08H,0F08H,0D08H,1010H,0F08H,0C08H,0C20HDW 0D08H,0D08H,0D08H,0F08H,0D08H,0C10H,0A10H,0920HDW 0A08H,0A08H,0A08H,0908H,0A10H,0C08H,0C08H,0C20HDW 0D08H,0D08H,0D08H,0C08H,0A10H,0C08H,0C08H,0C20H DW 0F08H,0F10H,0D08H,1010H,1010H,0F08H,0C08H,0C20H DW 1010H,0C10H,0F10H,1010H,1110H,1010H,0F10H,0E10HDW 0F10H,0E10H,0D10H,0C10H,0D40H,0020H,0004H,0F08HDW 1008H,1110H,1010H,0F10H,0E10H,0F10H,0E10H,0A10HDW 0C10H,0D20H,0008H,0D08H,0C08H,0D10H,0F10H,0F20HDW 0010H,0F20H,1010H,1110H,0F10H,1010H,0F10H,0D08HDW 0D08H,1210H,1110H,1010H,0F08H,1208H,1210H,1110HDW 1010H,0F10H,1030H,1110H,1008H,0F08H,0F20H,0F10HDW 1010H,1120H,0F10H,1410H,1310H,1108H,1008H,0F10HDW 0D30H,0010H,0C10H,0F10H,1110H,1310H,1408H,1108HDW 1008H,0F10H,0D10H,0F10H,0F08H,1010HF08H,0F40HDW 0001H*********************(童年)****************************;TAB5:DW 0A08H,0C08H,0C10H,0C08H,0A08H,0D08H,0D08H,0E08HDW 0D08H,0D08H,0D08H,0D08H,0C08H,0F10H,0F08H,0F08H DW 0F08H,0D08H,0F08H,0D08H,0C40H,0A08H,0C08H,0C10HDW 0C08H,0A08H,0D08H,0D08H,0E08H,0D08H,0D08H,0D08H DW 0D08H,0C08H,0F10H,0F08H,0F08H,0F08H,0D08H,0D08H DW 0F08H,1040H,1308H,1308H,1310H,1310H,1108H,1008H DW 0F08H,0F10H,0D08H,0D08H,0F08H,0D08H,0F08H,1008H DW 1008H,1008H,1008H,1008H,0F08H,1108H,1008H,1040H DW 1108H,1110H,1108H,1108H,1008H,1010H,0F08H,0F10H DW 0F08H,1008H,0F08H,0D08H,0C08H,0C08H,0C10H,0C08HDW 0D08H,0C08H,1008H,1108H,0F40H,0001H,0000HEND。
基于汇编的音乐弹奏程序夏超群【摘要】PC系列8253定时/计数器的2号计数器被初始化后,可产生扬声器发声的音调信号.文章分析了扬声器驱动电路的工作原理,通过程序控制能使扬声器发出不同频率的声音,进而设计出计算机键盘代替钢琴键弹奏音乐的程序.【期刊名称】《武汉工程职业技术学院学报》【年(卷),期】2011(023)003【总页数】3页(P58-60)【关键词】定时/计数器;频率;扬声器【作者】夏超群【作者单位】武汉工程职业技术学院湖北武汉 430080【正文语种】中文【中图分类】TP332.1+20 引言计算机系统中,由可编程定时/计数器集成芯片,可以为处理器和外设提供时间标记,也可以对外部事件进行计数。
而计数和定时两个概念如果联系起来,很容易让人联想到频率,由频率的振动可以产生声音,频率的高低,决定声音音调的高低。
在考虑发声频率高低时,如果还考虑发声时间的长短,或将二者灵活结合,便会产生不同节拍、不同音调的声音,若声音按乐谱输出即为音乐。
下面从PC系统发声原理及实现方法上,说明如何使用PC键盘八个数字键,代替钢琴键弹奏音乐的程序设计。
1 PC系统的发声原理1.1 定时/计数器8253定时/计数器8253有3个内置的计数器,3个计数器的数据端口地址分别是40H、41H、42H,命令端口地址43H。
3个计数器硬件结构基本相同,每个计数器内有一个16位存放初始值的寄存器;一个16位的输出锁存器,在写入锁存命令时,锁定计数器的当前值;一个16位可对初始值进行减1的减法计数器,其内的值不断递减,减到0时,从端口OUT输出一个脉冲信号。
定时/计数器8253的0号计数器作为日时钟计时,它每秒约发出18次中断以修正时间;1号计数器采用DMA传送数据;2号计数器控制扬声器发声,它其实是一个振荡电路,此振荡电路向扬声器发送用户设定频率的脉冲,当扬声器驱动电路的输出端口控制扬声器为接通状态时,就让OUT2信号通过,经滤波和功放电路,使扬声器发出指定频率的声音[3]。
51单片机汇编语言教程:第28课-音乐程序设计下面给出程序序清单,可直接在TD-III型学习机上演奏,对其它不一样型号的学习机,只需对应地改变一下地址即可。
本程序演奏的是民歌“八月桂花遍地开”,C调,节奏为94拍/分。
读者也能自行找出一首歌,按表1和表2给定的常数,将乐曲翻译成码表输入机器,而程序不变。
本实验办法简便,即使不懂音乐的人,将一首陌生的曲子翻译成代码也是易事,和着机器的演奏学唱一首歌曲,其趣味无穷。
程序清单(略,请参看源程序的说明)。
程序框图如图2所示。
<单片机音乐程序的设计图>本课由单片机教程网提供,有问题指出.硬件连接说明:随便找一个仿真机或者什么单片机实验板,只要能工作的就行,将程序输入,运行,然后找个音箱(你计算机旁边应当就有一对吧)拨出插头,插头的前端接在P1。
0上,后面部分找根线接单片机的地,就应当有声了,然后怎么改进硬件连接就是你的事了。
音乐程序汇编代码代码1-------------Voice.asm--------------------------ORG0000HLJMP STARTORG000BHINC20H;中断服务,中断计数器加1MOV TH0,#0D8HMOV TL0,#0EFH;12M晶振,形成10毫秒中断RETISTART:MOV SP,#50HMOV TH0,#0D8HMOV TL0,#0EFHMOV TMOD,#01HMOV IE,#82HMUSIC0:NOPMOV DPTR,#DAT;表头地址送DPTRMOV20H,#00H;中断计数器清0MOV B,#00H;表序号清0MUSIC1:NOPCLR AMOVC A,@A+DPTR;查表取代码JZ END0;是00H,则结束CJNE A,#0FFH,MUSIC5LJMP MUSIC3MUSIC5:NOPMOV R6,AINC DPTRMOV A,BMOVC A,@A+DPTR;取节拍代码送R7MOV R7,ASETB TR0;启动计数MUSIC2:NOPCPL P1.0MOV A,R6MOV R3,ALCALL DELMOV A,R7CJNE A,20H,MUSIC2;中断计数器(20H)=R7否?;不等,则继续循环MOV20H,#00H;等于,则取下一代码INC DPTR;INC BLJMP MUSIC1MUSIC3:NOPCLR TR0;休止100毫秒MOV R2,#0DHMUSIC4:NOPMOV R3,#0FFHLCALL DELDJNZ R2,MUSIC4INC DPTRLJMP MUSIC1END0:NOPMOV R2,#64H;歌曲结束,延时1秒后继续MUSIC6:MOV R3,#00HLCALL DELDJNZ R2,MUSIC6LJMP MUSIC0DEL:NOPDEL3:MOV R4,#02HDEL4:NOPDJNZ R4,DEL4NOPDJNZ R3,DEL3RETNOPDAT:db26h,20h,20h,20h,20h,20h,26h,10h,20h,10h,20h,80h,26h,20h,30h,20h db30h,20h,39h,10h,30h,10h,30h,80h,26h,20h,20h,20h,20h,20h,1ch,20h db20h,80h,2bh,20h,26h,20h,20h,20h,2bh,10h,26h,10h,2bh,80h,26h,20h db30h,20h,30h,20h,39h,10h,26h,10h,26h,60h,40h,10h,39h,10h,26h,20h db30h,20h,30h,20h,39h,10h,26h,10h,26h,80h,26h,20h,2bh,10h,2bh,10h db2bh,20h,30h,10h,39h,10h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,20h db20h,10h,20h,10h,2bh,10h,26h,30h,30h,80h,18h,20h,18h,20h,26h,20h db20h,20h,20h,40h,26h,20h,2bh,20h,30h,20h,30h,20h,1ch,20h,20h,20h db20h,80h,1ch,20h,1ch,20h,1ch,20h,30h,20h,30h,60h,39h,10h,30h,10h db20h,20h,2bh,10h,26h,10h,2bh,10h,26h,10h,26h,10h,2bh,10h,2bh,80h db18h,20h,18h,20h,26h,20h,20h,20h,20h,60h,26h,10h,2bh,20h,30h,20h db30h,20h,1ch,20h,20h,20h,20h,80h,26h,20h,30h,10h,30h,10h,30h,20h db39h,20h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,10h,40h,10h,20h,10h db20h,10h,2bh,10h,26h,30h,30h,80h,00HEND音乐程序汇编代码代码2-------------Voice1.asm--------------------------;标题'八月桂花香'发声程序;摘要详见'无线电'92年3期;作者周振安ORG0000HLJMP STARTORG000BHINC20H;中断服务,中断计数器加1MOV TH0,#0D8HMOV TL0,#0EFH;12M晶振,形成10毫秒中断RETISTART:MOV SP,#50HMOV TH0,#0D8HMOV TL0,#0EFHMOV TMOD,#01HMOV IE,#82HMUSIC0:NOPMOV DPTR,#DAT;表头地址送DPTRMOV20H,#00H;中断计数器清0MOV B,#00H;表序号清0MUSIC1:NOPCLR AMOVC A,@A+DPTR;查表取代码JZ END0;是00H,则结束CJNE A,#0FFH,MUSIC5LJMP MUSIC3MUSIC5:NOPMOV R6,AINC DPTRMOV A,BMOVC A,@A+DPTR;取节拍代码送R7MOV R7,ASETB TR0;启动计数MUSIC2:NOPCPL P1.0MOV A,R6MOV R3,ALCALL DELMOV A,R7CJNE A,20H,MUSIC2;中断计数器(20H)=R7否?;不等,则继续循环MOV20H,#00H;等于,则取下一代码INC DPTR;INC BLJMP MUSIC1MUSIC3:NOPCLR TR0;休止100毫秒MOV R2,#0DHMUSIC4:NOPMOV R3,#0FFHLCALL DELDJNZ R2,MUSIC4INC DPTRLJMP MUSIC1END0:NOPMOV R2,#64H;歌曲结束,延时1秒后继续MUSIC6:MOV R3,#00HLCALL DELDJNZ R2,MUSIC6LJMP MUSIC0DEL:NOPDEL3:MOV R4,#02HDEL4:NOPDJNZ R4,DEL4NOPDJNZ R3,DEL3RETNOPDAT:DB18H,30H,1CH,10HDB20H,40H,1CH,10HDB18H,10H,20H,10HDB1CH,10H,18H,40HDB1CH,20H,20H,20HDB1CH,20H,18H,20HDB20H,80H,0FFH,20HDB30H,1CH,10H,18HDB20H,20H,20H,26H DB40H,20H,20H,2BH DB20H,26H,20H,20H DB20H,30H,80H,0FFH DB20H,20H,1CH,10H DB18H,10H,20H,20H DB26H,20H,2BH,20H DB30H,20H,2BH,40H DB20H,20H,1CH,10H DB18H,10H,20H,20H DB26H,20H,2BH,20H DB30H,20H,2BH,40H DB20H,30H,1CH,10H DB18H,20H,15H,20H DB1CH,20H,20H,20H DB26H,40H,20H,20H DB2BH,20H,26H,20H DB20H,20H,30H,80H DB20H,30H,1CH,10H DB20H,10H,1CH,10H DB20H,20H,26H,20H DB2BH,20H,30H,20H DB2BH,40H,20H,15H DB1FH,05H,20H,10H DB1CH,10H,20H,20H DB26H,20H,2BH,20H DB30H,20H,2BH,40H DB20H,30H,1CH,10H DB18H,20H,15H,20HDB26H,40H,20H,20HDB2BH,20H,26H,20HDB20H,20H,30H,30HDB20H,30H,1CH,10HDB18H,40H,1CH,20HDB20H,20H,26H,40HDB13H,60H,18H,20HDB15H,40H,13H,40HDB18H,80H,00Hend51实验板推荐(点击下面的图片可以进入下载资料链接)HJ-1G HJ-3G。
课 程 设 计题 目 音乐演奏程序 学 院 自动化学院 专 业 电气工程及其自动化班 级 姓 名 指导教师课程设计任务书年月日学生姓名:专业班级:指导教师:工作单位:自动化学院题目:音乐演奏程序设计要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.使用汇编语言设计一个在计算机上运行的音乐演奏程序;2.屏幕显示钢琴图像;3.按大写字母“A”,唱乐曲1;按大写字母“B”,唱乐曲2;按大写字母“C”,唱乐曲3,依次类推;4.按"X"鍵,退出5.撰写课程设计说明书。
内容包括:摘要、目录、正文、参考文献、附录(程序清单)。
正文部分包括:设计任务及要求、方案比较及论证、软件设计说明(软件思想,流程,源程序设计及说明等)、程序调试说明和结果分析、课程设计收获及心得体会。
时间安排:12月26日-----12月28日查阅资料及方案设计12月29日-----1月2日编程1月3日-----1月7日调试程序1月8日-----1月9日撰写课程设计报告指导教师签名:年月日系主任(或责任教师)签名:年月日目录摘要 (1)1.音乐演奏的基本原理 (2)2.设计原理及思想 (2)2.1设计内容 (2)2.2 主要的宏和过程的实现 (2)2.2.1 DISPLAY显示宏................................. 错误!未定义书签。
2.2.2 音乐地址宏 .................................... 错误!未定义书签。
2.2.3 MUSIC宏....................................... 错误!未定义书签。
2.2.4 通用发声程序GENSOUND (4)2.2.5 WAITF延时程序 (6)2.2.6 CLEAR清屏程序 (6)2.2.7钢琴界面画图程序 (7)2.3主程序 (8)2.3.1 数据段定义 (8)2.3.2 堆栈段定义 (9)2.3.3 初始化 (9)2.3.4 程序的调试运行 (10)3软件设计 (11)3.1主程序流程图 (12)3.2子程序流程图 (13)4收获与心得体会 (13)参考资料 (15)附录 (16)摘要随着科技的高速发展,计算机已经过了好几代的更新,然而计算机的运行的基本原理没有改变。
一.背景分析及意义随着计算机的不断更新发展,计算机在各个领域的应用越来越多,更多的软件开发人员和相关技术人员在程序设计的过程中应用汇编程序或编制汇编语言。
而汇编语言做为计算机专业大学生必修之课,每个做为本专业的学生对汇编的理解和学习就显的尤为重要。
汇编语言是计算机能够提供给用户使用的最快而又最好最有效的语言,也是能够利用计算机所有硬件特性并能直接控制硬件的唯一语言。
因而,对程序的空间和时间要求很高的场合,汇编语言的应用就显的必不可少了,一些直接控制硬件的应用场合,则更是非用汇编语言不可了。
这次课程设计是在学习汇编语言与实践相结合的一次综合应用。
通过具体的问题分析、设计、调试、运行程序。
在实际问题中锻炼提高自己,增加了对本门课程内容的理解,锻炼了动手能力。
就这个程序具体而言:知道了音调与频率和时间的关系,就可以按照乐曲的曲谱将每个音符的频率和持续时间定义成两个数据表;然后编写程序依次取出表中的频率值和时间值,调用GENSOUNDF程序发出各种声音。
这个程序最终通过菜单所提示的信息选取所要欣赏的音乐,是执行此程序后,会很有速且有效的使扬声器接通并发出音频为896 Hz的声音。
二.总体设计思想ROM BIOS 中的BEEP子程序能根据BL中给出的时间计数植控制8254定时器,产生持续时间计数值控制8254定时器,产生持续时间为1个或几个0.5 秒,频率为896Hz的声音。
通过对BEEP的修改,可产生任一频率的声音。
用汇编语言写的GENSOUNG,能使Pc 机发出指定频率和指定延时的声音。
它是一个很好的通用发声程序。
组成乐曲的每个音符的频率值和持续时间定义成两个数据表,然后编程依次取出表中的频率值和时间值,调用GENSOUND程序发出各种声音。
本程序就是通过GENSOUNG程序演奏乐曲的例子。
该乐曲点播程序由一个乐曲点播主程序和五个子程序组成。
(1)歌曲设置程序;(2)打开另一个显示窗口程序;(3)接收键盘输入程序;(4)返回程序;(5)发声程序。
01 两只老虎NEXT BIT 10H ;定义标志位ORG 0000HJMP MAINORG 000BHJMP TONEORG 001BHJMP BEATORG 0100HMAIN: MOV TMOD,#11HMOV TH0,R2MOV TL0,R3MOV TH1,#3CHMOV TL1,#0B0HMOV R4,#00HMOV DPTR,#TABYD: MOV A,R4 ;取音调数据MOVC A,@A+DPTRMOV R2,AXRL A,#00HJNZ JP ;直接取节拍INC R4CALL PD ;判断指针是否溢出MOV A,R4MOVC A,@A+DPTRMOV R3,AXRL A,#0FFHJZ JPMOV A,R2XRL A,#0FFHJNZ MAINJP: INC R4 ;取节拍数据CALL PDMOV A,R4MOVC A,@A+DPTRMOV R5,ASETB EASETB ET0SETB ET1SETB TR0SETB TR1SETB NEXTJBNEXT,$ INCR4 CALLPDJMP YDPD: MOV A,R4CJNE A,#00H,L1INC DPHL1: RET;音调产生子程序TONE: CPL P2.0MOV TH0,R2MOV TL0,R3RETI;节拍产生子程序BEAT: DJNZ R5,L2MOV TH1,#3CHMOV TL1,#0B0HL3: RETIL2: CLR TR0CLR TR1CLR NEXTJMP L3;两只老虎音符表TAB: DB0FBH,0F9H,08H,0FCH,066H,08H,0FCH,0C7H,08H,0FBH,0F9H,08H DB0FBH,0F9H,08H,0FCH,066H,08H,0FCH,0C7H,08H,0FBH,0F9H,08HDB0FCH,0C7H,08H,0FCH,0F3H,08H,0FDH,4AH,10H,0FCH,0C7H,08H DB0FCH,0F3H,08H,0FDH,4AH,08H,0FDH,4AH,04H,0FDH,95H,04H DB0FDH,4AH,04H,0FCH,0F3H,04H,0FCH,0C7H,08H,0FBH,0F9H,08H DB0FDH,4AH,04H,0FDH,95H,04H,0FDH,4AH,04H,0FCH,0F3H,04H DB0FCH,0C7H,08H,0FBH,0F9H,08H,0FCH,66H,08H,0FAH,93H,08H DB 0FBH,0F9H,08H,00H,08H,0FCH,66H,04H,0FAH,93H,08HDB 0FBH,0F9H,08H,00H,10H,0FFH,0FFHEND02 祝你平安ORG 0000HLJMP STARTORG 000BHINC 20H ;中断服务,中断计数器加 1MOV TH0,#0D8HTL0,#0EFH ;12M 晶振,形成10 毫秒中断MOVRETISTART:MOV SP,#50HMOV TH0,#0D8HMOV TL0,#0EFHMOV TMOD,#01HMOV IE,#82HMUSIC0:NOPMOV DPTR,#DAT ;表头地址送DPTRMOV 20H,#00H ;中断计数器清0MOV B,#00H ;表序号清0MUSIC1:NOPCLR AMOVC A,@A+DPTR ; 查表取代码JZ END0 ;是00H,则结束CJNE A,#0FFH,MUSIC5LJMP MUSIC3MUSIC5:NOPMOV R6,AINC DPTRMOV A,BMOVC A,@A+DPTR ; 取节拍代码送R7MOV R7,ASETB TR0 ;启动计数MUSIC2:NOPCPL P3.3MOV A,R6MOV R3,ALCALL DELMOV A,R7CJNE A,20H,MUSIC2 ;中断计数器(20H)=R7 否?;不等,则继续循环MOV 20H,#00H ;等于,则取下一代码INC DPTR; INC BLJMP MUSIC1MUSIC3:NOPCLR TR0 ; 休止100 毫秒MOV R2,#0DHMUSIC4:NOPMOV R3,#0FFHLCALL DELDJNZ R2,MUSIC4INC DPTRLJMP MUSIC1END0:NOPMOV R2,#64H ;歌曲结束,延时1 秒后继续MUSIC6:MOV R3,#00HLCALL DELDJNZ R2,MUSIC6LJMP MUSIC0DEL:NOPDEL3:MOV R4,#02HDEL4:NOPDJNZ R4,DEL4NOPDJNZ R3,DEL3RETNOPDAT:db26h,20h,20h,20h,20h,20h,26h,10h,20h,10h,20h,80h,26h,20h,30h,20h db30h,20h,39h,10h,30h,10h,30h,80h,26h,20h,20h,20h,20h,20h,1ch,20h db20h,80h,2bh,20h,26h,20h,20h,20h,2bh,10h,26h,10h,2bh,80h,26h,20h db30h,20h,30h,20h,39h,10h,26h,10h,26h,60h,40h,10h,39h,10h,26h,20h db30h,20h,30h,20h,39h,10h,26h,10h,26h,80h,26h,20h,2bh,10h,2bh,10h db2bh,20h,30h,10h,39h,10h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,20h db20h,10h,20h,10h,2bh,10h,26h,30h,30h,80h,18h,20h,18h,20h,26h,20h db20h,20h,20h,40h,26h,20h,2bh,20h,30h,20h,30h,20h,1ch,20h,20h,20hdb20h,80h,1ch,20h,1ch,20h,1ch,20h,30h,20h,30h,60h,39h,10h,30h,10h db20h,20h,2bh,10h,26h,10h,2bh,10h,26h,10h,26h,10h,2bh,10h,2bh,80h db18h,20h,18h,20h,26h,20h,20h,20h,20h,60h,26h,10h,2bh,20h,30h,20h db30h,20h,1ch,20h,20h,20h,20h,80h,26h,20h,30h,10h,30h,10h,30h,20h db39h,20h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,10h,40h,10h,20h,10h db 20h,10h,2bh,10h,26h,30h,30h,80h,00HEND03 生日歌ORG 0000HJMP STARTORG 000BHJMP TIM0ORG 0030HSTART:MOV TMOD,#01HMOV IE,#82HSTART0:MOV 30H,#00HNEXT: MOV A,30HMOV DPTR,#TABLEMOVC A,@A+DPTRMOV R2,AJZ END0ANL A,#0FHMOV R5,AMOV A,R2SWAP AANL A,#0FHJNZ SINGCLR TR0JMP D1SING: DEC AMOV 22H,ARL AMOV DPTR,#TABLE1MOVC A,@A+DPTRMOV TH0,AMOV 21H,AMOV A,22HRL AINC AMOVC A,@A+DPTRMOV TL0,AMOV 20H,ASETB TR0D1: CALL DELAYINC 30HJMP N EXTEND0: CLR TR0JMP START0 TIM0: PUSH ACCPUSH PSWMOV TH0,21HMOV TL0,20HCPL P3.7POP PSWPOP ACCRETIDELAY: MOV R7,#02D2: MOV R4,#187D3: MOV R3,#248DJNZR3,$ DJNZR4,D3 DJNZR7,D2 DJNZR5,DELAY RETTABLE1:DW 64260,64400,64524,64580DW 64684,64777,64820,64898DW 64968,65030,65058,65110DW 65157,65178,65217TABLE:DB 82H,01H,81H,94H,84HDB 0B4H,0A4H,04HDB 82H,01H,81H,94H,84HDB 0C4H,0B4H,04HDB 82H,01H,81H,0F4H,0D4HDB 0B4H,0A4H,94HDB 0E2H,01H,0E1H,0D4H,0B4HDB 0C4H,0B4H,04HDB 82H,01H,81H,94H,84HDB 0B4H,0A4H,04HDB 82H,01H,81H,94H,84HDB 0C4H,0B4H,04HDB 82H,01H,81H,0F4H,0D4HDB 0B4H,0A4H,94HDB 0E2H,01H,0E1H,0D4H,0B4HDB 0C4H,0B4H,04HDB 00HEND04 八月桂花香ORG 0000HLJMP STARTORG 000BHINC 20H ;中断服务,中断计数器加 1MOV TH0,#0D8HMOV TL0,#0EFH ;12M 晶振,形成10 毫秒中断RETISTART:MOV SP,#50HMOV TH0,#0D8HMOV TL0,#0EFHMOV TMOD,#01HMOV IE,#82HMUSIC0:MOV DPTR,#DAT ;表头地址送DPTRMOV 20H,#00H ;中断计数器清0MUSIC1:NOPCLR A ;A 清零MOVC A,@A+DPTR ; 查表取代码JZ END0 ;是00H,则结束CJNE A,#0FFH,MUSIC5 ;如果是休止符,往下执行LJMP MUSIC3MUSIC5:NOPMOV R6,A ;R6=18H 音符的频率INC DPTR ;DPTR 加一MOV A,#0MOVC A,@A+DPTR ; 取节拍代码送R7MOV R7,A ;R7=30H 音符发音的时间SETB TR0 ;启动计数MUSIC2:NOPCPL P2.3 ;P2.3 是音乐输出引脚MOV A,R6MOV R3,A ; 籖3=R6=18HLCALL DELMOV A,R7CJNE A,20H,MUSIC2 ;中断计数器(20H)=R7 否? ;不等,则继续循环MOV 20H,#00H ;等于,则取下一代码INC DPTRLJMP MUSIC1MUSIC3:NOP ;休止100 毫秒CLR TR0MOV R2,#0DH ;R2=13MUSIC4:MOV R3,#0FFH ;R3=255LCALL DELDJNZ R2,MUSIC4INC DPTRLJMP MUSIC1END0:NOPMOV R2,#0FFH ;歌曲结束,延时1 秒后继续MUSIC6:MOV R3,#00HLCALL DELDJNZ R2,MUSIC6LJMP MUSIC0DEL:NOPDEL3:MOV R4,#02HDEL4:NOPDJNZ R4,DEL4NOPDJNZ R3,DEL3RETNOPDAT:DB 18H, 30H, 1CH, 10HDB 20H, 40H, 1CH, 10HDB 18H, 10H, 20H, 10HDB 1CH, 10H, 18H, 40HDB 1CH, 20H, 20H, 20HDB 1CH, 20H, 18H, 20HDB 20H, 80H, 0FFH, 20HDB 30H, 1CH, 10H , 18HDB 20H, 15H, 20H , 1CHDB 20H, 20H, 20H , 26HDB 40H, 20H , 20H , 2BHDB 20H, 26H, 20H , 20H DB 20H, 30H , 80H , 0FFH DB 20H, 20H, 1CH , 10H DB 18H, 10H, 20H , 20H DB 26H, 20H , 2BH , 20H DB 30H, 20H , 2BH , 40H DB 20H, 20H , 1CH , 10H DB 18H, 10H, 20H, 20H DB 26H, 20H , 2BH, 20H DB 30H, 20H, 2BH , 40H DB 20H, 30H, 1CH , 10H DB 18H, 20H , 15H , 20H DB 1CH, 20H , 20H , 20H DB 26H, 40H, 20H , 20H DB 2BH, 20H, 26H , 20H DB 20H, 20H, 30H , 80H DB 20H, 30H, 1CH , 10H DB 20H, 10H, 1CH , 10H DB 20H, 20H, 26H , 20H DB 2BH, 20H, 30H , 20H DB 2BH, 40H, 20H , 15H DB 1FH, 05H, 20H , 10H DB 1CH, 10H, 20H , 20H DB 26H, 20H, 2BH , 20H DB 30H, 20H, 2BH , 40H DB 20H, 30H, 1CH , 10H DB 18H, 20H , 15H , 20H DB 1CH, 20H , 20H , 20H DB 26H, 40H, 20H , 20H DB 2BH, 20H, 26H , 20H DB 20H, 20H, 30H, 30H DB 20H, 30H, 1CH, 10H DB 18H, 40H, 1CH, 20H DB 20H, 20H, 26H, 40H DB 13H, 60H, 18H , 20H DB 15H, 40H, 13H , 40H DB 18H, 80H, 00Hend05 兰花草SPK EQU P3.3 ; 蜂鸣器所在端口ORG 0000HJMP STARTSTART:MOVR3,#00HNEXT:MOVA,R3MOVDPTR,#TABLEMOVC A,@A+DPTRJZ STARTMOVR7,AINC R3MOVA,R3MOVC A,@A+DPTRMOVR2,AACALL SONGINC R3SJMPNEXT;================================================== =============================;=== 歌曲播放子程序===SONG:MOVA,R2 ; 取出节拍RL AJNZ KEEPMOVA,#01HKEEP:MOVR2,AREPEAT:ACALL EIGHTHDJNZ R2,REPEATRET;===============================================================================;=== 产生1/8 拍延时子程序===EIGHTH:MOVA,R7 ; 查表取出廷时参数,保存到R4MOVDPTR,#DELAY_TMOVC A,@A+DPTRMOVR4,AMOVA,R7 ; 查表取出1/8 拍周期数,保存到R5MOVDPTR,#S_PARAMOVC A,@A+DPTRMOVR5,ANEXTCYC:ACALL SOUNDDJNZ R5,NEXTCYCRET;===============================================================================;=== 发声子程序===SOUND:SETB SPKACALL SDELAYCLR SPKACALL SDELAYRET;===============================================================================;=== 延时子程序===SDELAY:XL2: DL1: MOVA,R4 ; 廷时值在R4 内MOVR0,AMOVR1,#03HNOPDJNZ R1,DL1DJNZ R0,XL2RET;================================================== =============================;=== 1/8 拍周期表===S_PARA:DS 1DHDB 15H,16H,00DB 19H,00H,1CH,00H,1FH,21H,00H,25HDB 00H,29H,2CH,00H,31H,34H,37H,00HDB 3EH,41H,00H,49H,00H,52H,57H,00HDB 62H;================================================== =============================;=== 延时参数表===DELAY_T:DS 1DHDB 7EH,77H,00HDB 6AH,00H,5EH,00H,54H,4FH,00H,46HDB 00H,3FH,3BH,00H,35H,32H,2FH,00HDB 2AH,27H,00H,23H,00H,1FH,1DH,0C0HDB 1AH;================================================== =============================;=== 歌曲表===TABLE:DW 2202H,2902H,2902H,2902H,2906H,2702H ;我从山中来DW 2502H,2702H,2502H,2402H,2208H ;带着兰花草DW 2E02H,2E02H,2E02H,2E02H,2E06H,2C02H ;种在小园中DW 2902H,2C02H,2D02H,2A02H,2908H ;祈祷花开早DW 2902H,2E02H,2E02H,2C02H,2906H,2702H ;一日看三回DW 2502H,2702H,2502H,2402H,2206H,1D02H ;看得花时过DW 1D02H,2502H,2502H,2402H,2206H,2902H ;兰花却依然DW 2702H,2502H,2402H,2002H,2208H ;苞也无一个DW 0000H ;END。
第三节音乐播放程序1硬件编程 (2)1.1 硬件开发的通用思路 (2)1.2 8253的功能与作用 (2)1.3 8253工作原理 (3)1.4 8253编程方法 (4)2 音乐程序编写 (6)2.1 扬声器驱动原理 (6)2.2 音符频率的确定 (6)2.3 定时器8253编程 (7)2.4 并口8255A编程 (7)3 实验步骤 (10)4 Turboc2的安装与使用 (11)4.1 turboc2的安装 (11)4.2 集成环境介绍 (11)4.3 turboc2的配置 (13)4.4 基本编程操作 (14)1硬件编程1.1 硬件开发的通用思路在学习的过程中,往往体现一个人的学习能力,并不是一个人在某一方面具体知识和技能掌握的如何,而是他是否掌握了有效的学习方法,是否能够建立起一个夯实的知识框架。
在本次实验中,通过大家学习本次实验,完成实验任务只是一个浅层次的目的,更重要的目的,也是通过实验,让大家亲身体验下硬件编程,掌握硬件编程的方法。
其实不光是在硬件开发上,对于其他的任何事物和问题,解决问题的方法也是一样的。
以下我们以8253定时器的开发,来简要介绍下我们的学习思路和方法,也可作为本小节内容组织的一个缩影。
图1.11.2 8253的功能与作用8253是可编程的定时器与计数器。
为外设与CPU 之间或外设与外设之间配合工作时,提供有效的时间配合条件。
8253有三个独立的16位计数器。
每个计数器均可按二进制或者BCD 码计数。
各个计数器有6种不同的工作方式。
是什么?为什么?怎么做? 8253的功能和作用8253的工作原理如何编程控制82531.3 8253工作原理1.3.1 8253内部结构图1.2 8253内部结构框图8253内部有六个模块,结构框图如图1.2所示。
1.3.2 8253计数原理计数器的输入为CLK 时钟信号,为计数器工作提供计数的基准参考。
在8253工作时,每输入一个时钟信号CLK ,便使定时或计数值减1。
2.2通用发声程序设计原理PC机发声系统以8254的2号计数器为核心。
系统初始化时,2号计数器I作在“方波发生器”方式,初值为二进制数,,写入顺序为先低后高,CLK2为1.193182MHz,当计数初值为533H时,OUT2输出的方波大约为900Hz,经过简单的滤波之后,送至扬声器。
改变1.4号计数器的计数初值就可以使扬声器发出不同频率的音响。
ROM BIOS 中有个BEEP子程序,这能根据BL中组出的时间计数值控制8254定时器,产生持续时间为1个或几个0.5秒,频率为896HZ的声音,我们可以利用并修改BEEP,使其产生任一频率的声音。
为此我们需要做两点修改,首先,BEEP程序只能产生896HZ的声音,我们的通用发声程序应能产生任一频率的声音。
其次,BEEP 产生声音的持续时间(音长)只能是0.5秒的倍数,我们希望声音的持续时间更易于调整,例如可以是10ms的倍数。
我们知道BEEP能将计数值533H送给定时器2产生896HZ的声音的,那么产生其它频率声音的时间计数值应为:533H×896÷给定频率=123280H÷给定频率发声程序包括3个步骤:(1)在8253中的42端口送一个控制字0B6H(10110110B),该控制字对定时器2进行初始化,使定时器2准备接收计数初值。
(2)在8253中的42H端口(Timer2)装入一个16位的计数值(533H×895/频率),以建立将要产生的声音频率。
(3)把输出端口61H的PB0、PB1两位置1,发出声音。
对于发音部分。
PC机上的大多数输入/输出(I/O)都是由主板上的8255(或8255A)可编程序外围接口芯片(PPI)管理的。
PPI包括3个8位寄存器,两个用于输入功能,一个用于输出功能。
输入寄存器分配的I/O端口号为60H和62H,输出寄存器分配的I/O端口号为61H。
由PPI输出寄存器中的0、1两位来选择扬声器的驱动方式。
连接到扬声器上的是定时器2,从上图可以看到,GATE2与端口61H的PB0相连,当PB0=1时,GATE2获得高电平,使定时器2可以在模式3(方波)下工作。
定时器2的OUT2与端口61H的PB1通过一个与门与扬声器的驱动电路相连。
当PB1=1时,允许OUT2的输出信号到达扬声器电路。
因此,只有PB0和PB1同时为“1”时,才能驱动扬声器地声。
通过以下指令实现:IN AL,61HOR AL,3OUT 61H,AL上面的指令用以打开扬声器,如要关闭扬声器时则为:AND AL,0FCHOUT 61H,AL当从8255中采集到输入的数据时,需要确定相应的频率,所以在软件编程时要建立一个数据表:TABLE DW 493,440,392,349,329,293,261把相应的频率送到一个寄存器上,通过公式:计数值=533H×896÷ f=1234DCH÷ f算出计数值,再把算得的计数值送给8253,就可产生所要频率的方波。
在把计数值送8253前,必须先把8253进行初始化:MOV AL,0B6HOUT 43H,AL使其选用通道2,工作在方式3下。
就整个电路而言,接好电路后,通过软件编程不断地采集从8255口中输入的信号,而8个开关都接在8255的A口上,只要有开关按下,就会采集到一个数据,根据这个数据与事先编好的表对应,得到一个计数值,把这个计数值送给8253的通道2,8253的通道2工作的方式3下,这样就可以产生满足频率要求的发声方波。
这个方波经驱动放大就可以使扬声器发出相应的声音。
所以8255在这里完成两个任务,它不仅从A口中采集到数据,而且B口的PB1和PB0两个位要控制发声。
8253的主要任务就是产生所要求发声的不同频率的方波。
3、详细设计3.1主要的宏和过程的实现3.1.1DISPLAY显示宏为将事先定义的数据段字符串显示在屏幕上,定一个参数为b的宏。
将b的地址传到DX。
随后调用DOS09号功能调用。
将字符串显示到屏幕。
调用DISPLAY的实例为:DISPLAY INFO1DISPLAY INFO2DISPLAY INFO3DISPLAY MUSLIST在此段代码中,程序显示提示作用的字符串和歌曲列表。
DISPLAY宏具体实现如下:DISPLAY MACRO bLEA DX,bMOV AH,9INT 21HENDM3.1.2ADDRESS音乐地址宏歌曲包含节拍和频率。
此处定义的音乐地址宏包含两个参数,将歌曲频率地址导入SI将歌曲节拍导入BP。
当选择不同的歌曲时,主程序调用该宏,将用户要求的歌曲的频率和节拍导入,以便在MUSIC中实现发声。
音乐地址宏实现如下:ADDRESS MACRO A,BLEA SI,ALEA BP,DS:BENDM3.1.3MUSIC宏在ADDRESS中,程序已经将歌曲的首个频率地址和首个节拍地址分别导入SI、BP。
为了检测歌曲是否结束,在MUSIC中,首先将SI传递到DI,DI与-1相减,如等于0,则得出该频率定义为-1 。
在歌曲频率表定义中将-1定为该歌曲结束标志,此时MUSIC跳出结束。
若该频率不为-1。
调用通用发生程序GENSOUND,将该音符按照频率和节拍表发声。
发声后SI、BP分别加2,跳转到下一个音符的频率和节拍,继续检测歌曲是否结束。
如频率不为0,继续将该音符发声,并循环此过程。
具体实现方法如下:MUSIC PROC NEARPUSH DSSUB AX,AXPUSH AXFREG:MOV DI,[SI]CMP DI,-1JE END_MUSMOV BX,DS:[BP]CALL GENSOUNDADD SI,2ADD BP,2JMP FREGEND_MUS:RETMUSIC ENDP3.1.4通用发生程序GENSOUND该发生程序是在修改BEEP发声程序的基础上,以实现为8088/86编写一个任意频率和任意持续时间的通用发声程序。
该程序包括以下三个步骤:(1)在8253/54 中的43端口送一个控制字0B6H(10110110B),该控制字对定时器2进行初始化,使得定时器2准备接受计数初值。
(2)在8253/54中的42H端口装入一个16位计数值,已建立将要产生的声音频率。
(3)把输出端口61H的0、1两位置1,发出声音。
具体实现如下:GENSOUND PROC NEARPUSH AXPUSH BXPUSH CXPUSH DXPUSH DIMOV AL,0B6HOUT 43H,ALMOV DX,12HMOV AX,348chDIV DIOUT 42H,ALMOV AL,AHOUT 42H,ALIN AL,61HMOV AH,ALOR AL,3OUT 61H,ALWAIT1:MOV CX,3314call waitfDELAY1:DEC BXJNZ WAIT1MOV AL,AHOUT 61H,ALPOP DIPOP DXPOP CXPOP BXPOP AXRETGENSOUND ENDP该GENSOUND程序能产生19~65535Hz的声音,这个频率的下限是使除法不产生溢出的最小值。
其上限65535是多余的,因为人能听到的声音最高频率为20000Hz。
此外一般情况下,GENSOUND程序产生的声音不单单和频率有关,还和CPU有关。
CPU工作频率越高,时延越短,产生的声音越急促。
为了使程序产生一个与CPU 工作频率无关的合适时延,在MUSCI中调用了一个时间延时程序WAITF。
3.1.5WAITF延时程序80x86的各种处理器采取了6~66MHz的工作频率,loop指令的执行时间在这些处理器上也不相同。
为了建立一个与处理器无关的延时,IBM采用了一种利用硬件产生时间延时的方法,即通过监控端口61H和PB4,使PB4每15.08微秒触发一次,一产生一个固定不变的时间基准。
在IBM PC AT BIOS 的WAITF子程序,就是一个产生Nx15.08微秒时间演示的程序。
调用WAITF子程序时,CX寄存器必须装入15.08微秒的倍数N。
利用WAITF子程序能获得任意的时间延时,而不必在考虑CPU的型号和工作频率。
具体实现如下:waitf proc nearpush axwaitf1:in al,61hand al,10hcmp al,ahje waitf1mov ah,alloop waitf1pop axretwaitf endp3.1.6CLEAR清屏程序当程序初始化或用户输入错误时,程序调用CLEAR清屏程序。
清屏程序将AX、BX、CX、DX先入栈,以保存现场,保证清屏后重新执行不会出现错误。
随后启用BIOS功能调用,将屏幕初始化或上卷。
其中AL=0表示初始化窗口,AL=上卷行数,BH=卷入行属性,CH/CL=左上角行/列号,DH/DL=右上角行/列号。
该程序段表示从左起0行0列到右起24行79列全部清屏。
将屏幕清空后重新将AX、BX、CX、DX出栈。
clear proc nearpush axpush bxpush cxpush dxmov ah,6mov al,0mov ch,0mov cl,0mov dh,24mov dl,79mov bh,7int 10hpop dxpop cxpop bxpop axretclear endp3.1.7RETU退出当程序要求退出时,主程序会调用RETU进行退出。
RETU程序内容实际为一个BIOS功能调用。
RETU:MOV AH,4CHINT 21H3.2主程序实现3.2.1数据段定义数据段分别定义了INFO1、INFO2、INFO3 、INFO4、INFO5各字符串分别显示程序运行之初对用户的提示。
MUSLIST 中显示用户能选择的三首歌曲列表。
程序用MUS_FREG、MUS_TIME分别定义了音乐频率和节拍。
使得发声程序可以按照理想的要求发出连续的乐曲。
节拍和频率定义原理如下:乐曲是按照一定的高低、长短和强弱关系组成的音调,在每一首乐曲中,每个音符的音高和音长与发声系统中的频率、节拍有关。
可参考下表:音名 C D E F G A B C D E F G A B C唱名 1 2 3 4 5 6 7 1 2 3 4 5 6 7 i频率(HZ)131 147 165 175 196 220 247 262 294 330 349 392 440 492 523其中,低音阶从低音C(131HZ)到中央C(262HZ),高音阶从中央C(262HZ)到高音C(523HZ)。
组成乐曲的音符的频率值和持续时间是乐曲程序发声所必需的两组数据,频率可以查上表,音符的持续时间根据乐曲的速度及每个音符的节拍数来确定。
在4/4拍中,四分音符为一拍,每小节四拍,全音符持续四拍,二分音符持续二拍,四分音符持续一拍,八分音符持续半拍。