发新话题
打印

查询传送方式

查询传送方式


查询传送方式
- }0 j! v1 v+ {( x" K  |; M. D  采用这种传送方式,传送前先查询外设的状态,当外设准备就绪后才进行传送,否则继续查询,直至外设准备就绪。实际上在外设准备就绪之前,CPU不能做别的事,一直处于等待状态。
: M8 O$ Y5 e* p) d  1.查询输入接口电路 6 u6 w. j9 s/ J! Q
  如图4.6所示是一个典型的查询方式输入接口电路。它包含了两个端口。一个是状态口,为输入端口,可理解为无条件的端口(CPU可随时读取输入设备的状态)。另一个是数据端口,也是一个输入端口,用来读取设备的数据。电路中的寄存器用来存放设备的数据,可理解为输入缓冲器。电路中的触发器(Ready)起两个作用,一是表示设备的状态,二是通知设备CPU是否已取走输入缓冲器中的数据。5 f4 x( n' j1 h7 G
) ]5 }( m" P5 Q  J0 `5 x+ y
# ?& v/ P/ k; {' r
9 Q: J5 U) v, ^4 k

8 A2 \+ p4 {6 S- c# r4 D& ? 7 l3 ?( u% q  @& h& ]' ?2 Q
    当外设准备好一个数据后,STB(strobe)端产生一个选通信号,该信号将数据送入输入缓冲器,供CPU读取,同时将Ready触发器置成1。Ready被置1起两个作用:一是表示设备已准备好,输入数据已经放到输入缓冲器中;二是通过与设备的IBF(Input Buffer Full)端的连接告诉设备,输入缓冲器满,CPU尚未取走数据,暂时不要送新的数据。
5 T7 A$ z! l5 t    CPU可按照图4.7所示的流程来读取输入设备的数据。/ h2 ^$ C! ^$ q
+ v/ s  h6 q3 A& z7 ?" u' {3 j9 S
3 p1 y1 E5 I' ?
) R7 T; y4 U8 C% ?

3 `  L/ j5 g2 n3 L 2 C; \. T" m. }  Y) y
实现这个流程的8086/8088汇编程序如下:7 T# O3 @! _; F* m; ]

; f) s' Z- P. x/ D4 A! S7 v  G0 a2 D. U' D1 P. N6 U! v1 o2 ^+ `

6 y" |1 `, M; f5 L1 y) v( D& p/ H
% B. O0 j, K; S/ m2 m2 m
实现这个流程的c语言程序为 0 W* x: x. a8 @# e5 t6 a& X
    While((inportb(status_port)&1)==0);    /*“==”是等号*/
8 B, N" S" w8 K0 C5 k    A=inportb(data_port); * s5 p! V0 p+ W1 i% @/ d7 H! }: Y
    第一个语句中的“&;amp;”是“按位与”运算符。之所以将从状态口读入的值和1相与,是因为状态信息经三态缓冲器接到数据线DO上。该While语句没有循环体。它的作用是读取设备状态,如果状态为0(与的结果为0),则继续读设备状态,直至状态变为1。也可这样说,读取设备状态,如果状态为0,则等待,直至状态变为1。第二语句的作用等同于上面汇编程序的第四条指令,从数据口读取数据。
) F! M2 Q1 i7 U; X" g; _( U: p3 j  有时为了简化电路将状态位和数据共用一个端口。例如,某设备的数据为12位,这时,可将低8位数据设置用一个端口,而将数据的高4位和状态位共用一个端口。将状态信息接到数据线D15,将设备数据的高4位分别接到数据线D1l~D8,这样,从该状态/数据端口
% H# b' x5 \9 C读人的信息的格式如下所示:
1 ~+ {# J+ q9 E, r5 w  Q; v0 H. h* X* y6 K$ _

& y, o: A9 @* @
$ v8 z. \  Y$ v6 H     
* ]6 U' [9 H6 C' u8 ^: c  如果所设计的接口仅使用数据总线的低8位,则可这样安排:将状态信息接到数据线D7,将设备数据的高4位分别接到数据线D3~D0,这样,从该状态/数据端口读人的信息的格式如下所示: 0 E# ~( e* n2 X' W8 |+ z
2 C9 L' ]- ]/ d3 n
2 a0 K# o/ [1 C

8 P$ D1 ], G4 S7 q  n
% v; b0 u' s6 ~/ N# D* L   
: K+ m- s& L: B3 H( A( l, X0 D  无论是哪一种接法,都首先读取含有状态信息的端口。当发现状态位有效时,这一次同时读入的数据位也有效。在从低8位数据端口读取数据之后,将两个字节数据进行下面简单的运算可得到12位设备数据:
" [1 t' v* m. s  12位设备数据=(从状态/数据端口读出的内容 &;amp; OxOf)×256 低8位数据。 ; z& x1 F& f( o" s5 {) s3 s
  另外,如果将这两个字节型端口的地址设计成连续的,则它们可组成一个字型端口。这时,可用一条字型输入指令或c语言的字型输人语句一次读入状态信息和12位数据。
6 {* n* I2 Y. ^2 ]  w6 Q) B' _7 N  2.查询输出接口电路
2 Y0 k0 [0 g* \! W, P9 |# K" W7 J+ ^, [9 O$ l2 Y
4 f( D1 U' o. ~" P, ]
5 G  X1 G8 n% ]/ Z6 Z& E# E
" j$ M' C! W4 T) v2 c2 a
图4.8是一个典型的查询方式输出的接口电路。它包含了两个端口:一个是状态口,为输入端口,可理解为无条件的端口(CPU可随时读取输出设备的状态);另一个是数据端口,是输出端口,用来存放输出的数据。该端口的寄存器可理解为输出缓冲器。电路中的触发器(Busy)起两个作用。一是表示设备的状态,为1时,表示设备忙”。二是通知设备,CPU是否已将数据送到输出缓冲器中,为1表示数据已送到输出缓冲器。当输出设备利用完输出缓冲器中的数据时,发出一个响应信号(Acknowledge),将Busy触发器清0。因此,要了解外设是否为空,只要看Busy是否为0。CPU输出一个字节数据的流程如图4.9所示。实现这个流程的8086/8088汇编程序如下:  ]& }2 P2 W( Q/ m
  $ o# w' k. x4 ?1 x1 z2 J

1 z+ f8 J) g) ^6 I- j1 t& t  y7 ?  m3 \( e8 t
  * W+ C' n4 G; H
RDSTS:IN AL,STATUS_PORT      ;读入状态信息(STATUS_PORT为状态口符号   地址)
  c7 c: n) T' ~8 u; n    TEST AL,80H                                ;检查设备是否“忙”(状态位接数据线D7)
0 i3 ]' b  r7 [; y9 m0 g/ ^    JNZ RDSTS + K# l$ q/ }2 D0 D$ \
    MOV AL,DATA_V                        ;将输出数据送AL(变量DATA_V中存放着要输出的数据) : `* p7 L; u, f% h+ b/ O
    OUTD ATA_PORT,AL            ;输出数据至端口,同时将Busy置1,通知设备,
4 u1 V4 F* }' y7 S. e- h                                                         ;输出缓冲器中已有新的数据,设备可以利用。
9 t1 `" R& I2 O6 F4 [9 |                                                         ;(DATA PORT为数据口符号地址)
" ~2 \; T, F5 m( V) d  ]  实现这个流程的c语言程序为   K6 ]  H  ~! F+ W
    While((inportb(status_port)&0x80)!=0);    /*“!=”是不等号*/
: _7 m3 G( A/ _7 P    outportb(data_port,data); + V, t/ b; j- D5 ^) b, h
  第一个语句的功能和前面查询输入程序中的第一个语句相似,不同点在于这里状态位接的是数据线D7,所以读出的状态口内容要和0x80“相与”。当“与”的结果为0时,While语句的判断条件不再成立,故转去执行第二个语句,输出数据至数据端口。   x) ^4 K0 g* V
  3.查询传送方式举例 0 g" _- T# F; s
  图4.10所示为一个采用查询方式的数据采集系统的电路,该系统使用8位A/D (Analog/Digital)转换器采集16路模拟量信号。这里的模拟量是指模拟电压信号,即连续变化的直流电压信号,一般为0~5 V或0~10V。A/D转换器一次只能转换一个模拟量,如果有多个模拟信号需要转换,一种低成本的做法是通过模拟开关,每次选择其中的一路信号接通A/D转换器的输入端。对于16路模拟信号,可以用4位二进制数来选择,称这4位二进制数为通道地址,一个通道地址对应一路模拟信号。选择模拟通道,即给出通道地址需要一个输出口,显然这是一个无条件输出口。模拟开关实际是一种电子开关,内部具有译码功能。理想的模拟开关应具有这样的特性:接通时电阻为0,断开时电阻为无穷大,而接通或断开的延时为0。
+ A* `8 _) x2 ]  T/ E0 G/ O& o7 h$ d* d+ g+ u. ~0 T2 I2 B% }& t6 Z

9 V" i/ H0 H6 T3 A" d% p# `  R+ \4 [% s) U7 _3 ^
8 Z1 w. Q7 H8 u! f/ x! K& I
   启动A/D转换需要一个启动信号(START)。这里假定它是一个负脉冲,其后沿(上升沿)启动A/D转换。启动信号可用硬件方法产生,也可用软件方法产生。这里采用后者,并和送模拟通道地址共用一个输出口,占用其中一位(D4)。A/D转换需要一定的时间,是否转换结束看EOC(End 0f Conyren)信号。在启动A/D时,EOc由高电平变低电平,低电平表示正在进行转换,一旦转换完成,则由低电平变高电平。读EOC信号需要一个输入端口。在EOC变为高电平即转换结束时,可读取转换数据,这需要一个输入端口。如图4.10中的三个端口都采用了简略表示。例如,标注“端口3”的方框表示在同时满足三个条件时,A/D转换数据可通过该端口的三态缓冲器进入数据总线。这三个条件是:M/IO为低电平,即当前为I/O操作周期;而为低电平,即处于而命令有效期间;地址译码器在端口3的地址出现时
, @* [' n* d6 L. ?) ^  _对应的输出有效(为低电平)。参考图4.2和图4.4,读者可以自行完成这三个端口完整的逻辑表示图。0 f! L' b. ?( e4 c2 S) ~& j" ?! K
    @. x4 m9 N& V: |
3 Z! A7 r, ]8 n
" m: z' }: V1 P3 r# ^( ~2 ~3 E+ s" Y
  
/ `. ~! G1 u6 E3 F    依次对16路模拟量转换一次的程序流程如图4.11所示。其中i既作循环变量,又表示通道地址。实现这一流程的c程序如下:. z8 K1 J( Z& ?8 u: Z
: r' x; C! N  V

7 U! e) O! ]% `' U$ h* D+ Q. f/ \' Z$ `- N/ v

2 ~: o. [8 e' {* Q0 H. f
% z0 u' I  }- N  K
2 P3 x  T+ H6 c
* X+ b, l1 a3 c; f- ]- ?1 _
! T% N( x. g1 k; b, o: `% x+ R0 s 其中,“|”是“按位或”运算符;Addr_port、Status_port、Data_port分别为送通道地址端口、读转换结束状态端口和读转换数据端口的地址;adv[]是一个外部数组,用来存放转换数据。
. h/ V( M+ S4 S5 R' h2 x! `2 M* }# ~/ a注意到送通道地址端口的第4位(D4)输出对应START信号,低4位(D3~D0)为通道地址,这就不难理解程序中数据OxeO和OxfO的作用了。
1 X! r0 r3 ^: j4 [& r7 n( g' }  主程序需要使用A/D转换数据时,调用一次ad convert()函数即可,如下所示:- n% G2 X5 e% }8 l  Y
……
% N. S( `; P( p# i0 Uad_convert();
# g8 q4 v! {' p9 Q. J; u& a. N……    /*可直接利用adv[  ]中的元素*/



点击图标进入精品网摘收藏 欢迎大家加入网络收藏夹

TOP

发新话题