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
Reply by Oliver Betz●March 14, 20072007-03-14
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
Reply by PFC●March 14, 20072007-03-14
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.
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 */
/* 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 */
...
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
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!
Reply by PFC●March 14, 20072007-03-14
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.
**************************************
Reply by Mike McCarty●March 14, 20072007-03-14
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.
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 */
/* 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 */
...
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
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!
Reply by BobG...@aol.com●March 13, 20072007-03-13
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.
Reply by PFC●March 13, 20072007-03-13
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.