我已经阅读了数据表和Google,但我仍然不明白。
在我的情况下,我在输入模式下设置PIC18F26K20的PIN RC6:
TRISCbits.TRISC6 = 1;
然后我用PORT和LATCH读取值,我有不同的值!
v1 = LATCbits.LATC6;
v2 = PORTCbits.RC6;
v1给出0,其中v2给出1。
这是正常的吗?在这种情况下,我们必须使用PORT,在这种情况下使用LATCH?
答案 0 :(得分:31)
锁存器是输出锁存器,其上写入了值。端口是实际引脚的电压。
在某些情况下,它们可能会有所不同。我经常遇到的一个问题是你的针脚(意外)是否短路接地。如果将锁存器设置为高电平,则锁存器将读为高电平,但端口将读为低电平,因为引脚上的电压仍接近接地。
导致您所描述的另一种情况是端口引脚未正确配置。我(和我一起工作的每个人)都花了很多时间试图弄清楚为什么我们的PIC没有达到预期目的,最终发现我们在关闭模拟模块时掩饰了。请务必查看I / O端口部分 - > PORT?,TRIS?和LAT?在数据表中注册。您可以在Microchip wiki page中获得更多信息,其中解释了在连接到容性负载的引脚上写入输出后立即读取错误的值。
该维基页面也解释了:
读取端口锁存寄存器会返回输出驱动器的设置,同时读取端口寄存器会返回引脚上的逻辑电平。
此外,这是18F14K50上I / O端口部分的片段(应该与18F系列的其余部分相同):
每个端口都有三个寄存器 操作。这些寄存器是:
- TRIS寄存器(数据方向寄存器)
- PORT寄存器(读取器件引脚上的电平)
- LAT寄存器(输出锁存器)
因此在大多数情况下,您将写入锁存器并从端口读取。
答案 1 :(得分:15)
我将改编电气工程my answer。
让我们使用手册中的图片:
当您在I / O引脚中写入一个位时,您将此位从数据总线存储到数据寄存器(D-FlipFlop)。如果该位的TRISx为0,则数据寄存器Q的数据将位于I / O引脚中。写入LATx或PORTx是一样的。见下文红色:
另一方面,从LATx读取与PORTx的读取不同。
当您从LATx阅读时,您正在阅读数据寄存器中的内容(D-FlipFlop)。请参见下面的绿色图片:
当您从PORTx读取时,您正在读取实际的I / O引脚值。见下文蓝色:
PIC使用读 - 修改 - 写操作,这可能是problem,所以他们使用这个影子寄存器来避免它。
答案 2 :(得分:10)
以下是数据表中的有用摘要。
11.2.3 LAT登记册PORT和LAT寄存器之间的差异可归纳如下:
答案 3 :(得分:4)
是的,阅读PORTx和LATx是正常的,偶尔会发现它们有不同的值。
当您想要读取某些外部硬件是否将引脚驱动为高电平或低电平时,必须将引脚设置为输入模式(使用TRIS或DIR寄存器),并且必须读取PORTx。该读数告诉您引脚的实际电压是高还是低。
当您想要将引脚驱动为高电平或低电平时,必须将引脚设置为输出(使用TRIS或DIR寄存器);你应该把这个位写入LATx寄存器。
(将该位写入PORTx寄存器可能似乎做正确的事情:该引脚将 - 最终 - 根据命令变为高或低。但是有很多情况 - 例如当该端口上的某个其他引脚连接到开路集电极总线时 - 写入PORTx寄存器的一个位会弄乱该端口上其他引脚的状态,从而导致难以调试的问题)。
答案 4 :(得分:3)
我的建议是将PORT值视为只读。可以读取或写入LAT值,但读取的值将是写入的最后一个值,而不是引脚的输入值。
在较旧的PIC上,LATx值不存在;写入端口的唯一方法是通过PORTx寄存器。奇怪的是,从通用仪器(Microchip早期)开始,一些非常老的PIC支持LATx,但是在PIC18x线路之前,Microchip没有添加该功能。
答案 5 :(得分:0)
我最近经历过,当另一个PORTx Rj(例如PORTC RC0)已经设置时,PIC18F14K50的PORTx Ri(例如PORTC RC1)上的写入无效。 我在PORTx Ri的示波器上看到了一眼,但我无法维持输出。 一旦我在LATx上写作,这个问题就消失了。
在禁止PIC18和PORTx写入时,LATx写入看起来是强制性的。
答案 6 :(得分:0)
使用LATx
:写入输出引脚
使用PORTx
:读取输入引脚
对于所有带有LATx
寄存器的PIC,所有INPUT必须从PORTx
开始,所有OUTPUT应该到LATx
,这完全避免了在写入单个寄存器时翻转位的问题。端口的位。
答案 7 :(得分:0)
总是建议写入LAT,从PORT读取,原因是当端口用作输出时,PORT的位操作会读取修改写入指令。
读取修改写入指令会由于执行两个连续的READ Modify WRITE指令时可能将端口引脚设置为错误值的输出电容(端口引脚的上升时间)而存在一些陷阱。
因此,始终写入LAT并从PORT(输入引脚)读取