⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yinxiang.asm

📁 这是一个有关C8051F020单片机的实验教学材料,相信对于单片机的研究人员会有很大的帮助.
💻 ASM
字号:
;-----------------------------------------------------------------------------
; 版权归新华龙电子公司所有
;-----------------------------------------------------------------------------
;
;文件名:	YinXiang.asm
;
;编写人:	LC
;
;编写时间:2005/03/10
;
;目标器件: C8051F02x
;
;编译工具: Silicon Laboratories IDE
;
;程序说明:	此程序将某段音乐用特定的频率播放出来

;P54--MUSIC

;ch--->R7	halfflg--->R5	lasttime--->R0
;------------------------------------------------------------------------------------
; 头文件包含
;------------------------------------------------------------------------------------
$include (C8051F020.inc)


	ORG		0
	LJMP	main
	ORG		0BH
	LJMP	timer0int
	ORG		100H



;延时子程序
Delay:
	PUSH	5					;进栈
	PUSH	6
	PUSH	7
	MOV  	R5,#00H
De_2:
	MOV  	A,R5
	CLR  	C
	SUBB 	A,R0
	JNC  	De_8
	MOV  	R6,#00H
	MOV  	R7,#00H
De_5:
	CLR  	C
	MOV  	A,R6
	SUBB 	A,#09H
	JNC  	De_4
	INC  	R7
	MOV  	A,R7
	JNZ  	De_46
	INC  	R6
De_46:
	SJMP 	De_5
De_4:
	INC  	R5
	SJMP 	De_2
De_8:
	POP		7					;出栈
	POP		6
	POP		5
	RET  	

;判定字符是否是数字键
;YES(C=1)	NO(C=0)
isdigit:
	MOV		A,R7
	CLR		C
	SUBB	A,#30H
	JC		digit_1
	MOV		A,R7
	SUBB	A,#3AH
	JNC		digit_1
	SETB	C
	RET
digit_1:
	CLR	C
	RET

;判定字符是否是字母键
;YES(C=1)	NO(C=0)
isalpha:
	MOV		A,R7
	CLR		C
	SUBB	A,#41H
	JC		alpha_2
	MOV		A,R7
	SUBB	A,#5BH
	JNC		alpha_2
	LJMP	alpha_3
alpha_2:	
	MOV		A,R7
	CLR		C
	SUBB	A,#61H
	JC		alpha_1
	MOV		A,R7
	SUBB	A,#7BH
	JNC		alpha_1
alpha_3:
	SETB	C
	RET
alpha_1:
	CLR		C		
	RET

;定时器0用来产生方波
timer0int:
	PUSH	ACC
	MOV		TH0,R3			;定时初值
	MOV		TL0,R4
	MOV		A,P5
	XRL		A,#10H
	MOV		P5,A			;改变P5.4状态
	POP		ACC
	RETI

;开定时器0
Sound:
	SETB	TR0				;开定时器0
	SETB	ET0
	RET


;停止发声
SoundOff:
	PUSH	ACC
	CLR		TR0				;禁止定时0
	CLR		ET0
	MOV		A,P5
	ORL		A,#10H			;改变P5.4状态
	MOV		P5,A
	POP		ACC
	RET

;依据音鸣取对应的频率
GetFreq:
	PUSH	DPH
	PUSH	DPL
	CJNE	R5,#00H,G_F_1		;判定是全音/半音
	MOV		DPTR,#timreg		;取音频65536l-(OSFREQ/(24l*freq))表的收地址
	MOV		R1,DPH				;保存此地址到R1,R2
	MOV		R2,DPL	
	MOV		DPTR,#notename		;取音名表的首地址
	SJMP	GLOOP
G_F_1:
	MOV		DPTR,#halftimreg	;取半音频65536l-(OSFREQ/(24l*freq))表的收地址	
	MOV		R1,DPH				;保存此地址到R1,R2
	MOV		R2,DPL
	MOV		DPTR,#halfnotename	;取半音名表的首地址
