汇编:输入输出


预备知识

  1. 乐曲简谱中的每个音符及其节拍,在微机中对应了扬声器的发声频率和持续时间。其中简谱音符与扬声器的发声频率的对应关系见下表:

  2. 如何使 PC 机的扬声器发出指定频率和指定时间长度的声音?下面简单介绍一下 PC 机的发声原理:
    IBM-PC 系列机的主机箱装有一个小扬声器,系统板上的定时器 8253(或 8254)利用工作方式3 产生一定频率信号,通过可编程的并行外围接口芯片 8255(或 8255A)控制其发音。扬声器的控制驱动电路如下图所示。

  • 可编程的并行接口芯片 8255 有三个 8 位的并行端口:A 口、B 口和 C 口。在 IBM 系列微机中,BIOS 在开机自检后已将 8255 初始化为 A 口和 C 口用于输入,B 口用于输出。B 口的 I/O 端口地址
    为 61H。
  • 由图可见, 8255 的 B 口的低两位用来控制扬声器驱动,当 61H 端口的 D0 位为“1”时,控制 8254定时器产生驱动扬声器发声的音频信号,该位为“0”则不发信号。8254 有三个定时器,分为 0 号、1号和 2 号定时器,驱动扬声器的是 2 号定时器,该定时器工作在方式 3,是一个频率发生器,它负责向扬声器发送指定频率的脉冲信号。
  • 输出端口 61H 的 D1 位为“1”或为“0”时,将使控制驱动器的与门电路接通或关闭,使 8254 所发出的音频信号能到达驱动器或被阻断。这样通过控制 D1 位的变化,可使扬声器接通和断开,控制扬声器是否能发出声音。此外,通过控制 D1 位的通断时间,就能发出不同的音长。
  • 故当 8255 输出端口 61H 的 D1 位为“1”时,在 61H 的 D0 位为“1”,8254 发出指定频率的声音信号的前提下,声音信号通过与门到达驱动器驱动扬声器发声。即是,如要 8255 控制 8254 的 2 号定时器驱动扬声器发声,则需要的汇编命令如下:
OR AL, 00000011B
OUT 61H,AL
  • 同时,定时器 8254 的 2 号定时器使用 1.19MHz 的基准频率,故若要 8254 驱动扬声器发出指定频率的声音,则需要向 2 号定时器的计数常数寄存器(即 I/O 端口 42H)存放基准频率除以指定频率的商(即 122870H/指定频率),该商需分两次送往 I/O 端口 42H,先送商的低字节,再送商的高字节。同时,在使用定时器 8254 的 2 号定时器之前,需要初始化,即往 8254 的 2 号定时器的控制寄存器(即 I/O 端口 43H)写控制字 0B6H:
MOV AL, 0B6H
OUT 43H,AL

以上是控制扬声器发出一定频率的声音,若要让声音按指定时间持续,可使用 BIOS 提供的时间中断 INT 1AH 的 00H 号功能作延时,该功能提供了时间计数器的当前值。时间计数器计数一次的时间约为 55.072ms。
3. 实验箱电路及具体接线
(1)在实验箱中,原 8255 的 61H 端口使用发生了变化:
需要把实验箱 8255 的控制口(28bh)进行初始化,然后再对 288H 端口进行写操作。因为以上端口号超过了 255,故写端口时,需要用 DX 寄存器暂存端口号,如下:

mov dx,28bH
mov al,10000000B
out dx, al
mov dx,288h
mov al,03h
out dx, al

(2)8254 的 2 号定时器初始化的端口从 43H 变成了 283H,且需要写控制字 00110110B,如下:

mov dx, 283H
mov al, 00110110B
out dx, al

且原 2 号定时器的计数常数寄存器端口(42H 端口)改为了 280H。

8255/CS接I/O 地址译码/Y1(288H——28FH)
8255/PA0接与门/A
8254/CLK0接时钟/1MHz
8254/CS接I/O 译码/Y0(280H——287H)
8254/OUT0接 与门/B
8254/GATE0接与门/Y
8255/PA1接 喇叭

要求

试设计一个程序,能够使用键盘中字母键模拟钢琴按键发音。其中,按照字母在键盘中的排列方式,字母键 z/x/c/v/b/n/m 分别发出低 1—低 7 共 7 个低音音符,字母键 a/s/d/f/g/h/j 分别发出中 1—中 7 共 7 个中音音符,字母键 q/w/e/r/t/y/u 分别发出高 1—高 7 共 7 个高音音符。按 ESC 键退出程序。

源代码

assume ds:data, ss:stack, cs:code
data segment

    dw 'z', 'x', 'c', 'v', 'b', 'n', 'm'
    dw 'a', 's', 'd', 'f', 'g', 'h', 'j'
    dw 'q', 'w', 'e', 'r', 't', 'y', 'u'
    dw 131, 147, 165, 175, 196, 220, 247
    dw 262, 294, 330, 349, 392, 440, 494
    dw 524, 587, 659, 698, 784, 880, 988

data ends

stack segment
    dw   128  dup(0)
stack ends

code segment
start:
; set segment registers:
    mov ax, data
    mov ds, ax    
    mov ax, stack
    mov ss, ax 
    mov sp, 256
;调用子程序
    call piano
; exit to operating system.
    mov ax, 4c00h 
    int 21h  

piano proc              
    ;初始化2号定时器

    mov dx, 283h      
    mov al, 00110110b
    out dx, al  
      
lop:   
    ;char 输入至 al.存入bl    
    mov ah, 1
    int 21h
    mov bl, al  
    ;判断esc
    cmp bl, 27   
    je stop 
    
    ;循环比较key----------------------
    mov cx, 21
    mov si, 0         ;记录key位置
compare:   
    cmp bl, ds:[si]
    ;不同则跳过
    jne continue 
    ;相同则发声并退出compare
        mov bx, ds:[si][42]; 存频率
        ;求商 -> 2号定时器的计数常数寄存器
        mov dx, 12h
        mov ax, 2870h
        div bx

        mov dx, 280h
        out dx, al
        mov al, ah
        out dx, al
                       
        ;控制2号定时器驱动扬声器发声 

        mov dx, 28bh        ;初始化控制口
        mov al, 10000000b    
        out dx, al
        
        mov dx, 288h        ;写端口
        mov al, 03h
        out dx, al 
        
        ;持续一会就结束  
        call delay 

            
        mov dx, 288h        ;写端口
        mov al, 0h
        out dx, al 
            

 
        jmp break
continue:    
    add si, 2
    loop compare  
    ;循环比较key---------------------
    
break:    
    jmp lop
stop:
    ret ;返回主程序 
piano endp       

delay proc 
    push cx
    push ax 
    push bx 
    push dx
    mov ah, 0 ;获取时钟
    int 1ah        
    mov bx, dx;存闹钟
    add bx, 50 ;延时0.2s
dlop:    
    mov ah, 0 ;获取时钟        
    int 1ah 
    cmp dx, bx 
    jb dlop
    pop dx
    pop bx    
    pop ax
    pop cx
    ret
delay endp    
code ends

end start ; set entry point and stop the assembler.


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM