第6章 DMA传输 6.1 DMA传输原理 6.2 DMA控制器8237A 6.3 8237A的编程使用 欢迎辞
(Direct Memory Access—DMA) 直接存储器传送 (Direct Memory Access—DMA) 将外设的数据不经过CPU直接送入内存储器,或者,从内存储器不经过CPU直接送往外部设备 一次DMA传送只需要执行一个DMA周期(相当于一个总线读/写周期),因而能够满足高速外设数据传输的需要。
6.1 DMA传输原理 1. DMA控制器 使用DMA方式传输时,需要一个专门的器件来协调外设接口和内存储器的数据传输,这个专门的器件称为DMA控制器,简称DMAC。
DMAC内部的寄存器: 地址寄存器:存放DMA传输时存储单元地址; 字节计数器:存放DMA传输的字节数; 控制寄存器:存放由CPU设定的DMA传输方式, 控制命令等; 状态寄存器:存放DMAC当前的状态,包括有无 DMA请求,是否结束等。
图6-1
DMAC在系统中有二种不同的作用: 总线从模块: CPU对DMAC进行预置操作,也就是向DMAC写入内存传送区的首地址、传送字节数和控制字时,DMAC相当于一个外设接口,称为总线从模块。 总线主模块: 进行DMA传输时,CPU暂停对系统总线的控制,DMAC取得了对总线的控制权,这时的DMAC称为总线主模块。
2. DMA传输过程 总线请求:DMAC向CPU申请使用总线 总线控制转移:CPU同意DMAC管理总线 数据传输:外设接口和存储器之间传输数据 修改地址和计数器:为下一次传输做准备 结束处理:DMAC放弃对总线的控制权 以上的过程完全由硬件电路实现,速度很快。 用DMA方式进行一次数据传输所经历的时间称为“DMA周期”,大体上相当于一次总线读写周期的时间。
[例]:用DMA方式将串行通信口接收到的200字节 的数据存入以BUFFER为首地址内存区域 对DMAC进行预置:向DMAC写入内存首地址,传输字 节数(200),传输方向(外设接口→内存),控制命令 (允许DMA传输)等; 对串行通信接口进行初始化,设置串行通信的参数,允 许串行输入等; 串口每输入一个数据,自动进行DMA传输; 最后一个数据传输结束后,DMAC发出传输结束信号 EOP。CPU可以通过查询知道传输已经结束,也可以利 用EOP信号申请中断,在中断服务程序里进行结束处理。 DMA方式传输200字节过程为:1次对DMAC初始化, 1次对串口初始化, 200次DMA周期,1次结束处理。
8086系统中的DMA信号 最小模式 CPU通过HOLD接收DMA控制器的总线请求; 在HLDA引脚上发出对总线请求的允许信号。 最大模式 通过RQ/GT0和RQ/GT1引脚接收DMA控制器的总线请求,发送对总线请求的允许信号。 RQ/GT0引脚有较高的优先权。
6.2 DMA控制器8237A 1. 8237A芯片的主要特点 有4个完全独立的DMA通道,可分别进行编程控制。 数据块最大为64KB,每传送一个字节后地址自动加1或减1。 DMA请求可以由外部输入,也可以由软件设置。 可以用级联的方法扩展DMA通道数。 可以进行从存储器到存储器的数据传输,用于对存储区域进 行初始化。
2. 8237A的工作方式 (1)单字节传输方式 8237A每申请一次总线,进行1个字节传输,然后释放系统总线,一次DMA传输结束。 CPU可以在每个DMA周期结束后控制总线,进行数据传输,所以不会对系统的运行产生大的影响。 (2)块传输方式 DMA控制器获得总线控制权后,可以连续进入多个DMA周期,进行多个字节的传输(最多64K字节)。 这种方式可以获得最高的数据传输速度。如果一次传输的数据较多,对系统工作可能产生一定的影响。
(3)请求传输方式 申请一次总线可以连续进行多个数据的传输。 每传输1个字节后,8237A都对外设接口的请求信号 进行测试: DREQ端无效,暂停传输; DREQ有效,接着进行下一个数据的传输。 允许数据不连续,按照外设的最高速度进行数据传输, 使用比较灵活。
(4)级联传输方式 几个8237A进行级联,一片8237A用作主片,其余用 作从片,构成主从式DMA系统。 从片收到外设接口的DMA请求信号后,向DMA控制器 主片申请,再由主片向CPU申请。 一片主片最多可以连接四片从片。这样,五片8237A 构成的二级DMA系统,可以得到16个DMA通道。 级联时,主片通过软件在方式寄存器中设置为级联 传输方式。从片设置成上面的三种方式之一。
3. 8237A的传输类型 (1)DMA写传输(I/O→存储器) (2)DMA读传输(存储器→I/O) (3)DMA检验 (4)存储器到存储器传输
6.2.2 8237A的内部结构和外部连接 8237A的内部结构分成二部分: 四个DMA通道和一个公共控制部分
1. DMA通道 8237A有四个独立的通道(CH0一CH3) 每个通道: 16位地址寄存器; 16位字节计数器; 8位方式寄存器; 1位的屏蔽触发器。 四个通道公用一个控制寄存器和一个状态寄存器。
DMA通道--地址寄存器 由基地址寄存器和当前地址寄存器组成。 对8237编程时,把本通道DMA传输的地址初值写入基地址寄 存器,再由8237A传送到当前地址寄存器。 当前地址寄存器在每次DMA传输后自动加 1或减1。 CPU可以通过输入指令读出当前地址寄存器值(每次读8位)。 基地址寄存器不能被读出,且一直保持初值。 数据块传送完成后,可以把当前地址寄存器的内容恢复为基 地址寄存器保存的初值。 (需要在编程时设置“自动预置”方式)
DMA通道--字节计数器 字节计数器由基本字节计数器和当前字节计数器组成。 每进行一次DMA传输,当前字节计数器自动减1。它的值由0 减到FFFFH(-1)时,产生计数结束信号EOP。 当前计数器的值可以由CPU通过输入指令分两次读出。
2. 读/写逻辑 8237A在系统总线中作为“从模块”时 接收CPU对I/O接口的读(IOR#)、写(IOW#)信号; 2. 读/写逻辑 8237A在系统总线中作为“从模块”时 接收CPU对I/O接口的读(IOR#)、写(IOW#)信号; 对地址总线的低4位 (A0 ~A3) 译码; 片选和IOW#信号有效时,把数据总线的内容写入所寻 址的寄存器; 片选和IOR#有效时,把选择的寄存器内容送到数据总 线上。
2. 读/写逻辑 8237A在系统总线中作为“主模块”时 DMA写周期: DMA读周期: 读/写逻辑产生IOR# 2. 读/写逻辑 8237A在系统总线中作为“主模块”时 DMA写周期: 读/写逻辑产生IOR# 控制逻辑产生存储器写(MEMW#) 数据从外设接口传送到存储器单元; DMA读周期: 读/写逻辑产生IOW# 控制逻辑产生存储器读(MEMR#) 数据从存储器单元传送到外设接口。
3. 控制逻辑 DMA周期内,控制逻辑通过产生控制信号和16位要存取的存储单元地址来控制DMA操作步骤。 3. 控制逻辑 DMA周期内,控制逻辑通过产生控制信号和16位要存取的存储单元地址来控制DMA操作步骤。 初始化时,通过对方式寄存器编程,使控制逻辑可以对各个通道的操作进行控制。
4. 锁存缓冲器(外接) 使用8237A工作时,需要外接一个八位的地址锁存缓冲电路,它能够储存八位的地址信号,通过可控的三态门连接系统地址总线。 在DMA传送之前,8237A从DB0~DB7把存储器地址的A8~A15送入这个锁存器。 在DMA周期里,锁存器将锁存的地址送往系统地址总线的A8~A15,同时从A0~A7引脚发送地址的低八位。
5. 页面地址寄存器(外接) 8237A控制了地址总线的16位,所以最多只能连续传送64K字节的数据。 为了控制8086系统20位的物理地址,需要外接一个四位的“页面地址寄存器”(PC机地址:83H) 页面地址寄存器的值由CPU写入 8237A发送低16位地址时,高四位的地址从页面地址寄存器发往地址总线的A16~A19
6.2.3 8237A的对外连接信号 8237A作为从模块时的引脚信号(1) RESET—复位输入端,高电平有效。复位时,屏蔽寄存器 被置1,其他寄存器均清0。 CS# ——片选输入端,低电平有效,由A4~A15译码得到。 为低电平时,8237A被选中,CPU可以对8237A进 行读写(进行预置或读取工作状态)。 A3~A0—最低的4位地址线,双向信号引脚。DMA控制器 作为从模块时,A3~A0作为输入端,用来选择 DMAC内部的16个端口地址。
8237A作为从模块时的引脚信号(2) IOR#——I/O设备读信号,双向、三态、低电平有效。 作为从模块时为输入。有效时,CPU读DMA控 制器内部寄存器的值。 IOW#——I/O设备写信号,双向、三态、低电平有效。 作为从模块时输入。有效时,CPU向DMA控制 器的内部寄存器中写入信息(进行编程)。 DB7~DB0——8位双向三态数据线。DMA控制器作为从 模块时,CPU通过DB7~DB0对8237A进行读写。
8237A作为总线主模块时的引脚信号 (1)地址信号 A3~A0—— DMAC为主模块时,提供存储器最低4位地址 (输出) 。 DB7~DB0— 输出当前地址寄存器中的高8位地址,并通过信号 ADSTB打入外部锁存器,和A7~A0输出的低8位 地址一起构成16位地址。
地址信号 ADSTB——地址选通信号,输出,高电平有效。信号有效 时,将DMAC高8位地址经DB7~DB0送到外部 锁存器。 AEN——地址允许信号,输出,高电平有效。 把高12位地址(地址锁存器中高8位、页面地址寄 存器最高4位)一起送到地址总线上,与芯片直接 输出的低8位地址共同构成20位内存地址。 AEN信号也使与CPU相连的地址锁存器无效。保证 地址总线上的信号来自DMA控制器,而不是来自 CPU。
(2)对存储器/外设接口的读写控制信号 IOR#——作为主模块时,IOR#输出外设接口的读控制信 号,信号有效时,I/O接口部件中的数据被读出 送往数据总线。 IOW#——作为主模块时,IOW#输出外设接口的写控制信 号,信号有效时,存储器中读出的数据被写入 I/O接口中。 READY——准备就绪信号,输入,高电平有效。所用的存 储器或I/O接口的速度较慢时,使READY处于 低电位,8237A会自动插入等待周期。数据准备 就绪时,READY端为高电平,表示可以进行数 据传输。
(2)对存储器/外设接口的读写控制信号 MEMR#——存储器读信号,低电平有效,输出。信号有效 时,所选中的存储器单元的内容被读到数据 总 线。 MEMW#——存储器写信号,低电平有效,输出。信号有 效时,数据总线上的内容被写入选中的存储单 元。
(3) DMA联络信号 DREQ——通道DMA请求信号,输入。 每个通道对应一个DREQ信号端,它的极性可以 通过编程来选择。 外设接口要求DMA传输时,使DREQ处于有效, DMAC控制器送来DMA响应信号DACK以后, 接口撤除DREQ的有效电平。 DACK——通道DMA应答信号,输出。DMAC送给接口的回答 信号,每个通道有一个DACK信号端。 DMAC获得CPU送来的总线允许信号HLDA以后, 产生DACK信号送到外设接口。 DACK信号的极性可以通过编程选择。该信号相当 于IO接口的地址选择信号。
HRQ——总线请求信号,输出。8237A收到外设接口发来 DREQ信号后,如果该通道的DMA请求没有被 屏蔽,DMAC通过HRQ端向CPU发出总线请求。 HLDA——总线响应信号,输入。DMAC向CPU发总线请 求信号HRQ以后,CPU发回的总线响应信号。 8237A收到该信号后,便获得了总线控制权。HLDA 也称为总线保持回答信号。 EOP#——DMA传输结束信号,低电平有效,双向。 从外部向DMAC送一个 EOP# 信号时,DMA传输过程 被强制性地结束。 DMAC任一通道计数结束时,EOP#会输出一个有效 电平,作为DMA传输结束信号。可以使用EOP#信号向 CPU申请中断,进行DMA传输的结束处理。
3. 其他引脚信号 CLK——时钟输入端。 8237A的时钟频率为3MHz; 8237A-4的时钟频率为4MHz; 8237A-5的时钟频率为5MHz 后面两种DMA控制器是8237A的改进型,工作 速度比较高,但工作原理及使用方法相同。 电源,地——提供8237A工作所需要的+5V电源。
4. 小结 (1)作为从模块工作时 CPU对8237A进行预置或读取状态,8237A相当于一个I/O接口 4. 小结 (1)作为从模块工作时 CPU对8237A进行预置或读取状态,8237A相当于一个I/O接口 CPU发来的高12位地址经过地址译码器产生片选信号,使得CS为低电平,表示本芯片片被选中。 CPU发来的低4位地址送到8237A的相应引脚,选择内部寄存器。 IOR#和IOW#作为输入信号,用作对8237A的读写控制。 IOR#为低电平:CPU读取8237A内部寄存器的值。 IOW#为低电平:CPU将数据写入8237A的内部寄存器。
(2)作为主模块工作时 向总线提供要访问的内存地址: 高八位地址在ADSTB信号的配合下,通过DB7~DB0输出到外部连接的地址锁存缓冲器。 低八位通过A7~A0输出 AEN输出高电平: 选通外部锁存器的输出三态门,将锁存器高8位地址送往A15~A8 页面地址寄存器向A16~A19输出4位地址 与CPU相连的三个地址锁存器停止工作 在整个数据块的传输过程中,页面4位地址保持不变,因此,DMA传输的字节数限制在 216以下。
(2)作为主模块工作时 向接口和存储器提供读写控制信号: 输出IOR#和IOW#,控制外设接口的数据传输方向。 输出MEMR#和MEMW#,控制存储器的读写。
6.2.4 8237A的工作时序 8237A使用独立于CPU的时钟; 时钟周期分为两大类: 空闲周期 有效周期 周期也称为状态(STATUS)。
1. 空闲周期SI 8237A复位后就处于空闲周期: 在此周期,CPU可对8237A作初始化编程 或者,虽然已经初始化,但还未有DMA请求输入。 空闲周期中,8237A要检查DREQ的状态,确定是否有通道请求DMA服务。 同时也对CS端采样,判定CPU是否要对8237A进行读写操作。
2. 有效周期(由S0~S4五种周期组成) S0--等待周期 S1—地址周期 8237A接到外设的DREQ请求,向CPU发出了HRQ,等待CPU让出总线控制权。 得到来自CPU的HLDA响应后,结束S0状态。 S1—地址周期 8237用DB0~DB7送出高8位地址A8~A15 用ADSTB将高8位地址送入锁存器 使AEN有效 传输一段连续的数据时,存储器地址是相邻的,高8位地址往往是不变的。此时,S1可以省略。
S2—数据读出周期: S3--数据写入周期: 向外设送出DACK信号,启动外设工作 送出数据读控制信号 送出写操作所需的控制信号: DMA读操作--送出MEMR# DMA写操作--送出IOR# S3--数据写入周期: 送出写操作所需的控制信号: DMA读操作--送出IOW# DMA写操作--送出MEMW# S3状态结束时: READY无效,插入SW周期 READY有效,进入S4周期
? S4之后应该是哪一个周期? S4—结束周期: 结束本次一个字节传输。 存储器之间数据传输: 从源地址中读出一个字节,存入8237A暂存寄存器 将这个字节写入目的地址中 每个阶段的完成都要经过4个周期(状态)。
扩展写 写控制信号一般在S3开始有效; 采用扩展写方式,写信号在S2就开始变得有效这种做法可以增加写操作时间,满足某些设备的需要。
压缩时序 正常时序中,S1用于锁定高8位地址 S3是一个延长周期,用来保证可靠的读写操作 省略S3之后的时序称为压缩时序
6.3 8237A的编程使用 8237A: 地址锁存器(外配,不占用端口地址): 页面寄存器(外配,端口地址83H): 共占用16个端口地址(PC机内地址00~0FH) 每个通道占用2个端口地址(共8个) 其余8个端口地址由各通道共用 地址锁存器(外配,不占用端口地址): 锁存8237A送出的高8位地址信号 发送高8位地址信号 页面寄存器(外配,端口地址83H): 存储和发送最高4位地址信号A19~A16 与8237A发出的16位地址组合得到20位地址信号
地址 读操作 写操作 读通道0基地址寄存器 写通道0当前地址寄存器 1 读通道0基本字节计数器 写通道0当前字节计数器 2 读通道0基地址寄存器 写通道0当前地址寄存器 1 读通道0基本字节计数器 写通道0当前字节计数器 2 读通道1基地址寄存器 写通道1当前地址寄存器 3 读通道1基本字节计数器 写通道1当前字节计数器 4 读通道2基地址寄存器 写通道2当前地址寄存器 5 读通道2基本字节计数器 6 读通道3基地址寄存器 写通道3当前地址寄存器 7 读通道3基本字节计数器 写通道3当前字节计数器 8 读状态寄存器 写命令寄存器 9 写请求寄存器 10 写单个屏蔽寄存器 11 写工作方式寄存器 12 清除先/后触发器 13 读暂存寄存器 写总清寄存器 14 屏蔽位总清命令 15 综合屏蔽命令
6.3.1 8237A通道专用寄存器 每一通道内包含四个16位的寄存器: 每个通道内有一个8位的模式寄存器 基地址寄存器 基字节数寄存器 现行地址寄存器 现行字节数计数器 存放DMA传输的存储器地址及数据字节数 每个通道内有一个8位的模式寄存器 记录通道的工作方式
1. 基地址寄存器和基字节数寄存器 基地址寄存器存放DMA传送的内存起始地址: 基字节数寄存器存放DMA传送的字节数减1 寄存器的内容在初始化时由程序写入 先写低字节,后写高字节 在整个数据块的DMA传输过程中内容保持不变 写入后,其内容同时传送到现行地址寄存器 基字节数寄存器存放DMA传送的字节数减1 写入后,其内容同时传送到现行字节数寄存器 这二个寄存器的内容只能写入,不能读出。
2. 现行地址寄存器 来自基地址寄存器 存放DMA传送的当前地址值 每次DMA传送后,该寄存器的值自动增量或减量 2. 现行地址寄存器 来自基地址寄存器 存放DMA传送的当前地址值 每次DMA传送后,该寄存器的值自动增量或减量 可由CPU读出(先低位,后高位) 若设置为自动预置,则在每次计数结束后,自动恢复为它的初始值(即保存在基地址寄存器中的初值)。
3. 现行字节数寄存器 存放DMA传送过程中没有传送完的字节数减1 每次传送后,寄存器的值自动减1 3. 现行字节数寄存器 存放DMA传送过程中没有传送完的字节数减1 每次传送后,寄存器的值自动减1 该寄存器的值减为FFFFH(-1)时,数据块传送结束,EOP#引脚变为低电平 寄存器的值可由CPU读出 若设置为自动预置,则在每次计数结束后,自动恢复为它的初始值(即保存在基字节数寄存器中的初值)。
4. 方式寄存器 (BASE+0BH) 图6-3
6.3.2 8237A通道公用寄存器
1. 控制寄存器(BASE+08H) 图6-4
2. 状态寄存器(BASE+08H) 图6-5
3. 请求寄存器(BASE+09H) 图6-6
屏蔽寄存器(BASE+0AH) 图6-7
综合屏蔽寄存器(BASE+0FH) 图6-8
4. 复位命令(BASE+0DH) 复位命令的功能和RESET功能相同: 使控制寄存器,状态寄存器、DMA请求寄存器、暂存器以及先/后触发器都清0 使屏蔽寄存器置位 对端口地址为BASE+0DH的端口实施一次写操作, 可以实现对8237A的复位操作。
清除先/后触发器(BASE+0CH) 8237A内的“先/后触发器” : 为0时,访问16位寄存器的低字节; 为1时,访问高字节 每访问一次16位寄存器,能自动翻转(0变1或1变0) 写入内存起始地址或字节计数器初值之前,将这个触发器清0,就可以按照先低位字节,后高位字节的顺序写入初值
6.3.3 8237A端口地址及通道分配 PC机中,8237A占据00H~0FH共16个端口地址。 8237A控制器各通道在PC机内的任务: CH0:用作动态存储器的刷新控制 CH1:为用户预留 CH2:软盘驱动器数据传输用的DMA控制 CH3:硬盘驱动器数据传输用的DMA控制
6.3.4 8237A的编程 (1)发复位命令(*) (2)写命令字,设置8237A的工作方式(*) (3)写方式字,设置需使用的通道的工作方式 (4)清除先/后触发器 (5)写入内存储器起始地址(先写低位,后写高位) (6)写入传送的字节数-1(先写低位,后写高位) (7)清除该通道的屏蔽位 (8)启动外部设备,如果是内存到输出设备,用指令 设置第一次DMA请求
说 明 对于IBM-PC系列微型计算机,它的8237A通道0、2、3已分配使用,而且在开机时已对8237A作了初始化。在这种情况下,不允许再对它重新初始化和重新设置控制字 上述编程过程的(1)、(2)二步改为:将所需使用的通道置屏蔽状态(这样做是为了在其他设置未完成时避免误动作)。
2. 应用举例 用DMA方式从网络接收数据存入内存缓冲区 使用8237A的通道1; 8237A端口地址00H~0FH; 总长度不超过300字节。
MOV AL,00000101B OUT 0AH,AL ;写屏蔽寄存器,屏蔽通道1 MOV AL,00000101B ;方式字:请求传输,地址增 OUT 0BH,AL ;非自动预置,写传输,通道1 MOV AL, 02H OUT 83H, AL ;页面地址 = 02H OUT 0CH,AL ;清先/后触发器 MOV AL, 30H OUT 02H,AL ;写低位地址( 30H ) MOV AL,10H OUT 02H,AL ;写高位地址( 10H )
MOV AX,300 ;传输字节数 DEC AX OUT 03H,AL ;写字节数低位 MOV AL,AH OUT 03H,AL ;写字节数高位 MOV AL,00000001B OUT 0AH,AL ;清除通道1屏蔽 CALL SET_NET ;对网络设备进行设置 PUSH DS MOV AX,2103H MOV DS,AX ;DS置初值,缓冲区首地址 DS:0000H
WT:OUT 0CH,AL ;清先/后触发器 IN AL, 03H MOV BL, AL IN AL, 03H MOV BH, AL ;未传输字节数送BX SUB BX, 300-1 NEG BX ;BX中为已传输字节数 CMP BYTE PTR[BX],1AH ;传输完成否? JNZ WT ;没完成则等待 MOV AL,00000101B OUT 0AH,AL ;完成后屏蔽通道1 POP DS
习题6 1 什么是DMA传输? DMA传输有什么优点?为什么? 2 叙述一次数据块DMA传输和一个数据DMA传输的全过程。 4 DMA控制器8237A的成组传送方式和单字节传送方式各有什么特点?它们的适用范围各是什么? 5 怎样用指令启动一次DMA传输?怎样用指令允许/关闭一个通道的DMA传输? 6 DMA控制器8237A能不能用中断方式工作?请说明。 7 如何判断某通道的DMA传输是否结束?有几种方法可供使用?
8 叙述一次DMA控制器8237A编程使用的主要步骤。