我正在使用 IC DS1620 读取单行上的 1 位串行数据。我需要使用 ARM 微控制器 (LPC2378) 的端口之一读取这些数据。ARM 端口是 32 位的。如何将此值转换为 1 位变量?
编辑:换句话说,我需要直接引用端口引脚。
我正在使用 IC DS1620 读取单行上的 1 位串行数据。我需要使用 ARM 微控制器 (LPC2378) 的端口之一读取这些数据。ARM 端口是 32 位的。如何将此值转换为 1 位变量?
编辑:换句话说,我需要直接引用端口引脚。
没有 1 位变量,但您可以隔离特定位,例如:
uint32_t original_value = whatever();
uint32_t bit15 = (original_value >> 15) & 1; /*bit15 now contains either a 1 or a 0 representing the 15th bit */
注意:我不知道你是从 0 还是 1 开始计算位数,所以>> 15
可能会减一,但你明白了。
另一种选择是使用位字段,但这会变得混乱,而且 IMO 不值得这样做,除非值中的每一位都以某种方式有用。如果你只想要一两个位,移位和屏蔽是要走的路。
总的来说,这篇文章可能对你有用。
对于您的 CPU,应该使用 Evan Teran 的答案。我只是想提一下其他一些 ARM CPU 的位带特性,比如 Cortex-M3。对于 RAM/外设的某些区域,所有位都映射到单独的地址以便于访问。
有关详细信息,请参阅http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/Behcjiic.html。
如果您可以直接访问端口寄存器(我对 ARM 没有任何经验),这很简单,只需使用与您想要的位相对应的二进制掩码按位与它:
var = (PORT_REGISTER & 0x00008000);
现在 var 如果第 15 位为“0”则包含 0,如果第 15 位为“1”则包含 0x00008000。
此外,如果你想要“0”或“1”,你可以改变它:
var = ((PORT_REGISTER & 0x00008000) >> 15);
编译器附带的头文件将包含所有微控制器寄存器的声明,以及这些寄存器中的位。
在这篇具体的文章中,假设端口输入寄存器被调用PORTA
,并且您想要的位有一个为其定义的掩码,称为PORTA15
。
然后读取该引脚的状态:
PinIsSet = (PORTA & PORTA15) == PORTA15;
或者等效地,使用三元运算符:
PinIsSet = (PORTA & PORTA15) ? 1 : 0;
一般来说,请参阅参考手册了解所有寄存器和位的作用。另外,看看一些例子。(Keil 网站上的这个页面包含这两者,网上还有很多其他示例。)
在 LPC2378(与其他 LPC2xxxx 微控制器系列一样)中,I/O 端口位于系统内存中,因此您需要声明一些变量,如下所示:
#define DALLAS_PIN (*(volatile unsigned long int *)(0xE0028000)) /* Port 0 data register */
#define DALLAS_DDR (*(volatile unsigned long int *)(0xE0028008)) /* Port 0 data direction reg */
#define DALLAS_PIN (1<<15)
请注意0xE0028000是port0的数据寄存器地址,0xE0028008是port0的数据方向寄存器地址。您需要根据应用程序中使用的端口和位来修改它。之后,在您的代码函数中,写 1、写 0 和读的代码或宏必须是这样的:
#define set_dqout() (DALLAS_DDR&=~DALLAS_PIN) /* Let the pull-up force one, putting I/O pin in input mode */
#define reset_dqout() (DALLAS_DDR|=DALLAS_PIN,DALLAS_PORT&=~DALLAS_PIN) /* force zero putting the I/O in output mode and writing zero on it */
#define read_dqin() (DALLAS_DDR&=~DALLAS_PIN,((DALLAS_PORT & DALLAS_PIN)!= 0)) /* put i/o in input mode and test the state of the i/o pin */
我希望这会有所帮助。
问候!
如果测试位,最好记住 C 的运算符评估顺序,例如
if( port & 0x80 && whatever() )
正如您刚刚写的那样,可能会导致意外的行为
if( port & (0x80 && whatever()) )
但可能
if( (port & 0x80) && whatever() )