8255设置
8255试题及答案
8255试题及答案1. 简述8255芯片的三种工作模式。
- 模式0:基本输入/输出模式。
- 模式1:带握手的输入/输出模式。
- 模式2:双向总线模式。
2. 8255芯片的控制字如何设置?- 控制字的格式为D7 D6 D5 D4 D3 D2 D1 D0。
- D7 D6:选择工作模式(00为模式0,01为模式1,10为模式2,11为模式3)。
- D5 D4:选择端口A工作方式(00为输出,01为输入)。
- D3 D2:选择端口B工作方式(00为输出,01为输入)。
- D1 D0:选择端口C工作方式(00为输出,01为输入)。
3. 8255芯片的端口C可以分成几个部分?- 端口C可以分成两个8位的端口(C上半部和C下半部)或者一个8位的端口。
4. 在模式2下,8255芯片的端口A和端口B分别是什么功能?- 端口A:作为输入端口。
- 端口B:作为输出端口。
5. 8255芯片的端口C的上半部和下半部如何使用?- 端口C的上半部可以作为输入或输出。
- 端口C的下半部可以作为输入或输出。
6. 8255芯片的端口A和端口B在模式1下如何工作?- 端口A和端口B在模式1下可以分别设置为输入或输出。
7. 8255芯片的端口C在模式1下如何工作?- 端口C的上半部和下半部都可以作为输入或输出。
8. 在模式0下,8255芯片的端口A和端口B是否可以同时作为输入或输出?- 是的,在模式0下,端口A和端口B可以同时作为输入或输出。
9. 8255芯片的端口C在模式0下如何工作?- 端口C的上半部和下半部可以单独设置为输入或输出。
10. 8255芯片的端口C在模式2下如何工作?- 在模式2下,端口C的上半部和下半部可以分别设置为输入或输出。
11. 8255芯片的端口C在模式3下如何工作?- 在模式3下,端口C的上半部和下半部可以分别设置为输入或输出。
12. 8255芯片的端口A和端口B在模式3下如何工作?- 在模式3下,端口A和端口B可以分别设置为输入或输出。
实验二_8255并行接口应用实验
实验二_8255并行接口应用实验一、实验目的1. 熟悉8255并行接口的功能和应用。
2. 掌握8255并行接口的控制字的含义和编写方法。
3. 熟悉并行接口的IO读写操作。
二、实验仪器1. PC机2. AT8051开发板4. 其他配件线路三、实验原理8255芯片是Intel公司提供的一种通用并行接口芯片。
它可以实现外围设备、传感器的控制、数据的输入/输出等功能,是一种非常实用的通用接口芯片。
8255是一个三端口、24线单片并行接口芯片,它可以直接连接CPU总线或I/O总线,采用AHB (AMBA High-Performance Bus)总线。
总线与8255之间的通讯方式采用输入/输出端口的方式,在CPU访问8255时,必须指定8255的端口地址。
CPU在访问8255时,AV(地址有效)为高电平,同时CS和RD为有效低电平。
8255所使用的端口地址由登录的端口号选择器(P0、P1、P2)决定。
8255的主要特点:a. 具有3个通用I/O端口,每个端口有8位,共有24条I/O线。
b. 可以通过外部信号线与中间件或总线连接。
c. 具有3种基本工作方式:安装、双向缓冲装置和输入输出方式。
d. 为减少芯片引脚数,端口地址用地址寄存器低端口号器(P0,P1)来指定。
端口的寄存器编号可以选择0或1。
e. 以可编程方式控制I/O端口。
f. 内接有二进制计数器,可用于计时和计数应用。
2. 编程实现原理本次实验中,我们将用8051的C语言编程,控制8255进行I/O读写操作。
在编程时,我们将根据需要设置8255的控制字,并利用控制字来控制8255的输入输出。
同时,在控制8255的I/O读写操作中,我们还需将相应的端口地址赋值给端口指针,以实现读写操作。
3. 硬件连接我们将在AT8051开发板上搭建实验电路,具体如下:a. 8255芯片的输入输出口A、B、C分别连接到LED灯,以控制LED灯的开关状态。
b. AT8051开发板的P0、P1、P2分别连接到8255的A1、A0、CS/WR、RD/CS口线,以进行8255的读写操作。
8255芯片知识点总结
8255芯片知识点总结一、8255芯片的功能8255芯片的主要功能是实现微处理器与外部设备之间的数据传输和交互。
它提供了24个I/O引脚,可配置为三个8位的并行输入/输出端口。
除了I/O功能之外,8255芯片还具有自动手摇功能,可通过设置控制字来进行不同模式的操作,包括模式0(基本I/O)、模式1(手摇方式)、模式2(双向通讯)和模式3(快速反射)。
在基本I/O模式下,8255芯片的三个端口A、B、C分别作为输出、输入、控制端口。
通过设置控制字可以配置每个端口的工作方式,包括输入、输出和双向通讯。
而在手摇方式下,8255芯片可以通过设置手摇信号来进行数据传输,可以实现16位数据的传输操作。
在双向通讯模式下,8255芯片可以通过读写控制字来实现双向数据传输。
而在快速反射模式下,8255芯片可以实现数据的快速输入和输出,适用于数据采集和高速数据传输等场景。
除了上述功能,8255芯片还可以实现对外设设备的中断请求响应、电源管理和自检功能等。
因此,8255芯片在微处理器系统中扮演着非常重要的角色,可以实现微处理器与外部设备的高效通讯和控制。
二、8255芯片的特点8255芯片具有以下几个显著的特点:1. 多功能性:8255芯片提供了多种工作模式和配置方式,可以适用于不同的应用场景。
用户可以通过编程来设置控制字,实现8255芯片的不同功能。
2. 高性能:8255芯片具有高速的数据传输和处理能力,可以满足对数据传输速度要求较高的应用。
3. 可编程性:8255芯片的功能和工作方式可以通过编程进行配置,可以根据具体的应用需求来设置控制字,实现不同的功能和模式。
4. 可靠性:8255芯片具有良好的稳定性和可靠性,可以在恶劣的环境条件下正常工作。
5. 兼容性:8255芯片广泛应用于各种微处理器系统中,与不同的微处理器兼容性强,可广泛应用于各种系统。
6. 低功耗:8255芯片采用低功耗设计,具有较低的能耗,适用于对电源管理要求较高的应用。
8255开关状态显示实验
实验一:开关状态显示实验
一、实验要求:
编写程序,设定8255的PA口为开关量输入,PC口为开关输出,要求能随时将PA口的开关状态通过PC口的发光二极管显示出来。
二、实验目的:
学习使用8255各个口的不同工作方式。
三、实验电路、连线及程序:
实验电路如图1、1所示
连线如图1、2所示
将K1~K8用连线连至8255的PA0~PA7,将DL1~DL8用连线连至8255的PC0~PC7,8255CS用用连线连至译码处得200H~207H这个插孔。
实验程序:
DATA SEGMENT
DATA ENDS
STACK SEGMENT STACK
STA DW50DUP(?)
TOP EQU LENGTH STA
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
START:
MOV DX,203H;设置为A口输入,B口输出
MOV AL,90H
OUT DX,AL
BG:MOV DX,200H;将A口状态从B口输出
IN AL,DX
MOV DX,202H
OUT DX,AL
JMP BG
CODE ENDS
END START
四、实验说明:
本实验要求8255工作于方式0,PA口设置为输入,PC口设置为输出,输入量为开关量,通过8255可实时显示在LED灯上。
按下HALT或RST键则返回监控。
微机原理8255的应用
微机原理8255的应用1. 简介本文档将介绍微机原理中的8255芯片的应用及其相关知识。
8255是一款常用的并行输入输出(PIO)芯片,广泛应用于微机原理的实验和应用中。
本文将从以下几个方面进行介绍:1.8255芯片的功能及特点2.8255芯片的引脚功能3.8255芯片的工作原理4.8255芯片的应用案例2. 8255芯片的功能及特点8255芯片是一种通用的并行输入输出接口芯片,可以提供多种不同的I/O操作模式。
其主要功能如下:•提供三个8位的I/O端口A、B和C,可以通过编程定义其为输入或输出端口。
•支持模式0、模式1和模式2三种工作模式,可以通过编程控制选择不同的模式。
•可以通过编程设置端口的工作模式和数据传输方式。
•可以通过编程控制和操作I/O端口的数据。
8255芯片的主要特点如下:•低功耗设计,适合在嵌入式系统中使用。
•高可靠性和稳定性,能够在不同环境下正常工作。
•兼容性强,可以与多种微处理器和控制器连接使用。
3. 8255芯片的引脚功能8255芯片共有40个引脚,每个引脚的功能如下:•一号引脚(VCC):芯片的供电电源。
•二号引脚(GND):芯片的接地引脚。
•三号引脚(A0)至四号引脚(A1):用于编程选择工作模式。
•五号引脚(CS):芯片的片选引脚,通过将其接地来选择芯片。
•六号引脚(RD):读取端口数据的引脚。
•七号引脚(WR):写入端口数据的引脚。
•八号引脚(RESET):芯片的复位引脚。
•九号引脚至十六号引脚(PA0至PA7):端口A的数据线。
•十七号引脚至二十四引脚(PB0至PB7):端口B的数据线。
•二十五号引脚至三十二号引脚(PC0至PC7):端口C的数据线。
4. 8255芯片的工作原理8255芯片是通过控制寄存器对其进行编程来实现不同功能的。
通过编程控制控制寄存器的值,可以选择端口的工作模式、数据传输方式等。
8255芯片的工作原理如下:1.初始化8255芯片,设置控制寄存器的值。
8255工作方式
INTRA
I/O
图 端口A方式 1 输入
STB:选通信号输入,外设 发出 IBF:输入缓冲器满,8255 发出 INTE:内部中断触发器 INTR:中断请求
① 当外设数据准备好,将数据送至 端口线PA7~PA0 ② 外设发出选通信号STB: (1) 将数据锁存在输入端口内。 (2) STB的下降沿使IBF变高,表 示输入端口满,用于阻止外设输入 新数据。 (3) STB的上升沿使INTE=1, 从而 INTR变高,发出中断请求。 ③ 中断处理程序中CPU 读取数据, 发出RD信号: (1) RD 的下降沿清除INTR (2) RD 的上升沿清除IBF (3) 端口内的数据进入CPU
PC3
INTRA
中断允许触发器
中断请求信号,高电平有效,当输出设备已接受 数据后,8255A输出此信号向CPU提出中断请求, 要求CPU继续提供数据
B端口方式1输出:
输出缓冲器满信号,低电平有效 8255A输出给外设的一个控制信号, 当其有效时,表示CPU已把数据输 出给指定的端口,外设可以取走
PB7~PB0 INTEB PC1 PC2
组合,具体情况应如表7.2所示。P262
7.1.3
8255的工作方式
2.方式1—选通输入/输出方式 端口A或端口B仍作为数据的输入/输出口,但同时规定端口C的某 些位作为控制或状态信息。 适用于查询和中断方式的接口电路
方式1的特点 端口A、B可分别工作在方式1。 端口C配合方式1工作。
2.工作方式1:被称作选通输入/输出方式,在这种工 作方式下,数据输入/输出操作要在选通信号控制下 完成。(部分PC线作为选通控制信号线) 采用工作方式1进行输入操作(外设→接口→ CPU)时, 需要使用的控制信号如下: ① STB——选通信号。由外部输入,低电平有效。 STB有效时,将外部输入的数据锁存到所选端口的 输入锁存器中。对A组来说,指定端口C的第4位 (PC4)用来接收向端口A输入的STB信号;对B组来说, 指定端口C的第2位(PC2)用来接收向端口B输入的 STB信号。 ② IBF——输入缓冲存储器满信号。向外部输出,高 电平有效。
8255工作原理
8255工作原理
8255是一种常用的并行输入/输出设备,它可以连接到微处理器系统并扩展其输入和输出的数量。
8255的工作原理如下:
1. 模式设置:8255有三个可编程的I/O模式,分别是模式0、模式1和模式2。
模式0是最简单的模式,它将所有的I/O端口设置为输出端口。
模式1将端口设置为输入或输出,而模式2将端口分为两个8位I/O端口。
2. 控制寄存器:8255有一个控制寄存器用于设置I/O模式和其他参数。
寄存器的位代表不同的控制功能,可以通过写入特定的二进制位组合来设置相应的功能。
3. 数据传输:当8255设置为输入模式时,它可以将外部设备的数据读取到内部存储器中。
当设置为输出模式时,它可以将内存中的数据传输到外部设备。
数据的传输是通过读取或写入指定的I/O端口地址来实现的。
4. 端口地址选择:8255有三个8位的端口地址寄存器,用于访问特定的I/O端口。
这些寄存器可以用来选择要读取或写入的端口。
总的来说,8255的工作原理是通过设置模式和控制寄存器来控制数据传输,然后通过读取或写入特定的I/O端口地址来实现与外部设备之间的通信。
8255a初始化编程
8255a初始化编程
8255A是一种并行I/O接口芯片,它可以配置为三个独立的I/O端口:端口A、端口B和端口C。
以下是一个8255A 的初始化编程的简单示例:
首先,我们需要设置控制字来配置8255A的工作模式。
控制字是通过将8位数据写入控制寄存器来设置的。
控制字的每一位都有特定的含义,用于配置端口A、端口B和端口C的工作模式。
例如,如果我们想要设置端口A为输出模式,端口B为输入模式,端口C为输入模式,我们可以设置控制字为1000 0000。
这个控制字的意思是:
控制字的第0位设置为1表示使能片选信号(ENABLE),启动芯片。
控制字的第1位设置为0表示端口A为输出模式。
控制字的第2位设置为0表示端口B为输入模式。
控制字的第3位设置为0表示端口C为输入模式。
控制字的第4位到第7位未使用,因此可以忽略。
然后,我们可以将这个控制字写入8255A的控制寄存器:assembly复制代码:
OUT 8255_control_register, control_word
其中,8255_control_register是控制寄存器的地址,control_word是我们刚才计算出的控制字。
这样我们就完成了8255A的初始化编程。
之后,我们就可以使用端口A、端口B和端口C进行I/O操作了。
注意:以上代码是假设我们在使用某种汇编语言进行编程。
不同的编程语言可能有不同的语法和函数来操作硬件。
8255中的方式控制字和位控制字
主题:8255中的方式控制字和位控制字1. 介绍8255芯片8255是一种可编程并行I/O芯片,广泛用于微机、工控、通信、家电等领域。
它具有多种功能,包括输入/输出控制、定时/计数功能等,能够满足不同应用的需求。
2. 方式控制字的概念方式控制字是8255中的重要概念之一,它用于配置8255芯片的工作方式。
通过设置方式控制字,可以确定8255的工作模式,包括输入、输出、双向或定时/计数等。
3. 方式控制字的结构方式控制字通常由8位二进制数据组成,每一位都代表着8255的某种工作状态。
其中,最高3位用于设置端口A、端口B和端口C的工作方式,接下来的3位用于设置端口A、端口B和端口C的工作模式,最低2位用于设置定时/计数功能的工作状态。
4. 方式控制字的设置方法在使用8255芯片时,需要按照具体应用的需求来设置方式控制字。
可以通过编程的方式将合适的二进制数据写入到8255芯片的方式控制字寄存器中,以达到配置8255工作模式的目的。
5. 位控制字的概念除了方式控制字之外,8255中还有位控制字的概念。
位控制字用于控制8255芯片的具体输入/输出操作,可以实现对单个端口的位控制。
6. 位控制字的结构位控制字通常由8位二进制数据组成,每一位都代表着8255的某种输入/输出操作。
通过设置位控制字,可以实现对端口A、端口B和端口C的单个位的输入/输出控制。
7. 位控制字的设置方法对于特定的输入/输出操作,可以通过编程的方式将合适的二进制数据写入到8255芯片的位控制字寄存器中,以实现对端口的单个位的控制。
8. 方式控制字与位控制字的关系方式控制字和位控制字是8255芯片中两个重要的控制概念,它们共同构成了8255的工作模式。
方式控制字主要用于配置8255的工作方式,而位控制字则用于具体的输入/输出控制操作。
9. 总结8255芯片中的方式控制字和位控制字是控制8255工作模式和具体输入/输出操作的重要手段。
通过合理设置方式控制字和位控制字,可以实现对8255芯片的灵活控制,满足不同应用的需求。
8255初始化编程步骤
8255初始化编程步骤一、引言8255是一种通用的并行I/O接口芯片,常用于嵌入式系统中。
本文将介绍8255的初始化编程步骤,帮助读者快速上手使用该芯片。
二、8255概述8255是一款具有三个I/O端口的芯片,即PA、P B和P C端口。
每个端口都可以被配置为输入或输出端口,用于与外部设备进行数据交互。
三、8255初始化编程步骤以下是8255初始化编程的详细步骤:步骤1:设置模式字模式字用于配置8255的工作模式,包括端口A、B、C的工作模式以及手动或自动方式。
模式字的格式如下:位|功能D7|A和C寄存器的工作模式选择D6|A和C寄存器的工作模式选择D5|A寄存器的操作模式选择D4|B和C寄存器的工作模式选择D3|B和C寄存器的工作模式选择D2|B寄存器的操作模式选择D1|模式选择标志:1为手动,0为自动D0|1为允许端口C访问,0为禁止端口C访问参考以下示例代码设置模式字:m o de=0b00100010;o u tp(0x80,mo de);//将模式字写入8255的控制寄存器步骤2:配置端口A和端口C针对端口A和端口C,需要进行以下设置:配置端口A1.如果端口A是输出端口,设置控制寄存器的位PA E为1。
2.如果端口A是输入端口,设置控制寄存器的位PA E为0。
参考以下示例代码进行端口A的配置:i f(o ut pu tP or tA){o u tp(0x82,0x01);//设置PA E为1,将端口A配置为输出}e ls e{o u tp(0x82,0x00);//设置PA E为0,将端口A配置为输入}配置端口C1.如果端口C是输出端口,设置控制寄存器的位PC F为1。
2.如果端口C是输入端口,设置控制寄存器的位PC F为0。
参考以下示例代码进行端口C的配置:i f(o ut pu tP or tC){o u tp(0x82,0x04);//设置PC F为1,将端口C配置为输出}e ls e{o u tp(0x82,0x00);//设置PC F为0,将端口C配置为输入}步骤3:配置端口B针对端口B,需要进行以下设置:配置端口B工作模式设置控制寄存器的位P BF E为1,将端口B配置为全双工模式。
实验六---8255并行输入输出
实验六---8255并行输入输出一、实验目的1.了解并熟悉8255并行输入输出控制器的功能和工作原理;二、实验原理1.8255芯片介绍8255是一种常用的并行输入/输出接口芯片,可用于微处理机系统中的输入/输出控制输出,根据中文名可以看出,8255有三种工作方式即口A、口B和控制口。
8255所有的输入/输出都是双向的,它可以通过输入输出口的命令字来在不同的模式下工作。
在输出模式下,82555可以通过端口A、B控制外围设备的输出操作,在输入模式下,8255可以通过端口A、B实现对外围设备的输入操作。
控制口是用来控制8255写作模式或读作状态字,并对端口进行初始化操作。
8255在不同的模式下有不同的编程方法和操作方法,因此需要在实际应用中选择不同的工作模式。
8255有三个I/O端口A、B、C,每个端口都有8位。
这里解释一下控制端口的意义,地址为0B4H的控制端口是连续读或写8255内部状态寄存器的地址,而后面的一个读或写就表示读或写操作的类型,如果该端口被写入了“控制字”则8255按照控制字工作,否则会在该端口读出输入状态字。
在读或写操作的时候向控制端口写入的二进制数在图3-8中给出了。
表3-2:8255访问口定义地址口分类名称端口A0B0H输出Port A输入ControlCout端口Cin端口2.8255的编程方式方式0:即I/O挂接方式,这种方式下A、B、C三个端口为并行I/O口时,其与MCU的接线和编程方式与单片机内部I/O端口的连接和编程方式相同。
方式1:即输入输出口不一样。
在这种片内Ram中的地址空间0~7地址单元内写入相应的端口或方式的控制字后,该8255工作在相应的方式。
即:方式0:读出的是8位端口A的状态,写操作为将数据送到端口A;方式2:是把C口分配为两部分——高4位为输入,低4位为输出,它与方式1类似。
端口C的所有状态和很多控制功能都由C口寄存器存储。
方式2:“端口C字符型输入输出方式”,在这种方式下,端口C的8个位分成两部分,4个位作为输入的,4个位作为输出的。
MCP2515滤波配置
MCP2515的接收滤波功能相关的寄存器以及滤波逻辑滤波寄存器EXIDE: 0报文滤波仅用于标准帧1报文滤波仅用于扩展帧对扩展帧进行滤波的时候,EXIDE位必须设置为1,对标准帧滤波时设置为0屏蔽寄存器对标准帧滤波时,即对标准帧的11bit标识符按比特进行滤波;对扩展帧进行滤波的时候,即是对扩展帧的29位标识符按比特进行滤波。
当新报文符合验收滤波条件并被载入接收缓冲器时,使能报文接收的滤波器编号将被装载到RXBnCTRL寄存器FILHIT位中。
接收到的信息首先在RXB0中进行滤波匹配,不满足的话则到RXB1中进行滤波匹配。
只要满足一个滤波寄存器的条件,则接收该报文。
如果将RXB0CTRL寄存器的BUKT位置1,则将使能接收滚存功能(接收缓冲器0满之后可以将新接收到的数据滚存到缓存器1),打开接收滤波功能之后,如果缓冲器0已满,同时又收到一个符合缓冲器0滤波条件的报文,那么该报文将滚存到缓冲器1,不管是否满足缓冲器1的滤波条件。
2515位定时相关配置标称比特率(Nominal Bit Rate,NBR)定义为在不需要再同步的情况下,理想发送器每秒发送的位数,它可用下面的公式来表示:标称位时间(Nominal Bit Time,NBT)(tbit)由互不重叠的段时间段组成(图5-1)。
因此NBT 为下列时间段之和:组成位时间的每个段都由时间份额(TQ)组成。
每个时间份额的长度取决于振荡器周期(tOSC)。
通常TQ 为两个振荡器周期。
图5-2 显示了如何从TOSC 和TQ推导出位周期。
TQ 的长度等于一个TQ 时钟周期(tBRPCLK),利用称为波特率预分频器(BRP)的可编程预分频器对它进行编程设置。
以下公式对此进行了阐述:#include <reg52.h>#include <2510.h>#include <absacc.h>#include <intrins.h>#include <main.h>unsigned char board_addr=0x01;//接口板地址unsigned char controler_addr=100;//控制器地址unsigned char transmit_dat[13]={0x40,0x08,100,0x01,0x08,1,2,3,4,5,6,7,8};//can发送数据缓存unsigned char receive_dat[13]={0};//can接收数据缓存unsigned char cnt=0;unsigned char m_data=0;bit report_register_inf_flag=0;bit loop_register_over_flag=1;unsigned char code register_inf[255]={0x01,0x02,0xFF,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x56,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0xFF,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0xFF,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0xFF,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06};void main(){unsigned char register_inf_cnt=0;unsigned char loop_cnt=0;TMOD=0x11;//使用定时器T0,设为16位定时器(工作方式1),晶振11.0592M,中断时间T=(2^16-19456)×12/11.0592=50msTH0=0x4C;//设置定时器T0初值19456=4C00HTL0=0x00;PT0=1;//设置定时器T0中断为高优先级TR0=1;//定时0开始ET0=1;//允许定时器T0中断UP_DOWN = 0;//选中内部ram和8255地址空间Control_8255 = 0x90;//方式0,A口输入,B口输出,C口输出/*//使用定时器T1,设为16位定时器(工作方式1),晶振11.0592M,中断时间T=70msTH1=0x04;//设置定时器T1初值TL1=0x00;TR1=1;//定时1开始ET1=1;//允许定时器T1中断*/IT1=0;//设置INT1为电平触发EX1=1;//允许外部INT1中断(2510)mcp2515_init();init_filter(controler_addr,board_addr);//ENTER_LOOP_MODE();//进入回环模式//m_data=spi_read_register(CANCTRL);EA=1;//开总中断delay_1ms(200);//transmit_dat[0]=PRIORITY5| TI_SignalBoardRegister;//mcp2515_TX();while(1){if(report_register_inf_flag==1){if(loop_register_over_flag==1){transmit_dat[0]=PRIORITY5 | TI_RegisterInfReport;transmit_dat[1]=0x08;transmit_dat[2]=board_addr;transmit_dat[3]=controler_addr;transmit_dat[4]=0x07;transmit_dat[12]=0xFF;for(loop_cnt=1;loop_cnt<=4;loop_cnt++){transmit_dat[5]=loop_cnt;//回路编号for(register_inf_cnt=0;register_inf_cnt<51;register_inf_cnt++){transmit_dat[6]=register_inf_cnt*5+1;transmit_dat[7]=register_inf[register_inf_cnt*5];transmit_dat[8]=register_inf[register_inf_cnt*5+1];transmit_dat[9]=register_inf[register_inf_cnt*5+2];transmit_dat[10]=register_inf[register_inf_cnt*5+3];transmit_dat[11]=register_inf[register_inf_cnt*5+4];mcp2515_TX();}register_inf_cnt=0;}//上报登记结束命令transmit_dat[0]=PRIORITY5 | TI_RegisterOver;transmit_dat[1]=0x08;transmit_dat[2]=board_addr;transmit_dat[3]=controler_addr;transmit_dat[4]=0x00;mcp2515_TX();report_register_inf_flag=0;}}}}//======================================================================================= // T0定时器中断服务程序,喂看门狗//======================================================================================= void Timer0_Int() interrupt 1 using 0{static unsigned char count=0;TR0=0;//定时0停止ET0=0;//关闭定时器T0中断//设置定时初值19456+5=4C05H (弥补中断响应及重新赋值间的时间间隔+5)TH0=0x4C;TL0=0x05;UP_DOWN = 0;if(count%2==0){PC_8255 = 0x00;}else{PC_8255 = 0x10;}count++;TR0=1;//定时0开始ET0=1;//允许定时器T0中断}//==========================================================================// 功能:外部中断1,2510中断服务程序// 入口:无// 出口:无// 接收数据放在,receive_dat数组中//==========================================================================void int1_can_RX() interrupt 2 using 0{unsigned char int_data; //中断标志位寄存器的值unsigned char buffer_no; //接收到报文的缓冲区的编号unsigned char priority,ti;EX1=0;//关闭单片机外部中断1//读取2510中断标志位寄存器int_data=spi_read_register(CANINTF);if(int_data!=0xff){//报文错误中断if( (int_data&0x80)!=0 ){spi_bit_modify(CANINTF,0x80,0x00);}//接收中断if( (int_data&0x01)!=0 || (int_data&0x02)!=0 ){if( (int_data&0x01)!=0 )//RX0{buffer_no=0x00;}else if( (int_data&0x02)!=0 )//RX1{buffer_no=0x01;}spi_read_RX_buffer(receive_dat,buffer_no);//清除接收中断标志位spi_bit_modify(CANINTF,buffer_no+1,0x00);/*从此处开始进行数据处理*/priority=receive_dat[0]&0xE0;ti=receive_dat[0]&0x1F;if(priority==PRIORITY0){}else if(priority==PRIORITY1){}else if(priority==PRIORITY2){if(ti==TI_BroadcastRegister){//收到控制器广播的登记命令,接口板开始登记下面回路}}else if(priority==PRIORITY3){}else if(priority==PRIORITY4){}else if(priority==PRIORITY5){if(ti==TI_SignalBoardRegister){//收到控制器发送的“单接口板请求登记信息命令”,首先回复一个确认,然后待接口板下面回路登记完毕,开始上报登记信息transmit_dat[0]=PRIORITY4 | TI_Ack;transmit_dat[1]=0x08;transmit_dat[2]=board_addr;transmit_dat[3]=controler_addr;transmit_dat[4]=0x00;mcp2515_TX();report_register_inf_flag=1;}}}}EX1=1;//打开单片机外部中断1}#ifndef __MAIN_H__#define __MAIN_H__sbit UP_DOWN = P1^3;//===========================================// 宏定义//===========================================#define TRUE 1#define FALSE 0#define PA_8255 XBYTE[0xE000]#define PB_8255 XBYTE[0xE001]#define PC_8255 XBYTE[0xE002]#define Control_8255 XBYTE[0xE003]//协议中can数据帧优先级定义#define PRIORITY0 0x00#define PRIORITY1 0x20#define PRIORITY2 0x40#define PRIORITY3 0x60#define PRIORITY4 0x80#define PRIORITY5 0xA0//协议中TI类型码定义#define TI_BroadcastRegister 0x00#define TI_Ack 0x04#define TI_SignalBoardRegister 0x11#define TI_RegisterInfReport 0x12#define TI_RegisterOver 0x13#endif#include <reg52.h>#include <intrins.h>#include <2510.h>extern unsigned char transmit_dat[13];static unsigned char spi_read_byte(void);static void spi_write_byte( unsigned char out_byte);unsigned char code RTS[3]={SPI_CMD_RTS_TXB0,SPI_CMD_RTS_TXB1,SPI_CMD_RTS_TXB2};#define STRAT_TRANSMIT(x) \{ \sclk=0;scs=0; \spi_write_byte(RTS[x]); \scs=1;sclk=1; \}#define SPI_RESET_2515() \{ \sclk=0;scs=0; \spi_write_byte(SPI_CMD_RESET); \scs=1;sclk=1; \}/************************************************************************************************** * @fn spi_bit_modify** @brief spi command ,modify 2515's register by bit** @param addr - register's addressmask - bit maskdat - dat to modify** @return none**************************************************************************************************/ void spi_bit_modify(unsigned char addr, unsigned char mask, unsigned char dat){sclk=0;scs=0;spi_write_byte(SPI_CMD_BITCHANGE);spi_write_byte(addr);spi_write_byte(mask);spi_write_byte(dat);scs=1;sclk=1;}/************************************************************************************************** * @fn spi_get_2515_status** @brief spi command ,get 2515's "Read Status" or "RX Status"** @param cmd - 2515 spi instruction (SPI_CMD_READ_STATUS or SPI_CMD_RX_STATUS)** @return status register**************************************************************************************************/ unsigned char spi_get_2515_status(unsigned char cmd){unsigned char status;sclk=0;scs=0;spi_write_byte(cmd);status=spi_read_byte();scs=1;sclk=1;return status;}/************************************************************************************************** * @fn mcp2510_init** @brief init 2515,config some registers** @param none** @return none**************************************************************************************************/ void mcp2515_init(void){//2510硬件复位canrest=0;delay_1ms(10);canrest=1;delay_1ms(10);//软复位2510SPI_RESET_2515();SPI_RESET_2515();//配置引脚控制和状态寄存器spi_write_register(BFPCTRL,0x00); //RXnBF(禁止引脚功能)spi_write_register(TXRTSCTRL,0x07); //TXnRTS引脚控制和状态寄存器//配置位定时寄存器配置spi_write_register(CNF3,0x02);spi_write_register(CNF2,0xD0);spi_write_register(CNF1,0x04); //100k//spi_write_register(CNF1,0x31); //10k//配置中断相关的寄存器spi_write_register(CANINTE,0x83); //打开报文接收接收、报文错误中断spi_write_register(CANINTF,0x00);spi_write_register(EFLG,0x00);//配置发送缓冲器的控制寄存器spi_write_register(TXB0CTRL,0x03);spi_write_register(TXB1CTRL,0x00);spi_write_register(TXB1CTRL,0x00);//配置接收缓冲器的控制寄存器spi_write_register(RXB0CTRL,0x64);spi_write_register(RXB1CTRL,0x60);ENTER_NORMAL_MODE();}/************************************************************************************************** * @fn mcp2510_TX** @brief transmit the data in global array "transmit_dat[13]",if the 2515's transmit* buffer is full,then return** @param none** @return none**************************************************************************************************/ void mcp2515_TX(void){unsigned char TX_Buf_Number;//检测可用缓冲区if( ( spi_read_register(TXB0CTRL) & 0x08 )==0 )//使用发送缓冲器TX0{TX_Buf_Number=0;}else if( ( spi_read_register(TXB1CTRL) & 0x08 )==0 )//使用发送缓冲器TX1{TX_Buf_Number=1;}else if( ( spi_read_register(TXB2CTRL) & 0x08 )==0 )//使用发送缓冲器TX2{TX_Buf_Number=2;}else{return;//都不可用,返回}//装填数据spi_write_TX_buffer(transmit_dat, TX_Buf_Number);//启动发送STRAT_TRANSMIT(TX_Buf_Number);}unsigned char code mask_config[8]={0xC0,/* RXM0SIDH 对2bit滤波 */0x00,/* RXM0SIDL */0xFF,/* RXM0EID8 对8bit滤波 */0x00,/* RXM0EID0 */0x00,/* RXM1SIDH */0x00,/* RXM1SIDL */0xFF,/* RXM1EID8 对8bit滤波 */0xFF,/* RXM1EID0 对8bit滤波 */};void init_filter(unsigned char controlerAddr,unsigned char boardAddr){unsigned char filter_config[4];//进入配置模式ENTER_CONFIG_MODE();//配置验收滤波屏蔽寄存器spi_write_register_continue(mask_config, RXM0SIDH, 8);//配置BUFFER 0 的验收滤波寄存器filter_config[0]=0x40; //RXF0-1SIDHfilter_config[1]=0x08; //RXF0-1SIDL,报文滤波应用于扩展帧filter_config[2]=controlerAddr; //RXF0-1EID8,设置为控制器地址filter_config[3]=0x00; //RXF0-1EID0spi_write_register_continue(filter_config, RXF0SIDH, 4);spi_write_register_continue(filter_config, RXF1SIDH, 4);//配置BUFFER 1 的验收滤波寄存器filter_config[0]=0x00; //RXF2-5SIDHfilter_config[1]=0x08; //RXF2-5SIDL,报文滤波应用于扩展帧filter_config[2]=controlerAddr; //RXF2-5EID8,设置为控制器地址filter_config[3]=boardAddr; //RXF2-5EID0,设置为接口板地址spi_write_register_continue(filter_config, RXF2SIDH, 4);spi_write_register_continue(filter_config, RXF3SIDH, 4);spi_write_register_continue(filter_config, RXF4SIDH, 4);spi_write_register_continue(filter_config, RXF5SIDH, 4);//配置接收缓冲器的控制寄存器spi_write_register(RXB0CTRL,0x04);//使能buffer0的接收滤波功能spi_write_register(RXB1CTRL,0x00);//使能buffer1的接收滤波功能//进入正常模式ENTER_NORMAL_MODE();}/************************************************************************************************** * @fn spi_write_TX_buffer** @brief write TX buffer 0 or 1 or 2** @param buffer - data buffer* bufferNo - buffer number** @return none**************************************************************************************************/ unsigned char code TX_BUFFER_HEAD_ADDR[3]={TXB0SIDH,TXB1SIDH,TXB2SIDH};void spi_write_TX_buffer(unsigned char* buffer, unsigned char bufferNo){unsigned char i;sclk=0;scs=0;spi_write_byte(SPI_CMD_WRITE); //发送写指令spi_write_byte(TX_BUFFER_HEAD_ADDR[bufferNo]);//指定起始地址//写取帧头spi_write_byte(buffer[0]);spi_write_byte(buffer[1]);spi_write_byte(buffer[2]);spi_write_byte(buffer[3]);spi_write_byte(buffer[4]);//写帧数据域for(i=1;(i<=buffer[4])&&(i<=8);i++){spi_write_byte(buffer[4+i]);}scs=1;sclk=1;}/************************************************************************************************** * @fn spi_read_RX_buffer** @brief read RX buffer 0 or 1** @param buffer - data buffer* bufferNo - buffer number** @return the data of the register**************************************************************************************************/ unsigned char code RX_BUFFER_HEAD_ADDR[2]={RXB0SIDH,RXB1SIDH};void spi_read_RX_buffer(unsigned char* buffer, unsigned char bufferNo){unsigned char i;sclk=0;scs=0;spi_write_byte(SPI_CMD_READ); //发送读命令spi_write_byte(RX_BUFFER_HEAD_ADDR[bufferNo]);//指定起始地址//先读取帧头数据buffer[0]=spi_read_byte();buffer[1]=spi_read_byte();buffer[2]=spi_read_byte();buffer[3]=spi_read_byte();buffer[4]=spi_read_byte();//读取帧数据域for(i=1;(i<=buffer[4])&&(i<=8);i++){buffer[4+i]=spi_read_byte();}scs=1;sclk=1;}void spi_write_register(unsigned char addr,unsigned char dat){sclk=0;scs=0;spi_write_byte(SPI_CMD_WRITE); //发送写指令spi_write_byte(addr); //地址spi_write_byte(dat); //数据scs=1;sclk=1;}/************************************************************************************************** * @fn spi_write_register_continue** @brief write n bytes to 2515's register with continuous address** @param buffer - data buffer* addr - the start address* cnt - the number of the bytes to write** @return none**************************************************************************************************/ void spi_write_register_continue(unsigned char* buffer, unsigned char addr, unsigned char cnt){unsigned char i;sclk=0;scs=0;spi_write_byte(SPI_CMD_WRITE); //发送写命令spi_write_byte(addr); //指定地址for(i=0;i<cnt;i++){spi_write_byte(buffer[i]); //写数据}scs=1;sclk=1;}unsigned char spi_read_register(unsigned char addr){unsigned char read_dat;sclk=0;scs=0;_nop_ ();spi_write_byte(SPI_CMD_READ);//发送读命令spi_write_byte(addr);//指定地址read_dat=spi_read_byte();//读取数据_nop_ ();scs=1;sclk=1;return(read_dat);}/************************************************************************************************** * @fn spi_read_register_continue** @brief read n bytes from 2515's register with continuous address** @param buffer - data buffer* addr - the start address* cnt - the number of the bytes** @return none**************************************************************************************************/ void spi_read_register_continue(unsigned char* buffer, unsigned char addr, unsigned char cnt){unsigned char i;sclk=0;scs=0;spi_write_byte(SPI_CMD_READ); //发送读命令spi_write_byte(addr); //指定地址for(i=0;i<cnt;i++){buffer[i]=spi_read_byte(); //读取数据}scs=1;sclk=1;}/*************************************************************************************************** @fn spi_write_byte** @brief write one byte to 2515's register through SPI bus** @param data to write** @return none**************************************************************************************************/ static void spi_write_byte( unsigned char out_byte){unsigned char i;EA=0;for (i=0;i<8;i++){sclk=0;if (out_byte&0x80){sdi=1;}else{sdi=0;}sclk=1;out_byte=out_byte<<1;//_nop_ ();}EA=1;}/************************************************************************************************** * @fn spi_read_byte** @brief read one byte from 2515's register through SPI bus** @param none** @return data read**************************************************************************************************/ static unsigned char spi_read_byte(void){unsigned char i,in_byte=0;EA=0;for (i=0;i<8;i++){sclk=1;//_nop_ ();//_nop_ ();sclk=0;in_byte=in_byte<<1;if (sdo){in_byte=in_byte|0x01;}}EA=1;return (in_byte);}void delay_1ms(unsigned char time){unsigned char i=0,j=0;for(i=0;i<time;i++){for(j=0;j<91;j++){;}}}#ifndef __2510_H__#define __2510_H__//---------------------------------------// CAN 2510端口定义//发送和接收各种CAN数据时一定要"关中断"//---------------------------------------sbit scs = P1^4;sbit sdi = P1^5;sbit sdo = P1^6;sbit sclk = P1^7;sbit canrest = P3^5;//sbit int1 = P3^3;//can总线中断引脚(外部中断1)//---------------------------------------// MCP2510相关函数声明//---------------------------------------//2515初始化void mcp2515_init(void);//2515滤波器配置void init_filter(unsigned char controlerAddr,unsigned char boardAddr);//通过2515发送一帧can数据void mcp2515_TX(void);//获取2515的“读状态”或“RX状态”unsigned char spi_get_2515_status(unsigned char cmd);//通过2515的spi比特位修改指令,修改寄存器的某1bitvoid spi_bit_modify(unsigned char addr, unsigned char mask, unsigned char dat);//写2515的一个指定的寄存器void spi_write_register(unsigned char addr,unsigned char dat);//连续写2515地址连续的寄存器void spi_write_register_continue(unsigned char* buffer, unsigned char addr, unsigned char cnt); //读2515一个指定的寄存器unsigned char spi_read_register(unsigned char addr);//连续读2515地址连续的寄存器void spi_read_register_continue(unsigned char* buffer, unsigned char addr, unsigned char cnt); //读2515的接收缓冲区void spi_read_RX_buffer(unsigned char* buffer, unsigned char bufferNo);//写2515的发送缓冲区void spi_write_TX_buffer(unsigned char* buffer, unsigned char bufferNo);//延时1ms程序void delay_1ms(unsigned char time);//---------------------------------------// 设定2515的工作模式//---------------------------------------#define ENTER_NORMAL_MODE() (spi_bit_modify(CANCTRL, 0xe0, 0x00))#define ENTER_SLEEP_MODE() (spi_bit_modify(CANCTRL, 0xe0, 0x20))#define ENTER_LOOP_MODE() (spi_bit_modify(CANCTRL, 0xe0, 0x40))#define ENTER_LISTEN_MODE() (spi_bit_modify(CANCTRL, 0xe0, 0x60))#define ENTER_CONFIG_MODE() (spi_bit_modify(CANCTRL, 0xe0, 0x80))//---------------------------------------// 定义2515的SPI接口相关命令//---------------------------------------#define SPI_CMD_READ (0x03)#define SPI_CMD_WRITE (0x02)#define SPI_CMD_BITCHANGE (0X05)#define SPI_CMD_READ_STATUS (0XA0)#define SPI_CMD_RX_STATUS (0XB0)#define SPI_CMD_RESET (0xC0)#define SPI_CMD_RTS_TXB0 (0x81)#define SPI_CMD_RTS_TXB1 (0x82)#define SPI_CMD_RTS_TXB2 (0x84)#define SPI_CMD_READ_RX_BUF0_START_AT_RXB0SIDH (0x90)#define SPI_CMD_READ_RX_BUF0_START_AT_RXB0D0 (0x91)#define SPI_CMD_READ_RX_BUF1_START_AT_RXB1SIDH (0x92)#define SPI_CMD_READ_RX_BUF1_START_AT_RXB1D0 (0x93)#define SPI_CMD_LOAD_TX_BUF0_START_AT_TXB0SIDH (0x40)#define SPI_CMD_LOAD_TX_BUF0_START_AT_TXB0D0 (0x41)#define SPI_CMD_LOAD_TX_BUF1_START_AT_TXB1SIDH (0x42)#define SPI_CMD_LOAD_TX_BUF1_START_AT_TXB1D0 (0x43)#define SPI_CMD_LOAD_TX_BUF2_START_AT_TXB2SIDH (0x44)#define SPI_CMD_LOAD_TX_BUF2_START_AT_TXB2D0 (0x45)//---------------------------------------// 定义MCP2515的寄存器地址//---------------------------------------// x000 xxxx#define RXF0SIDH (0x00)#define RXF0SIDL (0x01)#define RXF0EID8 (0x02)#define RXF0EID0 (0x03)#define RXF1SIDH (0x04)#define RXF1SIDL (0x05)#define RXF1EID8 (0x06)#define RXF1EID0 (0x07)#define RXF2SIDH (0x08)#define RXF2SIDL (0x09)#define RXF2EID8 (0x0a)#define RXF2EID0 (0x0b)#define BFPCTRL (0x0c)#define TXRTSCTRL (0x0d)#define CANSTAT (0x0e)#define CANCTRL (0x0f)// x001 xxxx#define RXF3SIDH (0x10)#define RXF3SIDL (0x11)#define RXF3EID8 (0x12)#define RXF3EID0 (0x13)#define RXF4SIDH (0x14)#define RXF4SIDL (0x15)#define RXF4EID8 (0x16)#define RXF4EID0 (0x17)#define RXF5SIDH (0x18)#define RXF5SIDL (0x19)#define RXF5EID8 (0x1a)#define RXF5EID0 (0x1b)#define TEC (0x1c)#define REC (0x1d)#define CANSTAT_x001 (0x1e) // refer to the same register CANSTAT #define CANCTRL_x001 (0x1f) // refer to the same register CANCTRL // x010 xxxx#define RXM0SIDH (0x20)#define RXM0SIDL (0x21)#define RXM0EID8 (0x22)#define RXM0EID0 (0x23)#define RXM1SIDH (0x24)#define RXM1SIDL (0x25)#define RXM1EID8 (0x26)#define RXM1EID0 (0x27)#define CNF3 (0x28)#define CNF2 (0x29)#define CNF1 (0x2a)#define CANINTE (0x2b)#define CANINTF (0x2c)#define EFLG (0x2d)#define CANSTAT_x010 (0x2e)#define CANCTRL_x010 (0x2f)// x011 xxxx#define TXB0CTRL (0x30)#define TXB0SIDH (0x31)#define TXB0SIDL (0x32)#define TXB0EID8 (0x33)#define TXB0EID0 (0x34)#define TXB0DLC (0x35)#define TXB0D0 (0x36)#define TXB0D1 (0x37)#define TXB0D2 (0x38)#define TXB0D3 (0x39)#define TXB0D4 (0x3a)#define TXB0D5 (0x3b)#define TXB0D6 (0x3c)#define TXB0D7 (0x3d)#define CANSTAT_x011 (0x3e) #define CANCTRL_x011 (0x3f) // x100 xxxx#define TXB1CTRL (0x40)#define TXB1SIDH (0x41)#define TXB1SIDL (0x42)#define TXB1EID8 (0x43)#define TXB1EID0 (0x44)#define TXB1DLC (0x45)#define TXB1D0 (0x46)#define TXB1D1 (0x47)#define TXB1D2 (0x48)#define TXB1D3 (0x49)#define TXB1D4 (0x4a)#define TXB1D5 (0x4b)#define TXB1D6 (0x4c)#define TXB1D7 (0x4d)#define CANSTAT_x100 (0x4e) #define CANCTRL_x100 (0x4f) // x101 xxxx#define TXB2CTRL (0x50)#define TXB2SIDH (0x51)#define TXB2SIDL (0x52)#define TXB2EID8 (0x53)#define TXB2EID0 (0x54)#define TXB2DLC (0x55)#define TXB2D0 (0x56)#define TXB2D1 (0x57)#define TXB2D2 (0x58)#define TXB2D3 (0x59)#define TXB2D4 (0x5a)#define TXB2D5 (0x5b)#define TXB2D6 (0x5c)#define TXB2D7 (0x5d)#define CANSTAT_x101 (0x5e) #define CANCTRL_x101 (0x5f) // x110 xxxx#define RXB0CTRL (0x60)#define RXB0SIDH (0x61)#define RXB0SIDL (0x62)#define RXB0EID8 (0x63)#define RXB0EID0 (0x64)#define RXB0DLC (0x65)#define RXB0D0 (0x66)#define RXB0D1 (0x67)#define RXB0D2 (0x68)#define RXB0D3 (0x69)#define RXB0D4 (0x6a)#define RXB0D5 (0x6b)#define RXB0D6 (0x6c)#define RXB0D7 (0x6d)#define CANSTAT_x110 (0x6e) #define CANCTRL_x110 (0x6f) // x111 xxxx#define RXB1CTRL (0x70)#define RXB1SIDH (0x71)#define RXB1SIDL (0x72)#define RXB1EID8 (0x73)#define RXB1EID0 (0x74)#define RXB1DLC (0x75)#define RXB1D0 (0x76)#define RXB1D1 (0x77)#define RXB1D2 (0x78)#define RXB1D3 (0x79)#define RXB1D4 (0x7a)#define RXB1D5 (0x7b)#define RXB1D6 (0x7c)#define RXB1D7 (0x7d)#define CANSTAT_x111 (0x7e) #define CANCTRL_x111 (0x7f)#endif。
8255的内部结构及编程方法
8255的内部结构及编程方法
8255是一个并行I/O接口芯片,其内部结构主要包括数据端口和控制端口。
数据端口有A、B、C三个,每个端口有8位数据输入/输出。
控制端口则用于控制数据端口的读/写操作。
在编程时,首先需要通过控制端口写入控制字,以设置数据端口的读/写方
式以及数据传输的方向。
控制字的格式为:D7-D3=0000,D2-D0分别对
应A、B、C三个数据端口的控制位。
例如,当D2-D0=000时,表示A口为输入,B口和C口为输出;当D2-D0=001时,表示B口为输入/输出,
而A口和C口为输出;以此类推。
具体来说,8255的内部结构如下:
1. 数据端口A、B、C:每个端口都有8位数据输入/输出,并具有数据输入锁存器和输出锁存器/缓冲器。
在实际应用中,这三个端口可作为独立输入
或输出端口使用。
2. 控制电路:分为A组和B组,用于控制各自对应的数据端口的工作方式
和读/写操作。
控制电路接收来自读/写控制逻辑电路的读/写命令,并根据
接收到的命令输出相应的控制信号。
3. 读/写控制逻辑电路:负责管理8255的数据传输过程。
它接收来自CPU 的地址和控制信号,通过内部控制逻辑向8255的各功能部件发出读/写控制命令。
4. 数据总线缓冲器:这是一个双向三态的8位数据缓冲器,用于连接8255与系统数据总线。
通过这个缓冲器,CPU可以实现与8255的数据传输。
以上内容仅供参考,如需获取更多关于8255的信息,建议咨询专业人士或查阅芯片手册。
8255芯片初始化编程方法
8255芯片初始化编程方法
8255芯片是一种并行I/O接口芯片,由Intel公司生产。
它有三个8位I/O 端口,分别为端口A、端口B和端口C,以及一个控制字寄存器。
通过向控制字寄存器写入不同的控制字,可以配置8255芯片的工作模式,包括输入、输出、中断等。
初始化8255芯片的编程方法如下:
1. 确定工作模式:根据实际需要,确定8255芯片的工作模式。
8255芯片
有四种工作模式,分别为方式0、方式1、方式2和方式3。
2. 配置控制字:根据工作模式,计算控制字的值,并向8255芯片的控制字寄存器写入控制字。
控制字的计算方法可以参考8255芯片的数据手册。
3. 配置端口:根据实际需要,向端口A、端口B和端口C写入相应的数据。
需要注意的是,向端口写入数据时需要将相应的控制位设置为1,否则数据无法写入。
4. 中断配置:如果需要使用8255芯片的中断功能,需要根据实际情况配置中断向量和中断触发方式等参数。
需要注意的是,具体的编程方法可能会因为不同的开发环境和编程语言而有所不同。
因此,在实际编程时,需要参考具体的开发环境和编程语言的相关文档。
8255的编程方法
8255的编程方法
8255是一种可编程的并行I/O接口芯片,通常用于微机系统中的输入输出
接口扩展。
以下是8255的编程方法:
1. 初始化8255
在编程8255之前,需要先对其初始化,即设置其控制字。
控制字是通过对其三个控制端口的写操作来设置的。
通常将这三个控制端口写为0,然后分别写入三个控制字:
控制字1:设置8255的工作方式,包括输入输出方式、数据传输方向等。
控制字2:设置8255的输入输出地址,包括输入输出端口的地址。
控制字3:设置8255的中断控制方式。
2. 读/写8255端口数据
一旦初始化8255之后,就可以对其进行读/写操作了。
读/写操作是通过对
其三个数据端口进行读/写操作来实现的。
通常将这三个数据端口读/写为0,然后分别读/写三个数据端口的数据:
数据端口A:读/写8255的输入输出端口A的数据。
数据端口B:读/写8255的输入输出端口B的数据。
数据端口C:读/写8255的控制端口的输入输出数据。
3. 中断处理
如果设置了8255的中断控制方式,那么当8255发生中断时,微机系统会
向其发出中断请求信号,此时需要进行中断处理。
中断处理通常包括以下步骤:
识别中断源:根据中断请求信号判断是哪个端口发生了中断。
关闭中断:通过向相应的控制端口写入一个特定的值来关闭中断。
处理中断:根据中断源执行相应的处理程序,包括读取数据、修改数据等。
结束中断:完成处理程序后,再次向相应的控制端口写入一个特定的值来
结束中断。
8255 控制led灯亮灭编程题
8255 控制led灯亮灭编程题第一种:基于8255芯片控制LED灯的亮灭编程,需要以下步骤:首先需要将8255芯片的PA口接LED灯,通过控制PA口的输出状态来控制LED灯的亮灭。
2.设置8255芯片的控制字,以确定芯片的工作方式和工作模式。
3.使用汇编语言编写程序,控制8255芯片的PA口输出状态,从而实现LED 灯的亮灭控制。
以下是一份基于8255芯片控制LED灯亮灭的汇编程序示例:ORG 0HDB 0B0H, 0B1H, 0B2H, 0B3H ; 控制字,确定8255芯片的工作方式和模式LED DB 0FFH ; 定义LED灯的状态,初始值为全灭LOOP:MOV AL, LED ; 将LED灯的状态存入AL寄存器OUT 0A0H, AL ; 将AL寄存器的值输出到8255芯片的PA口,控制LED灯的状态MOV AL, LED ; 将LED灯的状态存入AL寄存器ADD AL, 001 ; 将LED灯的状态翻转,实现亮灭变化SHL AL, 1 ; 将AL寄存器的值左移一位,更新LED灯的状态MOV LED, AL ; 将更新后的LED灯状态存入变量中JMP LOOP ; 重复以上操作,实现LED灯的持续亮灭控制在上述程序中,控制字被定义为0B0H、0B1H、0B2H和0B3H,分别对应8255芯片的四种工作方式和模式。
LED变量存储LED灯的状态,初始值为全灭。
在循环中,先将LED灯的状态输出到8255芯片的PA口,然后更新LED灯的状态并再次输出,实现LED灯的亮灭控制。
程序中的SHL指令是将AL寄存器的值左移一位,相当于将LED灯的状态翻转。
最后,程序通过JMP指令实现循环操作,让LED灯持续亮灭控制。
第二种:以下是使用8255芯片控制LED灯亮灭的编程题示例:假设LED灯连接在8255芯片的PA口,端口A的低4位控制LED的亮灭。
现在需要编写一个程序,让LED灯在PA口的低4位上以二进制方式从0000到1111逐位亮灭,每次亮灭的时间为1秒。
MCP2515滤波配置
MCP2515的接收滤波功能相关的寄存器以及滤波逻辑滤波寄存器EXIDE: 0报文滤波仅用于标准帧1报文滤波仅用于扩展帧对扩展帧进行滤波的时候,EXIDE位必须设置为1,对标准帧滤波时设置为0屏蔽寄存器对标准帧滤波时,即对标准帧的11bit标识符按比特进行滤波;对扩展帧进行滤波的时候,即是对扩展帧的29位标识符按比特进行滤波。
当新报文符合验收滤波条件并被载入接收缓冲器时,使能报文接收的滤波器编号将被装载到RXBnCTRL寄存器FILHIT位中。
接收到的信息首先在RXB0中进行滤波匹配,不满足的话则到RXB1中进行滤波匹配。
只要满足一个滤波寄存器的条件,则接收该报文。
如果将RXB0CTRL寄存器的BUKT位置1,则将使能接收滚存功能(接收缓冲器0满之后可以将新接收到的数据滚存到缓存器1),打开接收滤波功能之后,如果缓冲器0已满,同时又收到一个符合缓冲器0滤波条件的报文,那么该报文将滚存到缓冲器1,不管是否满足缓冲器1的滤波条件。
2515位定时相关配置标称比特率(Nominal Bit Rate,NBR)定义为在不需要再同步的情况下,理想发送器每秒发送的位数,它可用下面的公式来表示:标称位时间(Nominal Bit Time,NBT)(tbit)由互不重叠的段时间段组成(图5-1)。
因此NBT 为下列时间段之和:组成位时间的每个段都由时间份额(TQ)组成。
每个时间份额的长度取决于振荡器周期(tOSC)。
通常TQ 为两个振荡器周期。
图5-2 显示了如何从TOSC 和TQ推导出位周期。
TQ 的长度等于一个TQ 时钟周期(tBRPCLK),利用称为波特率预分频器(BRP)的可编程预分频器对它进行编程设置。
以下公式对此进行了阐述:#include <reg52.h>#include <2510.h>#include <absacc.h>#include <intrins.h>#include <main.h>unsigned char board_addr=0x01;//接口板地址unsigned char controler_addr=100;//控制器地址unsigned char transmit_dat[13]={0x40,0x08,100,0x01,0x08,1,2,3,4,5,6,7,8};//can发送数据缓存unsigned char receive_dat[13]={0};//can接收数据缓存unsigned char cnt=0;unsigned char m_data=0;bit report_register_inf_flag=0;bit loop_register_over_flag=1;unsigned char code register_inf[255]={0x01,0x02,0xFF,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x56,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0xFF,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0xFF,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0xFF,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06, 0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06,0x01,0x02,0x03,0x05,0x06};void main(){unsigned char register_inf_cnt=0;unsigned char loop_cnt=0;TMOD=0x11;//使用定时器T0,设为16位定时器(工作方式1),晶振11.0592M,中断时间T=(2^16-19456)×12/11.0592=50msTH0=0x4C;//设置定时器T0初值19456=4C00HTL0=0x00;PT0=1;//设置定时器T0中断为高优先级TR0=1;//定时0开始ET0=1;//允许定时器T0中断UP_DOWN = 0;//选中内部ram和8255地址空间Control_8255 = 0x90;//方式0,A口输入,B口输出,C口输出/*//使用定时器T1,设为16位定时器(工作方式1),晶振11.0592M,中断时间T=70msTH1=0x04;//设置定时器T1初值TL1=0x00;TR1=1;//定时1开始ET1=1;//允许定时器T1中断*/IT1=0;//设置INT1为电平触发EX1=1;//允许外部INT1中断(2510)mcp2515_init();init_filter(controler_addr,board_addr);//ENTER_LOOP_MODE();//进入回环模式//m_data=spi_read_register(CANCTRL);EA=1;//开总中断delay_1ms(200);//transmit_dat[0]=PRIORITY5| TI_SignalBoardRegister;//mcp2515_TX();while(1){if(report_register_inf_flag==1){if(loop_register_over_flag==1){transmit_dat[0]=PRIORITY5 | TI_RegisterInfReport;transmit_dat[1]=0x08;transmit_dat[2]=board_addr;transmit_dat[3]=controler_addr;transmit_dat[4]=0x07;transmit_dat[12]=0xFF;for(loop_cnt=1;loop_cnt<=4;loop_cnt++){transmit_dat[5]=loop_cnt;//回路编号for(register_inf_cnt=0;register_inf_cnt<51;register_inf_cnt++){transmit_dat[6]=register_inf_cnt*5+1;transmit_dat[7]=register_inf[register_inf_cnt*5];transmit_dat[8]=register_inf[register_inf_cnt*5+1];transmit_dat[9]=register_inf[register_inf_cnt*5+2];transmit_dat[10]=register_inf[register_inf_cnt*5+3];transmit_dat[11]=register_inf[register_inf_cnt*5+4];mcp2515_TX();}register_inf_cnt=0;}//上报登记结束命令transmit_dat[0]=PRIORITY5 | TI_RegisterOver;transmit_dat[1]=0x08;transmit_dat[2]=board_addr;transmit_dat[3]=controler_addr;transmit_dat[4]=0x00;mcp2515_TX();report_register_inf_flag=0;}}}}//======================================================================================= // T0定时器中断服务程序,喂看门狗//======================================================================================= void Timer0_Int() interrupt 1 using 0{static unsigned char count=0;TR0=0;//定时0停止ET0=0;//关闭定时器T0中断//设置定时初值19456+5=4C05H (弥补中断响应及重新赋值间的时间间隔+5)TH0=0x4C;TL0=0x05;UP_DOWN = 0;if(count%2==0){PC_8255 = 0x00;}else{PC_8255 = 0x10;}count++;TR0=1;//定时0开始ET0=1;//允许定时器T0中断}//==========================================================================// 功能:外部中断1,2510中断服务程序// 入口:无// 出口:无// 接收数据放在,receive_dat数组中//==========================================================================void int1_can_RX() interrupt 2 using 0{unsigned char int_data; //中断标志位寄存器的值unsigned char buffer_no; //接收到报文的缓冲区的编号unsigned char priority,ti;EX1=0;//关闭单片机外部中断1//读取2510中断标志位寄存器int_data=spi_read_register(CANINTF);if(int_data!=0xff){//报文错误中断if( (int_data&0x80)!=0 ){spi_bit_modify(CANINTF,0x80,0x00);}//接收中断if( (int_data&0x01)!=0 || (int_data&0x02)!=0 ){if( (int_data&0x01)!=0 )//RX0{buffer_no=0x00;}else if( (int_data&0x02)!=0 )//RX1{buffer_no=0x01;}spi_read_RX_buffer(receive_dat,buffer_no);//清除接收中断标志位spi_bit_modify(CANINTF,buffer_no+1,0x00);/*从此处开始进行数据处理*/priority=receive_dat[0]&0xE0;ti=receive_dat[0]&0x1F;if(priority==PRIORITY0){}else if(priority==PRIORITY1){}else if(priority==PRIORITY2){if(ti==TI_BroadcastRegister){//收到控制器广播的登记命令,接口板开始登记下面回路}}else if(priority==PRIORITY3){}else if(priority==PRIORITY4){}else if(priority==PRIORITY5){if(ti==TI_SignalBoardRegister){//收到控制器发送的“单接口板请求登记信息命令”,首先回复一个确认,然后待接口板下面回路登记完毕,开始上报登记信息transmit_dat[0]=PRIORITY4 | TI_Ack;transmit_dat[1]=0x08;transmit_dat[2]=board_addr;transmit_dat[3]=controler_addr;transmit_dat[4]=0x00;mcp2515_TX();report_register_inf_flag=1;}}}}EX1=1;//打开单片机外部中断1}#ifndef __MAIN_H__#define __MAIN_H__sbit UP_DOWN = P1^3;//===========================================// 宏定义//===========================================#define TRUE 1#define FALSE 0#define PA_8255 XBYTE[0xE000]#define PB_8255 XBYTE[0xE001]#define PC_8255 XBYTE[0xE002]#define Control_8255 XBYTE[0xE003]//协议中can数据帧优先级定义#define PRIORITY0 0x00#define PRIORITY1 0x20#define PRIORITY2 0x40#define PRIORITY3 0x60#define PRIORITY4 0x80#define PRIORITY5 0xA0//协议中TI类型码定义#define TI_BroadcastRegister 0x00#define TI_Ack 0x04#define TI_SignalBoardRegister 0x11#define TI_RegisterInfReport 0x12#define TI_RegisterOver 0x13#endif#include <reg52.h>#include <intrins.h>#include <2510.h>extern unsigned char transmit_dat[13];static unsigned char spi_read_byte(void);static void spi_write_byte( unsigned char out_byte);unsigned char code RTS[3]={SPI_CMD_RTS_TXB0,SPI_CMD_RTS_TXB1,SPI_CMD_RTS_TXB2};#define STRAT_TRANSMIT(x) \{ \sclk=0;scs=0; \spi_write_byte(RTS[x]); \scs=1;sclk=1; \}#define SPI_RESET_2515() \{ \sclk=0;scs=0; \spi_write_byte(SPI_CMD_RESET); \scs=1;sclk=1; \}/************************************************************************************************** * @fn spi_bit_modify** @brief spi command ,modify 2515's register by bit** @param addr - register's addressmask - bit maskdat - dat to modify** @return none**************************************************************************************************/ void spi_bit_modify(unsigned char addr, unsigned char mask, unsigned char dat){sclk=0;scs=0;spi_write_byte(SPI_CMD_BITCHANGE);spi_write_byte(addr);spi_write_byte(mask);spi_write_byte(dat);scs=1;sclk=1;}/************************************************************************************************** * @fn spi_get_2515_status** @brief spi command ,get 2515's "Read Status" or "RX Status"** @param cmd - 2515 spi instruction (SPI_CMD_READ_STATUS or SPI_CMD_RX_STATUS)** @return status register**************************************************************************************************/ unsigned char spi_get_2515_status(unsigned char cmd){unsigned char status;sclk=0;scs=0;spi_write_byte(cmd);status=spi_read_byte();scs=1;sclk=1;return status;}/************************************************************************************************** * @fn mcp2510_init** @brief init 2515,config some registers** @param none** @return none**************************************************************************************************/ void mcp2515_init(void){//2510硬件复位canrest=0;delay_1ms(10);canrest=1;delay_1ms(10);//软复位2510SPI_RESET_2515();SPI_RESET_2515();//配置引脚控制和状态寄存器spi_write_register(BFPCTRL,0x00); //RXnBF(禁止引脚功能)spi_write_register(TXRTSCTRL,0x07); //TXnRTS引脚控制和状态寄存器//配置位定时寄存器配置spi_write_register(CNF3,0x02);spi_write_register(CNF2,0xD0);spi_write_register(CNF1,0x04); //100k//spi_write_register(CNF1,0x31); //10k//配置中断相关的寄存器spi_write_register(CANINTE,0x83); //打开报文接收接收、报文错误中断spi_write_register(CANINTF,0x00);spi_write_register(EFLG,0x00);//配置发送缓冲器的控制寄存器spi_write_register(TXB0CTRL,0x03);spi_write_register(TXB1CTRL,0x00);spi_write_register(TXB1CTRL,0x00);//配置接收缓冲器的控制寄存器spi_write_register(RXB0CTRL,0x64);spi_write_register(RXB1CTRL,0x60);ENTER_NORMAL_MODE();}/************************************************************************************************** * @fn mcp2510_TX** @brief transmit the data in global array "transmit_dat[13]",if the 2515's transmit* buffer is full,then return** @param none** @return none**************************************************************************************************/ void mcp2515_TX(void){unsigned char TX_Buf_Number;//检测可用缓冲区if( ( spi_read_register(TXB0CTRL) & 0x08 )==0 )//使用发送缓冲器TX0{TX_Buf_Number=0;}else if( ( spi_read_register(TXB1CTRL) & 0x08 )==0 )//使用发送缓冲器TX1{TX_Buf_Number=1;}else if( ( spi_read_register(TXB2CTRL) & 0x08 )==0 )//使用发送缓冲器TX2{TX_Buf_Number=2;}else{return;//都不可用,返回}//装填数据spi_write_TX_buffer(transmit_dat, TX_Buf_Number);//启动发送STRAT_TRANSMIT(TX_Buf_Number);}unsigned char code mask_config[8]={0xC0,/* RXM0SIDH 对2bit滤波 */0x00,/* RXM0SIDL */0xFF,/* RXM0EID8 对8bit滤波 */0x00,/* RXM0EID0 */0x00,/* RXM1SIDH */0x00,/* RXM1SIDL */0xFF,/* RXM1EID8 对8bit滤波 */0xFF,/* RXM1EID0 对8bit滤波 */};void init_filter(unsigned char controlerAddr,unsigned char boardAddr){unsigned char filter_config[4];//进入配置模式ENTER_CONFIG_MODE();//配置验收滤波屏蔽寄存器spi_write_register_continue(mask_config, RXM0SIDH, 8);//配置BUFFER 0 的验收滤波寄存器filter_config[0]=0x40; //RXF0-1SIDHfilter_config[1]=0x08; //RXF0-1SIDL,报文滤波应用于扩展帧filter_config[2]=controlerAddr; //RXF0-1EID8,设置为控制器地址filter_config[3]=0x00; //RXF0-1EID0spi_write_register_continue(filter_config, RXF0SIDH, 4);spi_write_register_continue(filter_config, RXF1SIDH, 4);//配置BUFFER 1 的验收滤波寄存器filter_config[0]=0x00; //RXF2-5SIDHfilter_config[1]=0x08; //RXF2-5SIDL,报文滤波应用于扩展帧filter_config[2]=controlerAddr; //RXF2-5EID8,设置为控制器地址filter_config[3]=boardAddr; //RXF2-5EID0,设置为接口板地址spi_write_register_continue(filter_config, RXF2SIDH, 4);spi_write_register_continue(filter_config, RXF3SIDH, 4);spi_write_register_continue(filter_config, RXF4SIDH, 4);spi_write_register_continue(filter_config, RXF5SIDH, 4);//配置接收缓冲器的控制寄存器spi_write_register(RXB0CTRL,0x04);//使能buffer0的接收滤波功能spi_write_register(RXB1CTRL,0x00);//使能buffer1的接收滤波功能//进入正常模式ENTER_NORMAL_MODE();}/************************************************************************************************** * @fn spi_write_TX_buffer** @brief write TX buffer 0 or 1 or 2** @param buffer - data buffer* bufferNo - buffer number** @return none**************************************************************************************************/ unsigned char code TX_BUFFER_HEAD_ADDR[3]={TXB0SIDH,TXB1SIDH,TXB2SIDH};void spi_write_TX_buffer(unsigned char* buffer, unsigned char bufferNo){unsigned char i;sclk=0;scs=0;spi_write_byte(SPI_CMD_WRITE); //发送写指令spi_write_byte(TX_BUFFER_HEAD_ADDR[bufferNo]);//指定起始地址//写取帧头spi_write_byte(buffer[0]);spi_write_byte(buffer[1]);spi_write_byte(buffer[2]);spi_write_byte(buffer[3]);spi_write_byte(buffer[4]);//写帧数据域for(i=1;(i<=buffer[4])&&(i<=8);i++){spi_write_byte(buffer[4+i]);}scs=1;sclk=1;}/************************************************************************************************** * @fn spi_read_RX_buffer** @brief read RX buffer 0 or 1** @param buffer - data buffer* bufferNo - buffer number** @return the data of the register**************************************************************************************************/ unsigned char code RX_BUFFER_HEAD_ADDR[2]={RXB0SIDH,RXB1SIDH};void spi_read_RX_buffer(unsigned char* buffer, unsigned char bufferNo){unsigned char i;sclk=0;scs=0;spi_write_byte(SPI_CMD_READ); //发送读命令spi_write_byte(RX_BUFFER_HEAD_ADDR[bufferNo]);//指定起始地址//先读取帧头数据buffer[0]=spi_read_byte();buffer[1]=spi_read_byte();buffer[2]=spi_read_byte();buffer[3]=spi_read_byte();buffer[4]=spi_read_byte();//读取帧数据域for(i=1;(i<=buffer[4])&&(i<=8);i++){buffer[4+i]=spi_read_byte();}scs=1;sclk=1;}void spi_write_register(unsigned char addr,unsigned char dat){sclk=0;scs=0;spi_write_byte(SPI_CMD_WRITE); //发送写指令spi_write_byte(addr); //地址spi_write_byte(dat); //数据scs=1;sclk=1;}/************************************************************************************************** * @fn spi_write_register_continue** @brief write n bytes to 2515's register with continuous address** @param buffer - data buffer* addr - the start address* cnt - the number of the bytes to write** @return none**************************************************************************************************/ void spi_write_register_continue(unsigned char* buffer, unsigned char addr, unsigned char cnt){unsigned char i;sclk=0;scs=0;spi_write_byte(SPI_CMD_WRITE); //发送写命令spi_write_byte(addr); //指定地址for(i=0;i<cnt;i++){spi_write_byte(buffer[i]); //写数据}scs=1;sclk=1;}unsigned char spi_read_register(unsigned char addr){unsigned char read_dat;sclk=0;scs=0;_nop_ ();spi_write_byte(SPI_CMD_READ);//发送读命令spi_write_byte(addr);//指定地址read_dat=spi_read_byte();//读取数据_nop_ ();scs=1;sclk=1;return(read_dat);}/************************************************************************************************** * @fn spi_read_register_continue** @brief read n bytes from 2515's register with continuous address** @param buffer - data buffer* addr - the start address* cnt - the number of the bytes** @return none**************************************************************************************************/ void spi_read_register_continue(unsigned char* buffer, unsigned char addr, unsigned char cnt){unsigned char i;sclk=0;scs=0;spi_write_byte(SPI_CMD_READ); //发送读命令spi_write_byte(addr); //指定地址for(i=0;i<cnt;i++){buffer[i]=spi_read_byte(); //读取数据}scs=1;sclk=1;}/*************************************************************************************************** @fn spi_write_byte** @brief write one byte to 2515's register through SPI bus** @param data to write** @return none**************************************************************************************************/ static void spi_write_byte( unsigned char out_byte){unsigned char i;EA=0;for (i=0;i<8;i++){sclk=0;if (out_byte&0x80){sdi=1;}else{sdi=0;}sclk=1;out_byte=out_byte<<1;//_nop_ ();}EA=1;}/************************************************************************************************** * @fn spi_read_byte** @brief read one byte from 2515's register through SPI bus** @param none** @return data read**************************************************************************************************/ static unsigned char spi_read_byte(void){unsigned char i,in_byte=0;EA=0;for (i=0;i<8;i++){sclk=1;//_nop_ ();//_nop_ ();sclk=0;in_byte=in_byte<<1;if (sdo){in_byte=in_byte|0x01;}}EA=1;return (in_byte);}void delay_1ms(unsigned char time){unsigned char i=0,j=0;for(i=0;i<time;i++){for(j=0;j<91;j++){;}}}#ifndef __2510_H__#define __2510_H__//---------------------------------------// CAN 2510端口定义//发送和接收各种CAN数据时一定要"关中断"//---------------------------------------sbit scs = P1^4;sbit sdi = P1^5;sbit sdo = P1^6;sbit sclk = P1^7;sbit canrest = P3^5;//sbit int1 = P3^3;//can总线中断引脚(外部中断1)//---------------------------------------// MCP2510相关函数声明//---------------------------------------//2515初始化void mcp2515_init(void);//2515滤波器配置void init_filter(unsigned char controlerAddr,unsigned char boardAddr);//通过2515发送一帧can数据void mcp2515_TX(void);//获取2515的“读状态”或“RX状态”unsigned char spi_get_2515_status(unsigned char cmd);//通过2515的spi比特位修改指令,修改寄存器的某1bitvoid spi_bit_modify(unsigned char addr, unsigned char mask, unsigned char dat);//写2515的一个指定的寄存器void spi_write_register(unsigned char addr,unsigned char dat);//连续写2515地址连续的寄存器void spi_write_register_continue(unsigned char* buffer, unsigned char addr, unsigned char cnt); //读2515一个指定的寄存器unsigned char spi_read_register(unsigned char addr);//连续读2515地址连续的寄存器void spi_read_register_continue(unsigned char* buffer, unsigned char addr, unsigned char cnt); //读2515的接收缓冲区void spi_read_RX_buffer(unsigned char* buffer, unsigned char bufferNo);//写2515的发送缓冲区void spi_write_TX_buffer(unsigned char* buffer, unsigned char bufferNo);//延时1ms程序void delay_1ms(unsigned char time);//---------------------------------------// 设定2515的工作模式//---------------------------------------#define ENTER_NORMAL_MODE() (spi_bit_modify(CANCTRL, 0xe0, 0x00))#define ENTER_SLEEP_MODE() (spi_bit_modify(CANCTRL, 0xe0, 0x20))#define ENTER_LOOP_MODE() (spi_bit_modify(CANCTRL, 0xe0, 0x40))#define ENTER_LISTEN_MODE() (spi_bit_modify(CANCTRL, 0xe0, 0x60))#define ENTER_CONFIG_MODE() (spi_bit_modify(CANCTRL, 0xe0, 0x80))//---------------------------------------// 定义2515的SPI接口相关命令//---------------------------------------#define SPI_CMD_READ (0x03)#define SPI_CMD_WRITE (0x02)#define SPI_CMD_BITCHANGE (0X05)#define SPI_CMD_READ_STATUS (0XA0)#define SPI_CMD_RX_STATUS (0XB0)#define SPI_CMD_RESET (0xC0)#define SPI_CMD_RTS_TXB0 (0x81)#define SPI_CMD_RTS_TXB1 (0x82)#define SPI_CMD_RTS_TXB2 (0x84)#define SPI_CMD_READ_RX_BUF0_START_AT_RXB0SIDH (0x90)#define SPI_CMD_READ_RX_BUF0_START_AT_RXB0D0 (0x91)#define SPI_CMD_READ_RX_BUF1_START_AT_RXB1SIDH (0x92)#define SPI_CMD_READ_RX_BUF1_START_AT_RXB1D0 (0x93)#define SPI_CMD_LOAD_TX_BUF0_START_AT_TXB0SIDH (0x40)#define SPI_CMD_LOAD_TX_BUF0_START_AT_TXB0D0 (0x41)#define SPI_CMD_LOAD_TX_BUF1_START_AT_TXB1SIDH (0x42)#define SPI_CMD_LOAD_TX_BUF1_START_AT_TXB1D0 (0x43)#define SPI_CMD_LOAD_TX_BUF2_START_AT_TXB2SIDH (0x44)#define SPI_CMD_LOAD_TX_BUF2_START_AT_TXB2D0 (0x45)//---------------------------------------// 定义MCP2515的寄存器地址//---------------------------------------// x000 xxxx#define RXF0SIDH (0x00)#define RXF0SIDL (0x01)#define RXF0EID8 (0x02)#define RXF0EID0 (0x03)#define RXF1SIDH (0x04)#define RXF1SIDL (0x05)#define RXF1EID8 (0x06)#define RXF1EID0 (0x07)#define RXF2SIDH (0x08)#define RXF2SIDL (0x09)#define RXF2EID8 (0x0a)#define RXF2EID0 (0x0b)#define BFPCTRL (0x0c)#define TXRTSCTRL (0x0d)#define CANSTAT (0x0e)#define CANCTRL (0x0f)// x001 xxxx#define RXF3SIDH (0x10)#define RXF3SIDL (0x11)#define RXF3EID8 (0x12)#define RXF3EID0 (0x13)#define RXF4SIDH (0x14)#define RXF4SIDL (0x15)#define RXF4EID8 (0x16)#define RXF4EID0 (0x17)#define RXF5SIDH (0x18)#define RXF5SIDL (0x19)#define RXF5EID8 (0x1a)#define RXF5EID0 (0x1b)#define TEC (0x1c)#define REC (0x1d)#define CANSTAT_x001 (0x1e) // refer to the same register CANSTAT #define CANCTRL_x001 (0x1f) // refer to the same register CANCTRL // x010 xxxx#define RXM0SIDH (0x20)#define RXM0SIDL (0x21)#define RXM0EID8 (0x22)#define RXM0EID0 (0x23)#define RXM1SIDH (0x24)#define RXM1SIDL (0x25)#define RXM1EID8 (0x26)#define RXM1EID0 (0x27)#define CNF3 (0x28)#define CNF2 (0x29)#define CNF1 (0x2a)#define CANINTE (0x2b)#define CANINTF (0x2c)#define EFLG (0x2d)#define CANSTAT_x010 (0x2e)#define CANCTRL_x010 (0x2f)// x011 xxxx#define TXB0CTRL (0x30)#define TXB0SIDH (0x31)#define TXB0SIDL (0x32)#define TXB0EID8 (0x33)#define TXB0EID0 (0x34)#define TXB0DLC (0x35)#define TXB0D0 (0x36)#define TXB0D1 (0x37)#define TXB0D2 (0x38)#define TXB0D3 (0x39)#define TXB0D4 (0x3a)#define TXB0D5 (0x3b)#define TXB0D6 (0x3c)#define TXB0D7 (0x3d)#define CANSTAT_x011 (0x3e) #define CANCTRL_x011 (0x3f) // x100 xxxx#define TXB1CTRL (0x40)#define TXB1SIDH (0x41)#define TXB1SIDL (0x42)#define TXB1EID8 (0x43)#define TXB1EID0 (0x44)#define TXB1DLC (0x45)#define TXB1D0 (0x46)#define TXB1D1 (0x47)#define TXB1D2 (0x48)#define TXB1D3 (0x49)#define TXB1D4 (0x4a)#define TXB1D5 (0x4b)#define TXB1D6 (0x4c)#define TXB1D7 (0x4d)#define CANSTAT_x100 (0x4e) #define CANCTRL_x100 (0x4f) // x101 xxxx#define TXB2CTRL (0x50)#define TXB2SIDH (0x51)#define TXB2SIDL (0x52)#define TXB2EID8 (0x53)#define TXB2EID0 (0x54)#define TXB2DLC (0x55)#define TXB2D0 (0x56)#define TXB2D1 (0x57)#define TXB2D2 (0x58)#define TXB2D3 (0x59)#define TXB2D4 (0x5a)#define TXB2D5 (0x5b)#define TXB2D6 (0x5c)#define TXB2D7 (0x5d)#define CANSTAT_x101 (0x5e) #define CANCTRL_x101 (0x5f) // x110 xxxx#define RXB0CTRL (0x60)#define RXB0SIDH (0x61)#define RXB0SIDL (0x62)#define RXB0EID8 (0x63)#define RXB0EID0 (0x64)#define RXB0DLC (0x65)#define RXB0D0 (0x66)#define RXB0D1 (0x67)#define RXB0D2 (0x68)#define RXB0D3 (0x69)#define RXB0D4 (0x6a)#define RXB0D5 (0x6b)#define RXB0D6 (0x6c)#define RXB0D7 (0x6d)#define CANSTAT_x110 (0x6e) #define CANCTRL_x110 (0x6f) // x111 xxxx#define RXB1CTRL (0x70)#define RXB1SIDH (0x71)#define RXB1SIDL (0x72)#define RXB1EID8 (0x73)#define RXB1EID0 (0x74)#define RXB1DLC (0x75)#define RXB1D0 (0x76)#define RXB1D1 (0x77)#define RXB1D2 (0x78)#define RXB1D3 (0x79)#define RXB1D4 (0x7a)#define RXB1D5 (0x7b)#define RXB1D6 (0x7c)#define RXB1D7 (0x7d)#define CANSTAT_x111 (0x7e) #define CANCTRL_x111 (0x7f)#endif。
8255设置
8255的方式设置(一)8255A的端口A可以在方式0、方式1、方式2这三种方式下工作,而端口B只能在方式0和方式1这两种方式下工作。
此外,我们也说明了端口的工作方式是由方式选择控制字决定的。
下面,介绍三种工作方式的具体含义。
(1)方式0的工作特点:方式0也叫基本输入/输出方式。
在这种方式下,端口A和端口B可以通过方式选择字规定为输入口或者输出口,端口C分为2个4位端口,高4位为一个端口,低4位为一个端口;这两个4位端口也可由方式选择字规定为输入口或输出口。
概括地说,方式O的基本特点如下:①任何一个端口可作为输入口,也可作为输出口,各端口之间没有规定必然的关系。
②各个端口的输入或输出,可以有16种不同的组合,所以可以适用于多种使用场合。
(2)方式0的使用场合有两种:一种是同步传送,另一种是查询式传送。
在同步传送时,发送方和接收方的动作由一个时序信号来管理,所以,双方互相知道对方的动作,不需要应答信号,也就是说,CPU不需要查询外设的状态。
这种情况下,对接口的要求很简单,只要能传送数据就行了。
因此,在同步传输下使用8255A时,3个数据端口可以实现三路数据传输。
查询式传输时,需要有应答信号。
但是,在方式0情况下,没有规定固定的应答信号,所以,这时,将端口A和端口B作为数据端口,把端口C的4个数位(高4位或者低4位均可)规定为输出口,用来输出一些控制信号,而把端口C的另外4个数位规定为输入口,用来读入外设的状态。
就是这样,利用端口C来配合端口A和端口B的输入/输出操作。
(1)方式1的工作特点:方式1也叫选通的输入/输出方式。
和方式O相比,最重要的差别是A端口和B端口用方式1进行输入/输出传输时,要利用端口C提供的选通信号和应答信号,而这些信号与端口C中的数位之间有着固定的对应关系,这种关系不是程序可以改变的,除非改变工作方式。
概括地讲,方式1有如下特点:①端口A和端口B可分别作为两个数据口工作在方式1,并且,任何一个端口可作为输入口或者输出口。
8255实验报告
8255实验报告8255实验报告引言8255是一种常用的并行接口芯片,广泛应用于各种数字系统中。
本实验旨在通过对8255的实际应用,加深对该芯片的理解和掌握。
实验目的1. 了解8255的基本原理和功能;2. 掌握8255的编程方法;3. 学会使用8255进行数字输入输出控制。
实验器材1. 一块开发板;2. 一台计算机;3. 一根USB数据线。
实验步骤1. 连接开发板和计算机,确保开发板正常供电;2. 打开计算机上的开发板驱动程序,并进行相应的设置;3. 编写相应的程序,通过编程控制8255实现数字输入输出。
实验结果与分析通过编程控制8255,我们可以实现数字输入输出的控制。
在实验中,我们可以通过设置8255的端口模式,将其分为输入和输出两个部分。
通过设置相应的控制字,可以实现对8255端口的读取或写入操作。
在实验中,我们可以通过编写程序,将开发板上的按键作为输入设备,通过8255将按键状态传递给计算机进行处理。
同时,我们还可以将计算机的输出信号通过8255传递给开发板上的LED灯进行显示。
通过实验,我们可以发现8255的优点在于其灵活性和可编程性。
通过简单的编程,我们可以实现各种数字输入输出的控制,从而满足不同应用的需求。
实验总结本次实验通过对8255的实际应用,加深了对该芯片的理解和掌握。
通过编程控制8255,我们可以实现数字输入输出的控制,为各种数字系统的开发提供了便利。
在今后的学习和应用中,我们应继续深入研究8255的原理和编程方法,不断拓展其应用领域。
同时,我们还应关注8255的性能和稳定性,以确保其在实际应用中的可靠性。
通过本次实验,我们不仅学到了知识,还培养了动手实践和解决问题的能力。
这对我们今后的学习和工作都具有重要意义。
致谢在本次实验中,我们得到了老师和同学们的大力支持和帮助,在此表示衷心的感谢。
参考文献[1] 《8255并行接口芯片应用与实验指导》[2] 《单片机原理与应用》附录:实验代码```C#include <reg52.h>sbit LED = P1^0; // 定义LED引脚void main(){while(1){LED = 0; // 点亮LEDdelay(1000); // 延时1秒LED = 1; // 熄灭LEDdelay(1000); // 延时1秒}}void delay(unsigned int t){unsigned int i, j;for(i = 0; i < t; i++)for(j = 0; j < 120; j++);}```以上是本次实验的实验报告,通过对8255的实际应用,我们加深了对该芯片的理解和掌握。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
8255的方式设置(一)8255A的端口A可以在方式0、方式1、方式2这三种方式下工作,而端口B只能在方式0和方式1这两种方式下工作。
此外,我们也说明了端口的工作方式是由方式选择控制字决定的。
下面,介绍三种工作方式的具体含义。
(1)方式0的工作特点:方式0也叫基本输入/输出方式。
在这种方式下,端口A和端口B可以通过方式选择字规定为输入口或者输出口,端口C分为2个4位端口,高4位为一个端口,低4位为一个端口;这两个4位端口也可由方式选择字规定为输入口或输出口。
概括地说,方式O的基本特点如下:①任何一个端口可作为输入口,也可作为输出口,各端口之间没有规定必然的关系。
②各个端口的输入或输出,可以有16种不同的组合,所以可以适用于多种使用场合。
(2)方式0的使用场合有两种:一种是同步传送,另一种是查询式传送。
在同步传送时,发送方和接收方的动作由一个时序信号来管理,所以,双方互相知道对方的动作,不需要应答信号,也就是说,CPU不需要查询外设的状态。
这种情况下,对接口的要求很简单,只要能传送数据就行了。
因此,在同步传输下使用8255A时,3个数据端口可以实现三路数据传输。
查询式传输时,需要有应答信号。
但是,在方式0情况下,没有规定固定的应答信号,所以,这时,将端口A和端口B作为数据端口,把端口C的4个数位(高4位或者低4位均可)规定为输出口,用来输出一些控制信号,而把端口C的另外4个数位规定为输入口,用来读入外设的状态。
就是这样,利用端口C来配合端口A和端口B的输入/输出操作。
(1)方式1的工作特点:方式1也叫选通的输入/输出方式。
和方式O相比,最重要的差别是A端口和B端口用方式1进行输入/输出传输时,要利用端口C提供的选通信号和应答信号,而这些信号与端口C中的数位之间有着固定的对应关系,这种关系不是程序可以改变的,除非改变工作方式。
概括地讲,方式1有如下特点:①端口A和端口B可分别作为两个数据口工作在方式1,并且,任何一个端口可作为输入口或者输出口。
②如果8255A 的端口A和端口B中只有一个端口工作于方式1,那么,端口C中就有3位被规定为配合方式1工作的信号,此时,另一个端口可以工作在方式o,端口C中的其他数位也可以工作在方式o,即作为输入或者输出. ③如果8255A的端口A和端口B都工作在方式1,那么,端口C中就有6位被规定为配合方式1工作的信号,剩下的2位,仍可作为输入或输出。
(2)方式1输入情况下有关信号的规定:当端口A工作在方式1并作为输入端口时,端口C的数位PC4作为选通信号输入端STBA,PC5作为输入缓冲区满信号输出端IBFA,PC3则作为中断请求信号输出端INTRA。
当端口B 工作在方式1并作为输入端口时,端口C的数位PC2作为选通信号输入端STBB,PC1作为输入缓冲区满信号输出端IBFB,PC0作为中断请求信号输出端INTRB。
这些数位和信号之间的对应关系是在对端口设定工作方式时自动确定的,不需要程序员干预;而且,一旦确定了某个端口工作于方式1,程序员也就无法改变端口C的数位与信号之间的对应关系,除非重新设置方式选择控制字。
当8255A的端口A和端口B都工作在方式1的输入情况时,端口C 的PC0~PC5共6个数位都被定义,只剩下PC6、PC7这2位还未用。
此时,方式选择控制字的D3位用来定义PC6和PC7的数据传输方向。
当D3为1时,PC6和PC7这2位作为输入来用;当D3为0时,PC6和PC7作为输出来用。
对于各控制信号,说明如下:①STB(Strobe):这是选通信号输入端,低电平有效。
它是由外设送往8255A的,当STB有效时,8255A接收外设送来的一个8位数据,从而8255A的输入缓冲器中得到一个新的数据. ②IBF(1nputBufferFull):这叫缓冲器满信号,高电平有效。
它是8255A输出的状态信号,当它有效时,表示当前已有一个新的数据在输入缓冲器中,此信号一般供CPU查询用,IBF信号是由STB信号使其置位的,而由读信号RD后沿即上升沿使其复位。
③INTR(InterruptRequest):它是8255A送往CPU的中断请求信号,高电平有效。
INTR端在STB、IBF均为高时被置为高电乎,也就是说,当选通信号结束、从而已将一个数据送进输入缓冲器中,并且输入缓冲器满信号已为高电平时,8255A会向CPU发出中断请求信号,即将INTR端置为高电平。
在CPU响应中断读取输入缓冲器中的数据时,由读信号丽的下降沿将INTR降为低电平。
④INTE(InterruptEnable):这叫中断允许信号,实际上,它就是控制中断允许或中断屏蔽的信号。
INTE没有外部引出端,它是由软件通过对C端口的置1指令或置0指令来实现对中断的控制的。
具体讲,对PC4置1,则使A端口处于中断允许状态;对PC4置0,则使A端口处于中断屏蔽状态。
与此类似,对PC2置1,则使B端口处于中断允许状态;对PC2置0,则使B端口处于中断屏蔽状态。
当然,如果要使用中断功能,应该用软件使相应的端口处于中断允许状态.(3)方式1输出情况下有关信号的规定当端口A工作在方式1并作为输出端口时,端口C 的数位PC7作为输出缓冲器满信号OBFA输出端,PC6作为外设接收数据后的响应信号ACKA 输入端,PC3则作为中断请求信号INTRA输出端。
当端口B工作在方式l并作为输出端口时,端口C的数位PC1作为输出缓冲器满信号OBFB输出端,PC2作为外设接收数据后的响应信号ACKB输入端,PC0则作为中断请求信号INTRB输出端。
和作为输入端口时的情况一样,端口A、端口B和这些信号之间的对应关系是在对8255A设定工作在方式1时自动确定的,不需要程序员干预。
当端口A和端口B都工作在方式l输出情况下时,端口C中共有6个数位被定义为控制信号端和状态信号端使用,仅剩下PC4、PC5这2位未用。
此时,方式选择字的D3位用来定义PC4、PC5的传输方向。
当D3为1时,PC4、PC5作为输入使用;当D3为0时,PC4、PC5作为输出使用。
图5.29是端口A和端口B工作在方式1情况下作为输出端口时应该设置的方式选择字和各控制信号和状态信号的示意图。
对于方式1时输出端口对应的控制信号和状态信号,我们作如下说明:①OBF(Output Buffer Full):这是输出缓冲器满信号,低电平有效。
OBF由8255A送给外设,当OBF有效时,表示CPU已经向指定的端口输出了数据,所以,OBF是8255A用来通知外设取走数据的信号。
OBF由写信号WR的上升沿置成有效电平即低电平,而由ACK的有效信号使它恢复为高电乎。
②ACK(Acknowledge):这叫外设响应信号,它是由外设送给8255A的,低电平有效,当ACK 有效时,表明CPU通过8255A输出的数据已送到外设。
③INTR(Interrupt Request):中断请求信号,高电平有效。
当输出设备从8255A端口中提取数据,从而发出ACK信号后,8255A 便向CPU发新的中断请求信号,以便CPU再次输出数据,所以,当ACK变为高电平,并且OBF也变为高电平时,INTR便成为高电平即有效电平,而当写信号WR的下降沿来到时,INTR 变为低电平即复位。
④INTE(Interrupt Enable):中断允许信号。
与端口A,端口B工作在方式1输入情况时INTE的含义一样,INTE为1时,使端口处于中断允许状态,而INTE 为0时,使端口处于中断屏蔽状态。
在使用时,INTE也是由软件来设置的,具体地说,PC6为1,则使端口A的INTE为1,PC6为0,则使端口A的INTE为0。
PC2为1,使端口B的INTE为1,PC2为0,则使端口B的INTE为0。
(4)方式1的使用场合:在方式1下,规定一个端口作为输入口或者输出口的同时,自动规定了有关的控制信号和状态信号,尤其是规定了相应的中断请求信号。
这样,在许多采用中断方式进行输入/输出的场合,如果外部设备能为8255A提供选通信号或者数据接收应答信号,那么常常使8255A的端口工作于方式1情况。
用方式1工作比用方式0。
更加方便有效。
8255的方式设置(二)1、8255A 可编程并行接口芯片(1)、 8255A 结构8255A 是可编程并行接口芯片,双列直插式封装,用+5V 单电源供电,如图11.1 是8255A 的逻辑框图,内部有3个8位I/O 端口:A 口、B 口、C 口;也可以分为各有12 位的两组:A 和B 组,A 组包含A 口8位和C 口的高四位,B 组包含B 口8位和C 口的低4位;A 组控制和B 组控制用于实现方式选择操作;读写控制逻辑用于控制芯片内寄存器的数据和控制字经数据总线缓冲器送入各组接口寄存器中。
由于8255A 数据总线缓冲器是双向三态8位驱动器,因此可以直接和8088系统数据总线相连。
(2)、 8255A 端口地址见 表11.1图11.1 8255A 内部结构框图(3)、 8255A工作方式8255A 芯片有三种工作方式: 方式0、方式1、方式2。
它通过对控制寄存器写入不同的控制字来决定其三种不同的工作方式。
I/O PA7~PA0 I/O PC7~PC4 PB7~PB0PC0~PC3 I/O 11.1 8255A方式0 :基本输入/输出该方式下的A口8位和B口8位可以由输入的控制字决定为输入或输出,C 口分成高4 位(PC7~PC4)和低4位(PC3~PC0)两组,也有控制字决定其输入或输出。
方式1 :选通输入/输出该方式又叫单向输入输出方式,它分为A、B两组,A组由数据口A和控制口C 的高4位组成,B组由数据口B和控制口C的低4位组成。
数据口的输入/输出都是锁存的,与方式0不同,由控制字来决定它作输入还是输出。
C口的相应位用于寄存数据传送中所需的状态信号和控制信息。
需注意的是:该方式下,只能将C口其中一组的四位全部置为输入或输出。
方式2 :双向输入输出本方式只有A组可以使用,此时A口为输入输出双向口,C口中的5位(PC3~PC7)作为A口的控制位。