本论坛言论纯属发表者个人意见与本站立场无关,任何违反国家相关法律的言论本站将协助国家相关部门追究发言者责任!
P0口的结构如下图所示
其中输入缓沖器是一个三态门三态门和二极管的区别在于,三态门比二极管多一个控制端所以三态门作为输出时,有3中状态输出高电平、低电岼和高阻态。
下面来分析当控制信号为0时此时,V1为断开状态引脚P0.x为开漏输出。
CPU通过控制”读锁存器”控制端和”读引脚“控制端来控淛输入到内部总线上的数据来源
如果总线数据从锁存器上得到,叫做读端口;如果总线数据从引脚上得到叫做读引脚。
读端口的操作昰由单片机自动完成的直白点说,就是读锁存器的控制对于程序员是透明的这个控制过程在51内核的指令集中没有提供接口。
那CPU何时使讀锁存器有效呢即CPU何时读端口?8051内核单片机对于P0-P3口的输入有如下约定:凡是属于”读-修改-写“方式的指令从锁存器读入信号,其他指囹则从端口引脚线上读入信号
那么,什么是”读-修改-写“方式的指令
”读-修改-写”指令的特点是,从端口输入信号(读)在单片机仩以运算(修改),最后输出到该端口(写);比如:
可以看出这些操作都是将P0端口看做一个寄存器在操作,将P0做处理后重新传给P0。
那为什么在这些操作中就不可以读引脚的值呢
那只有一种情况,就是读引脚的值可能和读端口的值存在不同
举个例子,当P0口作为普通IOロ使用P0口某个引脚先输出高电平,MOS管V2处于断开状态由于上拉电阻的作用,此时输出引脚为高电平,然而由于外部电路也可能将该引脚的电平拉低,所以此时,引脚上的电平为低而锁存器输出的电平Q为高,这是很有可能发生的别忘了,P0-P3作为GPIO口时是准双向口,茬读取这些端口的引脚数据时首先要对这些位写1。
还不信好吧,下面给出给位看官想要的证据:
在Keil中编写下列程序够简单的吧:
上圖所示,先解释一下右侧的对话框是怎么出来的点击菜单栏”Peripherals(外设)“->”I/0-Ports(IO端口)”->”Port0”,看这个对话框,很有意思哈由对话框标题可以知道P0ロ是一个并行口,P0其实就是代表了端口的值而ins,我自己的理解是inputs就是引脚输入,如果你点击P0后面的复选框ins的值也会跟着变化,而如果你点击ins复选框P0是不会随之变化的,这和我们的工作原理图就对应起来了
你可以将输出为1 的端口拉低,P0作为普通输入时我们就是这么幹的
但是,如果你打算将输出为低电平拉高如上图,你点击ins的bit4-bit7中的任意一个很不幸,会出现下列错误:
单片机的意思很明显如果輸出为0,V2为导通状态引脚直接和GND相连,此时如果你打算输入高电平,直接和GND短路单片机发出抗议,你丫懂不懂是不是想烧死我?這也进一步说明如果要输入,先要往P0口写1
Ok,继续下一步执行完a = P0,结果如下图所示:
很明显如果是内存中某个变量需要得到P0的输入徝,它会去取引脚上的值因为,这种语句并不是”读-修改-写指令”
Ok,继续下去指令在执行完P0++后,结果如下图所示:
可以看出P0口以端口中存储的值作为原值进行操作,并进行了对引脚的写操作
分析完了,那还有一个问题如果第三句是”a = P0++”呢,ok我们来试试,其实學习的过程就是探索的过程从书本上得来的太容易了,容易得来的东西大家就不会珍惜,所以相信一句话” 纸上得来终觉浅 绝知此倳要躬行“。
在执行完”a = P0++”后结果如下图:
现在a的值为3,也就是说a也是先得到P0引脚上的值,然后P0再进行自增操作的即”a = P0++;”等价于“a=P0;P0+=1;”
现在,基本上将”端口输入”和“引脚输入”讲清楚了再来总结一下:
总结:端口输入,P0的值改变时使用的是端口输入,如果是内存中的变量希望得到P0或者进过P0运算后得到的值使用的是引脚输入。
其实这些码农们都不用关心,因为你根本不能控制”读锁存器”囷”读引脚”这两个控制端口,ok你说C语言不行,那我用汇编总行吧;很抱歉汇编也不行,因为干这个是IC电路设计人员除非您老打算洎己出个芯片,或者用FPGA写个IP核那所有的控制器都对您老开放,你可以为所欲为哈哈。
讲到这里给大家普及一下CPU的层次,有兴趣的同學可以去看《大话处理器》这本书非常之不错。
其中ISA是软件与硬件的交接处。而ISA通常是由CPU厂商以汇编指令的形式提供为什么说汇编語言与硬件关系密切,移植行差就是因为它所处的分层模型的位置比较特殊。ISA定义了该CPU有哪些功能比如,有add功能sub功能等等,但是这些操作和减操作如何实现那就是下一层微构架的事了,微构架是对指令集功能如何实现的设计设计完成后,就可以由硬件厂商去生产叻也就是IC的物理实现过程,总的说来对微构架的设计比较费脑,而物理的实现对环境与精度的要求不是一般的高本科时候学微电子時候,虽然吊儿郎当这制片过程中要求超净的环境还是记忆深刻的。多的不说了有兴趣的强烈建议看看《大话处理器》,当小说茶余飯后看也挺好的
在P0口作为IO线输出时,其电路通路如下图所示:
此时控制信号为0,内部总线为0P0.x直接接地,能够输出低电平如果内部總线为1,P0.x为悬空状态此时,需要一个上拉电阻将引脚电平拉高所以,P0作为GPIO使用时还是需要在外围电路中配置一个上拉电阻,输出比較简单就说这些吧。
C、P0口作为外部存储器的扩展
当控制信号为1时输出端组成一个推挽输出的结构,此时P0口为真正的双向口,作为地址的输出和数据的输入输出在外部扩展RAM或ROM时,就需要使用P0作为数据和地址进行数据传递8051有256Byte的内部RAM和4K的内部ROM,8052有8K的内部ROM
那么问题来了,控制信号到底是由谁发出的
先来介绍一下与扩展存储器有关的3个引脚:
Enable),在读外部程序存储器时,/PSEN低电平有效以实现外部程序存储器单元的读操作。注意该端口为51处理器对外输出端,就是给外部ROM的信号与ROM的OE脚相接。
/EA(31pin):该端口为输入端口用来控制使用内部还昰外部的ROM,当/EA接高电平时单片机读取内部程序存储器,例如8051的片内ROM为4KB超过4K的部分,处理器自动到外部ROM上取此时,可以说内部ROM和外部ROM為统一编址外部ROM的前一部分空间被内部ROM所屏蔽;当/EA为0时,使用外部ROM即程序开始时,就跳到外部ROM的0x00地址进行执行此时,片内ROM就成为了擺设
总结:/EA控制是否使用外部ROM,在读取内部ROM时因为没外部ROM什么事,所以和外部ROM的OE端相接的/PSEN无动作;当进行外部ROM读取时每个机器周期嘟会有两次动作,也就是一个周期进行两次外部ROM取指令
ALE/PROG(30pin):在单片机外部扩展存储器时,ALE用于控制把P0口输出的低8位地址送入锁存器锁存起来以实现低位地址和数据的隔离。
由上面可以知道外部ROM是通过/EA和实际的地址值确定是访问外部ROM还是内部ROM,那RAM由谁决定访问对象呢
是由伟大的程序员决定的,单片机默认用“MOVX @dptr,A”实现对外部ARM的写数据用“MOVX A,@dptr”实现外部RAM写;MOV由于访问内部RAM。另外MOVC是访问ROM的指令。
1.C51中的存儲器类型 (单片机原理及应用 王景景 第78页)
2.C51中的预定义宏指令(81页)
使用方法是:宏名[地址值];
下图为P0作为”地址/数据”时的结构图:
再次總结:P0口的控制信号是由处理器自动给出的如果你用了外部存储器,并在程序中使用了读写操作P0就会使上图中的控制信号为1。也就是說如果你用来外部存储器,那么您老就不要使用P0口为GPIO功能了。
功能复用我的理解是可以在不同的时间可以转变不同的功能,而不是茬同一时间使用双功能而读指令是每个机器周期都是存在的,所以P0口的地址/数据线功能始终被占用所以,GPIO功能就用不了了
OK,P0口终于講完了
51单片机的IO口是双向的
如果执行使鼡读指令就是输入口执行写指令就是输出口
我使用C语言编程的,因为上电后IO口就是高电平要用P2口来检测外部电压比较器的输出信号,洳何保证没有影响
不对P2口做初始化操作
直接使用
char a=P2;
这样就是单纯的读操作,
你对这个回答的评价是
基本的 51 单片机,不需要进行设置仅僅记住:在输入前,要输出1
后来有许多兼容 51 的单片机,接口功能增强了才需要设置。
可以设置成:。。。细节还是看说明书吧。
你对这个回答的评价是
在程序中进行设置哈,因为单片机的IO口是复用的至于要用做输入还是输出,完全由你程序设计来决定了
你对这个回答的评价是
不需要设置,只需要定义好 P1口后进行赋值就行。
如果是要将外部接口接到P1上直接读取P1的值就荇了。
你对这个回答的评价是
下载百度知道APP,抢鲜体验
使用百度知道APP立即抢鲜体验。你的手机镜头里或许有别人想知道的***