#bit define

Started by PFC March 13, 2007
A little bit off the topic of spicific HC11's. For the past few years I have been using a compiler which allows a bit within a register to be defined with a name. Example: #bit mybit = PortA.1 This will give bit 1 of PortA the name mybit which can be used for read and write operations of that bit.
I am returning to a compiler used for a 11F1 processor which does not have this #bit function and would like some feedback on how to implement this function in C code. I have looked at using struct's and union's which can be used to point to the bit but my code to set, clear or read the bit is not clean.
Does anyone out ther have any pointers on how to write this #bit function.
With thanks in advance.

PFC.
You can use #define to name each bit... the trick is whether you name it as
a mask... a power of 2 like 0x80 0x40 0x20 0x10 0x08 0x04 0x02 0x01... or as a
bit position....7 6 5 4 3 2 1 0. Use bitwise or operator to set bits, use
bitwise and to reset bits...

#define EN 0x80 //used as a mask
PORTA |= EN; //EN hi
PORTA &= ~EN; //EN lo
#define EN 7 //used as a bit position
PORTA |= (1 << EN); //EN hi
PORTA &= ~(1 << EN); //EN lo

I like the 1st way, but lots of examples are written the 2nd way.



**************************************
AOL now offers free
email to everyone. Find out more about what's free from AOL at
http://www.aol.com.
PFC wrote:
> A little bit off the topic of spicific HC11's. For the past few

It has nothing to do with the '11 at all :-)

> years I have been using a compiler which allows a bit within a
> register to be defined with a name. Example: #bit mybit = PortA.1
> This will give bit 1 of PortA the name mybit which can be used for
> read and write operations of that bit.

> I am returning to a compiler used for a 11F1 processor which does not
> have this #bit function and would like some feedback on how to
> implement this function in C code. I have looked at using struct's

You now understand the importance of writing portable code. The use
of struct and union is inadvisable, as there is no standard for
how they get implemented.

> and union's which can be used to point to the bit but my code to set,
> clear or read the bit is not clean.

> Does anyone out ther have any pointers on how to write this #bit
> function.

Yes, of course.

I do sth like this...

in

#ifndef BIT0

#define BIT0 0x01
#define BIT1 0x02
...
#define BIT7 0x80

#endif
in

#ifndef M6811_H_INCLUDED
#define M6811_H_INCLUDED
#include

typedef volatile unsigned char REG8;
typedef volatile unsigned short int REG16;

/* note that the above presumes that a short int is 16 bits*/
/* with a "modern" compiler, one would use a guaranteed */
/* size integer type instead, like the following */

/* typedef volatile uint8_t REG8 */
/* typedef volatile uint16_t REG16 */

#define REGBASE (unsigned char *)0x1000

/* one could also make it an extern */
/* extern unsigned char REGBASE[]; */

#define PORTAo 0x00
#define PORTAadr ((REG8 *)((REGBASE)+PORTAo))
#define PORTA (*PORTAadr)

/* one could also omit the PORTAadr and just do...*/
/* #define PORTA (*(REG8 *)((REGBASE)+PORTAo) */
/* or even omit the offset, but that sometimes comes */
/* in handy */
...

#endif

in an include file particular to my project



#ifndef MOTOR_H_INCLUDED
#define MOTOR_H_INCLUDED

#define MOTOR_ENABLE_PORT PORTA
#define MOTOR_ENABLE_BIT BIT3
#define MOTOR_ON MOTOR_ENABLE_BIT
#define MOTOR_OFF 0
#define MOTOR_ENABLE(Value) (MOTOR_ENABLE_PORT= \
(MOTOR_ENABLE_PORT & ~MOTOR_ENABLE_BIT)| Value)

#define MOTOR_DIRECTION_PORT PORTA
#define MOTOR_DIRECTION_BIT BIT2
#define MOTOR_DIRECTION_LEFT MOTOR_DIRECTION_BIT
#define MOTOR_DIRECTION_RIGHT 0
#define MOTOR_DIRECTION(Direction) \
(MOTOR_DIRECTION_PORT = \
(MOTOR_DIRECTION_PORT & ~MOTOR_DIRECTION_BIT) | \
Direction)
#endif

Now you can write portable code like

#include

MOTOR_ENABLE(MOTOR_ON);
MOTOR_ENABLE(MOTOR_OFF);
MOTOR_DIRECTION(MOTOR_DIRECTION_LEFT);

etc.

Slightly safer code is...

#define MOTOR_ENABLE(Value) (MOTOR_ENABLE_PORT= \
(MOTOR_ENABLE_PORT & ~MOTOR_ENABLE_BIT) | \
(Value)?MOTOR_ENABLE_BIT:0)

#define MOTOR_DIRECTION(Direction) \
(MOTOR_DIRECTION_PORT = \
(MOTOR_DIRECTION_PORT & ~MOTOR_DIRECTION_BIT) | \
(Direction)==MOTOR_DIRECTION_LEFT ? \
MOTOR_DIRECTION_LEFT : 0)

It's not as concise or as pretty, perhaps, and maybe a little
more work, but it is almost absolutely portable to any
C89 ANSI compiler. For a C99 ANSI compiler, one can specify
the exact sizes of integers. In that case, I would use

uint8_t
uint16_t

for the exact size integers. This would give complete portability
to all C99 ANSI compilers.

Or you can use structs and have to modify your code yet again
when a new version comes out, or you change compilers again,
or whatever.

Try to make sure that your macroes do not ever evaluate their
arguments more than one time, to avoid surprising side effects.
Do not, for example, use

#define MOTOR_DIRECTION(Direction) \
(MOTOR_DIRECTION_PORT = \
(MOTOR_DIRECTION_PORT & ~MOTOR_DIRECTION_BIT) | \
(Direction)==MOTOR_DIRECTION_LEFT ? \
(Direction) : 0)

Mike
--
p="p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
Oppose globalization and One World Governments like the UN.
This message made from 100% recycled bits.
You have found the bank of Larn.
I can explain it for you, but I can't understand it for you.
I speak only for myself, and I am unanimous in that!
Bob,
Thank you for your reply.
I was looking for something which was a bit cleaner than the bit toggling.
I have written code for another processor using a different compiler and am porting it to a 11F1 for test.
The first compiler offers a #bit definition function which allows direct bit manipulation. Example:

#bit mybit = porta.1
you can then write;

mybit = 1; // to set the bit.
mybit = 0; // to clear the bit.
if(mybit); // to test the bit.

This is convenient when testing register bits e.g. interrupt flag register bits, and then clearing the bit e.g. interrupt flag.

while(!TMR0_int);
TMR0_int = 0;

I understand that this will possibly be a function which has to be written to a library, but it does make the code a lot cleaner.
PFC.

You can use #define to name each bit... the trick is whether you name it as
a mask... a power of 2 like 0x80 0x40 0x20 0x10 0x08 0x04 0x02 0x01... or as a
bit position....7 6 5 4 3 2 1 0. Use bitwise or operator to set bits, use
bitwise and to reset bits...

#define EN 0x80 //used as a mask
PORTA |= EN; //EN hi
PORTA &= ~EN; //EN lo
#define EN 7 //used as a bit position
PORTA |= (1 << EN); //EN hi
PORTA &= ~(1 << EN); //EN lo

I like the 1st way, but lots of examples are written the 2nd way.




**************************************
Mike,
> It has nothing to do with the '11 at all :-)

Surprisingly enough it does, for my query. I am porting code to the ICC compiler for some 11F1 applications for test purposes. I agree that this could be a generic C code question also.

> You now understand the importance of writing portable code. The use
> of struct and union is inadvisable, as there is no standard for
> how they get implemented.

One tends to use the tools currently available. The other compiler gave the option for the use of a #BIT operator which allowed the direct manipulation and reading of a bit within a register. This proved to be very beneficial as it kept the code very clean.
Example:
#bit mybit = porta.1
Then one could read or write that bit as follows;
Mybit = 1;
or
If(!mybit);
I agree that using operators specific to a compiler is not the best policy. What I wanted to do was see if there was a method of implementing this function in a generic fashion to suit the ICC compiler, or in fact any compiler.
The use of unions did allow a neat way of pointing at a bit and I thought that unions were common among most compilers.

Thank you for the code examples. I will need to work through them but it still looks like calling a function to set or clear or read the bit.
PFC.

----- Original Message -----
From: Mike McCarty
To: m...
Sent: Wednesday, March 14, 2007 8:27 AM
Subject: Re: [m68HC11] #bit define
PFC wrote:
> A little bit off the topic of spicific HC11's. For the past few

It has nothing to do with the '11 at all :-)

> years I have been using a compiler which allows a bit within a
> register to be defined with a name. Example: #bit mybit = PortA.1
> This will give bit 1 of PortA the name mybit which can be used for
> read and write operations of that bit.

> I am returning to a compiler used for a 11F1 processor which does not
> have this #bit function and would like some feedback on how to
> implement this function in C code. I have looked at using struct's

You now understand the importance of writing portable code. The use
of struct and union is inadvisable, as there is no standard for
how they get implemented.

> and union's which can be used to point to the bit but my code to set,
> clear or read the bit is not clean.

> Does anyone out ther have any pointers on how to write this #bit
> function.

Yes, of course.

I do sth like this...

in

#ifndef BIT0

#define BIT0 0x01
#define BIT1 0x02
...
#define BIT7 0x80

#endif

in

#ifndef M6811_H_INCLUDED
#define M6811_H_INCLUDED
#include

typedef volatile unsigned char REG8;
typedef volatile unsigned short int REG16;

/* note that the above presumes that a short int is 16 bits*/
/* with a "modern" compiler, one would use a guaranteed */
/* size integer type instead, like the following */

/* typedef volatile uint8_t REG8 */
/* typedef volatile uint16_t REG16 */

#define REGBASE (unsigned char *)0x1000

/* one could also make it an extern */
/* extern unsigned char REGBASE[]; */

#define PORTAo 0x00
#define PORTAadr ((REG8 *)((REGBASE)+PORTAo))
#define PORTA (*PORTAadr)

/* one could also omit the PORTAadr and just do...*/
/* #define PORTA (*(REG8 *)((REGBASE)+PORTAo) */
/* or even omit the offset, but that sometimes comes */
/* in handy */
...

#endif

in an include file particular to my project



#ifndef MOTOR_H_INCLUDED
#define MOTOR_H_INCLUDED

#define MOTOR_ENABLE_PORT PORTA
#define MOTOR_ENABLE_BIT BIT3
#define MOTOR_ON MOTOR_ENABLE_BIT
#define MOTOR_OFF 0
#define MOTOR_ENABLE(Value) (MOTOR_ENABLE_PORT= \
(MOTOR_ENABLE_PORT & ~MOTOR_ENABLE_BIT)| Value)

#define MOTOR_DIRECTION_PORT PORTA
#define MOTOR_DIRECTION_BIT BIT2
#define MOTOR_DIRECTION_LEFT MOTOR_DIRECTION_BIT
#define MOTOR_DIRECTION_RIGHT 0
#define MOTOR_DIRECTION(Direction) \
(MOTOR_DIRECTION_PORT = \
(MOTOR_DIRECTION_PORT & ~MOTOR_DIRECTION_BIT) | \
Direction)
#endif

Now you can write portable code like

#include

MOTOR_ENABLE(MOTOR_ON);
MOTOR_ENABLE(MOTOR_OFF);
MOTOR_DIRECTION(MOTOR_DIRECTION_LEFT);

etc.

Slightly safer code is...

#define MOTOR_ENABLE(Value) (MOTOR_ENABLE_PORT= \
(MOTOR_ENABLE_PORT & ~MOTOR_ENABLE_BIT) | \
(Value)?MOTOR_ENABLE_BIT:0)

#define MOTOR_DIRECTION(Direction) \
(MOTOR_DIRECTION_PORT = \
(MOTOR_DIRECTION_PORT & ~MOTOR_DIRECTION_BIT) | \
(Direction)==MOTOR_DIRECTION_LEFT ? \
MOTOR_DIRECTION_LEFT : 0)

It's not as concise or as pretty, perhaps, and maybe a little
more work, but it is almost absolutely portable to any
C89 ANSI compiler. For a C99 ANSI compiler, one can specify
the exact sizes of integers. In that case, I would use

uint8_t
uint16_t

for the exact size integers. This would give complete portability
to all C99 ANSI compilers.

