Pin Mask Conventions for Embedded Development - c

For embedded C applications I have always used the following convention for defining GPIO pin masks:
'Traditional' Example: 32-bit CPU with 32-bit GPIO port
Assert bit5 in the GPIO output register to turn an led on.
#define BIT5 (1u << 5) //or maybe even just hardcode as 0x20
...
#define PIN_LED_CTRL (BIT5) //LED_CTRL is Pin #5
...
void gpio_set(uint16_t pin_mask) {
GPIO_OUT |= pin_mask;
}
...
//turn the led on
gpio_set(PIN_LED_CTRL);
On a recent multi-developer embedded project, one developer has chosen the following syntax
'Alternative Example: 32-bit CPU with 32-bit GPIO port
#define PIN(x) (1u << (x##_PIN_NUM))
...
#define LED_CTRL_PIN_NUM (5)
...
void gpio_set(uint16_t pin_mask) {
GPIO_OUT |= pin_mask;
}
...
//turn the led on
gpio_set(PIN(LED_CTRL));
No real clear explanation of why this was chosen was given. As with all lightly documented code, it seems mysterious enough to 'cleary' warrant its implementation. Surely the developer knew something I did not. And in this case, the guy is a smart cookie from the CPU-driver world.
Objection
I don't like the 'alt' method at all. It seems too cute for its own good. But the only justifications I can give are:
'LED_CTRL' is not a compile time constant
additionally you then can't descend/inspect it within an IDE
'LED_CTRL_PIN_NUM' is the complete opposite of a uri-naming-schema
e.g. PIN_NUM_abc is preferred
No one else does it*
It looks weird
But this just appears to me like complaining; none of these are real objections
to using the 'alt' method.
Question
Why would someone use the 'alt' method at all? Is this a hand-me-down from register-usage in the desktop driver land perhaps?
Do any common embedded MCU libraries, alternative targets or programming languages use this 'alt' method?
Thanks!
*at the end of the day; I'm likely to stick with 'it looks weird' :).

Both methods are nearly the same, only the style is different, but the problems are the same.
Normally a pin isn't defined by a bit number only, you also need to know the port.
So when changing the port, you need to modify not only the definitions, you also need to modify code.
#define PIN_LED_CTRL (BIT5) //LED_CTRL is Pin #5
...
void gpio_set_port2(uint16_t pin_mask) {
GPIO2_OUT |= pin_mask;
}
...
//turn the led on
gpio_set_port2(PIN_LED_CTRL);
I prefere to define the pin only once and all the different dependencies are build by macros or in functions.
#define HW_SPI_CLOCK 2,5 // uses port2,bit5
#define HW_RESET_EXT 4,3 // uses port4,bit3
Then I use some macros to define get the port direction, pushPull and other registers.
These macros depends hardly on the plattform and the toolchain.
/**
* Generic GH-Macros
*/
#define PASTE2(a,b) a##b
#define PASTE3(a,b,c) a##b##c
#define __PASTE3(a,b,c) PASTE3(a,b,c)
#define PASTE4(a,b,c,d) a##b##c##d
#define PASTE6(a,b,c,d,e,f) a##b##c##d##e##f
#define __PASTE6(a,b,c,d,e,f) PASTE6(a,b,c,d,e,f)
#define GH_PORT(port,pin) port
#define GH_PIN(port,pin) pin
#define GPIO_PIN(gh) __PASTE6(FIO,GH_PORT(gh),PIN_bit.P,GH_PORT(gh),_,GH_PIN(gh))
#define GPIO_DIR(gh) __PASTE6(FIO,GH_PORT(gh),DIR_bit.P,GH_PORT(gh),_,GH_PIN(gh))

