第六章“输入输出及接口”习题答案
- 格式:doc
- 大小:45.50 KB
- 文档页数:4
出问题较多的题目6.4 在CPU与外设之间的数据接口上一般加有三态缓冲器,其作用如何?参考答案要点:1)实现CPU和不同外设的速度匹配。
CPU通过数据总线和I/O设备交换数据,但大多数外设的速度比CPU慢很多,无法在时序上和CPU同步,因此,需在I/O接口电路中设置缓冲器,暂存数据,以使高速工作的CPU与慢速工作的外设起协调和缓冲作用,实现数据传送的同步。
2)实现外设和数据总线的有效隔离。
众多外设中,在某一时段仅允许被CPU 选中的设备通过接口享用总线与CPU 交换信息,这就要求接口电路具备使外设与总线隔离的作用。
因此,需选用起缓冲和隔离作用的三态门电路,只有当CPU 选中此接口,三态门选通时,才允许选定的输入设备将数据送至系统数据总线,而其他没有被选中的输入设备,此时相应的接口三态门“关闭”,从而达到与数据总线隔离的目的。
存在的问题:大多数同学对于第2点的回答有欠缺。
6.8 CPU响应(可屏蔽)中断有哪些条件?为什么需要这些条件?参考答案要点:三个条件:1)CPU执行完当前指令;2)有中断请求,且无NMI请求和DMA请求;3)CPU开放中断(或中断允许标志IF=1)。
存在的问题:部分同学把有中断请求这个条件忽略了。
6.9 CPU在中断周期要完成那些主要的操作?参考答案要点:1)关中断;2)保存程序断点和PSW;3)获取中断服务程序入口地址,转入相应的中断服务程序。
存在的问题:中断周期IT这个概念有明确的含义,是响应过程的一个专用的过渡周期,有的机器称之为中断响应总线周期。
在这个周期中依靠硬件(也称中断隐指令)实现程序切换。
中断周期结束后,就进入取指周期。
我们教科书(P213)把中断周期和中断的全过程混为一谈了,容易误导大家。
6.16试比较保护断点与保护现场的主要异同点。
参考答案要点:相同点:二者均用于程序切换时保存原程序的运行数据或状态信息。
不同点:1)保护断点是把程序的断点值(IP和CS值)压栈保存;而保护现场则是把相关寄存器和PSW的值保存起来(通常是压栈保存);2)保护断点通常是在中断响应阶段完成,而保护现场则通常在中断处理阶段完成(8086/8088系统保存PSW的值在中断响应阶段完成)。
第六章习题答案1、简述可编程控制器设计的一般原则和步骤可编程控制系统设计时应遵循以下原则:(1)最大限度地满足被控对象的要求;(2)在满足控制要求的前提下,力求使控制系统简单、经济、适用及维护方便;(3)保证系统的安全可靠;(4)考虑生产发展和工艺改进的要求,在选型时应留有适当的余量。
由于PLC的结构和工作方式与一般微机和继电器相比各有特点,所以其设计的步骤也不尽相同,具体设计步骤如下:(1)详细了解被控对象的生产工艺过程,分析控制要求;(2)根据控制要求确定所需的用户输入/输出设备;(3)选择PLC类型;(4)分配PLC的I/O点,设计I/O连接图;(5)PLC软件设计,同时可进行控制台的设计和现场施工;(6)系统调试,固化程序,交付使用。
2、可编程控制器的选型需要考虑哪些问题?(1)PLC容量的选择①首先要对控制任务进行详细的分析,把所有的I/O点找出来,包括开关量I/O和模拟量I/O 这些I/O点的性质。
②然后要对用户存储器容量进行估算。
总存储器字数=(开关量输入点数+开关量输出点数)×10+模拟量点数×150。
然后按计算存储器字数的25%考虑余量。
(2)PLC机型的选择由于生产PLC的厂家众多,实现的功能虽基本相同,性能、价格和编程语言却有较大差别,一般从以下几个方面考虑。
①功能方面:所有PLC一般都具有常规的功能,但对某些特殊要求,就要知道所选用的PLC 是否有能力完成控制任务。
②价格方面:不同厂家的PLC产品价格相差很大,有些功能类似、质量相当、I/O点数相当的PLC的价格能相差40%以上。
在使用PLC较多的情况下,性价比是一个重要的因素。
③售后服务:应考虑相关的技术支持,统一型号方便维护,系统改造、升级等因素。
3、附加题:电动葫芦起升机构的动负荷试验控制要求如下:①可手动上升、下降(点动)②自动运行时,选择开关转向自动位置,葫芦就开始运行,即:上升5秒→停10秒→下降5秒→停10秒,然后发出声光信号,并停止运行。
C 语言程序设计习题解答(第六章)6.1 题目略[解答] (1) A (2) A (3) C (4) D6.2 略6.3 从键盘输入3个整数, 要求设3个指针变量p1, p2, p3, 使p1指向3个数中的最大者, p2指向次大者, p3指向最小者, 最后按由大到小的顺序输出这3个数.[解答]#include <stdio.h>void main(){int x1, x2, x3, *p1=&x1, *p2=&x2, *p3=&x3, *p;printf("请输入3 个整数: ");scanf("%d%d%d", &x1, &x2, &x3);if(*p1<*p2){p=p1; p1=p2; p2=p;}if(*p1<*p3){p=p1; p1=p3; p3=p;}if(*p2<*p3){p=p2; p2=p3; p3=p;}printf("从大到小: %d, %d, %d\n", *p1, *p2, *p3);}6.4 想使指针变量pt1指向a和b中的较大者, pt2指向a和b中的较小者, 请问以下程序能否达到此目的?#include <stdio.h>void swap(int *p1, int *p2){int *p;p=p1; p1=p2; p2=p;}int main(void){int a, b;int *pt1, *pt2;scanf("%d, %d", &a, &b);pt1=&a; pt2=&b;if(a<b) swap(pt1, pt2);printf("%d, %d\n", *pt1, *pt2);return 0;}请分析此程序的执行情况, 指出pt1和pt2的指向并修改程序, 使之能够实现题目要求. [解答]main函数调用swap函数时, 将指针pt1和pt2的值分别赋给形式参数p1和p2, pt1与p1虽然都指向变量a, 但它们是不同的指针变量, 同样, pt2与p2也是不同的指针变量, swap函数中虽然改变了p1和p2的指向, 但不影响main函数中pt1和pt2的指向. 为了实现题目的要求, 可以修改程序, 将pt1与pt2的地址传给函数swap, 同时将swap的形式参数改为二级指针. 正确的程序如下:#include <stdio.h>void swap(int **p1, int **p2){int *p;p=*p1; *p1=*p2; *p2=p;}int main(void){int a, b;int *pt1, *pt2;scanf("%d, %d", &a, &b);pt1=&a; pt2=&b;if(a<b) swap(&pt1, &pt2);printf("%d, %d\n", *pt1, *pt2);return 0;}6.5 略6.6(1) 想输出数组a的10个元素, 用以下程序行不行? 为什么?#include <stdio.h>void main(){int a[10]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, i;for(i=0; i<10; i++, a++)printf(“%d”, *a);}请修改程序使之能实现题目要求.(2) 想输出数组a的10个元素, 用以下程序行不行? 请与上题对比并进行分析, 得到必要的结论.#include <stdio.h>void print_arr(int a[], int n){int i;for(i=0; i<n; i++, a++)printf("%d", *a);}void main(){int arr[10]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10};print_arr(arr, 10);}请修改程序使之能实现题目要求.[解答](1) 不行, 因为数组名a表示该数组的首地址, 是一个指针常量, 其值是不能改变的, 因此不能进行++ 运算. 正确的程序如下:void main(){int a[10]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, i;for(i=0; i<10; i++)printf("%d ", *(a+i));}(2) 可以, 因为形参数组本质上是一个指针变量, 其值可以改变, 可以进行++ 运算.6.7 有一个数列, 含有20个整数, 现要求编一个函数, 能够对从指定位置开始的几个数按相反顺序排列, 并在main函数中输出新的数列. 例如, 原数列为:1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20若要求对从第5个数开始的10个数进行逆序处理, 则得到的新数列为1, 2, 3, 4, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 15, 16, 17, 18, 19, 20[解答]#include <stdio.h>#define N 20void reverse(int a[], int m, int k) /* 将数组a 从第m 个数开始的k 个数按相反顺序排列*/ {int temp, *p, *q;for(p=a+m-1, q=p+k-1; p<q; p++, q--) /* p, q 初始时分别指向要反序的起始与终止位置*/{temp=*p; *p=*q; *q=temp;}}void main(){int i, m, k, a[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};printf("请输入要反序的数列的起始位置和长度: ");scanf("%d%d", &m, &k);reverse(a, m, k);printf("反序后的数列为: ");for(i=0; i<N; i++)printf("%d ", a[i]);printf("\n");}6.8 有n个人围成一圈, 顺序排号, 从第1号开始报数, 从1报到m, 凡报到m的人退出圈子.问最后留下的是原来第几序号的人? 要求如下:(1) 用函数实现报数并退出;(2) n和m的值由main函数输入并通过实参传递给该函数, 最后结果由main函数输出;(3) 要求使用指针.[解答]#include <stdio.h>#define N 100int baoshu(int a[], int n, int m) /* n 个人围成一圈, 从1 到m 报数的函数*/{int i, cnt, num, *p, last;for(i=0; i<n; i++) /*给每一个人赋予一个初始位置号*/*(a+i)=i+1;cnt=0; /* cnt 用于从1 到m 记数, 模拟报数*/num=0; /* num 用于记录出圈人数*/while(num<n)for(p=a; p<a+n; p++) /* 报数*/if(*p) /* 若*p 在圈中*/{cnt++; /* 报数记数器加1 */if(cnt==m) /* 若报数记数器到达m */{/* 处理出圈事宜*/last=*p; /* 用last 记录当前出圈者的位置号*/*p=0; /* 位置号清零, 表示从圈中删除此人*/cnt=0; /* 报数记数器清零, 下一个人重新开始报数*/num++; /* 出圈人数加1 */}}return last;}void main(){int n, m;int a[N]; /* 用数组 a 记录每一个人在圈中的位置 */printf("输入人数 n (<%d) 和所报的最大数 m: ", N);scanf("%d%d", &n, &m);printf("最后留下的是原来第 %d 号的人.\n", baoshu(a, n, m));}6.9 有一个二维数组a, 大小为53⨯, 其元素为⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡=2927252321191715131197531a (1) 请说明以下各表达式的含义:a, a+2, &a[0], a[0]+3, *(a+1), *(a+2)+1, *(a[1]+2), &a[0][2], *(a[0][2]), *(*(a+2)+1), a[1][3].(2) 如果输出a+1和&a[1][0], 它们的值是否相等? 为什么? 它们各代表什么含义?[解答](1)a : 数组首地址, 等价于 &a[0]a+2 : 第 2 行的地址, 等价于 &a[2]&a[0] : a[0]的地址, 即第0行的地址, 也是整个数组的首地址, 等价于a a[0]+3 : 第 0 行第 3 列元素的地址, 即 &a[0][3]*(a+1) : 第 1 行第 0 列元素的地址, 等价于 a[1] 和 &a[1][0]*(a+2)+1 : 第 2 行第 1 列元素的地址, 即与 &a[2][1] 等价*(a[1]+2) : 第 1 行第 2 列元素的值, 即 a[1][2] = 15&a[0][2] : 第 0 行第 2 列元素的地址*(a[0][2]) : 无意义*(*(a+2)+1) : 第 2 行第 1 列元素的值, 即 a[2][1] = 23a[1][3] : 第 1 行第 3 列元素的值, 等于 17.(2) 如果输出a+1和&a[1][0], 它们的值相等, 但它们有着不同的含义, a+1 等价于 &a[1], 表示第1行的首地址, 是一个二级指针; &a[1][0] 表示第1行第0列的地址, 是一个一级指针. 由于a[1][0] 是第1行的首元素, 因此它的地址刚好就是第1行的首地址, 从而两者输出的值相等.6.10 有一个整型二维数组, 大小是n m ⨯, 要求找出最大值所在的行和列以及该最大值, 请编写一个程序max, 要求如下:(1) 以数组名和数组大小为该函数的形参;(2) 数组元素的值在main 函数中输入, 结果在max 函数中输出.[解答]#include <stdio.h>#define M 3#define N 4void max(int a[], int m, int n){int i, j, row=0, col=0, max=*a;for(i=0; i<m; i++)for(j=0; j<n; j++, a++)if(*a>max){max=*a;row=i;col=j;}printf("最大值是%d, 在第%d, 第%d 列.\n", max, row, col);}void main(){int i, j, a[M][N];printf("请输入%d * %d 个整数:\n", M, N);for(i=0; i<M; i++)for(j=0; j<N; j++)scanf("%d", &a[i][j]);max(*a, M, N);}6.11 有n个学生, 每个学生参加m门课程的考试, 要求编写一函数, 能检查n个学生有无不及格的课程, 如果某个学生有一门或一门以上课程不及格, 就输出该学生的学号(学号从0算起, 即0, 1, 2, …) 及其全部课程成绩.[解答]#include <stdio.h>#define M 5 /*学生数*/#define N 3 /*课程数*/void proc(float s[][N]){int i, j, k;for(i=0; i<M; i++){for(j=0; j<N; j++)if(s[i][j]<60.0) break;if(j<N){printf("第%d 个学生有不及格的课程, 其各门课的成绩为:\n", i);for(k=0; k<N; k++)printf("%7.2f", s[i][k]);printf("\n");}}}void main(){float score[M][N];int i, j;for(i=0;i<M;i++){printf("请输入第%d 个学生的成绩: ", i);for(j=0;j<N;j++)scanf("%f", &score[i][j]);}proc(score);}6.12 输入3行字符(每行60个字符以内), 要求统计出其中共有多少个大写字母, 小写字母, 空格及标点符号.[解答]#include <stdio.h>#include <string.h>#define M 3#define N 60void main(){int i, j, upper=0, lower=0, blank=0, punc=0; /* upper, lower, blank, punc 分别记录大写字母, 小写字母, 空格及标点符号的个数*/char str[M][N];printf("请输入%d 行字符, 每行不超过%d 个字符:\n", M, N);for(i=0; i<M; i++)gets(str[i]);for(i=0; i<M; i++)for(j=0; j<N && str[i][j]!='\0'; j++)if(str[i][j]>='A' && str[i][j]<='Z')upper++;else if(str[i][j]>='a' && str[i][j]<='z')lower++;else if(str[i][j]==' ')blank++;else if(str[i][j]>' ' && str[i][j]<'0' || str[i][j]>'9' && str[i][j]<127)punc++;printf("大写字母, 小写字母, 空格及标点符号的个数分别是%d, %d, %d, %d.\n", upper, lower, blank, punc);}6.13 指出下列程序的错误, 并分析出错的原因.#include <stdio.h>void Print(char *[], int len);int main(void){char *pArray[]={"Fred", "Barrey", "Wilma", "Betty"};int num=sizeof(pArray)/sizeof(char);printf("Total string numbers = %d\n", num);Print(pArray, num);return 0;}void Print(char *arr[], int len){int i;for(i=0; i<len; i++)printf("%s\n", arr[i]);}[解答]程序第6行试图计算指针数组pArray所含元素的个数, 但这是错误的, 一个数组所含元素个数应该等于数组大小除以数组元素类型的大小, 这个数组的元素是字符指针类型, 而不是字符类型, 正确的语句是:int num=sizeof(pArray)/sizeof(char *);6.14 建立一个动态二维数组, 用来存储1~10的1~4次幂.[解答]#include <stdio.h>#include <stdlib.h>#define M 10#define N 4void main(){int i, j, (*p)[N], pow;p=(int (*)[N])malloc(M*N);if(!p){printf("内存分配出错.\n");exit(1);}for(i=0; i<M; i++){pow=1;for(j=0; j<N; j++)p[i][j]=pow*=(i+1);}for(i=0; i<M; i++){for(j=0; j<N; j++)printf("%6d", p[i][j]);printf("\n");}// free(p);}6.15 略.6.16 题目略.[解答] (1) A (2) C.。
第六章输入输出接口6.1 微机接口技术为了使CPU能适应各种各样的外设,就需要在CPU与外设之间增加一个接口电路,由它完成相应的信号转换、速度匹配、数据缓冲等功能,以实现CPU与外设的连接,完成相应的输入输出操作。
一个接口的基本作用是在系统总线和I/O设备之间架起一座桥梁,以实现CPU与I/O设备之间的信息传输。
CPU内存终端、调制解调器A/D转换器D/A转换器键盘、鼠标、麦克风、扫描仪打印机显示器磁盘、U盘、光盘通信接口信号接口输入接口输出接口外存接口DB AB CB1.采用I/O接口的必要性速度不匹配:CPU速度高,外设的速度低。
不同的外设速度差异大,如硬盘速度高,每秒能传送兆位数量级,串行打印机每秒钟只能打印百位字符,而键盘的速度则更慢。
信号不匹配:CPU的信号为数字信号,数据采集输入的是模拟信号,需要对外部信号进行模/数转换,才能被计算机处理;同样,计算机输出的是数字信号,需要输出模拟信号时,必须要通过数/模转换。
信号格式不匹配:计算机接收和处理的是并行数据,而有些外部设备的信号为串行数据,这就需要使用接口电路进行串行数据和并行数据转换。
提高CPU的传输效率,需要利用接口电路对外设进行控制。
2.接口的功能:1)寻址功能识别是否是I/O口的操作信号,识别是否为端口的片选信号,识别是芯片的哪个寄存器被访问。
2)输入/输出功能根据CPU通过控制总线送来的读写信号决定是输入操作还是输出操作。
3) 可编程功能有些接口具有可编程特性,可以通过指令设定接口的工作方式,工作参数,以满足不同外设的要求。
4) 数据转换功能当外设提供的数据形式不是CPU能直接接受的形式时,则通过接口转换成CPU可接受的形式。
如A/D,串/并转换等,反之也一样。
5) 联络功能当CPU要访问外设时,首先要查询外设状态,能否接受访问,接口应将外设状态准备好,供CPU 查询;或向CPU发特定的信号通知外设已准备好。
6) 数据缓冲功能主机与外设速度相差很大,为了防止数据丢失,I/O接口均设有双向数据缓冲器。
第2章微型计算机基础2.8 在执行指令期间,BIU能直接访问存储器吗?为什么?解:可以.因为EU和BIU可以并行工作,EU需要的指令可以从指令队列中获得,这时BIU预先从存储器中取出并放入指令队列的。
在EU执行指令的同时,BIU 可以访问存储器取下一条指令或指令执行时需要的数据。
2.9 8086与8088CPU的主要区别有哪些?解:主要区别有以下几点:①8086的外部数据总线有16位,而8088的外部数据总线只有8位。
②8086指令队列深度为6个字节,而8088的指令队列深度为4个字节.③因为8086的外部数据总线有16位,故8086每个总线周期可以存取两个字节.而8088的外部数据总线因为只有8位,所以每个总线周期只能存取1个字节.④个别引脚信号的含义稍有不同.2.10 解:(1)要利用信号线包括WR#、RD#、IO/M#、ALE 以及AD0~AD7、A8~A19。
(2)同(1)。
(3)所有三态输出的地址信号、数据信号和控制信号均置为高阻态。
2.11解:在每个总线周期的T3的开始处若READY 为低电平,则CPU在T3后插入一个等待周期TW。
在TW的开始时刻,CPU还要检查READY状态,若仍为低电平,则再插入一个TW 。
此过程一直进行到某个TW开始时,READY已经变为高电平,这时下一个时钟周期才转入T4。
可以看出,插入TW周期的个数取决于READY电平维持的时间。
2.14 解:通用寄存器包含以下8个寄存器:AX、BX、CX和DX寄存器一般用于存放参与运算的数据或运算的结果。
除此之外:AX:主要存放算术逻辑运算中的操作数,以及存放I/O操作的数据。
BX:存放访问内存时的基地址。
CX:在循环和串操作指令中用作计数器。
DX:在寄存器间接寻址的I/O指令中存放I/O地址。
在做双字长乘除法运算时,DX与AX合起来存放一个双字长数。
SP:存放栈顶偏移地址。
BP:存放访问内存时的基地址。
SP和BP也可以存放数据,但它们的默认段寄存器都是SS。
第六章习 题 (二)填空题 1 . MCS-51可提供 和 两种存储器、最大存储空间可达 的两个并行存储器扩展系统。 2. 为扩展存储器而构造系统总线,应以P0口的8位口线作为 线,以P2口的口线作为 。 3. 在存储器编址技术中,不需要额外增加电路,但却能造成存储器映象区重叠的编址方法是 法,能有效利用存储空间适用于大容量存储器扩展的编址方法是 法。 4. 为实现内外程序存储器的衔接,应使用 信号进行控制。 5. 访问内部RAM使用 指令,访问外部RAM使用 指令,访问内部ROM使用 指令,访问外部ROM使用 指令。 6. 与微型机不同,单片机必须具有足够容量的程序存储器是因为 。 7. 在存储器扩展中,无论是线选法还是译码法,最终都是为扩展芯片的 端提供信号。 8. 在接口电路中,把已经编址并能进行读写操作的寄存器称为 。 9. 从单片机的角度上看,连接到数据总线上的输出口应具有 功能,连接到数据总线上的输入口应具有 功能。 10. 在三态缓冲电路中,除了数据输入线和数据输出线外,还应当有一个 信号线。 11. 在MCS-51单片机系统中,采用的编址方式是 。 12. 在单片机中,为实现数据的I/O传送,可使用3种控制方式,即 方式、 方式和 方式。 13. 在查询和中断两种数据输入输出控制方式中,效率较高的是 。 14. 在多位LED显示器接口电路的控制信号中,必不可少的是 控信号和 控信号。 15. 简单输入口扩展是为了实现输入数据的 缓冲 功能,而简单输出口扩展是为了实现输出数据的 功能。 16. 8255A能为数据I/O操作提供A、B、C 3个8位口,其中A口和B口只能作为数据口使用,而C口则既可作为 口使用,又可作为 口使用。 17. 与8255A比较,8155的功能有所增强,主要表现在8155具有 单元的 和一个 位的 。 (三)选择题 1.在MCS-51中,需双向传递信号的是 (A)地址线 (B)数据线 (C)控制信号线 (D)电源线 2.在MCS-51中,为实现P0口线的数据和低位地址复用,应使用 (A)地址锁存器 (B)地址存储器 (C)地址缓冲器 (D)地址译码器 3.在下列信号中,不是给程序存储器扩展使用的是 (A)PSEN (B)EA (C)ALE (D)WR 4.在下列信号中,不是给程序存储器扩展使用的是 (A)EA (B)RD (C)WR (D)ALE 5.如在系统中只扩展一片Intel2764,除应使用P0口的8条口线外,至少还应使用P2口的口线 (A)4条 (B)5条 (C)6条 (D)7条 6.如在系统中只扩展二片Intel2764,除应使用P0口的8条口线外,至少还应使用P2口的口线 (A)5条 (B)6条 (C)7条 (D)8条 7.在使用译码法同时扩展多片数据存储器芯片时,不能在各存储芯片间并行连接的信号是 (A)读写信号 (B)地址译码输出信号 (C)数据信号 (D)高位地址信号 8. 下列叙述中,不属于单片机存储器系统特点的是 (A)程序和数据两种类型的存储器同时存在 (B)芯片内外存储器同时存在 (C)扩展数据存储器与片内数据存储器存储空间重叠 (D)扩展程序存储器与片内数据存储器存储空间重叠 9. 下列功能中不是由I/O接口实现的是 (A)速度协调 (B)数据缓冲和锁存 (C)数据转换 (D)数据暂存 10. 三态缓冲器的输出应具有3种状态,其中不包括 (A)高阻抗状态 (B)低阻抗状态 (C)高电平状态 (D)低电平状态 11. 为给扫描法工作的键盘提供接口电路,在接口电路中只需要 (A)一个输入口 (B)一个输入口和一个输出口 (C)一个输出口 (D)两个输入口和一个输出口 12. 在接口电路中的“口”一定是一个 (A)已赋值的寄存器 (B)数据寄存器 (C)可编址的寄存器 (D)既可读又可写的寄存器 13.下列理由中,不能说明MCS-51的I/O编址是统一方式而非独立方式的理由是 (A)没有专用的I/O指令 (B)没有区分存储器和I/O的控制信号 (C)使用存储器指令进行I/O操作 (D)P3口线具有第二功能 14. 在LED显示中,为了输出位控和段控信号,应使用指令 (A)MOV (B)MOVX (C)MOVC (D)XCH 15. 在8155芯片中,决定口和RAM单元编址的信号是 (A)AD7~AD0和WR (B)AD7~AD0和CE (C)AD7~AD0和IO/M (D)A07~AD0和ALE 16. 如果把8255A的A1、A0分别与80C51的P0.l\P0.0连接,则8255A的A、B、C 口和控制寄存器的地址可能是 (A)××00H~××03H (B)00××H~03××H (C)0×××H~3×××H (D) ×00×H~×03×H
1
第六章 输入输出及接口
〔习题6.2〕
I/O端口与存储器地址常有_____和_____两种编排方式,8088/8086处理器
支持后者,设计有专门的I/O指令。其中指令IN是将数据从_____传输到_____,
执行该指令时8088/8086处理器引脚产生_____总线周期。指令“OUT DX, AL”的目
的操作数是_____寻址方式,源操作数是_____寻址方式。
〔解答〕
(I/O端口与存储器地址)统一编址
(I/O端口与存储器地址)独立编址
外设
处理器
I/O读
(I/O端口的DX)寄存器间接
寄存器
〔习题6.4〕
基于教程P142图6-7接口电路,编程使发光二极管循环发光。具体要求是:单独按下
开关K0,发光二极管以L0、L1、L2、……L7顺序依次点亮,每个维持200ms,并不断重复,
直到有其他按键操作;单独按下开关K1,发光二极管以L7、L6、L5、……L0顺序依次点亮,
每个也维持200ms,并不断重复,直到有其他按键操作;其他开关组合均不发光,单独按下
开关K7,则退出控制程序。延时200ms可以直接调用子程序DELAY实现。
〔解答〕
again: mov dx,6000h
mov al,0ffh
out dx,al ;全不亮
again1: in al,dx
cmp al,7fh ;D7~D0=0111111B ?
jz done ;单独按下K7,退出
cmp al,0feh ;D7~D0=11111110B ?
jz next1 ;单独按下K0,转移到next1
cmp al,0fdh ;D7~D0=11111101B ?
jz next2 ;单独按下K1,转移到next2
jmp again ;其它情况不点亮
next1: mov cx,8
mov al,1 ;从K0开始
next11: out dx,al ;某个LED电亮
call delay ;延时200ms
shl al,1 ;rol al,1
loop next11
jmp again1
next2: mov cx,8
2
mov al,80h ;从K7开始
next21: out dx,al ;某个LED电亮
call delay ;延时200ms
shr al,1 ;ror al,1
loop next21
jmp again1
done: mov al,0ffh
out dx,al ;全不亮
〔习题6.5〕
有一个查询输入接口电路类似图6-9,但其数据端口为8F40H、状态端口为8F42H。从
状态端口最低位可以获知输入设备是否准备好一个字节的数据:D0=1表示准备好,D0=0
说明没准备好。不考虑查询超时,编程从输入设备读取100个字节保存到INBUF缓冲区。
〔解答〕
mov bx,offset inbuf
mov cx,100
again: mov dx,8f42h
status: in al,dx ;查询一次
test al,01h
jz status
mov dx,08f40h
in al,dx ;输入一个字节
mov [bx],al
inc bx
loop again ;循环,输入100个字节
〔习题6.5〕(第二版)
请描述采用查询方式进行CPU与外设间传送数据的过程。如果有一个输入设备,其数
据口地址为FFE0H,状态口地址为FFE2H,当状态标志D0=1时,表明一个字节的输入数
据就绪,请编写利用查询方式进行数据传送的程序段。要求从该设备读取100个字节并写到
从2000H:2000H开始的内存中。注意在程序中添加注释。
〔解答〕
通过读取状态寄存器的标志位来检查外设是否就绪。若不就绪就继续查询,即程序不
断循环;直至就绪。然后,进行下一步的传送工作。
mov bx,2000h
mov ds,bx
mov cx,100
again: mov dx,0ffe2h
status: in al,dx ;查询一次
test al,01h
jz status
mov dx,0ffe0h
3
in al,dx ;输入一个字节
mov [bx],al
inc bx
loop again ;循环,输入100个字节
〔习题6.6〕
有一个查询输出接口电路类似图6-10,但其数据端口和状态端口均为8000H,并从状
态端口的D6位获知输出设备是否能够接收一个字节的数据:D6=1表示可以接收、D6=0
说明不能接收。不考虑查询超时,编程将存放于缓冲区OUTBUF处的字符串(以0为结束
标志)传送给输出设备。
〔解答〕
mov bx,offset outbuf
mov dx,8000h
again: mov ah,[bx]
cmp ah,0
jz done
status: in al,dx ;查询一次
test al,40h
jnz status
mov al,ah
out dx,al ;输出一个字节
inc bx
jmp again ;循环
done: ……
〔习题6.6〕(第二版)
某字符输出设备,其数据口和状态口的地址均为80H。在读取状态时,当标志位D7=0
时,表明该设备闲,可以接收一个字符,请编写利用查询方式进行数据传送的程序段。要求
将存放于符号地址ADDR处的一串字符(以$为结束标志)输出给该设备。注意在程序中添
加注释。
〔解答〕
mov bx,offset addr
again: mov ah,[bx]
cmp ah,’$’
jz done
status: in al,80h ;查询一次
test al,80h
jnz status
mov al,ah
out 80h,al;输出一个字节
inc bx
jmp again ;循环
done: ……
〔习题6.7〕
结合中断传送的工作过程,简述有关概念:中断请求、中断响应、中断关闭、断点保护、
4
中断源识别、现场保护、现场恢复、中断开放、中断返回、以及中断优先权和中断嵌套。
〔解答〕参看教程P147-150。
中断源识别:处理器明确此次中断的具体来源,以便转向为其服务的程序中。
中断嵌套:当一个中断服务时处理器又响应新的中断请求就形成中断嵌套。
〔习题6.7〕(第二版)
以可屏蔽中断为例,说明一次完整的中断过程主要包括哪些环节?8088响应可屏蔽中
断请求,需要先满足哪些前提条件?
〔解答〕
习题6.7解答:参考教材第6.4.2节(第165页)
〔习题6.10〕
查询、中断和DMA传送是微机中常用的外设数据交换方式,请说明各自的特点。
〔解答〕参看教程P143-152及课件。
〔习题6.10〕(第二版)
DMA的意思是,主要用于高速外设和内存间的数据传送。进行DMA传送的一般
过程是:外设先向DMA控制器提出,DMA控制器通过信号有效向CPU提出总
线请求,CPU回以信号有效表示响应。此时CPU的三态信号线将输出状态,即
将它们交由进行控制,完成外设和内存间的直接数据传送。
〔解答〕
DMA的意思是 直接存储器存取 ,主要用于高速外设和内存间的数据传送。进行DMA
传送的一般过程是:外设先向DMA控制器提出 DMA请求 ,DMA控制器通过 总线请求
HOLD 信号有效向CPU提出总线请求,CPU回以 总线响应HLDA 信号有效表示响应。此
时CPU的三态信号线将输出 高阻 状态,即将它们交由 DMAC(DMA控制器) 进行控制,
完成外设和内存间的直接传送。