在8086系统中用汇编语言写一个钢琴键盘,利用中断实现,要求只需要8个键位按键盘上的顺序从‘A'到’K',对应C调到
时间: 2023-06-17 22:04:30 浏览: 25
下面是一个简单的钢琴键盘程序,按下对应的键位可以发出对应的音符。
```assembly
.model small
.stack 100h
.data
keymap db 0,0,0,0,0,0,0,0
keyindex db 0
toneTable dw 3822, 3405, 3033, 2863, 2551, 2272, 2024, 1911, 1703, 1517, 1432
; C5, D5, E5, F5, G5, A5, B5, C6, D6, E6, F6
; toneTable 中的值分别对应 C 调中的 C D E F G A B C D E F 音符的频率
.code
mov ax, @data
mov ds, ax
; 初始化键盘映射表
mov cx, 8
mov di, offset keymap
mov al, 'A'
init_keymap:
stosb
inc al
loop init_keymap
; 初始化键盘中断
mov ax, 0
mov es, ax
mov word ptr es:[9*4], offset keyboardHandler
mov word ptr es:[9*4+2], cs
mov ah, 25h
mov al, 9
int 21h
; 设置音符输出端口
mov al, 10110000b
out 43h, al
mov ax, 3577
out 42h, al
mov al, ah
out 42h, al
; 主循环
mainLoop:
mov ah, 0
int 16h
cmp ah, 0
je mainLoop
; 检查按键是否在键盘映射表中
mov bl, ah
mov bh, 0
mov di, offset keymap
mov cx, 8
check_key:
cmp [di], bl
je found_key
inc di
inc bh
loop check_key
jmp mainLoop
; 找到按下的键位在键盘映射表中的索引
found_key:
mov [keyindex], bh
; 输出对应的音符
mov si, offset toneTable
mov cx, [keyindex]
shl cx, 1
add si, cx
mov ax, [si]
out 0x61, al
mov al, inportb(0x61)
or al, 3
out 0x61, al
; 等待音符发射完毕
mov cx, 1000
wait:
loop wait
; 关闭音符输出端口
mov al, 10110000b
out 43h, al
mov ax, 0
out 42h, al
out 42h, al
jmp mainLoop
keyboardHandler:
push ax
push bx
push cx
push dx
; 读取键盘状态
in al, 60h
mov ah, al
mov al, 20h
out 20h, al
; 检查按键是否释放
test ah, 80h
jnz keyboardHandler_exit
; 发送键码到主程序
mov ah, 0
mov al, [keymap+ah]
stosb
keyboardHandler_exit:
pop dx
pop cx
pop bx
pop ax
iret
end
```
这个程序中,键盘中断处理程序会将按下的键码存储到 `keymap` 数组中。主程序会在每次循环中检查 `keymap` 数组,如果有键码被存储则会根据键码输出对应的音符。音符的控制使用了 x86 中的可编程中断控制器。程序中使用的音符频率表是 C 调中的音符频率表,可以根据需要修改。
注意,在运行此程序时需要将其编译成 DOS 可执行文件,并在 DOS 环境下运行。另外,这个程序只是一个简单的示例,实际的钢琴键盘程序可能需要更复杂的音符控制和键盘映射逻辑。