With the first method, the compiler will interpret the last line as following:
gpio_set(((1u << 5)));
And with the second method, the compiler will interpret the last line as following:
gpio_set((1u << ((5)));
You may fail to count without me saying it, but there is a parenthesis issue there. Either you have mistyped the #define PIN(x) (1u << x##_PIN_NUM) as #define PIN(x) (1u << (x##_PIN_NUM), or the one that you call looks weird won't even work.
In case you have simply just mistyped it, then both of them get simplified into the same thing:
gpio_set(1u << 5);
In the end, it is just a matter of style.
Note: If you are asking for opinions, you shouldn't.
Edit #1:
Okay, with the second approach, assuming that there are some other special pins, you can do things like this:
#define NAMEFOR0_PIN_NUM (0)
#define NAMEFOR1_PIN_NUM (1)
#define NAMEFOR2_PIN_NUM (2)
#define NAMEFOR3_PIN_NUM (3)
#define NAMEFOR4_PIN_NUM (4)
#define LED_CTRL_PIN_NUM (5)
#define NAMEFOR6_PIN_NUM (6)
#define NAMEFOR7_PIN_NUM (7)
#define NAMEFOR8_PIN_NUM (8)
// and so on...
#define PIN(x) (1u << (x##_PIN_NUM))
...
// and then gpio_set(PIN(nameyouwant)) whichever pin you want
// for example
gpio_set(PIN(LED_CTRL));
// or
gpio_set(PIN(NAMEFOR3));
However, I personally wouldn't do it with token concatenation; I would rather directly define like:
#define LED_CTRL 5
...
#define PIN(x) (1u << x)
...
gpio_set(PIN(LED_CTRL));
But then again, if you take this literally, defining LED_CTRL as 5 would imply LED_CTRL is 5, although actually rather it's pin number is 5. So it would make more sense to use it that way, the alternate way you've shown. Both more natural and makes literal sense, so, yeah...
Edit #2:
Of course, you could do something for the traditional approach as well, but then you'd have to write more lines, more defines:
#define BIT0 (1u << 0)
#define BIT1 (1u << 1)
...
#define BIT5 (1u << 5)
// and so on...
#define PIN_NAMEFOR0 (BIT0)
#define PIN_NAMEFOR1 (BIT1)
...
#define PIN_LED_CTRL (BIT5)
// and so on...
#define PIN(x) (1u << (x##_PIN_NUM))
...
// and then gpio_set(PIN_nameyouwant) whichever pin you want
// for example
gpio_set(PIN_LED_CTRL);
// or
gpio_set(PIN_NAMEFOR3);
It still makes just as much syntactic sense, but requires more lines to get written...

Assuming a typo in the "Alternative" example (in the last line, where you specify "LED_CTRL", which is not defined... I assume you meant "LED_CTRL_PIN_NUM"), then I believe these two examples will produce identical machine code. So, between these two choices... it's just a matter of style preference. (the ## in the second example is just an embedded comment.)
Personally, I would use a different approach entirely. I would use the built-in bit-field construct to modify a bit-wise field, and that way the compiler can decide what is the most efficient way to do this. Example follows:
struct {
unsigned int :4, LED_CTRL:1, :27;
} GPIO_OUT;
...
GPIO_OUT.LED_CTRL = 1;
Note that the ":4" and ":27" refer to the other bits in the register... you would likely want to map the entire I/O register, not just one bit of it.

Bitfields: SGeorgiades put an answer above that is risky business*
if you're making use of C Bitfields to define your pins, be very darn careful with it.
bitfield 'type' is implementation-dependent (needs quote; int/uint)
fields aren't contiguous bitwise by default and get promoted to impl-dependent size
bitfields that span across the int-bitsize boundary will not be contiguous in bitfield-mapping! (needs quote)
for GCC/C11 the following bitfield-syntax is what I would use (if I were to use it)
struct gpio_out {
int b0 : 1;
int led_ctrl : 1;
....
int b30 : 1;
int b31 : 1;
} __attribute__((packed));
Notes
by merging the concept of pin location into the struct, you can't share it with other
registers in gpio (i.e. maybe DIR, IN, INT_EN, IFG, etc).
I will put up x86 disassembly examples of the points made here tmrw. they are very dependent on implementation and compiler configuration!
*correct me if I'm mistaken.

Related

Programming AVR in C

I'm using an Atmega328. I have output pins that are "randomly" distributed along the pinout, i.e. they don't belong to the same ports. For example, my output pins could be PB0, PB4, PC1, PC3 and PD1.
I have always used Assembly to program microcontrollers, so this would be my first time using C. What I want to know is if there is a way to avoid using DDRx and Px for each pin to set them or clear them.
For example, I would like to use something like this to set the first bit of Port B:
#define NAME_1 DDRB,0
sbi NAME_1;
Is this possible?
EDIT:
Maybe I didn't express myself clearly. What I want is to be able to refer to certain I/O port pins with some meaningful names. For example, name PD3 "blue_LED", so that the code is more readable and, if the blue LED's position is changed later, the code can be easily modified. Stated another way, I want to be able to turn on and off certain pins with their names not being hard-coded. Is there a way?
The sbi instruction is special in that it directly manipulates a bit in an I/O Port on the AVR platform. The normal course with I/O ports is that you have to use other instructions (like out) to copy whole words between the I/O port and a register.
That said, there's no sbi in C. C just doesn't know about these special features of one particular platform. For the assembly you give as an example, you would write in C:
DDRB |= 1<<0;
I personally think this looks quite concise, but of course you COULD define a macro
#define sbi(x,b) (x) |= 1<<(b)
sbi(DDRB, 0);
(where b is the "bit number") and maybe the other way around
#define cbi(x,b) (x) &= ~(1<<(b))
cbi(DDRB, 0)
This would work, but I recommend not to use it. While the first notation DDRB |= 1<<0; is obvious to any C programmer, using macros like this probably isn't.
As a final note, if you are concerned about performance: I haven't verified this, but I'm pretty sure avr-gcc is smart enough to emit sbi and cbi instructions when a bit mask operation on an I/O port effectively just changes a single bit. edit: see JLH's answer for an experimental result that gcc-avr indeed is smart enough to emit these sbi/cbi instructions.
I use avg-gcc on to program Atmel AVRs and the support packages most definitely know about cbi, sbi, and all instructions for that matter. So there's no need to resort to assembly unless you want to. Here's some disassembled C to prove it.
PORTD |= (1 << PD0);
d8: 58 9a sbi 0x0b, 0 ; 11
Now I'll show you how. You can set each bit of each port to do either input or output very easily.
DDRA |= (1<<PA0);
has the effect of making pin 0 on port A an output as shown:
bit76543210
00000001 // or-ing the 1 adds 1 leaving the other bits alone.
To also make pin A3 an output, do this:
DDRA |= (1<<PA3);
bit76543210
00001001 // now the DDRA register looks like this, pins 0 and 3 set as outputs
Tedious, right? Well, these right-side expressions evaluate to constants so you can combine these into one statement:
DDRA |= (1<<PA0) | (1<<PA3);
and the compiler will fold the right hand side into one constant and |= it into the register. So, you really need only one statement like this per port, and the compiler makes it very efficient.
That takes care of direction -- input or output. The next is to set and clear outputs.
To set an output:
PORTD |= (1<<PD); // turns pin 0 on port D on (high) as an output.
PORTD &= ~(1<<PD); // turns pin 0 on port D off (low) as an output.
PORTD ^= (1<<PD); // toggles it (high-> low) or (low->high as an output.
EDIT:
To the extra requirements you named about using meaningful names, of course you can do that. I routinely do this to avoid having to remember what's connected to what. For example, from that same project:
#define LED_INDICATOR_PIN PA0
#define LED_INDICATOR_PORT PORTA
#define LED_INDICATOR_DDR DDRA
I refer to the 'friendly' names in my code:
void initialize(void)
{
// Set up an output pin to blink an LED to show sign of life.
LED_INDICATOR_DDR |= (1 << LED_INDICATOR_PIN);
// Set up TTY port.
init_uart();
}
void toggleLED(void)
{
LED_INDICATOR_PORT ^= (1 << LED_INDICATOR_PIN);
}
Much easier to read. Is that what you're after? I know it's what I do every time.
With C++ I wrote something like this:
//IO = I/O Subsystem
inline void Io_LEDred_Configure() {DDRB |= 1<<0; } //Port B0
inline void Io_LEDred_On() {PORTB |= 1<<0; }
inline void Io_LEDred_Off() {PORTB &= ~(1<<0);}
inline void Io_LEDgreen_Configure() {DDRD |= 1<<3; } //Port D3
inline void Io_LEDgreen_On() {PORTD |= 1<<3; }
inline void Io_LEDgreen_Off() {PORTD &= ~(1<<3);}
If you have to switch an IO to a different port you have to change only those three lines and you're done.
In C++ the compiler emits exactly that code what you as an assembler coder would write. In C you have to use a regular function. But the calls coming with some overhead. If you want to avoid this you have to use macros:
#define IO_LEDRED_CONFIGURE DDRB |= 1<<0
#define IO_LEDRED_ON PORTB |= 1<<0
...

Atmel C Pin Manipulation Macros

So I have been programming in Atmel C for a while and I have gotten used to all the C bit manipulation, so now I want to hide it. I want to hide the bit manipulation not only to make my code more readable but also make it easier to maintain and modify in case our hardware changes or we make new hardware.
So I am asking you what are the best macros for Atmel C for basic pin manipulation.
The features I am looking for are:
Set a Pin to be Input or Output
Set an Output Pin HIGH or LOW
Read the Value of an Input Pin
So I have found a few macros that I could use but none really fit my bill.
Links:
http://www.piconomic.co.za/fwlib/group___a_v_r___p_i_o.html (still have to keep multiple defines per pin)
http://www.starlino.com/port_macro.html (doesn't compile, AVR Studio 6.2)
Changing a global variable in C (best one, near the top of the question under "/* LCD DEFINES */"
What I would really like is something like this:
#define LED1 PA1
#define BUTTON1 PB0
set_output(LED1);
output_high(LED1);
delay_ms(100);
output_low(LED1);
set_input(BUTTON1);
uint8_t tmpVal = get_input(BUTTON1);
if( tmpVal == 1 )
{
// assuming button IS pressed here
}
else
{
// assuming button IS NOT pressed here
}
Any ideas on the cleanest way to do this?
I could handle keeping around a few more defines per pin but I feel like that shouldn't be needed. Shouldn't PA1 and PB0 be able to tell us everything or do they get defined into a single value?
EDIT: Using Atmel Studio 6.2 on Windows
Thanks,
Rob R.
Nevermind this does compile
http://www.starlino.com/port_macro.html
// MACROS FOR EASY PIN HANDLING FOR ATMEL GCC-AVR
//these macros are used indirectly by other macros , mainly for string concatination
#define _SET(type,name,bit) type ## name |= _BV(bit)
#define _CLEAR(type,name,bit) type ## name &= ~ _BV(bit)
#define _TOGGLE(type,name,bit) type ## name ^= _BV(bit)
#define _GET(type,name,bit) ((type ## name >> bit) & 1)
#define _PUT(type,name,bit,value) type ## name = ( type ## name & ( ~ _BV(bit)) ) | ( ( 1 & (unsigned char)value ) << bit )
//these macros are used by end user
#define OUTPUT(pin) _SET(DDR,pin)
#define INPUT(pin) _CLEAR(DDR,pin)
#define HIGH(pin) _SET(PORT,pin)
#define LOW(pin) _CLEAR(PORT,pin)
#define TOGGLE(pin) _TOGGLE(PORT,pin)
#define READ(pin) _GET(PIN,pin)
/*
BASIC STAMPS STYLE COMMANDS FOR ATMEL GCC-AVR
Usage Example:
———————————————–
#define pinLed B,5 //define pins like this
OUTPUT(pinLed); //typo fixed
//OUTPUT(pinLED); //compiles as DDRB |= (1<<5);
HIGH(pinLed); //compiles as PORTB |= (1<<5);
———————————————–
*/
There is just one typo which I have fixed

C preproc: pasting valid token and value of a token

I am working with an STM32F1 microcontroller, for which a header is provided that defines bit masks and values for registers as follows:
#define RCC_CFGR_PLLMULL //Mask of PLL multiplier setting bits
#define RCC_CFGR_PLLMULL1 //Value of PLL multiplier bits for PLL x1
#define RCC_CFGR_PLLMULL2 //Value of PLL multiplier bits for PLL x2
#define RCC_CFGR_PLLMULL3 //Value of PLL multiplier bits for PLL x3
etc etc.
What I want to do is define my PLL multiplier as an integer so I can use it to derive the clock value - ie PLLCLK = IN_CLK * PLL_MULT - and paste the value onto RCC_CFGR_PLLMULL to obtain the correct setting bits. The macros I would normally use for this are as follows:
#define APPEND_VAL_HELPER(A, B) A##B
#define APPEND_VAL(A, B) APPEND_VAL_HELPER(A,B)
Then if I define SOME_NUM as, say, 123:
#define FOO APPEND_VAL(BAR, SOME_NUM)
Results in the FOO defining as BAR123. Normally this works. Here's the problem: in this case, RCC_CFGR_PLLMULL is a valid token before being pasted. This results in it expanding in the invocation of APPEND_VAL and I get something like ((uint32_t)0x003C0000)123. I can't figure out how to get B to expand without also expanding A, at least in GCC. There are workarounds to this but I'm looking for a clean solution. Does it exist?
I'm not sure what you would consider a "clean" solution, but this works for me and doesn't seem too bad:
/* target header */
#define RCC_CFGR_PLLMULL 0x003C
#define RCC_CFGR_PLLMULL1 0x0003
/* pasting macros */
#define APPEND_VAL_HELPER(A, B) A ## B
#define APPEND_VAL(A, B) APPEND_VAL_HELPER(A, B)
#define RCC_CFGR(T, N) APPEND_VAL(RCC_CFGR_, APPEND_VAL(T, N))
You use that as, for example,
#define FOO RCC_CFGR(PLLMUL, 1)
You can also do
#define BAR RCC_CFGR(PLLMUL, )
to define BAR to RCC_CFGR_PLLMUL (no tail).
Obviously, this is specific to a subset of possible target macros, but it does the job and reads cleanly. To the best of my knowledge there is no way to write a fully general token-pasting macro -- those that are most general suffer from issues such as the one you described.

LUT in a macro C

I am currently working on setting up a framework in C for usage between several microcontrollers.
The framework has to carry all device specific code, so the application only contains the abstract usage of peripherals (like SerialPort_Read, write, SetBaudRate, etc etc.)
One of the things I am struggling with to find a solution for in C are the I/O pin map. I've seen projects (like the very very popular Arduino) where the pin map is putten in a LUT (look up table) which is used during runtime. However, this LUT will never be modified during runtime, so there is no use to have this in the memory.
For example, this function resolves some bit indexes and registers from some 'const uint' tables, and either sets or clears a bit:
void pinMode(uint8_t pin, uint8_t mode)
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *reg;
if (port == NOT_A_PIN) return;
// JWS: can I let the optimizer do this?
reg = portModeRegister(port);
if (mode == INPUT) {
uint8_t oldSREG = SREG;
cli();
*reg &= ~bit;
SREG = oldSREG;
} else {
uint8_t oldSREG = SREG;
cli();
*reg |= bit;
SREG = oldSREG;
}
}
Because this is actual C code running on the controller it's draining effiency and speed. I'd rather define some sort of macro that does the same thing, but is already resolved during compilation to a 'one-liner' that can be compiled much more efficiently:
GPIO_Write(PORTA, 5, 1); // Write '1' to pin 5 on PORTA
> LATA |= 1<<5; // Sets bit 5 high
GPIO_Tris(PORTA, 4, OUTPUT); // Set pin 4 on PORTA to output
> PORTA &= ~(1<<4); // sets pin 4 as output I/O type
Does anyone know if it's possible (and how) to define and use a look-up table with a macro in C?
At this moment I am using the MicroChip C30 compiler, which I believe is based in GCC. It's supposed to be portable between different compilers, including MicroChip C18, C32 and in further also ARM and AVR.
For your specific example, something along these lines will work:
#define WRITE_PORTA LATA
#define GPIO_Write(port, pin, value) \
(value ? WRITE_##port |= (1U << (pin)) \
: WRITE_##port &= ~(1U << (pin)))
#define INPUT 0
#define OUTPUT 1
#define GPIO_Tris(port, pin, direction) \
((direction) == INPUT ? port |= (1U << (pin)) \
: port &= ~(1U << (pin)))
You'll have to make sure to define LATA and PORTA in a way the system will understand - in particular trying to overload its meaning the way it seems to be in your example might be hard to resolve.
Which processor or microcontroller are you targeting?
You might be underestimating the usefulness of the LUT.
For many processors, the LUT does more than map a 'logical' pin number to a single value, the 'physical' pin number. The LUT maps the 'logical' pin number to several pieces of information.
In general, the 'logical' pin is mapped to the port address of the appropriate read/input or write/output register, and the bit offset within the read or write register. So the pin value, on many MCU's, is really mapped to a struct. It might also include a mapping to the data direction register and fields within it, as well as registers which set the state of pull-up or pull-down resistors.
For example, I have code to multiplex a 8x8 display. At run-time, I need to use pinMode to turn a pin from an output to a high impedance input, and so that information needs to be encoded somehow.
It is possible to do this sort of thing, with some ingenuity, on some MCU's.
ARM MCU's (and I believe 8051, though I've never used one) using 'bit band addressing' http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0179b/CHDJHIDF.html
This assigns a unique memory address for each port pin, and fixed offsets can derive the address of the pin for the other data register, and other functions. This is not magic, the code encodes the information that is often stored in the LUT.
For other MCU's, they really do need both port and bit position, so it is two values for each pin number.
If you are willing to ditch the idea of using integers for pins, and instead use names, like P0, P1, then you could initialise a lot of const struct's, one per pin name, and your functions would take the const struct values. The struct would contain the initialised port and bit offset or bit mask values. The compiler may be able to optimise for speed. This would avoid having a LUT, but would still use similar amounts of space for pins that are used. You might be able to arrange it so that unused pins would not need to be included in the code, and hence saving space.
Edit: If you are willing to use C++, I'd suggest C++ templates which can give a much better solution than macros. They can be type safe, and are often easier to debug (if you have hardware debugging, e.g. JTAG and gdb)
Consider the following macro:
#define write(port, pin, value) do { \
if (value) \
LAT##port |= 1 << pin; \
else \
LAT##port &= ~(1 << pin); \
} while (0)
Usage:
write(A, 3, 1); // compiles to LATA |= 1 << 3;
write(B, 2, 0); // compiles to LATB &= ~(1 << 2);
Is that the kind of thing you were after?
I've seen it done (https://github.com/triffid/Teacup_Firmware/blob/Gen7/arduino.h) with a couple macros:
/// Read a pin
#define _READ(IO) (IO ## _RPORT & MASK(IO ## _PIN))
/// write to a pin
#define _WRITE(IO, v) do { if (v) { IO ## _WPORT |= MASK(IO ## _PIN); } else { IO ## _WPORT &= ~MASK(IO ## _PIN); }; } while (0)
/// set pin as input
#define _SET_INPUT(IO) do { IO ## _DDR &= ~MASK(IO ## _PIN); } while (0)
/// set pin as output
#define _SET_OUTPUT(IO) do { IO ## _DDR |= MASK(IO ## _PIN); } while (0)
// why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
/// Read a pin wrapper
#define READ(IO) _READ(IO)
/// Write to a pin wrapper
#define WRITE(IO, v) _WRITE(IO, v)
/// set pin as input wrapper
#define SET_INPUT(IO) _SET_INPUT(IO)
/// set pin as output wrapper
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
with:
#define DIO0_PIN PIND0
#define DIO0_RPORT PIND
#define DIO0_WPORT PORTD
#define DIO0_PWM &OCR0B
#define DIO0_DDR DDRD
#define DIO1_PIN PIND1
#define DIO1_RPORT PIND
#define DIO1_WPORT PORTD
#define DIO1_PWM &OCR2B
#define DIO1_DDR DDRD
...
You could modify the macros to take straight integers rather than DIOn