Or you can use structs and have to modify your code yet again
when a new version comes out, or you change compilers again,
or whatever.

Try to make sure that your macroes do not ever evaluate their
arguments more than one time, to avoid surprising side effects.
Do not, for example, use

#define MOTOR_DIRECTION(Direction) \
(MOTOR_DIRECTION_PORT = \
(MOTOR_DIRECTION_PORT & ~MOTOR_DIRECTION_BIT) | \
(Direction)==MOTOR_DIRECTION_LEFT ? \
(Direction) : 0)

Mike
--
p="p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
Oppose globalization and One World Governments like the UN.
This message made from 100% recycled bits.
You have found the bank of Larn.
I can explain it for you, but I can't understand it for you.
I speak only for myself, and I am unanimous in that!
PFC wrote:

> > It has nothing to do with the '11 at all :-)

> Surprisingly enough it does, for my query. I am porting code to the
> ICC compiler for some 11F1 applications for test purposes. I agree
> that this could be a generic C code question also.

No, this is _only_ "a generic C code question" IMNSHO.

> > You now understand the importance of writing portable code. The use
> > of struct and union is inadvisable, as there is no standard for
> > how they get implemented.

> One tends to use the tools currently available. The other compiler

you can use them right or wrong, for example...

> gave the option for the use of a #BIT operator which allowed the

...using proprietary functions without need (!) is usually a bad
idea.

> direct manipulation and reading of a bit within a register. This
> proved to be very beneficial as it kept the code very clean.

Mike showed you how to keep the code clean with portable code.

> Example:
> #bit mybit = porta.1
> Then one could read or write that bit as follows;
> Mybit = 1;
> or
> If(!mybit);

> I agree that using operators specific to a compiler is not the best
> policy. What I wanted to do was see if there was a method of
> implementing this function in a generic fashion to suit the ICC
> compiler, or in fact any compiler.

read again and try to understand.

> The use of unions did allow a neat way of pointing at a bit and I

but _which_ bit does it point to? And how can you be sure how the bit
will be accessed, e.g. with byte or word accesses?

> thought that unions were common among most compilers.

Read the C standard, ISO/IEC 9899:1999 is cheap.

Read the compiler manual(s).

> Thank you for the code examples. I will need to work through them but
> it still looks like calling a function to set or clear or read the
> bit.

No, it's no function. A good compiler will generate optimal code. The
only issue is that the port definitions are not in the debugger
output file.

BTW: please trim your line length to 70 characters and don't top
post.

Oliver
--
Oliver Betz, Muenchen
PFC schrieb:
> Bob,
> Thank you for your reply.
> I was looking for something which was a bit cleaner than the bit toggling.

You can't avoid bit toggling, that's the way the processor works.
But you can hide it.
(Note: the following #defines should be on one line each and one
#define on each line, maybe the mail client inserts line breaks)

#define CONCAT(x,y) (x ## y)
#define BIT_TOGGLE(x) (CONCAT(x, _PORT) ^= (1<< CONCAT(x, _PIN)))
#define BIT_CLEAR(x) (CONCAT(x, _PORT) &= ~(1<< CONCAT(x, _PIN)))
#define BIT_SET(x) (CONCAT(x, _PORT) |= (1<< CONCAT(x, _PIN)))
#define BIT_FORCE(x, bValue) {if(bValue)
{BIT_SET(x);}else{BIT_CLEAR(x);}}
#define BIT_READ(x) (CONCAT(x, _INPORT) & (1<< CONCAT(x, _PIN)))
#define BIT_SETOUTPUT(x) (CONCAT(x, _DDR) |= (1<< CONCAT(x, _PIN)))
#define BIT_SETINPUT(x) (CONCAT(x, _DDR) &= ~(1<< CONCAT(x, _PIN)))
Make this four defines for each pin:
#define EN_PIN PB5
#define EN_PORT PORTB
#define EN_INPORT PINB
#define EN_DDR DDRB
Then us it like this:
BIT_SET_OUTPUT( EN ); //EN is an output
BIT_SET( EN ); //Enable the ???
BIT_CLEAR( EN ); // and disable it
BIT_FORCE( EN, b ); //Force EN to the state in the variable'b'

regards
Edi