简体   繁体   English

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

[英]How to get value from 15th pin of 32bit port in ARM?

I am using an IC, DS1620 to read 1 bit serial data coming on a single line. 我正在使用IC,DS1620来读取单行上的1位串行数据。 I need to read this data using one of the ports of ARM microcontroller (LPC2378). 我需要使用ARM微控制器(LPC2378)的一个端口读取这些数据。 ARM ports are 32 bit. ARM端口为32位。 How do I get this value into a 1 bit variable? 如何将此值转换为1位变量?

Edit: In other words I need direct reference to a port pin. 编辑:换句话说,我需要直接引用端口引脚。

there are no 1 bit variables, but you could isolate a particular bit for example: 没有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 */

Note: I don't know if you were counting bit numbers starting at 0 or 1, so the >> 15 may be off by one, but you get the idea. 注意:我不知道你是否计算从0或1开始的位数,所以>> 15可能会被一个关闭,但你明白了。

The other option is to use bit fields, but that gets messy and IMO is not worth it unless every bit in the value is useful in some way. 另一种选择是使用位字段,但这会变得混乱,除非值中的每一位都以某种方式有用,否则IMO是不值得的。 If you just want one or two bits, shifting and masking is the way to go. 如果你只想要一个或两个位,那么转移和屏蔽是最佳选择。

Overall, this article may be of use to you. 总的来说,这篇文章可能对您有用。

For your CPU the answer from Evan Teran should be used. 对于您的CPU,应该使用Evan Teran的答案。 I just wanted to mention the bit-band feature of some other ARM CPU's like the Cortex-M3. 我只是想提一下像Cortex-M3这样的其他ARM CPU的位带功能。 For some region of RAM/Peripherals all bits are mapped to a separate address for easy access. 对于RAM /外设的某些区域,所有位都映射到单独的地址以便于访问。

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

It's simple if you can access the port register directly (I don't have any experience with ARM), just bitwise AND it with the binary mask that corresponds to the bit you want: 如果你可以直接访问端口寄存器(我没有任何ARM经验),这很简单,只需按位和它与你想要的位对应的二进制掩码:

var = (PORT_REGISTER & 0x00008000);

Now var contains either 0 if the 15th bit is '0' or 0x00008000 if the 15th bit is '1'. 如果第15位为“0”,则var包含0或者如果第15位为“1”则包含0x00008000。

Also, you can shift it if you want to have either '0' or '1': 此外,如果你想要'0'或'1',你可以改变它:

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

The header file(s) which come with your compiler will contains declarations for all of the microcontroller's registers, and the bits in those registers. 编译器附带的头文件将包含所有微控制器寄存器的声明以及这些寄存器中的位。

In this specific article, let's pretend that the port input register is called PORTA , and the bit you want has a mask defined for it called PORTA15 . 在这篇特定文章中,让我们假设端口输入寄存器被称为PORTA ,并且您想要的位具有为其定义的掩码,称为PORTA15

Then to read the state of that pin: 然后读取该引脚的状态:

PinIsSet = (PORTA & PORTA15) == PORTA15;

Or equivalently, using the ternary operator : 或者等效地,使用三元运算符

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

As a general point, refer to the reference manual for what all the registers and bits do. 一般来说,请参考参考手册,了解所有寄存器和位的功能。 Also, look at some examples. 另外,看一些例子。 ( This page on the Keil website contains both, and there are plenty of other examples on the web.) Keil网站上的这个页面包含两者, 网上还有很多其他的例子。)

In LPC2378 ( as the other LPC2xxxx microcontroller family ), I/O ports are in system memory, so you need to declare some variables like this: 在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)

Please note that 0xE0028000 is the address for the data register of port0, and 0xE0028008 is the data direction register address for port0. 请注意,0xE0028000是port0的数据寄存器的地址,0xE0028008是port0的数据方向寄存器地址。 You need to modify this according to the port and bit used in your app. 您需要根据应用中使用的端口和位对其进行修改。 After that, in your code function, the code or macros for write 1, write 0 and read must be something like this: 在那之后,在你的代码函数中,写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 */

I hope this can help. 我希望这可以提供帮助。

Regards! 问候!

If testing for bits, it is good to keep in mind the operator evaluation order of C, eg 如果测试位,最好记住C的操作符评估顺序,例如

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

can result in unexpected behaviour, as you just wrote 正如你刚才写的那样,可能导致意外行为

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

but probably ment 但很可能

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM