MCS-51单片机I/O端口的存取
MCS-51单片机通常有4个8位I/O端口, 向各端口的写数据均写入到对应端口的锁存器中, 但对各端口的读操作却有两个方式:读锁存器和读引脚
1 读-修改-写操作
Pn(指P0,P1,P2,P3)在51汇编语言中是特殊的标识符,既代表Pn端口引脚,又代表Pn锁存器(Pn SFR)。在MCS-51指令系统中有些指令读锁存器的值, 有些指令则读引脚上的值。读锁存器指令是从锁存器中读取一个值并进行处理, 把处理后的值(原值或已修改后的值)重新写入锁存器中。这类指令称为读-修改-写指令, 表1列举了有该功能的指令 当目的操作数是Pn端口或Pn端口的某一位时. 该指令读取锁存器的值.
这些指令的一个共同特点, 就是要先并行读入Pn锁存器(非Pn端口引脚)中的值,作一定的修改,然后再写入谚端口的锁存器。表1中晶后三条指令读-修改-写关系不够明显。实际上它们的执行过程序是:先将Pn的8位锁存器内容一起读人,再对指定位进行修改, 然后又 8位一起写入锁存器。
对于读-修改-写指令。直接读锁存器而不是读端口引脚, 是因为从引脚上读出的数据不一定能真正反映锁存器的状态 例如:若用Pn的某一位引脚直接驱动一个NPN三极管的基极,当向此端口写“1” 时, 三极管导通并把端口引脚的电平钳位约0.7 V (对于硅管) 这时,CPU若从此引脚读取数据. 会把该数据(应为1)错读为0;若直接从锁存器读取, 则读出正确的数据。
理解了Pn的特殊性及读-修改-写指令后, 就不难理解指令PUSH Pn的含义了。它的执行过程是:读Pn引脚(非读Pn锁存器)的值, 然后将此数值压入堆栈 以下是一段测试程序:
ORG 1000H
75A07F MOV P2,#7FH
MOV R1,#00H
74FF MOV A,#0FFH
COA0 PUSH P2
D0A0 POP P2
100B F3 MOVX @R1,A
1 RET
这段程序原意是将FFH立即数存人外部RAM地址为7F00的单元中, 但具体的运行结果与这段程序是在片内或片外被执行有密切关系。若在片内,结果与程序原意一致;若在片外,MCU执行这段片外程序后 结果却把FFH错误地送到了外部RAM 的1000H地址去。为什么会出错?因为在执行片外程序时, 出现在P2端口引脚上的数据是PCH (程序指针的高8位,此时为10H),在执行PUSH P2指令时.读取P2引脚上的数据是10H.所
以将10H压入堆栈,紧跟的POP P2指令是将当前栈顶数据10H弹出并写入P2锁存器,然后执行的MOVX @R1,A指令,将A中的数据写入[P2R1](此
时P2RI=1000H)地址中 有兴趣的读者可以尝试一下。
2 可靠读取Pn锁存器中数据的方法
上述程序并无实际运行意义, 在这里只是引出如何可靠地读取Pn锁存器中的数据问题。在MCS51指令系统中并没有一条指令可以让汇编程序员直接读取Pn锁存器的数据。在表1中只有JBC Pn.Y,Label可以较快速地获取Pn锁存器第Y位的值。由于篇幅关系,本文只介绍P2锁存器的操作,其他锁存器的操作可参照P2写出 下面是获取P2锁存器值的子程序。
GetSfrP2:PUSH IE ;保护中断允许寄存器 CLR EA ;禁止所有中断 MOV A.#0FFH JBC P2.,$+;P2锁存器位0为"并跳 ;转到$+5地址(JBC P2.,$+) CLR ACC. ;否则ACC.0清为" JBC P2.,$+ CLR ACC. JBC P2.,$+ CLRACC2 JBC P2.,$+ CLR ACC JBC P2.,$+ CLR ACC JBC P2.,$+ CLRACC JBC P2.,$+ CLR ACC. JBC P2.,$+ CLR ACC. MOV P2,A ;恢复P2锁存器原值 POPIE ;恢复中断允许寄存器 RET
另外也可在RAM 中建立各Pn锁存器的映像.通过专用程序对Pn锁存器进行操作 这样就可以在不对引脚状态有任何影响的情况下,快速可靠地读取与Pn锁存器一致的数值。以在内部RAM 中建立P2映像为例:
EP2 Data 60H ;P2锁存器映像 WriteSfrP2: MOV EP2,A ;将A写人P2锁存器映像 MOV P2,A ;将A写人P2锁存器 RET ReadSfrP2: MOV A,EP2 ;将P2锁存器映像写入A RET
如果确信读P2端口时的值都等于P2锁存器中的值,则可以用51单片机地址指针及其应用的操作方法,简单地PUSHP2和POP P2指令来保护和恢复现场程序段中使用的P2锁存器
以上三种读取Pn锁存器值的方法, 第二种方法,即在RAM 中建立Pn锁存器映像的方法,存取速度较快,适台MCS-51的任何工作方式,在读过程中不会对Pn锁存器及端口引脚状态有任何干扰,是三种方法中最好的。
MCS-51单片机I/O端口的存取的更多相关文章
- 51单片机引脚ALE/PROG/PSEN/EA/Vpp
51单片机的4个控制引脚,其中一个引脚是复位引脚(RST/Vpd),RST是复位引脚,当RST输入端保持2个机器周期以上高电平时,就实现复位. ALE/PROG是地址锁存允许信号输出端,在读写外部存储 ...
- 关于51单片机P0口的结构及上拉问题
1.P0作为地址数据总线时,V1和V2是一起工作的,构成推挽结构.高电平时,V1打开,V2截止:低电平时,V1截止,V2打开.这种情况下不用外接上拉电阻.而且,当V1打开,V2截止,输出高电平的时候, ...
- 51单片机实现对24C02进行页写、顺序读取并显示验证
//************************************************************************************* //**程序名称:51单 ...
- 基于51单片机IIC通信的PCF8591学习笔记
引言 PCF8591 是单电源,低功耗8 位CMOS 数据采集器件,具有4 个模拟输入.一个输出和一个串行I2C 总线接口.3 个地址引脚A0.A1 和A2 用于编程硬件地址,允许将最多8 个器件连接 ...
- 51单片机I/O口直接输入输出实例(附调试及分析过程)
51单片机P0/P1/P2/P3口的区别: P0口要作为低8位地址总线和8位数据总线用,这种情况下P0口不能用作I/O,要先作为地址总线对外传送低8位的地址,然后作为数据总线对外交换数据: P1口只能 ...
- [学习笔记]15个QA让你快速入门51单片机开发
一.C语言相关 Q1:sbit与sfr代表是什么?有什么作用? Q2:#define OSC_FREQ 22118400L这句宏命令里的“L”是什么意思? Q3:我粘贴了别人的代码,怎么发现没有un ...
- 2017.11.18 手把手教你学51单片机-点亮LED
In Doing We Learning 在操作中学习.如果只是光看教程,没有实际的操作,对编程语言的理解很空泛,所以决定从单片机中学习C语言. #include<reg52.h> ...
- 51单片机数据类型int,float,指针所占字节数
1.int===2个字节 2.sfr===特殊功能寄存器,也是一种扩充数据类型,占用1个内存单元,利用它可以访问51单片机内的所有特殊功能寄存器. sfr P1 = 0x90;/////////这一句 ...
- 51单片机学习笔记(郭天祥版)(1)——单片机基础和点亮LED灯
关于单片机型号的介绍: STC89C52RC40C-PDIP 0721CV4336..... STC:STC公司 89:89系列 C:COMS 52(还有51,54,55,58,516,):2表示存储 ...
随机推荐
- JavaScript的闭包详解
(1)定义: 函数内部返回一个函数,返回出来的这个函数叫做被我们称之为闭包(个人理解的最简单的表现形式,) (2)为什么要使用闭包呢? 局部变量在函数执行完之后就会被GC回收,有时候我们想在外部访问内 ...
- [Redux] Store Methods: getState(), dispatch(), and subscribe()
console.clear(); const counter = (state = 0, action) => { switch (action.type) { case 'INCREMENT' ...
- 苹果Swift编程语言新手教程【中国版】
Swift代码语言教程:在刚刚过去的WWDC2014大会上,苹果公司新公布了一种编程语言Swift.据悉.Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题.对于广 ...
- C++11 tuple
tuple元组定义了一个有固定数目元素的容器,其中的每个元素类型都可以不相同,这与其他容器有着本质的区别.是对pair的泛化. 首先来介绍元组的创建和元组元素的访问.通过make_tuple()创建元 ...
- 配置NFS服务器
一.配置NFS服务器 1.安装软件包 [root@wjb10000 ~]# yum -y install nfs-utils.x86_64 2.修改配置文件[root@wjb10000 ~]# vim ...
- 属性动画详解 Interpolator TypeEvaluator
概述 产生原因 3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中又引入了一个新的动画系统:prope ...
- js动态新增组合Input标签
var x = 1; function addlink() { var linkdiv = document.getElementById("add1_0"); if (linkd ...
- Web Api学习一
接触WebApi读的第一篇文章: ASP.NET Web API(一):使用初探,GET和POST数据 实践过程中,用的Fiddler模拟Post请求时收到的对象总是为空null 解决:将文章中的内容 ...
- VIM打开文件与保存文件
打开文件 VIM /etc/inittab 默认的安装没有设置ctrl_W为退出.也可以设置::map <C-W> :close<CR> 或:map <C-W> : ...
- java操作csv文件之javacsv.jar应用
csv文件是分隔文件,如果使用java的io流来写,比较麻烦,这里为大家提供一个javacsv的jar包,这个很方便操作csv文件. 下载地址:https://pan.baidu.com/s/1i46 ...