单片机 电子琴程序,矩阵按键扫描处理
时间:10-02
整理:3721RD
点击:
项目要求电子琴程序能够实现8个音符、能播放歌曲,并且液晶屏显示操作的信息(按音符键液晶显示,按歌曲键则液晶屏显示歌词),还能变调,比如中1变为高1,这样
目前的话,网上找到一个独立按键的,修改之后适合在我板子上仅仅4个独立按键。前3个播放音符,后1个播放歌曲。这程序歌曲显示歌词,音符不显示操作信息
程序如下:(有部分程序因为不涉及,所以修改的时候没删去)主要关键在于中间键盘部分
RS BIT P2.4 ;定义液晶显示端口标号
RW BIT P2.5
E BIT P2.6
;********************************************
T0TH EQU 24H ;T0两个暂存变量
T0TL EQU 23H
ORG 0000H
LJMP INITION
ORG 000BH
LJMP T0INT
ORG 0100H
;********************************************
;*************************液晶初始化******************
INITION:
MOV SP,#70H
MOV P0,#01H ;清屏
CALL ENABLE
MOV P0,#38H ;8位,2行显示
CALL ENABLE
MOV P0,#0CH ;屏显on,关光标
CALL ENABLE
MOV P0,#06H ;计数地址加1,自动右移
CALL ENABLE
;******************************************
;开机提示
;******************************************
MOV P0,#80H
CALL ENABLE
MOV DPTR,#TABLE0 ;写数据的第一行
CALL WRITE1
MOV P0,#00010000B ;光标左移两位
CALL ENABLE
MOV P0,#00010000B
CALL ENABLE
CALL DEL0
LJMP MAIN
;*********************************************写指令
ENABLE:
CLR RS
CLR RW
SETB E
CALL DEL0
CLR E
RET
;**********************************************写数据
WRITE1:
MOV R1,#00H ;查表程序,从表头到表尾
A1:
MOV A,R1
MOVC A,@A+DPTR
CALL WRITE2
INC R1
CJNE A,#00H,A1 ;未到字符串末尾继续
RET
WRITE2:
MOV P0,A ;直接将数据写入液晶屏
SETB RS
CLR RW
SETB E
CALL DEL0
CLR E
RET
DEL0:MOV R4,#020H
C0:MOV R5,#020H
C1: DJNZ R5,C1
DJNZ R4,C0
RET
;******************************************
TABLE0:DB 'WELCOM HERE',00H
;*************************内存初始化******************
INITIAL:
MOV R3,#08H
MOV R0,#30H
M1:
MOV @R0,#00H
INC R0
DJNZ R3,M1
RET
;*************************选择按键播放八个音调******************
MAIN: MOV SP,#80H ;初始化堆栈
MOV TMOD,#11H ;定时器0工作方式0,定时器1工作
SETB EA
SETB ET0 ;计数器0允许
SETB ET1 ;计数器1允许
START: SETB P1.0 ;关蜂鸣器
CLR TR0 ;定时器不允许
SCAN: ;键盘扫描
MOV A,P3
CJNE A,#0FFH,SU_KEY ;判断键盘按下,跳到SU_KEY,若
NOP
LJMP SCAN
SU_KEY:
SU_KEY1:
JB P3.0,SU_KEY2 ;如果不是第1个键按下,转
MOV DPH,#0FCH
MOV DPL,#44H
SJMP PLAY
SU_KEY2:
JB P3.1,SU_KEY3 ;如果不是第2个键按下,转
MOV DPH,#0FCH
MOV DPL,#0ACH
SJMP PLAY
SU_KEY3:
JB P3.2,KEY1 ;如果不是第3个键按下,转
MOV DPH,#0FDH
MOV DPL,#09H
SJMP PLAY
PLAY:
MOV T0TH,DPH ;存高位字符
MOV T0TL,DPL ;存低位字符
MOV TH0,T0TH
MOV TL0,T0TL
SETB TR0 ;启动定时器0
MOV R2,#01B ;1/4拍
DJNZ R2,PLAY
LCALL DELAY
SJMP JUDGE
JUDGE:
JB P3.5,START ;按键未按下,则继续扫描,否则,开始放音乐
;*************************选择按键播放音乐******************
KEY1:
JB P3.3,NEXT_2 ;第一个键(P2.5)按下,放音音乐1
MOV R2,#00H
LCALL MODD ;歌曲号显示
MOV DPTR,#MU_TAB1
AJMP MUSIC
NEXT_2: LJMP START ;返回
MUSIC:
MOV TMOD,#01H
MOV IE,#82H ;允许T0中断
MOV R7,#00H
LOOP:
CLR A
MOVC A,@A+DPTR ;查表取代码
MOV R1,A ;定时器高八位存R1
INC DPTR
PUSH DPH ;保
PUSH DPL
GECI1:
JB P3.3,TIAOCHU ;第一个键(P2.5)按下,显示歌词1
MOV DPTR,#GE1
AJMP GECI
TIAOCHU:LJMP START
GECI:
LCALL QINGCHU
MOV P0,#0C0H ;显示的位置
CALL ENABLE
XIANSHI1: MOV A,R7 ;查表取音乐汉
MOVC A,@A+DPTR
CALL WRITE2
INC R7
CJNE A,#00H,XIANSHI1
MOV P0,#00010000B ;将光标左移一
CALL ENABLE
MOV P0,#00010000B ;将光标左移一
CALL ENABLE
POP DPL
POP DPH
CLR A
MOVC A,@A+DPTR
MOV R0,A ;定时器低八位存R0
ORL A,R1
JZ NEXT0 ;相或结果全0为休止符
MOV A,R0
ANL A,R1
CJNE A,#0FFH,NEXT ;相与结果为0FFH表示乐曲结束
MOV P0,#01H ;清屏
CALL ENABLE
LJMP INITION ;从头开始演奏
NEXT: MOV T0TH,R1 ;装定时初值
MOV TH0,T0TH
MOV T0TL,R0
MOV TL0,T0TL
SETB TR0 ;启动定时器
SJMP NEXT1
NEXT0: CLR TR0 ;关闭定时器
NEXT1: CLR A
INC DPTR
MOVC A,@A+DPTR ;查延时常数
MOV R2,A
LOOP1:
ACALL D200
DJNZ R2,LOOP1 ;控制延时次数
INC DPTR
AJMP LOOP
D200: MOV R3,#81H ;延时程序
D200B: MOV A,#0FFH
D200A: DEC A
JNZ D200A
DEC R3
CJNE R3,#00H,D200B
RET
QINGCHU:MOV A,#00100000B
MOV P0,#0C0H ;将第二行的第一位置0
LCALL ENABLE
LCALL WRITE2
MOV A,#00100000B ;将第二行的第二位置0
MOV P0,#0C1H
LCALL ENABLE
LCALL WRITE2
MOV A,#00100000B ;将第二行的第三位置0
MOV P0,#0C2H
LCALL ENABLE
LCALL WRITE2
MOV A,#00100000B ;将第二行的第四位置0
MOV P0,#0C3H
LCALL ENABLE
LCALL WRITE2
MOV A,#00100000B ;将第二行的第五位置0
MOV P0,#0C4H
LCALL ENABLE
LCALL WRITE2
MOV A,#00100000B ;将第二行的第六位置0
MOV P0,#0C5H
LCALL ENABLE
LCALL WRITE2
MOV A,#00100000B ;将第二行的第七位置0
MOV P0,#0C6H
LCALL ENABLE
LCALL WRITE2 ;将第二行的第三位置0
;以上等价程序如下
;GECI:MOV R3,#00H ;控制循环次数
;QINGCHU:
;MOV A,#00100000B ;置空格
;PUSH A
;MOV R4,#0C0H ;地址
;MOV A,R4
;MOV P0,A
;POP A
;INC R4
;DEC R3 ;控制循环次数
;CJNE R3,#00H,QINGCHU ;计满十次则执行转移
;***************************************************
;定时器0中断子程序,定时音乐
;***************************************************
T0INT: ;中断服务子程序
MOV TH0,T0TH
MOV TL0,T0TL
CPL P1.0 ;反相输出,演示音乐
RETI
;******************************************
;显示
;******************************************
MODD:
MOV P0,#8EH
LCALL ENABLE
MOV A,R2
MOV DPTR,#TABLE12
MOVC A,@A+DPTR
LCALL WRITE2
RET
TABLE12:DB 31H,32H,33H
GE1: db 'xin',00h,'nian',00h,'hao',00h,'ya',00h,'xin',00h,'nian',00h,'hao',00h,'ya',00h
db 'zhu',00h,'fu',00h,'da',00h,'jia',00h,'xin',00h,'nian',00h,'hao',00h
GE2: DB 'liang',00H,'zhi',00H,'lao',00H,'hu',00H,'liang',00H,'zhi',00H,'lao',00H,'hu',00H,'pao',00H,'de',00H,'kuai',00H
DB 'pao',00H,'de',00H,'kuai',00H,'yi',00H,'zhi',00H,'mei',00H,'you',00H,'yan',00H,'jing',00H,'yi',00H,'zhi',00H
DB 'mei',00H,'you',00H,'er',00h,'duo',00h,'zhen',00h,'qi',00h,'guai',00h,'zhen',00h,'qi',00h,'guai',00h
GE3: DB 'wo',00h,'ai',00h,'bei',00h,'jing',00h,'tian',00h,'an',00h,'men',00h,'tian',00h,'an',00h
;*************************延时子程序******************
DELAY:MOV 30H,#100 ;延长时间等待,键盘消抖
D1:MOV R5,#200
D2:DJNZ R5,D2
DJNZ 30H,D1
RET
;*******************新年好******************************
MU_TAB1: DB 0FEH,25H,04H,0FEH,25H,04H
DB 0FEH,25H,06H,0FDH,80H,06H
DB 0FEH,84H,04H,0FEH,84H,04H
DB 0FEH,84H,06H,0FEH,25H,06H
DB 0FEH,25H,04H,0FEH,84H,04H
DB 0FEH,0C0H,04H,0FEH,84H,04H
DB 0FEH,98H,04H,0FEH,84H,04H
DB 0FEH,57H,06H
DB 0FFH,0FFH
;*******************两只老虎****************************
MU_TAB2: DB 0FCH,44H,06H,0FCH,0ACH,06H,0FDH,09H,06H,0FCH,44H,06H
DB 0FCH,44H,06H,0FCH,0ACH,06H,0FDH,09H,06H,0FCH,44H,06H
DB 0FDH,09H,06H,0FDH,34H,06H,0FDH,0A6H,06H
DB 0FDH,09H,06H,0FDH,34H,06H,0FDH,0A6H,06H
DB 0FBH,04H,04H,0FDH,0C8H,04H,0FBH,04H,04H,0FDH,34H,04H
DB 0FDH,09H,04H,0FCH,44H,04H,0FBH,04H,04H,0FDH,0C8H,04H
DB 0FBH,04H,04H,0FDH,34H,04H,0FDH,09H,04H,0FCH,44H,04H
DB 0FCH,44H,06H,0FDH,0A6H,06H,0FCH,44H,06H
DB 0FCH,44H,06H,0FDH,0A6H,06H,0FCH,44H,06H
DB 0FFH,0FFH
;*******************我爱北京天安门****************************
MU_TAB3: DB 0FDH,82H,06H,0FEH,22H,04H,0FDH,82H,04H,0FDH,34H,04H
DB 0FDH,09H,04H,0FCH,0ACH,04H,0FCH,44H,06H
DB 0FFH,0FFH,0FFH,0FFH
END
目前小编是打算把中间独立键盘部分改成矩阵扫描程序,有两个方向的想法,第一个是矩阵行列状态扫描确定具体是某个按键按下后,给予这个按键响应的子程序播放赋给的音符/歌曲/其他操作信息,第二个方向是矩阵按键行列状态扫描时,比如行扫描,那么在确定哪一行扫描之后,第一二行给予查8个音符表,其他两行给予其他子程序。
首先先求解小编思路对不对 = =个人认为第一种每个按键赋予具体的子程序的话,那么项目要求里的变调就有点难实现了。但是第二种方向,改了好多个代码都不行,TAT
上述独立按键部分修改如下:
;*************************选择按键播放八个音调******************
MAIN: MOV SP,#80H ;初始化堆栈
MOV TMOD,#11H ;定时器0工作方式0,定时器1工作方式0
SETB EA
SETB ET0 ;计数器0允许
SETB ET1 ;计数器1允许
START: SETB P1.0 ;关蜂鸣器
CLR TR0 ;定时器不允许
SCAN: ;键盘扫描
MOV A,P3
CJNE A,#0FFH,KS ;判断键盘按下,跳到KS,若未按,继续扫描
NOP
LJMP SCAN
KS:
MOV DPTR,#7FFFH
CLR P3.4
MOVX A,@DPTR
MOV 37H,A
CPL A
JZ KSK1
LCALL DELAY
MOVX A,@DPTR
XRL A,37H
JZ KS1
KSK1:SETB P3.4
CLR P3.5
MOVX A,@DPTR
MOV 37H,A
CPL A
JZ KSK2
LCALL DELAY
MOVX A,@DPTR
XRL A,37H
JZ KS1
KSK2:SETB P3.5
CLR P3.6
MOVX A,@DPTR
MOV 37H,A
CPL A
JZ KSK3
LCALL DELAY
MOVX A,@DPTR
XRL A,37H
JZ KS1
KSK3:SETB P3.6
CLR P3.7
MOVX A,@DPTR
MOV 37H,A
CPL A
JZ KSK4
LCALL DELAY
MOVX A,@DPTR
XRL A,37H
JZ KS1
KSK4:AJMP KS5
KS1: MOVX A,@DPTR
CPL A
JNZ KS1
MOV A,37H
JB ACC.0,KS2
MOV 37H,#00H
AJMP KS6
KS2: JB ACC.1,KS3
MOV 37H,#01H
AJMP KS6
KS3: JB ACC.2,KS4
MOV 37H,#02H
AJMP KS6
KS4: JB ACC.3,KS5
MOV 37H,#03H
AJMP KS6
KS5: SETB ACC.3
AJMP KS7
KS6:
MOV A,37H
ANL A,#0FEH ;?待确定
JNB P3.4,KS7
ANL A,#0FDH ;?待确定
JNB P3.5,KS8
ANL A,#0FBH ;?待确定
JNB P3.6,KS9
ANL A,#0F7H ;?待确定
JNB P3.7,KS10
KS7:
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
MOV DPH,A
MOV 21H,A
MOV A,22H
RL A
INC A
MOVC A,@A+DPTR
MOV DPL,A
MOV 20,A
SJMP PLAY
KS8: MOV DPTR,#TABLE2
MOVC A,@A+DPTR
MOV DPH,A
MOV 21H,A
MOV A,22H
RL A
INC A
MOVC A,@A+DPTR
MOV DPL,A
MOV 20,A
SJMP PLAY
;9和10暂未处理
KS9: ORL P3,#03H
MOV 37H,A
JB ACC.2,KS10 ;如果不是第3个键按下,则转
MOV DPH,#0FDH
MOV DPL,#09H
SJMP PLAY
KS10: ORL P3,#03H
MOV 37H,A
JB ACC.3,KEY1 ;如果不是第4个键按下,则转
MOV DPH,#0FDH
MOV DPL,#34H
SJMP PLAY
PLAY:
MOV T0TH,DPH ;存高位字符
MOV T0TL,DPL ;存低位字符
MOV TH0,T0TH
MOV TL0,T0TL
SETB TR0 ;启动定时器0
MOV R2,#01B ;1/4拍
DJNZ R2,PLAY
LCALL DELAY
SJMP JUDGE
JUDGE:
JB P1.5,KS8 ;按键未按下,则继续扫描,否则,开始放音乐
TABLE1: DW 64021,64103,64260,64400 ;低音3,低音4,低音5,低音6
TABLE2: DW 64524,64580,64684,64777 ;低音7,中音1,中音2,中音3
求解这部分程序如何修改能符合项目要求。跪谢!
目前的话,网上找到一个独立按键的,修改之后适合在我板子上仅仅4个独立按键。前3个播放音符,后1个播放歌曲。这程序歌曲显示歌词,音符不显示操作信息
程序如下:(有部分程序因为不涉及,所以修改的时候没删去)主要关键在于中间键盘部分
RS BIT P2.4 ;定义液晶显示端口标号
RW BIT P2.5
E BIT P2.6
;********************************************
T0TH EQU 24H ;T0两个暂存变量
T0TL EQU 23H
ORG 0000H
LJMP INITION
ORG 000BH
LJMP T0INT
ORG 0100H
;********************************************
;*************************液晶初始化******************
INITION:
MOV SP,#70H
MOV P0,#01H ;清屏
CALL ENABLE
MOV P0,#38H ;8位,2行显示
CALL ENABLE
MOV P0,#0CH ;屏显on,关光标
CALL ENABLE
MOV P0,#06H ;计数地址加1,自动右移
CALL ENABLE
;******************************************
;开机提示
;******************************************
MOV P0,#80H
CALL ENABLE
MOV DPTR,#TABLE0 ;写数据的第一行
CALL WRITE1
MOV P0,#00010000B ;光标左移两位
CALL ENABLE
MOV P0,#00010000B
CALL ENABLE
CALL DEL0
LJMP MAIN
;*********************************************写指令
ENABLE:
CLR RS
CLR RW
SETB E
CALL DEL0
CLR E
RET
;**********************************************写数据
WRITE1:
MOV R1,#00H ;查表程序,从表头到表尾
A1:
MOV A,R1
MOVC A,@A+DPTR
CALL WRITE2
INC R1
CJNE A,#00H,A1 ;未到字符串末尾继续
RET
WRITE2:
MOV P0,A ;直接将数据写入液晶屏
SETB RS
CLR RW
SETB E
CALL DEL0
CLR E
RET
DEL0:MOV R4,#020H
C0:MOV R5,#020H
C1: DJNZ R5,C1
DJNZ R4,C0
RET
;******************************************
TABLE0:DB 'WELCOM HERE',00H
;*************************内存初始化******************
INITIAL:
MOV R3,#08H
MOV R0,#30H
M1:
MOV @R0,#00H
INC R0
DJNZ R3,M1
RET
;*************************选择按键播放八个音调******************
MAIN: MOV SP,#80H ;初始化堆栈
MOV TMOD,#11H ;定时器0工作方式0,定时器1工作
SETB EA
SETB ET0 ;计数器0允许
SETB ET1 ;计数器1允许
START: SETB P1.0 ;关蜂鸣器
CLR TR0 ;定时器不允许
SCAN: ;键盘扫描
MOV A,P3
CJNE A,#0FFH,SU_KEY ;判断键盘按下,跳到SU_KEY,若
NOP
LJMP SCAN
SU_KEY:
SU_KEY1:
JB P3.0,SU_KEY2 ;如果不是第1个键按下,转
MOV DPH,#0FCH
MOV DPL,#44H
SJMP PLAY
SU_KEY2:
JB P3.1,SU_KEY3 ;如果不是第2个键按下,转
MOV DPH,#0FCH
MOV DPL,#0ACH
SJMP PLAY
SU_KEY3:
JB P3.2,KEY1 ;如果不是第3个键按下,转
MOV DPH,#0FDH
MOV DPL,#09H
SJMP PLAY
PLAY:
MOV T0TH,DPH ;存高位字符
MOV T0TL,DPL ;存低位字符
MOV TH0,T0TH
MOV TL0,T0TL
SETB TR0 ;启动定时器0
MOV R2,#01B ;1/4拍
DJNZ R2,PLAY
LCALL DELAY
SJMP JUDGE
JUDGE:
JB P3.5,START ;按键未按下,则继续扫描,否则,开始放音乐
;*************************选择按键播放音乐******************
KEY1:
JB P3.3,NEXT_2 ;第一个键(P2.5)按下,放音音乐1
MOV R2,#00H
LCALL MODD ;歌曲号显示
MOV DPTR,#MU_TAB1
AJMP MUSIC
NEXT_2: LJMP START ;返回
MUSIC:
MOV TMOD,#01H
MOV IE,#82H ;允许T0中断
MOV R7,#00H
LOOP:
CLR A
MOVC A,@A+DPTR ;查表取代码
MOV R1,A ;定时器高八位存R1
INC DPTR
PUSH DPH ;保
PUSH DPL
GECI1:
JB P3.3,TIAOCHU ;第一个键(P2.5)按下,显示歌词1
MOV DPTR,#GE1
AJMP GECI
TIAOCHU:LJMP START
GECI:
LCALL QINGCHU
MOV P0,#0C0H ;显示的位置
CALL ENABLE
XIANSHI1: MOV A,R7 ;查表取音乐汉
MOVC A,@A+DPTR
CALL WRITE2
INC R7
CJNE A,#00H,XIANSHI1
MOV P0,#00010000B ;将光标左移一
CALL ENABLE
MOV P0,#00010000B ;将光标左移一
CALL ENABLE
POP DPL
POP DPH
CLR A
MOVC A,@A+DPTR
MOV R0,A ;定时器低八位存R0
ORL A,R1
JZ NEXT0 ;相或结果全0为休止符
MOV A,R0
ANL A,R1
CJNE A,#0FFH,NEXT ;相与结果为0FFH表示乐曲结束
MOV P0,#01H ;清屏
CALL ENABLE
LJMP INITION ;从头开始演奏
NEXT: MOV T0TH,R1 ;装定时初值
MOV TH0,T0TH
MOV T0TL,R0
MOV TL0,T0TL
SETB TR0 ;启动定时器
SJMP NEXT1
NEXT0: CLR TR0 ;关闭定时器
NEXT1: CLR A
INC DPTR
MOVC A,@A+DPTR ;查延时常数
MOV R2,A
LOOP1:
ACALL D200
DJNZ R2,LOOP1 ;控制延时次数
INC DPTR
AJMP LOOP
D200: MOV R3,#81H ;延时程序
D200B: MOV A,#0FFH
D200A: DEC A
JNZ D200A
DEC R3
CJNE R3,#00H,D200B
RET
QINGCHU:MOV A,#00100000B
MOV P0,#0C0H ;将第二行的第一位置0
LCALL ENABLE
LCALL WRITE2
MOV A,#00100000B ;将第二行的第二位置0
MOV P0,#0C1H
LCALL ENABLE
LCALL WRITE2
MOV A,#00100000B ;将第二行的第三位置0
MOV P0,#0C2H
LCALL ENABLE
LCALL WRITE2
MOV A,#00100000B ;将第二行的第四位置0
MOV P0,#0C3H
LCALL ENABLE
LCALL WRITE2
MOV A,#00100000B ;将第二行的第五位置0
MOV P0,#0C4H
LCALL ENABLE
LCALL WRITE2
MOV A,#00100000B ;将第二行的第六位置0
MOV P0,#0C5H
LCALL ENABLE
LCALL WRITE2
MOV A,#00100000B ;将第二行的第七位置0
MOV P0,#0C6H
LCALL ENABLE
LCALL WRITE2 ;将第二行的第三位置0
;以上等价程序如下
;GECI:MOV R3,#00H ;控制循环次数
;QINGCHU:
;MOV A,#00100000B ;置空格
;PUSH A
;MOV R4,#0C0H ;地址
;MOV A,R4
;MOV P0,A
;POP A
;INC R4
;DEC R3 ;控制循环次数
;CJNE R3,#00H,QINGCHU ;计满十次则执行转移
;***************************************************
;定时器0中断子程序,定时音乐
;***************************************************
T0INT: ;中断服务子程序
MOV TH0,T0TH
MOV TL0,T0TL
CPL P1.0 ;反相输出,演示音乐
RETI
;******************************************
;显示
;******************************************
MODD:
MOV P0,#8EH
LCALL ENABLE
MOV A,R2
MOV DPTR,#TABLE12
MOVC A,@A+DPTR
LCALL WRITE2
RET
TABLE12:DB 31H,32H,33H
GE1: db 'xin',00h,'nian',00h,'hao',00h,'ya',00h,'xin',00h,'nian',00h,'hao',00h,'ya',00h
db 'zhu',00h,'fu',00h,'da',00h,'jia',00h,'xin',00h,'nian',00h,'hao',00h
GE2: DB 'liang',00H,'zhi',00H,'lao',00H,'hu',00H,'liang',00H,'zhi',00H,'lao',00H,'hu',00H,'pao',00H,'de',00H,'kuai',00H
DB 'pao',00H,'de',00H,'kuai',00H,'yi',00H,'zhi',00H,'mei',00H,'you',00H,'yan',00H,'jing',00H,'yi',00H,'zhi',00H
DB 'mei',00H,'you',00H,'er',00h,'duo',00h,'zhen',00h,'qi',00h,'guai',00h,'zhen',00h,'qi',00h,'guai',00h
GE3: DB 'wo',00h,'ai',00h,'bei',00h,'jing',00h,'tian',00h,'an',00h,'men',00h,'tian',00h,'an',00h
;*************************延时子程序******************
DELAY:MOV 30H,#100 ;延长时间等待,键盘消抖
D1:MOV R5,#200
D2:DJNZ R5,D2
DJNZ 30H,D1
RET
;*******************新年好******************************
MU_TAB1: DB 0FEH,25H,04H,0FEH,25H,04H
DB 0FEH,25H,06H,0FDH,80H,06H
DB 0FEH,84H,04H,0FEH,84H,04H
DB 0FEH,84H,06H,0FEH,25H,06H
DB 0FEH,25H,04H,0FEH,84H,04H
DB 0FEH,0C0H,04H,0FEH,84H,04H
DB 0FEH,98H,04H,0FEH,84H,04H
DB 0FEH,57H,06H
DB 0FFH,0FFH
;*******************两只老虎****************************
MU_TAB2: DB 0FCH,44H,06H,0FCH,0ACH,06H,0FDH,09H,06H,0FCH,44H,06H
DB 0FCH,44H,06H,0FCH,0ACH,06H,0FDH,09H,06H,0FCH,44H,06H
DB 0FDH,09H,06H,0FDH,34H,06H,0FDH,0A6H,06H
DB 0FDH,09H,06H,0FDH,34H,06H,0FDH,0A6H,06H
DB 0FBH,04H,04H,0FDH,0C8H,04H,0FBH,04H,04H,0FDH,34H,04H
DB 0FDH,09H,04H,0FCH,44H,04H,0FBH,04H,04H,0FDH,0C8H,04H
DB 0FBH,04H,04H,0FDH,34H,04H,0FDH,09H,04H,0FCH,44H,04H
DB 0FCH,44H,06H,0FDH,0A6H,06H,0FCH,44H,06H
DB 0FCH,44H,06H,0FDH,0A6H,06H,0FCH,44H,06H
DB 0FFH,0FFH
;*******************我爱北京天安门****************************
MU_TAB3: DB 0FDH,82H,06H,0FEH,22H,04H,0FDH,82H,04H,0FDH,34H,04H
DB 0FDH,09H,04H,0FCH,0ACH,04H,0FCH,44H,06H
DB 0FFH,0FFH,0FFH,0FFH
END
目前小编是打算把中间独立键盘部分改成矩阵扫描程序,有两个方向的想法,第一个是矩阵行列状态扫描确定具体是某个按键按下后,给予这个按键响应的子程序播放赋给的音符/歌曲/其他操作信息,第二个方向是矩阵按键行列状态扫描时,比如行扫描,那么在确定哪一行扫描之后,第一二行给予查8个音符表,其他两行给予其他子程序。
首先先求解小编思路对不对 = =个人认为第一种每个按键赋予具体的子程序的话,那么项目要求里的变调就有点难实现了。但是第二种方向,改了好多个代码都不行,TAT
上述独立按键部分修改如下:
;*************************选择按键播放八个音调******************
MAIN: MOV SP,#80H ;初始化堆栈
MOV TMOD,#11H ;定时器0工作方式0,定时器1工作方式0
SETB EA
SETB ET0 ;计数器0允许
SETB ET1 ;计数器1允许
START: SETB P1.0 ;关蜂鸣器
CLR TR0 ;定时器不允许
SCAN: ;键盘扫描
MOV A,P3
CJNE A,#0FFH,KS ;判断键盘按下,跳到KS,若未按,继续扫描
NOP
LJMP SCAN
KS:
MOV DPTR,#7FFFH
CLR P3.4
MOVX A,@DPTR
MOV 37H,A
CPL A
JZ KSK1
LCALL DELAY
MOVX A,@DPTR
XRL A,37H
JZ KS1
KSK1:SETB P3.4
CLR P3.5
MOVX A,@DPTR
MOV 37H,A
CPL A
JZ KSK2
LCALL DELAY
MOVX A,@DPTR
XRL A,37H
JZ KS1
KSK2:SETB P3.5
CLR P3.6
MOVX A,@DPTR
MOV 37H,A
CPL A
JZ KSK3
LCALL DELAY
MOVX A,@DPTR
XRL A,37H
JZ KS1
KSK3:SETB P3.6
CLR P3.7
MOVX A,@DPTR
MOV 37H,A
CPL A
JZ KSK4
LCALL DELAY
MOVX A,@DPTR
XRL A,37H
JZ KS1
KSK4:AJMP KS5
KS1: MOVX A,@DPTR
CPL A
JNZ KS1
MOV A,37H
JB ACC.0,KS2
MOV 37H,#00H
AJMP KS6
KS2: JB ACC.1,KS3
MOV 37H,#01H
AJMP KS6
KS3: JB ACC.2,KS4
MOV 37H,#02H
AJMP KS6
KS4: JB ACC.3,KS5
MOV 37H,#03H
AJMP KS6
KS5: SETB ACC.3
AJMP KS7
KS6:
MOV A,37H
ANL A,#0FEH ;?待确定
JNB P3.4,KS7
ANL A,#0FDH ;?待确定
JNB P3.5,KS8
ANL A,#0FBH ;?待确定
JNB P3.6,KS9
ANL A,#0F7H ;?待确定
JNB P3.7,KS10
KS7:
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
MOV DPH,A
MOV 21H,A
MOV A,22H
RL A
INC A
MOVC A,@A+DPTR
MOV DPL,A
MOV 20,A
SJMP PLAY
KS8: MOV DPTR,#TABLE2
MOVC A,@A+DPTR
MOV DPH,A
MOV 21H,A
MOV A,22H
RL A
INC A
MOVC A,@A+DPTR
MOV DPL,A
MOV 20,A
SJMP PLAY
;9和10暂未处理
KS9: ORL P3,#03H
MOV 37H,A
JB ACC.2,KS10 ;如果不是第3个键按下,则转
MOV DPH,#0FDH
MOV DPL,#09H
SJMP PLAY
KS10: ORL P3,#03H
MOV 37H,A
JB ACC.3,KEY1 ;如果不是第4个键按下,则转
MOV DPH,#0FDH
MOV DPL,#34H
SJMP PLAY
PLAY:
MOV T0TH,DPH ;存高位字符
MOV T0TL,DPL ;存低位字符
MOV TH0,T0TH
MOV TL0,T0TL
SETB TR0 ;启动定时器0
MOV R2,#01B ;1/4拍
DJNZ R2,PLAY
LCALL DELAY
SJMP JUDGE
JUDGE:
JB P1.5,KS8 ;按键未按下,则继续扫描,否则,开始放音乐
TABLE1: DW 64021,64103,64260,64400 ;低音3,低音4,低音5,低音6
TABLE2: DW 64524,64580,64684,64777 ;低音7,中音1,中音2,中音3
求解这部分程序如何修改能符合项目要求。跪谢!