#define PORTX.x in Avr Studio 5 (ATmega16)

I'm writing a new and special library whith new algorithms and abilities for KS0108 GLCD Driver. I'm using ATMega16. My dot matrix GLCD dimension is 128x64.
How can I use #define code to define different port pins?
for example: #define GLCD_CTRL_RESTART PORTC.0
IDE: AVR Studio 5
Language: C
Module: 128x64 dot matrix GLCD
Driver: KS0108
Microcontroller: ATMega16
Please explain which headers I should use? and also write a full and very simple code for ATMEga16.
In ATmega, pin values are assembled in PORT registers. A pin value is the value of a bit in a PORT. ATmega doesn't have a bit addressable IO memory like some other processors have, so you cannot refer to a pin for reading and writing with a single #define like you suggest.
What you can do instead, if it helps you, is to define macros to read or write the pin value. You can change the name of the macros to suit your needs.
#include <avr/io.h>
#define PORTC_BIT0_READ() ((PORTC & _BV(PC0)) >> PC0)
#define WRITE_PORTC_BIT0(x) (PORTC = (PORTC & ~_BV(PC0)) | ((x) << PC0))
uint8_t a = 1, b;
/* Change bit 0 of PORTC to 1 */
WRITE_PORTC_BIT0(a);
/* Read bit 0 of PORTC in b */
b = PORTC_BIT0_READ();
thanks a lot, but i found this answer in AVR Freaks at here:
BV=Bit Value.
If you want to change the state of bit 6 in a byte you can use _BV(6) which is is equivalent to 0x40. But a lot us prefer the completely STANDARD method and simply write (1<<6) for the same thing or more specifically (1<<<some_bit_name_in_position_6)
For example if I want to set bit 6 in PORTB I'd use:
Code:
PORTB |= (1 << PB6);
though I guess I could use:
Code:
PORTB |= _BV(6);
or
Code:
PORTB |= _BV(PB6);
But, like I say, personally I'd steer clear of _BV() as it is non standard and non portable. After all it is simply:
Code:
#define _BV(n) (1 << n)
anyway.
Cliff

Resources