利用单片机8255制作电子琴程序如下:
设置定时器初值及端口地址
TIMER1L EQU 30H
TIMER1H EQU 31H
PORTB EQU 0FFFDH
PORTC EQU 0FFFEH
PORT8255 EQU 0FFFFH
ORG 0000H
SJMP MAIN
ORG 001BH
AJMP TIMER1
ORG 0040H
MAIN:MOV TMOD, #00010000B ;T1方式一,软件控制
MOV TCON,#00H ;关闭T1
MOV IE, #10001000B ;开T1中断
MOV IP, #10001000B ;T1优先
CLR P3.4 ;关扬声器
CLR P3.2 ;点亮灯
ACALL DELAY ;延时
;MAIN PROGRAM
START:ACALL DELAY ;延时
ACALL KEYSCA ;调用键盘扫描子程序
CJNE R4,#00H,PLAYKEY ;判断有无键按下
CLR TR1 ;无键按下关闭T1
SETB P3.2 ;无键按下熄灭指示灯
SJMP START ;跳回开始位置
PLAYKEY: CJNE R4,#20H,K0 ;有键按下由键值给TIMER1L和TIMER1H赋值
MOV TIMER1L,#06H ;低音七初值
MOV TIMER1H,#0FEH
AJMP SOUND
K0:CJNE R4,#30H,K1
MOV TIMER1L,#22H ;中音1初值
MOV TIMER1H,#0FEH
AJMP SOUND
K1:CJNE R4,#50H,K2
MOV TIMER1L,#3DH ;中音#1初值
MOV TIMER1H,#0FEH
AJMP SOUND
K2:CJNE R4,#90H,K3
MOV TIMER1L,#56H ;中音2初值
MOV TIMER1H,#0FEH
AJMP SOUND
K3:CJNE R4,#21H,K4
MOV TIMER1L,#6EH ;中音#2初值
MOV TIMER1H,#0FEH
AJMP SOUND
K4:CJNE R4,#31H,K5
MOV TIMER1L,#85H ;中音3初值
MOV TIMER1H,#0FEH
AJMP SOUND
K5:CJNE R4,#51H,K6
MOV TIMER1L,#9AH ;中音4初值
MOV TIMER1H,#0FEH
AJMP SOUND
K6:CJNE R4,#91H,K7
MOV TIMER1L,#0AEH ;中音#4初值
MOV TIMER1H,#0FEH
AJMP SOUND
K7:CJNE R4,#23H,K8
MOV TIMER1L,#0C1H ;中音5初值
MOV TIMER1H,#0FEH
AJMP SOUND
K8:CJNE R4,#33H,K9
MOV TIMER1L,#0D3H ;中音#5初值
MOV TIMER1H,#0FEH
AJMP SOUND
K9:CJNE R4,#53H,K10
MOV TIMER1L,#0E4H ;中音6初值
MOV TIMER1H,#0FEH
AJMP SOUND
K10:CJNE R4,#93H,K11 ;中音#6初值
MOV TIMER1L,#0F4H
MOV TIMER1H,#0FEH
AJMP SOUND
K11:CJNE R4,#27H,K12
MOV TIMER1L,#03H ;中音7初值
MOV TIMER1H,#0FFH
AJMP SOUND
K12:CJNE R4,#37H,K13
MOV TIMER1L,#11H ;高音1初值
MOV TIMER1H,#0FFH
AJMP SOUND
K13:CJNE R4,#57H,K14
MOV TIMER1L,#1FH ;高音#1初值
MOV TIMER1H,#0FFH
AJMP SOUND
K14:CJNE R4,#97H,SOUND
MOV TIMER1L,#2BH ;高音2初值
MOV TIMER1H,#0FFH
SOUND:SETB TR1 ;开启t1
CLR P3.2 ;点亮指示灯
AJMP START ;跳回开始
;定时器1中断服务程序
TIMER1:MOV TL1,TIMER1L ;将初值付给t1
MOV TH1,TIMER1H
CPL P3.4 ;输出方波
RETI
;键盘扫描程序
KEYSCA: MOV A,#82H ; 初始化。控制字为:B口输入,C口输出
MOV DPTR,#PORT8255
MOVX @DPTR,A
MOV R4,#00H ;初值(无按键)付给r4
MOV DPTR,#PORTC ;全键盘扫描
MOV A,#00H
MOVX @DPTR,A
MOV DPTR,#PORTB ;读取扫描结果
MOVX A, @DPTR
ANL A,#0F0H ;屏蔽行信号,取出列信号
CJNE A,#0F0H,PRSD1 ;判断有无按键
SJMP DONE ;无按键退出
PRSD1:ACALL DELAY ;有按键延时后再扫描
MOV DPTR,#PORTB ;读取扫描结果
MOVX A, @DPTR
ANL A,#0F0H ;屏蔽行信号,取出列信号
CJNE A,#0F0H,PRSD2 ;判断有无按键
SJMP DONE ;无按键退出
PRSD2:MOV R2,#04H ;有按键逐行扫瞄
MOV R3,#01H ;行初值
SCAN:MOV A,R3 ;行初值送a
CPL A ;形成行扫描信号
MOV DPTR,#PORTC ;输出行扫描信号
MOVX @DPTR,A
MOV DPTR,#PORTB ;读取信号(扫描结果)
MOVX A, @DPTR
ANL A,#0F0H ;屏蔽行信号,取出列信号
CJNE A,#0F0H,FIND ;判断有无按键
MOV A,R3 ;无按键继续扫描,调整行信号
RL A ;调整行信号
MOV R3,A ;保存行信号
DJNZ R2,SCAN ;判断是否扫描完四行
SJMP DONE ;扫描完四行结束
FIND:CPL A ;找到按键计算键值
ADD A,R3 ;将行列值相加
MOV R4,A ;键值送R4
DONE:RET ;返回
DELAY:MOV R5,#20H ;延时
BB:MOV R6,#0FFH
AA:DJNZ R6,AA
DJNZ R5,BB
RET
END
设置定时器初值及端口地址
TIMER1L EQU 30H
TIMER1H EQU 31H
PORTB EQU 0FFFDH
PORTC EQU 0FFFEH
PORT8255 EQU 0FFFFH
ORG 0000H
SJMP MAIN
ORG 001BH
AJMP TIMER1
ORG 0040H
MAIN:MOV TMOD, #00010000B ;T1方式一,软件控制
MOV TCON,#00H ;关闭T1
MOV IE, #10001000B ;开T1中断
MOV IP, #10001000B ;T1优先
CLR P3.4 ;关扬声器
CLR P3.2 ;点亮灯
ACALL DELAY ;延时
;MAIN PROGRAM
START:ACALL DELAY ;延时
ACALL KEYSCA ;调用键盘扫描子程序
CJNE R4,#00H,PLAYKEY ;判断有无键按下
CLR TR1 ;无键按下关闭T1
SETB P3.2 ;无键按下熄灭指示灯
SJMP START ;跳回开始位置
PLAYKEY: CJNE R4,#20H,K0 ;有键按下由键值给TIMER1L和TIMER1H赋值
MOV TIMER1L,#06H ;低音七初值
MOV TIMER1H,#0FEH
AJMP SOUND
K0:CJNE R4,#30H,K1
MOV TIMER1L,#22H ;中音1初值
MOV TIMER1H,#0FEH
AJMP SOUND
K1:CJNE R4,#50H,K2
MOV TIMER1L,#3DH ;中音#1初值
MOV TIMER1H,#0FEH
AJMP SOUND
K2:CJNE R4,#90H,K3
MOV TIMER1L,#56H ;中音2初值
MOV TIMER1H,#0FEH
AJMP SOUND
K3:CJNE R4,#21H,K4
MOV TIMER1L,#6EH ;中音#2初值
MOV TIMER1H,#0FEH
AJMP SOUND
K4:CJNE R4,#31H,K5
MOV TIMER1L,#85H ;中音3初值
MOV TIMER1H,#0FEH
AJMP SOUND
K5:CJNE R4,#51H,K6
MOV TIMER1L,#9AH ;中音4初值
MOV TIMER1H,#0FEH
AJMP SOUND
K6:CJNE R4,#91H,K7
MOV TIMER1L,#0AEH ;中音#4初值
MOV TIMER1H,#0FEH
AJMP SOUND
K7:CJNE R4,#23H,K8
MOV TIMER1L,#0C1H ;中音5初值
MOV TIMER1H,#0FEH
AJMP SOUND
K8:CJNE R4,#33H,K9
MOV TIMER1L,#0D3H ;中音#5初值
MOV TIMER1H,#0FEH
AJMP SOUND
K9:CJNE R4,#53H,K10
MOV TIMER1L,#0E4H ;中音6初值
MOV TIMER1H,#0FEH
AJMP SOUND
K10:CJNE R4,#93H,K11 ;中音#6初值
MOV TIMER1L,#0F4H
MOV TIMER1H,#0FEH
AJMP SOUND
K11:CJNE R4,#27H,K12
MOV TIMER1L,#03H ;中音7初值
MOV TIMER1H,#0FFH
AJMP SOUND
K12:CJNE R4,#37H,K13
MOV TIMER1L,#11H ;高音1初值
MOV TIMER1H,#0FFH
AJMP SOUND
K13:CJNE R4,#57H,K14
MOV TIMER1L,#1FH ;高音#1初值
MOV TIMER1H,#0FFH
AJMP SOUND
K14:CJNE R4,#97H,SOUND
MOV TIMER1L,#2BH ;高音2初值
MOV TIMER1H,#0FFH
SOUND:SETB TR1 ;开启t1
CLR P3.2 ;点亮指示灯
AJMP START ;跳回开始
;定时器1中断服务程序
TIMER1:MOV TL1,TIMER1L ;将初值付给t1
MOV TH1,TIMER1H
CPL P3.4 ;输出方波
RETI
;键盘扫描程序
KEYSCA: MOV A,#82H ; 初始化。控制字为:B口输入,C口输出
MOV DPTR,#PORT8255
MOVX @DPTR,A
MOV R4,#00H ;初值(无按键)付给r4
MOV DPTR,#PORTC ;全键盘扫描
MOV A,#00H
MOVX @DPTR,A
MOV DPTR,#PORTB ;读取扫描结果
MOVX A, @DPTR
ANL A,#0F0H ;屏蔽行信号,取出列信号
CJNE A,#0F0H,PRSD1 ;判断有无按键
SJMP DONE ;无按键退出
PRSD1:ACALL DELAY ;有按键延时后再扫描
MOV DPTR,#PORTB ;读取扫描结果
MOVX A, @DPTR
ANL A,#0F0H ;屏蔽行信号,取出列信号
CJNE A,#0F0H,PRSD2 ;判断有无按键
SJMP DONE ;无按键退出
PRSD2:MOV R2,#04H ;有按键逐行扫瞄
MOV R3,#01H ;行初值
SCAN:MOV A,R3 ;行初值送a
CPL A ;形成行扫描信号
MOV DPTR,#PORTC ;输出行扫描信号
MOVX @DPTR,A
MOV DPTR,#PORTB ;读取信号(扫描结果)
MOVX A, @DPTR
ANL A,#0F0H ;屏蔽行信号,取出列信号
CJNE A,#0F0H,FIND ;判断有无按键
MOV A,R3 ;无按键继续扫描,调整行信号
RL A ;调整行信号
MOV R3,A ;保存行信号
DJNZ R2,SCAN ;判断是否扫描完四行
SJMP DONE ;扫描完四行结束
FIND:CPL A ;找到按键计算键值
ADD A,R3 ;将行列值相加
MOV R4,A ;键值送R4
DONE:RET ;返回
DELAY:MOV R5,#20H ;延时
BB:MOV R6,#0FFH
AA:DJNZ R6,AA
DJNZ R5,BB
RET
END