GLOOP:
	CLR		A
	MOVC	A,@A+DPTR
	CJNE	A,#00H,G_F_2		;音名是否等于0		
	MOV		R1,#00H				;清R1
	MOV		R2,#00H				;清R2
	POP		DPL
	POP		DPH
	RET
G_F_2:
	CLR		A
	MOVC	A,@A+DPTR			;读音名表读取音名
	XRL		A,R7				
	JZ		G_F_END				;是否相同
	INC		DPTR
	CLR		C					;音名不相同地址指针指到下一音名位置
	MOV		A,R2
	ADD		A,#02H
	MOV		R2,A				;低地址保存到R2
	JNC		G_F_3
	INC		R1					;高地址保存到R1
G_F_3:
	LJMP	GLOOP
G_F_END:
	MOV		DPH,R1				;取音频65536l-(OSFREQ/(24l*freq))表的地址
	MOV		DPL,R2
	CLR		A					;读取65536l-(OSFREQ/(24l*freq)的值到R3(HIGH),R4(LOW)
	MOVC	A,@A+DPTR
	MOV		R3,A
	CLR		A
	INC		DPTR
	MOVC	A,@A+DPTR
	MOV		R4,A
	POP		DPL
	POP		DPH
	RET
		

;/***************************************************************************************
;函数名称:	void PORT_Init(void)
;功能描述:	初始化I/O
;输入:		无
;输出:		无
;全局变量:	XBR2,P74OUT
;调用模块:	无
;***************************************************************************************/
PORT_Init:
	MOV		XBR2,#40H			;使能交叉开关和弱上拉
	ORL		P74OUT,#0ffH		;使能P6,P7推挽输出
	RET


Play:
	;无效看门狗
	MOV		WDTCN,#0deH
	MOV		WDTCN,#0adH
	LCALL	PORT_Init
	MOV		OSCICN,#014H		;使用内部晶振
	MOV		DPTR,#sing
LOOP:
	CLR		A
	MOVC	A,@A+DPTR			;是否' '字符
	XRL  	A,#020H
	JZ   	DEAL
	CLR		A
	MOVC  	A,@A+DPTR
	XRL  	A,#07CH				;是否'|'字符
	JZ   	DEAL
	CLR		A
	MOVC  	A,@A+DPTR
	XRL  	A,#0DH				;是否'\r'字符
	JZ   	DEAL
	CLR		A
	MOVC  	A,@A+DPTR
	CJNE 	A,#0AH,NEXT1		;是否'\n'字符
DEAL:
	INC  	DPTR
	SJMP 	LOOP
NEXT1:
	CLR		A
	MOVC  	A,@A+DPTR			;乐曲结束则播放完毕
	JNZ  	NEXT2
	LCALL	SoundOff
	RET  	
NEXT2:
	CLR		A
	MOVC  	A,@A+DPTR			;半音标志
	CJNE 	A,#023H,NEXT3
	MOV  	R5,#01H				;半音R5=0x01
	SJMP 	LOOP
NEXT3:	
	CLR		A
	MOVC	A,@A+DPTR			;从音名获取频率
	MOV		R7,A
	LCALL	isdigit				;是否使数字
	JC   	NEXT4
	CLR		A
	MOVC	A,@A+DPTR
	MOV  	R7,A
	LCALL	isalpha				;是否使字母
	JNC  	NEXT5
NEXT4:
	LCALL	GetFreq				;得到音频65536l-(OSFREQ/(24l*freq))的值
	MOV  	R0,#010H			;赋延时变量到R0
	SJMP 	NEXT6
NEXT5:
	MOV  	R5,#00H
	INC		DPTR			
	LJMP	LOOP
NEXT6:
	INC		DPTR
	CLR		A
	MOVC	A,@A+DPTR			;从下一个符号获取额外音长符号
LOOP2:
	JZ   	NEXT7				;非音长符号则下次处理
	CLR		A
	MOVC	A,@A+DPTR
	MOV  	R7,A
	LCALL	isdigit				;是否数字键
	JC   	NEXT7
	CLR		A
	MOVC  	A,@A+DPTR
	MOV		R7,A
	LCALL	isalpha				;是否字母键
	JNC  	NEXT8
	AJMP 	NEXT7
NEXT8:
	CLR		A
	MOVC  	A,@A+DPTR			;额外延时一拍
	CJNE 	A,#02DH,NEXT9
	MOV  	A,#08H
	ADD  	A,R0
	MOV  	R0,A
NEXT9:
	CLR		A
	MOVC  	A,@A+DPTR			;额外延时半拍
	CJNE 	A,#02EH,NEXT10
	MOV  	A,#04H
	ADD  	A,R0
	MOV  	R0,A
NEXT10:
	CLR		A
	MOVC  	A,@A+DPTR			;下划线相当于简谱中音名下面的下划线,延时减半
	CJNE 	A,#05FH,NEXT11
	MOV  	A,R0
	CLR  	C
	RRC  	A
	MOV  	R0,A
NEXT11:
	CLR		A
	MOVC  	A,@A+DPTR				;双下划线相当于简谱中音名下面的双下划线,延时减为1/4
	CJNE 	A,#03DH,NEXT12
	MOV  	A,R0
	RRC  	A
	RRC  	A
	ANL  	A,#03FH
	MOV  	R0,A
NEXT12:
	INC		DPTR					;取下一音名
	CLR		A
	MOVC	A,@A+DPTR
	MOV		R7,A
	LJMP	LOOP2
NEXT7:
	PUSH	0
	MOV		A,R3
	MOV		R0,A
	MOV  	A,R4					;发声
	ORL  	A,R0
	POP		0
	JZ   	NEXT13
	LCALL	Sound
	SJMP 	NEXT14
NEXT13:
	LCALL	SoundOff				;关闭声音
NEXT14:
	LCALL	Delay					;延时
	LCALL	SoundOff				
	MOV		R0,#01H
	LCALL	Delay					;两个引之间的间歇
	LJMP	LOOP
PLAY_END:
	RET


;编谱说明,低音(简谱中数字下面有一个点的)1234567对应的为小写cdefgab
;中音(简谱中数字上下都没有点的)1234567对应的也为1234567
;高音(简谱中数字上面有一个点的)1234567对应的为大写CDEFGAB
;对于降音符b或声音符#一律用#+合适的音名例如#5
;一个音符本身为一拍,加下划线后为半拍加等号为1/4拍 如:65_ 4= 则音6为一拍,音5为半拍,音4为1/4拍
;下划线或等号连续书写则音长连续变短
;音符后加-或.表示延长。‘-’延长一拍‘.’延长半拍多加则延长连续增加


main:
	MOV		TMOD,#11H
	SETB	ET0
	SETB	EA
	MOV		SP,#80H			;置堆栈指针
	MOV		R0,#0AH
	LCALL	Delay			;延时
	LCALL	Play			;播放音乐
	LCALL	SoundOff		;关闭声音
	AJMP	$
	RET

sing:
	DB	"g_g_ag  1b- g_g_ag  21-  g_g_53  1ba 004_4_  312  1--1  "	;生日快乐	
	DB	00H
;/*************音名***************/
notename:
	DB	063H,064H,065H,066H,067H,061H,062H,031H,032H,033H,034H,035H,036H,037H,043H,044H,045H,046H,047H,041H,042H,000H
;/*************音名***************/
halfnotename:
	DB	063H,064H,066H,067H,061H,031H,032H,034H,035H,036H,043H,044H,046H,047H,041H,000H

;音频65536l-(OSFREQ/(24l*freq))表
timreg:
	DW	0FE22H,0FE56H,0FE85H,0FE9AH,0FEC1H,0FEE4H,0FF03H,0FF11H,0FF2BH,0FF43H,0FF4DH,0FF61H,0FF72H,0FF82H,0FF89H,0FF96H,0FFA1H,0FFA7H,0FFB0H,0FFB9H,0FFC1H

;半音频65536l-(OSFREQ/(24l*freq))表
halftimreg:
	DW	0FE3DH,0FE6EH,0FEAEH,0FED3H,0FEF4H,0FF1FH,0FF37H,0FF57H,0FF29H,0FF7AH,0FF8FH,0FF9CH,0FFACH,0FFB5H,0FFBDH
	
	END


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -