有没有办法在不影响同一端口的其他引脚的情况下设置特定的端口引脚?
例如:
我将LATB[13:6]用于 7 段 LCD,其余的 LATB 位用于其他目的。
现在我需要为显示“0”设置LATB = 0x003F,如果我这样做,其余的位都会改变。
有人可以帮助我吗?
有没有办法在不影响同一端口的其他引脚的情况下设置特定的端口引脚?
例如:
我将LATB[13:6]用于 7 段 LCD,其余的 LATB 位用于其他目的。
现在我需要为显示“0”设置LATB = 0x003F,如果我这样做,其余的位都会改变。
有人可以帮助我吗?
您必须拆分操作,因为您无法专门处理 16 位寄存器中的第 6 位到第 13 位。例如,假设 LATB 是一个 16 位寄存器,其 6 到 13 位(8 位范围)映射到带周期的 7 段显示器(形成 8 段),我们希望将这些引脚特别设置为 0x3f = 0b00111111,我们可以这样做:
LATB = (LATB & ~(0xff<<6)) | (0x3f<<6);
0xff
是我们想要影响的位的位掩码,代表 8 位,我们使用 将其移到位置 6-13 <<6
。
但是,这不是原子的;我们正在读取,屏蔽我们想要调整的位,将它们设置为新值,然后写回整个寄存器,包括保留的其他位。因此,我们可能需要例如禁用这条线周围的中断。
对于许多 MCU,有特定的代码路径支持修改单个位,或用于清除/设置的专用逻辑。这可能意味着如果您坚持更简单的操作,您可以执行调整而不会冒着践踏另一个更改的风险,例如:
val = 0x3f;
LATB |= (val<<6); // set bits which should be set
LATB &= (val<<6) | ~(0xff<<6); // clear bits that should be clear
在这个例子中,我们不是一步完成显示更新,而是我们所做的每个更新都以编译器可能能够优化为单个指令的形式(分别为 IOR 和 AND)。
一些处理器也有指令来访问像这样的字的部分,通常称为位域操作。我认为 PIC24 不在其中。它确实有单位访问指令,但它们似乎要么对工作文件进行操作,要么需要固定的位位置,这意味着必须逐位设置。
C 也确实有位域的概念,这意味着可以定义锁存寄存器的结构解释,它确实为您想要影响的位命名,但这是一种相当脆弱的方法。无论如何,当依赖特定的寄存器名称时,您正在编写特定于体系结构的代码。最好检查编译器和平台库的文档。