打算整理汇编语言与接口微机这方面的学习记录。本部分介绍常用芯片接口技术、中断系统与可编程中断控制器8259A。
参考资料
由于设备种类繁多,通信的信息格式多样,所以CPU与设备之间不能直接通信,必须在两者之间设计一个电路将两者连接,这就是I/O接口电路。
硬件、软件两者合起来,就是I/O接口技术。
I/O接口电路介于系统总线和I/O设备之间。课本图示如下:
老师的图示如下:
一种信息要通过一个IO端口来传送
这个端口本质是一个缓冲器/锁存器/寄存器,用来存放一些信息。
状态信息(入)
以一个输出设备为例,CPU采集I/O设备的状态,如果可以响应CPU,则放入数据给设备
数据信息(入/出)
数据线将数据放到数据端口,
命令信息(出)
通过命令信息,让设备知道数据信息已经来到。比如一个负脉冲,告知设备数据有效,设备在该负脉冲器件就可将数据端口的数据取出。
出--CPU、入--CPU
一个I/O端口要分配一个I/O地址,叫I/O端口地址、端口地址。
同时上图还有片选信号CS,用于选中这个IO端口,也要针对它们设计I/O地址译码电路。
此前提到过:
独立编址(80x86):
8086CPU中表现为低16位地址线编址I/O,通过M/IOfei来区别是对存储器操作还是对I/O操作。
8088中是IO/Mfei
这样I/O地址不占用存储器地址空间。但是缺点是指令系统不能通用地操作存储器和I/O了,这样对I/O寻址的方式也不会像存储器那么丰富了(直接寻址和DX寄存器间接寻址),不那么灵活。
统一编址(MCS51CPU):
比如AT89C51,统一共享64kb的存储空间。
无条件输入输出方式和查询法输入输出以及 中断法
无条件输入/输出方式
一些简单设备(比如LED灯)永远处于准备好状态,不需要提前获取状态信息。
这种情况下,没有状态端口,也没有命令端口,只留数据端口即可。不过像第2节组成部分里讲的一样,还是需要锁存信息。(锁存常用74LS374和74LS273)
这里老师讲了74LS373,emm,涉及总线那一部分的时序问题,总之不选
查询法输入输出
测设备状态:
MOV DX,PORT_NUM
L1:
IN AL,DX ;设备状态读入AL
TEST AL, 01H
; 假如状态是低电平有效
JNZ L1 ;没准备好继续查询
电路实现比较简单,缺点是效率比较低,1是如果设备一直没准备好,需要反复询问,如果设备比较多,轮询的过程中可能错过某个设备准备好的时机。
如果CPU不忙,设备较少,可以使用这种方法。
中断法:重点
CPU查询效率太低,不如让设备准备好后向中断控制器8259提出请求,8259再向CPU提出请求。
当CPU开中断(允许中断),CPU就会保护当前程序的现场(几个重要寄存器),进而执行中断对应的中断服务程序,执行完毕后IRET返回。返回后恢复现场。
三种方法可以统称为:程序直接控制的输入输出方法(因为都是用IN、OUT指令)
重点并且此前计组和计操对这点掌握都不深刻。
3.1的中断法虽然很好了,但是:
而DMA方法完全由硬件(DMAC,DMA控制器,8237)完成,不受程序控制,速度很快。
DMA虽然不考,但好歹继续了解一下。
一个输入设备的完整DMA传送过程:
此后讲解的是3.1受程序控制的的例程,并且不包含中断法,中断法的例程在Part2单独一章。
前面已经用到了很多接口芯片,在笔记5中已经介绍了74LS244、74LS245(数据双向缓冲)、74LS373、74LS374 / 74LS273。
上面还提到了尽量选374而不是373,因为前者是上升沿有效,后者高电平有效,由于微处理器的时序关系,可以知道前者更好一点。
以及,不同的系统进行I/O端口地址译码以及I/O电路设计时,总线信号:
值得注意的是IBM PC/XT系统,对IO编址只用了A9~A0,共编址1KB,前为主机板上的I/O,后512B分配给插件板上的I/O。
当AEN=1时,表示正进行DMA操作,所以设计译码电路时,应使AEN=0。
可以通过缓冲器/总线驱动器来提高总线负载能力,比如74LS373 74LS244(单向8位) 74LS245(双向8位),双向系统数据总线驱动需要:
这里老师讲了书上231页例题7.1(无条件输出)、7.2(无条件输入),讲的很不错
2023-02-22,又听了一遍,跟后续查询法和中断法的设备难度差距很大,不做记录了。
2022-02-21,P93和P94回头再看吧,要考试了5555.
2022-02-22,昨天太焦虑了,又听了一遍,感觉还好
讲了一个查询法A/D转换器的例子,书上没有。
中断系统主要是8086系统,而8259A管理的是INTR引脚的可屏蔽中断。
已经讲过一次,是在笔记4的第五部分。
中断:CPU执行程序的过程中,由于某个时间的发生,CPU暂停当前程序,转去执行处理该事件的一个中断服务程序,待中断服务程序执行完后,返回被中断的程序继续执行。
中断源:内部中断源、外部中断源
中断类型号:为每个中断源编号,8位2进制编码,所以可以管理256个中断(最多),进而执行相应服务。
其中,内部中断源和外部不可屏蔽中断都有固定中断号,而INTR可屏蔽中断没有固定的中断号,要加一个中断控制器8259A,CPU要将相应中断号初始化到8259A上(OUT指令),中断响应期间,CPU就会从外部8259上取中断类型号。
所以外部可屏蔽中断号是可自己设置的。同时还可以设置这些外部可屏蔽中断的优先级(初始化时)
中断向量:32位,中断服务子程序的入口地址,段地址:偏移地址。
中断向量表:8086中将存储器1M最低的1024个单元作为中断向量表,依次有序存放中断向量(一个向量4个字节,前两字节偏移地址,后两字节段地址)。
中断过程:
如果是外部可屏蔽中断,需要IF=1才能响应
中断发生时,先将当前指令执行完。
保护现场再保护PSW CS IP等寄存器,依次压栈保护。
如果是外部中断,从8259A获取中断号
清除IF和TF=0,也就是拒绝外部可屏蔽中断请求。
如果允许中断嵌套,那在中断服务开始时,用指令
STI开中断
执行中断服务子程序,执行完毕后IRET返回主程序,恢复现场继续执行原程序。
首先是8259A的外部引脚,及其功能:
IR0~IR7:八个引脚,输入,用于外设向8259A发送中断请求信号
CSfei:片选,片外寻址
A0:片内寻址,用于寻址8259A内部的端口。
只有两个地址,但8259A不止两个端口,需要D0~D7中某些位为特征位来识别。
D0~D7:数据线。CS片选无效,则高阻态;CS片选有效,则两态,可供读写。
WRfei、RDfei:写控制端、读控制端
INT:高电平有效,当中断来临,且未被屏蔽,通过INT向8086CPU的INTR引脚发送中断请求。
如果CPU开中断,则通过INTAfei发送两个负脉冲(接收端是8259A的INTA引脚),第一个脉冲告知8259A其请求CPU可响应,第二个脉冲期间,8259A将此次中断源的中断类型号发到D0~D7,CPU读取中断类型号(8086的低八位数据线)。
SPfei/ENfei:主从设备设定/缓冲器读写控制,双向双功能。
缓冲方式是:D0~D7和CPU之间可再加一双向缓冲器,ENfei作为输出端控制该缓冲器的使能端(很少用)。
非缓冲方式:D0~D7直连CPU,该引脚作为输入,此时说明8259A是单片工作或是级联工作中的主片(是直接与CPU相连的8259A)
主片:SPfei接+5V
从片:SPfei接GND
CAS2~CAS0:三根双向级联线,主片上该引脚为输出,从片为输入。
当从片收到中断请求,从片发送给主片,主片向CPU发送,CPU若响应,则第一个负脉冲主从两片都收到,第二个负脉冲,也是主从两片都能收到,此时主片查看是哪个引脚到来的中断(假设从片接在IR1上,那就是IR1的中断),并从CS2CS0端口向从片发送编码001,表明是IR1的请求。后续级联的从片根据该001编码,检测主片是在呼叫哪一片从片,如果是自己,则将自己的中断找到对应的中断类型号,通过D0D7送到数据线上。
直接说可能太抽象了,看看图吧:
IRR 中断请求寄存器:8位,寄存外部中断请求信号,请求来到,则对应位置为1。能否寄存受IMR寄存器的控制。
IMR 中断屏蔽寄存器:8位,屏蔽对应位置的中断输入,比如0000_0001,屏蔽的是IR1的中断。
优先权分析器:把IRR8位中所有的1分析一下,找出最高优先级的中断,将其交给ISR寄存器,使其对应位置1。置为1说明8259A已经开始服务该中断。
接下来就是INT向CPU发送请求,CPU可响应的话向INTAfei发送两负脉冲,取出中断类型号。
中断结束方式:结束方式,8259A可以初始化为两种方式
中断自动结束,收到第二个负脉冲,8259A一方面发送中断类型号,另一方面将ISR对应位清0,中断服务结束。
一般不用。
非自动结束:发送中断类型号后并不清0,CPU执行完中断服务子程序,在IRET之前,向8259A发送OUT 中断结束指令,8259A收到后结束中断。
内部控制逻辑电路:
到现在已经有了7个端口,而只有一个A0用于片内寻址,还需要通过D0~D7的特征位进行区分。
最后还有几点:
基本已经讲的差不多了。8259A一次完整的中断响应过程如下:
跟上面的讲解多少有点出入,以此为准)
中断源在IR0~IR7上产生中断请求
中断请求锁存在IRR(经过IMR屏蔽),结果送给优先权分析器。
控制逻辑电路接收中断请求,向微处理器发送INT信号
CPU从INTR接收8259A的INT信号,发送连续两个INTA负脉冲
优先权分析后根据最高优先级中断置位ISR。
若8259A是主片(中断源不直接连在其上时),第一个INTA负脉冲将级联地址从CAS2~CAS0发出。
若8259A是单独使用或是由CAS0~CAS2选择的从片,则在第二个负脉冲将中断类型号发送到低八位数据总线。
8086CPU读取中断类型号,转移到对应的中断处理程序。
(非自动结束方式),中断服务子程序结束前,向8259A发送EOI(中断结束)命令,ISR复位,中断结束。
首先是对ICW的4个寄存器写
初始化ICW1:
举例:
MOV AL,11H
OUT 20H,AL;写到主片,编码为00010001
; 从片
; MOV AL,11H
; OUT 0A0H,AL
初始化ICW2:
MOV AL,08H
OUT 21H,AL
;从片
;MOV AL,70H
;OUT 0A1H,AL
初始化ICW3:级联必须初始化,单片不需要
;主片
MOV AL, 04H
OUT 21H, AL
;从片
MOV AL,02H
OUT 0A1H,AL
ICW4的初始化:
; 主片
MOV AL, 01H
OUT 21H, AL
; 从片
MOV AL, 01H
OUT 0A1H, AL
接着是OCW操作字。
操作OCW1:
OCW2:
MOV AL,20H
MOV 20H,AL
OCW3:
改变屏蔽方式,可自查。
讲了个例题,书上P262例8.4,挺好玩。
STACK SEGMENT STACK
DB 256 DUP(?)
STACK ENDS
DATA SEGMENT
; 读入的数据放置的地方
IN_BUFFER DB 100 DUP(?)
;
IN_POINER DW ?
; 读出IMR放在INT_IMR,查看并备份屏蔽情况
INT_IMR DB ?
DATA ENDS
;书上使用DOS功能调用的方法创建向量表
CODEM SEGMENT
ASSUME CS:CODEM,DS:DATA,SS:STACK
START:
;DOS功能调用方法建立中断向量
MOV AX, IN_INTR; 中断服务程序入口,自己设置的,在最下面
MOV DS, AX ;段地址给DS
LEA BX, IN_INTR ;偏移地址给BX
; 功能号250H,类型号0BH
MOV AX 250BH
INT 21H ; DOS设置中断向量
/*
更通用的思路(原理性),平替上面五行
mov ax,DATA
MOV DS,AX
CLI;关闭中断
PUSH DS
MOV AX,0
MOV DS,AX ;DS此时是中断向量表的首地址
MOV BX,4*0BH;BX是待建立的中断向量偏移地址
MOV AX,OFFSET IN_INTR ;IN_INTR是中断服务子程序
MOV [BX],AX;把中断服务程序偏移地址写入BX位置
MOV AX,SEGMENT IN_INTR
MOV [BX+2],AX;把中断服务程序的段地址写入BX+2位置
POP DS
STI ;开中断
*/
;装载数据段初值(如果pop完就不需要)
MOV AX,DATA
MOV DS, AX
; 立即数寻址,设置指针初值
MOV IN_POINTER, OFFSET IN_BUFFER
IN AL,21H ;读入IMR,默认BIOS已经初始化8259A
MOV INT_IMR, AL;放入备份位置,暂存原IMR
AND AL,F7H;OCW1, 1111_0111,屏蔽对应位置
OUT 21H, AL; 清除IR3屏蔽位
STI ;开中断
; 显示
MOVE:
;从键盘读一个字符,不等待,而如果没有输入,就等在这了
MOV AH,06H
MOV DL,0FFH
INT 21H
CMP AL,0DH ;比较输入是否是回车
JNZ MOVE ; 如果不是回车,继续回去等待回车引发的中断
MOV AL,INT_IMR; 结束输入了,恢复屏蔽字
OUT 21H,AL
...;结束处理
MOV AX,4C00H
INT 21H
CODES SEGMENT
ASSUME CS:CODES
IN_INTR PROC FAR
PUSH DS
PUSH AX
...;一些保护现场
STI; 设置开放中断,允许响应更高级中断
MOV BX,IN_POINTER
/*
注意,
上文程序中已经有MOV IN_POINTER, OFFSET IN_BUFFER,此时BX,就是IN_BUFFER的偏移地址,下面[BX],就相当于 DS:BX
*/
MOV DX,240H ;输入端口的地址,通过DX对IO间接寻址
IN AL, DX
MOV [BX],AL ; 数据存放进缓冲区
INC BX
MOV IN_POINTER,BX ;移动指针
EXIT:
CLI ;严谨一点,关中断
OUT 20H,AL ;向8259A发送eoi,中断结束命令
...; POP恢复信息
IRET ;中断服务子程序返回
IN_INTR ENDP
CODES ENDS
END START
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。 准备工作: 1、U盘一个(尽量使用8G以上的U盘)。 2、一台正常联网可使用的电脑。 3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。 4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。 U盘启动盘制作步骤: 注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU