Question

I am using an IC, DS1620 to read 1 bit serial data coming on a single line. I need to read this data using one of the ports of ARM microcontroller (LPC2378). ARM ports are 32 bit. How do I get this value into a 1 bit variable?

Edit: In other words I need direct reference to a port pin.

Was it helpful?

Solution

there are no 1 bit variables, but you could isolate a particular bit for example:

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.

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. 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.

OTHER TIPS

For your CPU the answer from Evan Teran should be used. I just wanted to mention the bit-band feature of some other ARM CPU's like the Cortex-M3. For some region of RAM/Peripherals all bits are mapped to a separate address for easy access.

See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/Behcjiic.html for more information.

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:

var = (PORT_REGISTER & 0x00008000);

Now var contains either 0 if the 15th bit is '0' or 0x00008000 if the 15th bit is '1'.

Also, you can shift it if you want to have either '0' or '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.

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.)

In LPC2378 ( as the other LPC2xxxx microcontroller family ), I/O ports are in system memory, so you need to declare some variables like this:

#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. 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:

#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, e.g.

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

can result in unexpected behaviour, as you just wrote

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

but probably ment

if( (port & 0x80) && whatever() )
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top