如何从ARM的32位端口的第15引脚获取值?

时间:2009-11-27 19:23:08

标签: c embedded arm microcontroller

我正在使用IC,DS1620读取单行上的1位串行数据。我需要使用ARM微控制器(LPC2378)的一个端口读取这些数据。 ARM端口为32位。如何将此值转换为1位变量?

编辑:换句话说,我需要直接引用端口引脚。

6 个答案:

答案 0 :(得分:5)

没有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是不值得的。如果你只想要一个或两个比特,那么转移和掩蔽是可行的方法。

总的来说,这个article可能对您有用。

答案 1 :(得分:3)

对于你的CPU,应该使用Evan Teran的答案。我只是想提一下像Cortex-M3这样的其他ARM CPU的位带功能。对于RAM /外设的某些区域,所有位都映射到单独的地址以便于访问。

有关详细信息,请参阅http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/Behcjiic.html

答案 2 :(得分:1)

如果你可以直接访问端口寄存器(我没有任何ARM经验),这很简单,只需按位并使用与你想要的位相对应的二进制掩码:

var = (PORT_REGISTER & 0x00008000);

如果第15位为“0”,则var包含0或如果第15位为“1”则包含0x00008000。

另外,如果你想要'0'或'1',你可以转移它:

var = ((PORT_REGISTER & 0x00008000) >> 15);

答案 3 :(得分:0)

编译器附带的头文件将包含所有微控制器寄存器的声明以及这些寄存器中的位。

在这篇特定文章中,让我们假设端口输入寄存器被称为PORTA,并且您想要的位具有为其定义的掩码PORTA15

然后读取该引脚的状态:

PinIsSet = (PORTA & PORTA15) == PORTA15;

或者等效地使用ternary operator

PinIsSet = (PORTA & PORTA15) ? 1 : 0;

作为一般观点,请参阅参考手册,了解所有寄存器和位的功能。另外,看一些例子。 (This page on the Keil website包含两者,网上还有很多其他例子。)

答案 4 :(得分:0)

在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 */

我希望这可以提供帮助。

问候!

答案 5 :(得分:0)

如果测试位,最好记住C的运算符评估顺序,例如

if( port & 0x80 && whatever() )

可能导致意外行为,正如您刚刚写的那样

if( port & (0x80 && whatever()) )

但可能是

if( (port & 0x80) && whatever() )