我已经阅读了数据手册和谷歌,但仍然不明白某些内容。
在我的情况下,我将PIC18F26K20的PIN RC6设置为输入模式:
TRISCbits.TRISC6 = 1;
然后我使用PORT
和LATCH
读取该值,但我得到了不同的值!
v1 = LATCbits.LATC6;
v2 = PORTCbits.RC6;
v1
给我 0
,而 v2
给我 1
。
这正常吗?
在什么情况下我们必须使用 PORT
,在什么情况下我们必须使用 LATCH
?
我已经阅读了数据手册和谷歌,但仍然不明白某些内容。
在我的情况下,我将PIC18F26K20的PIN RC6设置为输入模式:
TRISCbits.TRISC6 = 1;
然后我使用PORT
和LATCH
读取该值,但我得到了不同的值!
v1 = LATCbits.LATC6;
v2 = PORTCbits.RC6;
v1
给我 0
,而 v2
给我 1
。
这正常吗?
在什么情况下我们必须使用 PORT
,在什么情况下我们必须使用 LATCH
?
端口锁存器寄存器的读取返回输出驱动器的设置,而端口寄存器的读取返回设备引脚上的逻辑电平。
此外,下面是18F14K50的I/O Ports部分的一段片段(应该与18F系列的其余部分相同):端口
,输出 = 锁存器
。 - Mike这是来自数据表的有用摘要。
11.2.3 LAT 寄存器
与 I/O 引脚相关联的 LATx 寄存器消除了可能出现的读取-修改-写入指令所带来的问题。从 LATx 寄存器读取时,返回的是端口输出锁存器中保存的值,而不是 I/O 引脚上的值。与 I/O 端口相关联的 LAT 寄存器进行读取-修改-写入操作,避免了将输入引脚值写入端口锁存器的可能性。向 LATx 寄存器进行写入操作具有与向 PORTx 寄存器进行写入操作相同的效果。
PORT 和 LAT 寄存器之间的区别可以总结如下:
是的,读取PORTx和LATx时发现它们具有不同的值是正常的。
当您想要读取某些外部硬件是将引脚拉高还是拉低时,必须将引脚设置为输入模式(使用TRIS或DIR寄存器),并且必须读取PORTx。该读取告诉您引脚实际电压是高还是低。
当您想要将引脚拉高或拉低时,必须将引脚设置为输出模式(使用TRIS或DIR寄存器);您应该将位写入LATx寄存器。
(将该位写入PORTx寄存器可能会看起来做正确的事情:该引脚将根据指令最终变为高电平或低电平。但是存在许多情况 - 例如当该端口上的其他引脚连接到开漏总线时 - 写入PORTx寄存器的一个位将破坏该端口上其他引脚的状态,导致难以调试的问题)。
PORTx
寄存器的写操作会将数据值写入端口锁存器。
LATx
寄存器的写操作会将数据值写入端口锁存器。
PORTx
寄存器的读操作会读取I/O引脚上的数据值。
LATx
寄存器的读操作会读取端口锁存器上的数据值。
使用LATx
:向输出引脚写入数据
使用PORTx
:读取输入引脚的数据
对于所有带有LATx
寄存器的PIC,所有的输入必须来自PORTx
,所有的输出应该是LATx
,这完全避免了在写入端口的单个位时翻转位的问题。
建议始终写入LAT,从PORT读取,原因是当端口用作输出时,PORT的位操作将执行读取修改写入指令。
读取修改写入指令存在一些缺陷,基于输出电容(端口引脚的上升时间),可能会将端口引脚设置为错误值,当执行两个连续的读取修改写入指令时。
因此,始终从LAT中写入并从PORT(输入引脚)中读取。
最近我发现,在PIC18F14K50的PORTx Ri(例如PORTC RC1)上写入时,如果另一个PORTx Rj(例如PORTC RC0)已经设置,则无效。 我在PORTx Ri上观察到了一个峰值,但我无法维持输出。 只要我在LATx上写入,这个问题就消失了。
PIC18上必须使用LATx写入,禁止使用PORTx写入。