2017-10-13 108 views
0

我想弄清楚是否有一种简单的方法来一次修改8051端口的几个位。一次修改几个位而不会破坏操作 - 8051端口

我会重新解释我的困境更具体的风格。

我的应用程序有端口2分为两个功能。我们称他们为FA和FB。

FA依赖于低三位的输出值,而FB依赖于剩余的5位,但它们可以是I/O。

因为FB中的一位是控制时钟的输出位,所以当我修改FA时,我不想修改FB的任何部分,反之亦然。

以下种类的命令不会为我工作:

mov P2,#07h 
mov P2,#80h 

这是因为这些命令将覆盖值在错误的时间这两种功能可能触发一个功能。

我可以逃脱像下面这样:

setb P2.7 
setb P2.6 
clr P2.5 
clr P2.4 
setb P2.3 
setb P2.2 
clr P2.1 
clr P2.0 

因为我知道这些命令可以通过一个设置一个单独的位而不影响其他位,但我想尝试设置超过一次一点。

我阅读了关于read-modify-write和互联网告诉我MOV与端口引脚上的逻辑操作不同,所以我将尝试在这里进行猜测,看看我是否正确基于我的例子:

对FB说我想输出所有逻辑高和FA我想输出除最低位= 1之外的所有逻辑低。我想一次操作一个功能。

我知道这是行不通的,因为它所有设置一次:

mov P2, #0F9h 

但不知何故,我认为使用的端口逻辑可能的工作,但我想知道我的想法是正确的。假设在以下两种情况下,通过mov命令将P2的值设置为#0A1h,并且P2的引脚全部接地。

这是正确的?:

anl P2,#F8h ;value of P2 = #0A1h AND #F8h = #0A0h 
orl P2,#F9h ;value of P2 = #0A0h OR #F9h = #0F9h 
anl P2,#F0h ;value of P2 = #0F9h AND #F0h = #0F0h 

或者,这是比较正确的?:

anl P2,#F8h ;value of P2 = #00h AND #F8h = #00h 
orl P2,#F9h ;value of P2 = #00h OR #F9h = #0F9h 
anl P2,#F0h ;value of P2 = #00h AND #F0h = #00h 

在第二个例子中,我开始与#00H的方程,因为这就是价值P2会产生,如果我使用MOV A,P2,然后想要A的值,但我不确定该值是否将用于anl和orl的计算。

总的来说,我的问题是,我可以使用anl和orl来修改某个端口的某些位,而不会干扰其余的位?或者我坚持使用像setb和clr之类的位操作命令?

回答

1

首先,我想添加以下方面。涉及SETB和CLR指令的方法需要更多的机器周期来执行,并且在某些情况下可能不可行(即时钟产生,同步问题)。

与当代MCU相比,8051端口相当简陋。 '端口'有一个存储引脚状态的锁存器,该锁存器试图调节输出。这并不一定意味着该端口处于期望的状态。例如,如果外部驱动为低电平,则闩锁可能很高,但端口会较低。这正是我们如何设置一个端口作为输入。当我们将数据传送到端口时,我们写入锁存器,当我们从端口传送到寄存器时,无论锁存器的状态如何,我们都会读取实际状态。读 - 修改 - 写操作是一个例外,因为它们专门读取锁存器,执行所需的操作并写回锁存器。因此,在“这是正确的吗?”下给出的情况是正确的。

如果相反,我们要MOV A,P2然后执行anl P2,#F8h“或者这更正确吗?:”会是正确的。

因此,我们可以使用逻辑操作来修改此问题中给出的案例的端口。

+0

如果我将自定义值放在R7的高位半字节中,并希望将其作为端口2实际输出的高位半字节,同时保持端口2的低位半字节不变,那么我必须使用此编码方法:MOV R7,#70h MOV A,P2 ANL A,#0Fh ORL A,R7 MOV P2,A'。我在正确的轨道上吗? – Mike

相关问题