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

📄 music125.asm

📁 51单片机音乐程序
💻 ASM
字号:


	ORG	0000H
	LJMP	MAIN
	ORG	0003H		;外部中断0
	LJMP	SERV_INT0
        ORG     000BH
        LJMP    T0_INT          ;T0中断入口
        ORG     001BH
        LJMP    T1_INT          ;T1中断入口


MAIN:   MOV     SP,#2FH
        MOV     TMOD,#1H        ;初始化
        MOV     TH1,#9CH        ;T150ms初值
        MOV     TL1,#57H
        MOV	7AH,#1H	        ;显示缓冲区
	MOV	7BH,#2H
	MOV	7CH,#3H
	MOV	7DH,#4H
	MOV	7EH,#5H
	MOV	7FH,#6H
        MOV     80H,#14H        ;设置发声1s,即T1中断20次
        CLR     21H.0           ;清标志位
	MOV	DPTR,#3FFFH	;8255命令字地址
	MOV	A,#88H          ;PA输出,PB输出,PC0-PC3输出,PC4-PC7输入
	MOVX	@DPTR,A
	SETB	EA              ;中断设置
        SETB    ET0
        SETB    ET1
	SETB	EX0
        SETB    IT0             ;边沿触发方式

DISPLAY:MOV	R0,#7AH		;缓冲区首地址
	MOV	R1,#1H          ;选通LED
	MOV	R2,#6H		;字形码个数
LOOP:  ;**************奏乐代码段***********************
        JNB     21H.0,NEXT      ;按键一次,发声一次
        CLR     21H.0           ;--------------方案一:键释放后才发声-----------
        MOV     A,7AH           ;取音符
        LCALL   TONE            ;设置频率初值
        SETB    TR0
        SETB    TR1             ;启动定时器,开始发声
       ;***********************************************
NEXT:  ;**************显示代码段***********************
        MOV	A,@R0
	MOV	DPTR,#TAB
	MOVC	A,@A+DPTR	;取字形码
	MOV	DPTR,#3FFCH	;PA口
	MOVX	@DPTR,A		;输出字形
	MOV	DPTR,#3FFDH	;PB口
	MOV	A,R1
	MOVX	@DPTR,A		;选通第一个LED
	INC	R0		;下一个字形
        MOV     A,R1
	RL	A
        MOV     R1,A		;下一个LED
	LCALL	DELAY100MS	;延时
	DJNZ	R2,LOOP		;循环扫描
	LJMP	DISPLAY
	RET

TAB:                            ;字形码表
	DB	0C0H,0F9H,0A4H,0B0H,99H         ;0,1,2,3,4
        DB      92H,82H,0F8H,80H,90H            ;5,6,7,8,9
        DB      88H,83H,0C6H,0A1H,86H           ;A,B,C,D,E
        DB      8EH,0BFH,8CH,0FFH               ;F,-,P,暗

FREQ_TAB:                       ;音符频率初值表
        DB      0F1H,17H,0F2H,0A6H,0F4H,29H,0F4H,0D6H,0F5H,08H
        DB      0F7H,1FH,0F8H,17H
        DB      0F8H,8BH,0F9H,5BH,0FAH,14H,0FAH,6BH,0FBH,04H
        DB      0FBH,8FH,0FCH,0BH


TONE:   SUBB    A,#1H           ;设置频率初值子程序
        RL      A               ;调整偏移量
        PUSH    A		;保存A值
        MOV     DPTR,#FREQ_TAB
        MOVC    A,@A+DPTR
        MOV     TH0,A           ;设置TH0
        POP     A
        INC     A               ;取下个字节
        MOVC    A,@A+DPTR
        MOV     TL0,A           ;设置TL0
        RET

T0_INT: CPL     P3.4            ;T0中断服务程序
        RETI

T1_INT: DJNZ    80H,CON         ;判断发声时间
        CLR     TR0             ;发声时间到,关闭T0
        MOV     80H,#14H
CON:    MOV     TH1,#9CH        ;重装T1C初值,此音符继续发声
        MOV     TL1,#57H
ENDT1:  RETI


SERV_INT0:
        SETB    RS0
        SETB    RS1
	PUSH	ACC
	PUSH	DPL
	PUSH	DPH
	LCALL	DELAY10MS		;前沿消抖
	LCALL	KEYDOWN			;判断是否仍为按下状态
	JZ	ENDINT0
	MOV	R0,#0FEH		;列线轮流置0
	MOV	R1,#0H			;列号
	MOV	R2,#0H			;行号
	MOV	DPTR,#3FFEH		;PC口
COLU:	MOV	A,R0
	ANL	A,#0FH			;屏蔽高4位,行线状态
	MOVX	@DPTR,A			;置列线状态
	MOVX	A,@DPTR			;读取行线状态
	ORL	A,#0FH			;屏蔽低4位,列线状态
	CPL	A			;状态取反
        PUSH    ACC
        MOV     A,R0
	RL	A
        MOV     R0,A			;下条列线置0
        POP     ACC
	JNZ	LINE			;行线不全为0则有键按下,转判断行
	INC	R1			;列号加1
	AJMP	COLU			;继续判断列????????????!!!!!!!!!!!

LINE:	CLR	C			;清进位位
	RLC	A			;(行线)状态带进位左移
	JC	DONE			;进位位为1则此行有键按下
        PUSH    ACC
        MOV     A,R2
	ADD	A,#04H			;行号加4,判断下一行
        MOV     R2,A
        POP     ACC
        SJMP	LINE   			;??????????????!!!!!!!!!

DONE:	MOV	A,#0H			;清A
	ADD	A,R1
	ADD 	A,R2		        ;键号=行号+列号
       	PUSH	ACC                    	;保存键号
        ;----------方案二:按键期间发声-----------------
        ;CLR     EA                      ;关总中断
        ;LCALL   TONE                    ;设置频率初值
        ;SETB    EA                      ;开总中断
        ;SETB    TR0                     ;启动定时器,开始发声
        ;---------------------------------------------------------		
WAIT:	LCALL	DELAY10MS		;后沿消抖
	LCALL	KEYDOWN			;判断键是否释放
	JNZ	WAIT			;等待键释放
        ;CLR    TR0                     ;--------------方案二 键释放就停止发声---------
        SETB    21H.0                   ;--------------方案一 键释放后才发声-----------
	POP 	ACC			;取A值
        MOV	7AH,A			;字形码送入显示缓冲区
	MOV	7BH,A
	MOV	7CH,A
	MOV	7DH,A
	MOV	7EH,A
	MOV	7FH,A
ENDINT0:POP	DPH
	POP	DPL
	POP	ACC
        CLR     RS0
        CLR     RS1
        RETI

KEYDOWN:MOV	DPTR,#3FFEH		;PC口
	MOV	A,#0H			;列线全置0
	MOVX 	@DPTR,A
	MOVX	A,@DPTR			;读取行线状态
	ORL	A,#0FH			;屏蔽列线状态
	CPL	A			;状态取反,行线不全为0则有键按下
	RET

DELAY10MS:
        MOV   R4,#64H
 LOOP1: MOV   R5,#64H
        DJNZ  R5,$
        DJNZ  R4,LOOP1
        RET

DELAY100MS:
        MOV   R6,#010H
LOOP2:  MOV   R7,#064H
        DJNZ  R7,$
        DJNZ  R6,LOOP2
        RET
        END

⌨️ 快捷键说明

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