计算机接口技术
——课内实验报告
物联网31班
2130509005 田雨桥
2015 年12月11日
实验一:基本I/O扩展实验
一、实验目的
了解TTL 芯片扩展简单I/O 口的方法,掌握数据输入输出程序编制的方法。
二、实验内容
预备知识:
74LS244 是一种三态输出的8 总线缓冲驱动器,无锁存功能,当G 为低电平时,
Ai 信号传送到Yi,当为高电平时,Yi 处于禁止高阻状态。
74LS273 是一种8D 触发器,当CLR 为高电平且CLK 端电平正跳变时,D0——
D7 端数据被锁存到8D 触发器中。
实验原理图:
三、 实验说明
利用74LS244 作为输入口,读取开关状态,并将此状态通过74LS273 再驱动发光二极管显示出来,连续运行程序,发光二极管显示开关状态。
四、实验连线
(1)244的cs连到cpu地址A15,Y7~Y0连到开关K1~K8;
(2)273的cs连到cpu地址A14,Q7~Q0连到发光二极管L1~L8;
(3)该模块的WR.RD连到cpu的WR.RD,数据线AD7~AD0、地址线A7~A0分别与cpu的数据线AD7~AD0、地址线A7~A0相连;
五、 实验现象
按照实验流程图完成接线且调试成功后,通过对开关K01 到K08 可以对应依次控制
LED 灯的L1 到L8 。
即当将开关i 上拨时,对应的LED灯i被点亮, 开关i 下拨时,对应
的LED灯i 被熄灭。
开关拨到55H时,将会产生右移LED 灯的花样显示。
开关拨到AAH 时,将会产生左移LED 灯的花样显示。
六、心得体会
通过实验,我学会了如何编写汇编程序来控制端口,更加了解了课内学过的知识,又通过实际操作进而实现基本的输入输出,对自己的汇编编程能力也有了一定的提高。此外,培养自己排除障碍的能力,通过自己分析和动手来检查障碍。并且通过观察实验结果了解了输入输出在实际应用上的作用
实验二——A/D 转换实验
一、实验题目
基本 IO 口扩展实验。
二、实验目的
1,熟悉PLX9054操作环境,掌握简单的程序运行方法
2.掌握 0809A/D 转换芯片的硬件电路和软件编程
三、实验原理
1.实验内容说明
ADC0809 的主要性能:
(1) 8 位逐次逼近型 A/D 转换器,所有引脚的逻辑电平与 TTL 电平兼容。
(2) 带有锁存功能的 8 路模拟量转换开关,可对 8 路 0~5V 模拟量进行分时切换。
(3) 输出具有三态锁存功能。
(4) 分辨率:8 位,转换时间:100μs。
(5) 不可调误差:±1LBS,功耗:15mW。
(6) 工作电压:+5V,参考电压标准值+5V。
(7) 片内无时钟,一般需外加 640KHz 以下且不低于 100KHz 的时钟信号。
ADC0809 的内部结构:
ADC0809 是 CMOS 的 8 位模/数转换器,采用逐次逼近原理进行 A/D 转换,芯片内有模
拟多路转换开关和 A/D 转换两大部分,可对 8 路 0~5V 的输入模拟电压信号分时进行转换。
模拟多路开关由 8 路模拟开关和 3 位地址锁存译码器组成,可选通 8 路模拟输入中的任何
一路,地址锁存信号 ALE 将 3 位地址信号 ADDA、ADDB、ADDC 进行锁存,然后由译码电路
选通其中的一路,被选中的通道进行 A/D 转换。A/D 转换部分包括比较器、逐次逼近寄存
器(SAR)、256R 电阻网络、树状电子开关、控制与时序电路等。另外 ADC0809 输出具有
TTL 三态锁存缓冲器,可直接连到 CPU 数据总线上。
ADC0809 的多路转换:
在实时控制与实时检测系统中,被控制与被测量的电路往往是几路或几十路,对这些
电路的参数进行模/数、数/模转换时,常采用公共的模数、数模转换电路。因此,对各路
进行转换是分时进行的。此时,必须轮流切换各被测电路与模数、数模转换电路之间的通
道,以达到分时切换的功能。
ADC0809 转换时序:
首先输入地址选择信号,在 ALE 信号作用下,地址信号被锁存,产生译码信号,选中
一路模拟量输入。然后输入启动转换控制信号 START(不小于 100ns ),启动 A/D 转换。
转换结束,数据送三态门锁存,同时发出 EOC 信号,在允许输出信号控制下,再将转换结果输出到外部数据总线。
本实验利用实验板上的 ADC0809 做 A/D 转换实验,将模拟信号转换成数字信号并在屏幕上显示,调节电位器观察屏幕上显示的变化
2、实验原理图
3、实验步骤
(1) 实验连线:
信号源模块短路 262.14KHz,CLK0 连到 AD0809 模块的时钟输入端 ADCLK。
AD0809 模块的 ADWR、ADRD 连到分别连到 ISA 总线接口模块的 IOWR、IORD。
AD0809 模块的数据(AD0~AD7)、地址线(A0~A7)分别连到 ISA 总线接口模块的数据(LD0~LD7)、地址线(LA0~LA7)。
AD0809 模块选通线 ADCS 连到 ISA 总线接口模块的 0020H。
AD0809 模块 IN0 接到电位器的 DCOUT。
(2) 运行程序:0809.ASM,调节电位器观察屏幕的变化。
四、实验结果
完成连线成功运行调试程序后,发现当电位器旋钮旋转时,电脑中AD转换的数值也会发生相应的改变。
五、心得体会
通过这次实验我掌握了a/d转换,同时也练习了编程和软件的使用,有一次巩固了我编程的能力,并且学到了很多知识,也促进了我对接口这门课程的理解,也让课堂的知识没有那么抽象了,变成了实际可操作的过程。
实验三:可编程定时计数器8254实验
一、实验目的
了解可编程定时器/计数器8254 实验了解计数器的硬件连接方法及时序关系;
掌握8254 的各种模式的编程及其原理,用示波器观察各信号之间的时序关系。
二、实验内容
将32Hz 的晶振频率作为8254的时钟输入,利用定时器8254 产生1Hz 的方波,发光二极管不停闪烁,用示波器可看到输出的方波。
8254 是一种可编程的定时器/计数器芯片,它具有3 个独立的16 位计数器通道,每个计数器都可以按照二进制或二-十进制计数,每个计数器都有6 种工作方式,计数频率可高达24MHz,芯片所有的输入输出都与TTL 兼容。
计数器都有6 种工作方式:方式0—计数过程结束时中断;方式1—可编程的单拍脉冲;方式2—频率发生器;方式3—方波发生器;方式4—软件触发;方式5—硬件触发。6 种工作方式主要有5 点不同:一是启动计数器的触发方式和时刻不同;二是计数过程中门控信号GATE 对计数操作的影响不同;三是OUT 输出的波形不同;四是在计数过程中重新写入计数初值对计数过程的影响不同;五是计数过程结束,减法计数器是否恢复计数初值并自动重复计数过程的不同。
三、实验原理
8254 是Intel 公司生产的可编程间隔定时器。是8253 的改进型,比8253 具有更优
良的性能。8254 具有以下基本功能:
(1)有3 个独立的16 位计数器。
(2)每个计数器可按二进制或十进制(BCD)计数。
(3)每个计数器可编程工作于6 种不同工作方式。
(4)8254 每个计数器允许的最高计数频率为10MHz(8253 为2MHz)。
(5)8254 有读回命令(8253 没有),除了可以读出当前计数单元的内容外,还可以
读出状态寄存器的内容。
(6)计数脉冲可以是有规律的时钟信号,也可以是随机信号。计数初值公式为:
n=fCLKi÷fOUTi、其中fCLKi 是输入时钟脉冲的频率,fOUTi 是输出波形的频率。
下图是8254 的内部结构框图和引脚图,它是由与CPU 的接口、内部控制电路和三个
计数器组成。
8254 的工作方式如下述:
(1)方式0:计数到0 结束输出正跃变信号方式。
(2)方式1:硬件可重触发单稳方式。
(3)方式2:频率发生器方式。
(4)方式3:方波发生器。
(5)方式4:软件触发选通方式。
(6)方式5:硬件触发选通方式。
8254 的控制字有两个:一个用来设置计数器的工作方式,称为方式控制字;另一个用来设
置读回命令,称为读回控制字。这两个控制字共用一个地址,由标识位来区分。
8254控制字: 8254的方式控制字格式:
8254读出控制字格式
状态字格式
实验流程图:
四、实验现象
按照实验流程图完成接线且调试成功后,可以观察到二极管1 L 每秒一次有规律地亮灭交替地闪烁。
当改变信号源模块的频率或者修改计数器的计数初值时,二极管1 L 闪烁的频率也随之改变。通过改变频率,可以观测到定时器在该实验中起到的定时中断的作用。
五、心得体会
通过这次实验我对于8254芯片的功能有了更加深刻的认识。动手能力有了更加进一步的提升。
实验四 可编程并行接口 8255 实验(交通灯)
一、实验目的
了解可编程并行接口芯片 8255 的内部结构、工作方式、初始化编程及应用。
二、实验说明
1、8255A 的内部结构
(1)数据总线缓冲器:这是一个双向三态的 8 位数据缓冲器,它是 8255A 与微机系统数据总线的接口。输入输出的数据、CPU 输出的控制字以及 CPU 输入的状态信息都是通过这个缓冲器传送的。
(2)三个端口 A,B 和 C:A 端口包含一个 8 位数据输出锁存器和缓冲器,一个 8 位数据输入锁存器。B 端口包含一个 8 位数据输入/输出锁存器和缓冲器,一个 8 位数据输入缓冲器。C 端口包含一个 8 位数据输出锁存器及缓冲器,一个 8 位数据输入缓冲器(输入没有锁存器)。
(3)A 组和 B 组控制电路:这是两组根据 CPU 输出的控制字控制 8255 工作方式的电路,它们对于 CPU 而言,共用一个端口地址相同的控制字寄存器,接收 CPU 输出的一字节方式控制字或对 C 口按位复位字命令。方式控制字的高 5 位决定 A 组工作方式,低 3 位决定 B 组的工作方式。对 C 口按位复位命令字可对 C 口的每一位实现置位或复位。A 组控制电路控制 A 口和 C 口上半部,B 组控制电路控制 B 口和 C 口下半部。
(4)读写控制逻辑:用来控制把 CPU 输出的控制字或数据送至相应端口,也由它来控制把状态信息或输入数据通过相应的端口送到 CPU。
2、8255A 的工作方式
方式 0—基本输入输出方式;方式 1—选通输入输出方式;方式 2—双向选通输入输出方式。
3、8255A 的状态字
4、8255A 的控制字
三、实验原理图
四、实验步骤
(1) 实验连线:
该模块的 WR、RD 分别连到 ISA 总线接口模块的 IOWR、IORD。
该模块的数据(AD0~AD7)、地址线(A0~A7)分别连到 ISA 总线接口模块的数据(LD0~LD7)、地址线(LA0~LA7)。
8255 模块选通线 CE 连到 ISA 总线接口模块的 0000H。
8255 的 PA0-L7、PA1-L6、PA2-L5、PA3-L3、PA4-L2、PA5-L1。
(2)运行程序:Tracffic.ASM,观察发光二极管。
五、实验现象
共有两组灯,每组各有红黄绿色灯各一个,当第一组灯显示红色时,第二组先显
示黄色然后绿灯闪烁5下。紧接着,第二组显示红灯,第一组显示黄灯,然后,第二组显示绿灯,并闪烁5下。照此规律循环显示下去。
六、心得体会
通过这次实验我对8255芯片的功能有了更加深刻的了解与认识。同时自己的编程动手能力有了更加进一步的提升,也可以用计算机控制实现很多实际的功能。
附页:程序源代码
实验一:基本I/O扩展实验
MY_STACK SEGMENT PARA 'STACK'
DB 100 DUP(?)
MY_STACK ENDS
MY_DATA SEGMENT PARA 'DATA'
IO_9054base_address DB 4 DUP(0);PCI卡9054芯片I/O基地址暂存空间
IO_base_address DB 4 DUP(0) ;PCI卡I/O基地址暂存空间
pcicardnotfind DB 0DH,0AH,'pci card not find or address/interrupt error !!!',0DH,0AH,'$'
GOOD DB 0DH,0AH,'The Program is Executing !',0DH,0AH,'$'
LS244 DW 00000H
LS273 DW 00020H
RA DB ?
LB DB ?
DELAY_SET EQU 0FFFH ;延时常数
MY_DATA ENDs
MY_CODE SEGMENT PARA 'CODE'
MY_PROC PROC FAR
ASSUME CS:MY_CODE, DS:MY_DATA, SS:MY_STACK
MAIN:
.386 ;386模式编译
MOV AX,MY_DATA
MOV DS,AX
MOV ES,AX
MOV AX,MY_STACK
MOV SS,AX
CALL FINDPCI ;自动查找PCI卡资源及IO口基址
MOV CX,word ptr IO_base_address
; MOV CX,0E800H ;直接加入(E800:本机PCI卡IO口基址)
ADD LS244,CX ;PCI卡IO基址+偏移
ADD LS273,CX
MOV RA,7FH
MOV LB,0FEH
READ1: MOV DX,LS244 ;读取开关状态
IN AL,DX
CMP AL,55H ;如果是55右移
JE READ2
CMP AL,0AAH ;如果是AA左移
JE READ3
NOT AL ;取反
JMP READ4
READ2: CALL RIGHT
JMP READ4
READ3: CALL LEFT
READ4: MOV DX,LS273
OUT DX,AL ;送LED显示
CALL DELAY
CALL BREAK
JMP READ1
MY_PROC ENDp
;
RIGHT PROC NEAR
MOV AL,RA
ROR AL,1
MOV RA,AL
RET
RIGHT ENDP
LEFT PROC NEAR
MOV AL,LB
ROL AL,1
MOV LB,AL
RET
LEFT ENDP
;
;*****************************************************************************
; /*按任意键退出*/
;*****************************************************************************
;
BREAK PROC NEAR ;按任意键退出
PUSHF
PUSH AX
PUSH DX
MOV AH,06H
MOV DL,0FFH
INT 21H
JE RETURN
MOV AX,4C00H
INT 21H
RETURN: POP DX
POP AX
POPF
RET
BREAK ENDP
;
;*****************************************************************************
; /*延时程序*/
;*****************************************************************************
;
DELAY PROC NEAR ;延时程序
PUSHF
PUSH DX
PUSH CX
MOV DX,DELAY_SET
D1: MOV CX,-1
D2: DEC CX
JNZ D2
DEC DX
JNZ D1
POP CX
POP DX
POPF
RET
DELAY ENDp
;
;*****************************************************************************
; /* 找卡子程序 */
;*****************************************************************************
;
;FUNCTION CODE
IO_port_addre EQU 0CF8H ;32位配置地址端口
IO_port_data EQU 0CFCH ;32位配置数据端口
IO_PLX_ID EQU 200810B5H ;PCI卡设备及厂商ID
BADR0 = 10H ;基地址寄存器0
BADR1 = 14H ;基地址寄存器1
BADR2 = 18H ;基地址寄存器2
BADR3 = 1CH ;基地址寄存器3
FINDPCI PROC NEAR ;查找PCI卡资源并显示
PUSHAD
PUSHFD
MOV EBX,080000000H
FINDPCI_next:
ADD EBX,100H
CMP EBX,081000000H
JNZ findpci_continue
MOV DX,offset pcicardnotfind ;显示未找到PCI卡提示信息
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H ;退出
findpci_continue:
MOV DX,IO_port_addre
MOV EAX,EBX
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
CMP EAX,IO_PLX_ID
JNZ findpci_next ;检查是否发现PCI卡
MOV DX,IO_port_addre
MOV EAX,EBX
ADD EAX,BADR1
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
MOV dword ptr IO_9054base_address,EAX
AND EAX,1
JZ findPCI_next ;检查是否为i/o基址信息
MOV EAX,dword ptr IO_9054base_address
AND EAX,0fffffffeh
MOV dword ptr IO_9054base_address,EAX ;去除i/o指示位并保存
MOV DX,IO_port_addre
MOV EAX,EBX
ADD EAX,BADR2
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
MOV dword ptr IO_base_address,EAX
AND EAX,1
JZ findPCI_next ;检查是否为i/o基址信息
MOV EAX,dword ptr IO_base_address
AND EAX,0fffffffeh
MOV dword ptr IO_base_address,EAX ;去除i/o指示位并保存
MOV DX,offset good ;显示开始执行程序信息
MOV AH,09H
INT 21H
POPfd
POPad
RET
findPCI ENDP
MY_CODE ENDS
END MAIN
实验二——A/D 转换实验
MY_STACK SEGMENT PARA 'STACK'
DB 100 DUP(?)
MY_STACK ENDS
MY_DATA SEGMENT PARA 'DATA'
IO_9054base_address DB 4 DUP(0) ;PCI卡9054芯片I/O基地址暂存空间
IO_base_address DB 4 DUP(0) ;PCI卡I/O基地址暂存空间
pcicardnotfind DB 0DH,0AH,'pci card not find or address/interrupt error !!!',0DH,0AH,'$'
GOOD DB 0DH,0AH,'The Program is Executing !',0DH,0AH,'$'
MESS DB 0DH,0AH,'The AD result is ',0DH,0AH,'$'
AD0809 DW 0020H
DELAY_SET EQU 0FFH ;延时常数
DIDATA DB ? ;要显示的数据
MY_DATA ENDs
MY_CODE SEGMENT PARA 'CODE'
MY_PROC PROC FAR
ASSUME CS:MY_CODE, DS:MY_DATA, SS:MY_STACK
MAIN:
.386 ;386模式编译
MOV AX,MY_DATA
MOV DS,AX
MOV ES,AX
MOV AX,MY_STACK
MOV SS,AX
CALL FINDPCI ;自动查找PCI卡资源及IO口基址
MOV CX,word ptr IO_base_address
; MOV CX,0E800H ;直接加入(E800:本机PCI卡IO口基址)
ADD AD0809,CX ;PCI卡IO基址+偏移
MOV DX,offset MESS ;显示提示信息
MOV AH,09H
INT 21H
MOV DIDATA,00H
STARTAD: MOV DX,AD0809
MOV AL,00H
OUT DX,AL ;启动AD转换
CALL DELAY
IN AL,DX ;转换结束读取结果
CMP AL,DIDATA ;如果是原来的数据不刷新显示
CALL BREAK
JZ STARTAD
CALL DSUP ;显示
JMP STARTAD
MY_PROC ENDP
;
;*****************************************************************************
; /*显示子程序*/
;*****************************************************************************
;
DSUP PROC NEAR
PUSHF
PUSH CX
MOV DIDATA,AL
MOV CX,04 ;取高位
SHR AL,CL
CALL SEND
MOV AL,DIDATA
AND AL,0FH ;低位
CALL SEND
CALL CR
POP CX
POPF
RET
DSUP ENDP
SEND PROC NEAR
CMP AL,09H
JG SEND1
ADD AL,30H
JMP SEND2
SEND1: ADD AL,37H
SEND2: MOV AH,0EH
INT 10H
RET
SEND ENDP
CR PROC NEAR ;回车
MOV DL,0DH
MOV AH,02H
INT 21H
RET
CR ENDP
;
;***************************************************************
; /*延时子程序*/ *
;***************************************************************
;
DELAY PROC NEAR ;延时程序
PUSHF
PUSH DX
PUSH CX
MOV DX,DELAY_SET
D1: MOV CX,-1
D2: DEC CX
JNZ D2
DEC DX
JNZ D1
POP CX
POP DX
POPF
RET
DELAY ENDp
;
;*****************************************************************************
; /*按任意键退出*/
;*****************************************************************************
;
BREAK PROC NEAR ;按任意键退出
PUSHF
PUSH AX
PUSH DX
MOV AH,06H
MOV DL,0FFH
INT 21H
JE RETURN
EXEC_EXIT: MOV AX,4C00H
INT 21H
RETURN: POP DX
POP AX
POPF
RET
BREAK ENDP
;
;*****************************************************************************
; /* 找卡子程序 */
;*****************************************************************************
;
;FUNCTION CODE
IO_port_addre EQU 0CF8H ;32位配置地址端口
IO_port_data EQU 0CFCH ;32位配置数据端口
IO_PLX_ID EQU 200810B5H ;PCI卡设备及厂商ID
BADR0 = 10H ;基地址寄存器0
BADR1 = 14H ;基地址寄存器1
BADR2 = 18H ;基地址寄存器2
BADR3 = 1CH ;基地址寄存器3
FINDPCI PROC NEAR ;查找PCI卡资源并显示
PUSHAD
PUSHFD
MOV EBX,080000000H
FINDPCI_next:
ADD EBX,100H
CMP EBX,081000000H
JNZ findpci_continue
MOV DX,offset pcicardnotfind ;显示未找到PCI卡提示信息
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H ;退出
findpci_continue:
MOV DX,IO_port_addre
MOV EAX,EBX
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
CMP EAX,IO_PLX_ID
JNZ findpci_next ;检查是否发现PCI卡
MOV DX,IO_port_addre
MOV EAX,EBX
ADD EAX,BADR1
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
MOV dword ptr IO_9054base_address,EAX
AND EAX,1
JZ findPCI_next ;检查是否为i/o基址信息
MOV EAX,dword ptr IO_9054base_address
AND EAX,0fffffffeh
MOV dword ptr IO_9054base_address,EAX ;去除i/o指示位并保存
MOV DX,IO_port_addre
MOV EAX,EBX
ADD EAX,BADR2
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
MOV dword ptr IO_base_address,EAX
AND EAX,1
JZ findPCI_next ;检查是否为i/o基址信息
MOV EAX,dword ptr IO_base_address
AND EAX,0fffffffeh
MOV dword ptr IO_base_address,EAX ;去除i/o指示位并保存
MOV DX,offset good ;显示开始执行程序信息
MOV AH,09H
INT 21H
POPfd
POPad
RET
findPCI ENDP
MY_CODE ENDS
END MAIN
实验三:可编程定时计数器8254实验
MY_STACK SEGMENT PARA 'STACK'
DB 100 DUP(?)
MY_STACK ENDS
MY_DATA SEGMENT PARA 'DATA'
IO_9054base_address DB 4 DUP(0) ;PCI卡9054芯片I/O基地址暂存空间
IO_base_address DB 4 DUP(0) ;PCI卡I/O基地址暂存空间
pcicardnotfind DB 0DH,0AH,'pci card not find or address/interrupt error !!!',0DH,0AH,'$'
GOOD DB 0DH,0AH,'The Program is Executing !',0DH,0AH,'$'
P8254_T0 DW 0000H
P8254_T1 DW 0001H
P8254_T2 DW 0002H
P8254_MODE DW 0003H
MY_DATA ENDs
MY_CODE SEGMENT PARA 'CODE'
MY_PROC PROC FAR
ASSUME CS:MY_CODE, DS:MY_DATA, SS:MY_STACK
MAIN:
.386 ;386模式编译
MOV AX,MY_DATA
MOV DS,AX
MOV ES,AX
MOV AX,MY_STACK
MOV SS,AX
CALL FINDPCI ;自动查找PCI卡资源及IO口基址
MOV CX,word ptr IO_base_address
; MOV CX,0E800H ;直接加入(E800:本机PCI卡IO口基址)
ADD P8254_T0,CX ;PCI卡IO基址+偏移
ADD P8254_T1,CX
ADD P8254_T2,CX
ADD P8254_MODE,CX
MOV DX,P8254_MODE;写入方式控制字
MOV AL,37H ;计数器0,先读写低位,后读写高位,
OUT DX,AL ;方式3,BCD码计数
MOV DX,P8254_T0
MOV AL,20H ;初值低8位
OUT DX,AL
MOV AL,00H ;初值高8位
OUT DX,AL
NEXT: CALL BREAK
JMP NEXT
MY_PROC ENDp
;
;*****************************************************************************
; /*按任意键退出*/
;*****************************************************************************
;
BREAK PROC NEAR ;按任意键退出
PUSHF
PUSH AX
PUSH DX
MOV AH,06H
MOV DL,0FFH
INT 21H
JE RETURN
EXEC_EXIT: MOV AX,4C00H
INT 21H
RETURN: POP DX
POP AX
POPF
RET
BREAK ENDP
;
;*****************************************************************************
; /* 找卡子程序 */
;*****************************************************************************
;
;FUNCTION CODE
IO_port_addre EQU 0CF8H ;32位配置地址端口
IO_port_data EQU 0CFCH ;32位配置数据端口
IO_PLX_ID EQU 200810B5H ;PCI卡设备及厂商ID
BADR0 = 10H ;基地址寄存器0
BADR1 = 14H ;基地址寄存器1
BADR2 = 18H ;基地址寄存器2
BADR3 = 1CH ;基地址寄存器3
FINDPCI PROC NEAR ;查找PCI卡资源并显示
PUSHAD
PUSHFD
MOV EBX,080000000H
FINDPCI_next:
ADD EBX,100H
CMP EBX,081000000H
JNZ findpci_continue
MOV DX,offset pcicardnotfind;显示未找到PCI卡提示信息
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H ;退出
findpci_continue:
MOV DX,IO_port_addre
MOV EAX,EBX
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
CMP EAX,IO_PLX_ID
JNZ findpci_next ;检查是否发现PCI卡
MOV DX,IO_port_addre
MOV EAX,EBX
ADD EAX,BADR1
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
MOV dword ptr IO_9054base_address,EAX
AND EAX,1
JZ findPCI_next ;检查是否为i/o基址信息
MOV EAX,dword ptr IO_9054base_address
AND EAX,0fffffffeh
MOV dword ptr IO_9054base_address,EAX;去除i/o指示位并保存
MOV DX,IO_port_addre
MOV EAX,EBX
ADD EAX,BADR2
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
MOV dword ptr IO_base_address,EAX
AND EAX,1
JZ findPCI_next ;检查是否为i/o基址信息
MOV EAX,dword ptr IO_base_address
AND EAX,0fffffffeh
MOV dword ptr IO_base_address,EAX;去除i/o指示位并保存
MOV DX,offset good ;显示开始执行程序信息
MOV AH,09H
INT 21H
POPfd
POPad
RET
findPCI ENDP
MY_CODE ENDS
END MAIN
实验四 可编程并行接口 8255 实验(交通灯)
MY_STACK SEGMENT PARA 'STACK'
DB 100 DUP(?)
MY_STACK ENDS
MY_DATA SEGMENT PARA 'DATA'
IO_9054base_address DB 4 DUP(0) ;PCI卡9054芯片I/O基地址暂存空间
IO_base_address DB 4 DUP(0) ;PCI卡I/O基地址暂存空间
pcicardnotfind DB 0DH,0AH,'pci card not find or address/interrupt error !!!',0DH,0AH,'$'
GOOD DB 0DH,0AH,'The Program is Executing !',0DH,0AH,'$'
P8255_A DW 0000H
P8255_B DW 0001H
P8255_C DW 0002H
P8255_MODE DW 0003H
DELAY_SET EQU 0fffH
DELAY_SET1 EQU 08ffH
MES2 DB ' PCI CONFIG READ ERROR! $'
MY_DATA ENDs
MY_CODE SEGMENT PARA 'CODE'
MY_PROC PROC FAR
ASSUME CS:MY_CODE, DS:MY_DATA, SS:MY_STACK
START:
.386 ;386模式编译
MOV AX,MY_DATA
MOV DS,AX
MOV ES,AX
MOV AX,MY_STACK
MOV SS,AX
CALL FINDPCI ;自动查找PCI卡资源及IO口基址
MOV CX,word ptr IO_base_address
; MOV CX,0E800H ;直接加入(E800:本机PCI卡IO口基址)
ADD P8255_A,CX ;PCI卡IO基址+偏移
ADD P8255_B,CX
ADD P8255_C,CX
ADD P8255_MODE,CX
MOV DX,P8255_MODE
MOV AL,80H ;3个口全部为输出
OUT DX,AL
MOV DX,P8255_A
CALL ST0 ;全为红灯
TRAFFIC1: CALL ST1 ;南北为绿灯,东西为红灯
CALL ST2 ;南北红灯闪烁,东西为红灯
CALL ST3 ;南北为红灯,东西为绿灯
CALL ST4 ;南北为红灯,东西黄灯闪烁
CALL BREAK
JMP TRAFFIC1
MY_PROC ENDp
;
;*****************************************************************************
; /*初始状态全为红灯*/
;*****************************************************************************
;
ST0 PROC NEAR
MOV AL,1BH
OUT DX,AL
CALL DELAY
RET
ST0 ENDp
;
;*****************************************************************************
; /*南北为绿灯,东西为红灯子程序*/
;*****************************************************************************
;
ST1 PROC NEAR
MOV DX,P8255_A
MOV AL,33H
OUT DX,AL
CALL DELAY
RET
ST1 ENDp
;
;*****************************************************************************
; /*南北红灯闪烁,东西为红灯子程序*/
;*****************************************************************************
;
ST2 PROC NEAR
MOV CX,5H
ST20: MOV AL,2BH
OUT DX,AL
CALL DELAY
MOV AL,3BH
OUT DX,Al
CALL DELAY
LOOP ST20
RET
ST2 ENDp
;
;*****************************************************************************
; /*南北为红灯,东西为绿灯子程序*/
;*****************************************************************************
;
ST3 PROC NEAR
MOV AL,1EH
OUT DX,AL
CALL DELAY
RET
ST3 ENDp
;
;*****************************************************************************
; /*南北为红灯,东西黄灯闪烁子程序*/
;*****************************************************************************
;
ST4 PROC NEAR
MOV CX,5H
ST40: MOV AL,1DH
OUT DX,AL
CALL DELAY
MOV AL,1FH
OUT DX,AL
CALL DELAY
LOOP ST40
RET
ST4 ENDp
;
;*****************************************************************************
; /* 延时子程序 */
;*****************************************************************************
;
DELAY PROC NEAR ;延时程序
PUSHF
PUSH DX
PUSH CX
MOV DX,DELAY_SET
D1: MOV CX,-1
D2: DEC CX
JNZ D2
DEC DX
JNZ D1
POP CX
POP DX
POPF
RET
DELAY ENDp
DELAY1 PROC NEAR ;延时程序
PUSHF
PUSH DX
PUSH CX
MOV DX,DELAY_SET1
D3: MOV CX,-1
D4: DEC CX
JNZ D4
DEC DX
JNZ D3
POP CX
POP DX
POPF
RET
DELAY1 ENDp
;
;*****************************************************************************
; /* 按任意键退出子程序 */
;*****************************************************************************
;
BREAK PROC NEAR ;按任意键退出
PUSHF
PUSH AX
PUSH DX
MOV AH,06H
MOV DL,0FFH
INT 21H
JE RETURN
MOV AX,4C00H
INT 21H
RETURN: POP DX
POP AX
POPF
RET
BREAK ENDP
;
;*****************************************************************************
; /* 找卡子程序 */
;*****************************************************************************
;
;FUNCTION CODE
IO_port_addre EQU 0CF8H ;32位配置地址端口
IO_port_data EQU 0CFCH ;32位配置数据端口
IO_PLX_ID EQU 200810B5H ;PCI卡设备及厂商ID
BADR0 = 10H ;基地址寄存器0
BADR1 = 14H ;基地址寄存器1
BADR2 = 18H ;基地址寄存器2
BADR3 = 1CH ;基地址寄存器3
FINDPCI PROC NEAR ;查找PCI卡资源并显示
PUSHAD
PUSHFD
MOV EBX,080000000H
FINDPCI_next:
ADD EBX,100H
CMP EBX,081000000H
JNZ findpci_continue
MOV DX,offset pcicardnotfind;显示未找到PCI卡提示信息
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H ;退出
findpci_continue:
MOV DX,IO_port_addre
MOV EAX,EBX
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
CMP EAX,IO_PLX_ID
JNZ findpci_next ;检查是否发现PCI卡
MOV DX,IO_port_addre
MOV EAX,EBX
ADD EAX,BADR1
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
MOV dword ptr IO_9054base_address,EAX
AND EAX,1
JZ findPCI_next ;检查是否为i/o基址信息
MOV EAX,dword ptr IO_9054base_address
AND EAX,0fffffffeh
MOV dword ptr IO_9054base_address,EAX ;去除i/o指示位并保存
MOV DX,IO_port_addre
MOV EAX,EBX
ADD EAX,BADR2
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
MOV dword ptr IO_base_address,EAX
AND EAX,1
JZ findPCI_next ;检查是否为i/o基址信息
MOV EAX,dword ptr IO_base_address
AND EAX,0fffffffeh
MOV dword ptr IO_base_address,EAX;去除i/o指示位并保存
MOV DX,offset good ;显示开始执行程序信息
MOV AH,09H
INT 21H
POPfd
POPad
RET
findPCI ENDP
MY_CODE ENDS
END START