Chinaunix首页 | 论坛 | 博客
  • 博客访问: 226373
  • 博文数量: 45
  • 博客积分: 1850
  • 博客等级: 上尉
  • 技术积分: 473
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-11 10:21
文章分类
文章存档

2006年(17)

2005年(28)

我的朋友

分类:

2006-05-09 14:50:09

于计算机的中央处理单元CPU来说,与之进行数据交换的除了存储器之外,还有输入输出设备(统称为外设)。指令系统具有丰富的寻址存储器操作数的指令,但只有输入IN和输出OUT指令可以从外设读取数据和向外设提供数据,由于设备种类繁多,其工作原理、数据格式、操作时序各异,所以处理器与外设之间还有一个协调两者数据传送的逻辑电路,称为输入输出(I/O)接口电路。处理器并不直接操纵外设,而是通过I/O接口控制外设。I/O接口电路示意图及其寄存器见http://www.cublog.cn/u/8327/showart.php?id=42325
由于外设的工作特点,处理器与之交换数据就不像与存储器那么简单,具体的数据传送方式有主要由软件程序控制的直接、查询和中断方式,还有主要由硬件完成的DMA和I/O处理机方法。
一、程序直接控制输入输出
对于一些工作速度较慢、接口电路比较简单的外设,程序中只要执行输入IN或输出OUT指令就可以实现数据传送。这就是所谓的程序直接控制输入输出,也称为无条件传送方式。
例如,PC微机的扬声器就可以采用程序直接控制。如下图,定时器2输出OUT2产生一定频率的方波,经滤波驱动后就是扬声器声音信号;但扬声器发声与否则是由PB0和PB1两位控制。PB各位对应的端口地址是61H,PB0和PB1对应数据D0和D1。PB0PB1=11控制扬声器发声,而PB0PB1=00,则扬声器不响。
例32.1:扬声器声音的控制。
分析:分别编写控制扬声器“响”与“不响”的子程序。主程序首先让声音出现,然后用户在键盘上按任意键后声音停止。
        .model tiny
        .code
        .startup
        call speaker_on
        mov ah,1
        int 21h
        call speaker_off
        .exit 0
speaker_on proc
        push ax
        in al,61h
        or al,03h
        out 61h,al
        pop ax
        ret
speaker_on endp
speaker_off proc
        push ax
        in al,61h
        and al,0fch
        out 61h,al
        pop ax
        ret
speaker_off endp
        end
二、程序查询输入输出
外设必须处于就绪(Ready)状态,才能与处理器交换数据。由于外设与处理器并行工作,要了解外设当前的工作情况,处理器可以主动查询外设的状态。在确信外设可以提供或接收数据时,处理器再进行数据的输入输出。程序需要查询外设状态,然后进行数据交换就是程序查询输入输出。由于外设可能因为故障等原因无法准备好,为了防止长时间查询而使系统陷于循环等待,实际的输入输出程序规定一个超时参数,在规定的时间内,外设一直没有准备好,放弃此次数据交换的过程。
PC微机的打印机就可以采用程序查询方式。要打印的字符首先提供给数据端口;然后查询状态端口,确定打印机是否可以接受这个数据;如果没准备好,继续检测到一个固定时间;一旦可以接受数据,处理器利用控制端口将数据提供给打印机。第一个打印机的数据、状态和控制端口依次是378H、379H和37AH;第二个打印机接口分别为278H、279H和27AH。
例32.2:打印机输出的控制
分析:将字符打印写成子程序,主程序提供打印机的基地址(378H或278H),欲打印的字符和设定的超时参数(实际的时间由计算机速度决定)。如果打印机能够接受字符,就返回CF=0,否则CF=1表示打印出错。
        .model small
        .stack
        .data
okmsg   db 'Good,my printer!',0dh,0ah,'$'
errmsg  db 'Not Ready,My printer!',0dh,0ah,'$'
        .code
        .startup
        mov cx,(sizeof okmsg)-1
        mov si,offset okmsg
prnbegin:
        mov dx,378h
        mov bc,100
        mov al,[si]
        call printchar
        jc prnerr
        inc si
        loop prnbegin
        mov dx,offset okmsg
        jmp prnok
prnerr: mov dx,offset errmsg
prnok:  mov ah,9
        int 21h
        .exit 0
;字符打印子程序
;入口参数:DX=打印机基地址,AL=打印字符的ASCII码,BX=超时参数
;出口参数:标志CF=0,表示打印正常;CF=1,表示打印错误
printchar  proc
        push cx
        out dx,al
        inc dx
print0: sub cx,cx
print1: in al,dx
        test al,80h
        jnz print2
        loop print1
        dec bl
        jnz print0
        stc
        jmp print3
print2: inc dx
        mov al,0dh
        out dx,al
        nop
        mov al,0ch
        out dx,al
        clc
print3: pop cx
        ret
printchar endp
        end
阅读(2866) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~