====== Pin Operationen ======
Der folgende Code vereinfacht Operationen mit den AVR Pins.
* {{examples:pinops.h|pinops.h}}
//
// AVR IO pin simple operation macros
//
// Mikk Leini
// Department of Mechatronics
// Tallinn University of Technology
// 2009
//
//
// Gewoehnliche Funktionen zur Bit-Manipulation
//
#define BIT(x) (1 << (x))
#define SET_BIT(value, bit) value |= BIT(bit)
#define CLEAR_BIT(value, bit) value &= ~BIT(bit)
#define INVERT_BIT(value, bit) value ^= BIT(bit)
#define SET_BIT_TO(value, bit, state) value = ((state) ? (value | BIT(bit)) : (value & ~BIT(bit)))
#define IS_BIT_SET(value, bit) ((value) & (BIT(bit)))
//
// Funktionen zur Bit-Manipulation mit einer Bitmaske
//
#define SET_BITMASK(value, bitMask) value |= (bitMask)
#define CLEAR_BITMASK(value, bitMask) value &= ~(bitMask)
#define INVERT_BITMASK(value, bitMask) value ^= (bitMask)
#define SET_BITMASK_TO(value, bitMask, state) value = ((state) ? (value | (bitMask)) : (value & ~(bitMask)))
#define IS_BITMASK_SET(value, bitMask) ((value) & (bitMask))
//
// Einfache Port Operationen
//
// Methode 1
//
// Wenig Code, aber ermoeglicht nicht die Pin Value als Expression zu bekommen
//
#define PORTPIN(portChar, bitIndex) \
DDR ## portChar = simple_dir_op(DDR ## portChar, bitIndex); \
PORT ## portChar = simple_port_op(PORT ## portChar, bitIndex); \
simple_pin_op(PIN ## portChar, bitIndex);
#define setup_output_pin(simplePin) \
{ \
inline unsigned char simple_dir_op(unsigned char value, unsigned char bit) { return value | BIT(bit); } \
inline unsigned char simple_port_op(unsigned char value, unsigned char bit) { return value; } \
inline void simple_pin_op(unsigned char value, unsigned char bit) { } \
simplePin \
}
#define setup_input_pin(simplePin) \
{ \
inline unsigned char simple_dir_op(unsigned char value, unsigned char bit) { return value & ~BIT(bit); } \
inline unsigned char simple_port_op(unsigned char value, unsigned char bit) { return value | BIT(bit); } \
inline void simple_pin_op(unsigned char value, unsigned char bit) { } \
simplePin \
}
#define setup_tristate_input_pin(simplePin) \
{ \
inline unsigned char simple_dir_op(unsigned char value, unsigned char bit) { return value & ~BIT(bit); } \
inline unsigned char simple_port_op(unsigned char value, unsigned char bit) { return value; } \
inline void simple_pin_op(unsigned char value, unsigned char bit) { } \
simplePin \
}
#define set_pin(simplePin) \
{ \
inline unsigned char simple_dir_op(unsigned char value, unsigned char bit) { return value; } \
inline unsigned char simple_port_op(unsigned char value, unsigned char bit) { return value | BIT(bit); } \
inline void simple_pin_op(unsigned char value, unsigned char bit) { } \
simplePin \
}
#define clear_pin(simplePin) \
{ \
inline unsigned char simple_dir_op(unsigned char value, unsigned char bit) { return value; } \
inline unsigned char simple_port_op(unsigned char value, unsigned char bit) { return value & ~BIT(bit); } \
inline void simple_pin_op(unsigned char value, unsigned char bit) { } \
simplePin \
}
#define set_pin_to(simplePin, newState) \
{ \
inline unsigned char simple_dir_op(unsigned char value, unsigned char bit) { return value; } \
inline unsigned char simple_port_op(unsigned char value, unsigned char bit) \
{ \
return ((newState) ? (value | BIT(bit)) : (value & ~BIT(bit))); \
} \
inline void simple_pin_op(unsigned char value, unsigned char bit) { } \
simplePin \
}
#define toggle_pin(simplePin) \
{ \
inline unsigned char simple_dir_op(unsigned char value, unsigned char bit) { return value; } \
inline unsigned char simple_port_op(unsigned char value, unsigned char bit) { return value ^ BIT(bit); } \
inline void simple_pin_op(unsigned char value, unsigned char bit) { } \
simplePin \
}
#define get_pin_value(simplePin, variable) \
{ \
inline unsigned char simple_dir_op(unsigned char value, unsigned char bit) { return value; } \
inline unsigned char simple_port_op(unsigned char value, unsigned char bit) { return value | BIT(bit); } \
inline void simple_pin_op(unsigned char value, unsigned char bit) { variable = IS_BIT_SET(value, bit); } \
simplePin \
}
//
// Einfache Port Operationen
//
// Methode 2
//
// Ermoeglicht die Pin Value als Expression zu bekommen
// dafür allerdings Hardware-spezifisch
//
/*
#define SIMPLEPORT_A 0x0100
#define SIMPLEPORT_B 0x0200
#define SIMPLEPORT_C 0x0400
#define SIMPLEPORT_D 0x0800
#define SIMPLEPORT_E 0x1000
#define SIMPLEPORT_F 0x2000
#define SIMPLEPORT_G 0x4000
#define SIMPLEPORT_H 0x8000
#define PORTPIN(portChar, bitIndex) SIMPLEPORT_ ## portChar | (1 << bitIndex)
#define SIMPLE_PORT_CHECK(simplePin, portChar) ((simplePin) & SIMPLEPORT_ ## portChar)
#define SIMPLE_PIN_VALUE(simplePin) (simplePin) & 0x00FF
#define set_pin(simplePin) \
{ \
if SIMPLE_PORT_CHECK(simplePin, A) SET_BITMASK(PORTA, SIMPLE_PIN_VALUE(simplePin)); \
if SIMPLE_PORT_CHECK(simplePin, B) SET_BITMASK(PORTB, SIMPLE_PIN_VALUE(simplePin)); \
if SIMPLE_PORT_CHECK(simplePin, C) SET_BITMASK(PORTC, SIMPLE_PIN_VALUE(simplePin)); \
if SIMPLE_PORT_CHECK(simplePin, D) SET_BITMASK(PORTD, SIMPLE_PIN_VALUE(simplePin)); \
if SIMPLE_PORT_CHECK(simplePin, E) SET_BITMASK(PORTE, SIMPLE_PIN_VALUE(simplePin)); \
if SIMPLE_PORT_CHECK(simplePin, F) SET_BITMASK(PORTF, SIMPLE_PIN_VALUE(simplePin)); \
if SIMPLE_PORT_CHECK(simplePin, G) SET_BITMASK(PORTG, SIMPLE_PIN_VALUE(simplePin)); \
}
#define clear_pin(simplePin) \
{ \
if SIMPLE_PORT_CHECK(simplePin, A) CLEAR_BITMASK(PORTA, SIMPLE_PIN_VALUE(simplePin)); \
if SIMPLE_PORT_CHECK(simplePin, B) CLEAR_BITMASK(PORTB, SIMPLE_PIN_VALUE(simplePin)); \
if SIMPLE_PORT_CHECK(simplePin, C) CLEAR_BITMASK(PORTC, SIMPLE_PIN_VALUE(simplePin)); \
if SIMPLE_PORT_CHECK(simplePin, D) CLEAR_BITMASK(PORTD, SIMPLE_PIN_VALUE(simplePin)); \
if SIMPLE_PORT_CHECK(simplePin, E) CLEAR_BITMASK(PORTE, SIMPLE_PIN_VALUE(simplePin)); \
if SIMPLE_PORT_CHECK(simplePin, F) CLEAR_BITMASK(PORTF, SIMPLE_PIN_VALUE(simplePin)); \
if SIMPLE_PORT_CHECK(simplePin, G) CLEAR_BITMASK(PORTG, SIMPLE_PIN_VALUE(simplePin)); \
}
#define set_pin_to(simplePin, state) \
{ \
if SIMPLE_PORT_CHECK(simplePin, A) SET_BITMASK_TO(PORTA, SIMPLE_PIN_VALUE(simplePin), state); \
if SIMPLE_PORT_CHECK(simplePin, B) SET_BITMASK_TO(PORTB, SIMPLE_PIN_VALUE(simplePin), state); \
if SIMPLE_PORT_CHECK(simplePin, C) SET_BITMASK_TO(PORTC, SIMPLE_PIN_VALUE(simplePin), state); \
if SIMPLE_PORT_CHECK(simplePin, D) SET_BITMASK_TO(PORTD, SIMPLE_PIN_VALUE(simplePin), state); \
if SIMPLE_PORT_CHECK(simplePin, E) SET_BITMASK_TO(PORTE, SIMPLE_PIN_VALUE(simplePin), state); \
if SIMPLE_PORT_CHECK(simplePin, F) SET_BITMASK_TO(PORTF, SIMPLE_PIN_VALUE(simplePin), state); \
if SIMPLE_PORT_CHECK(simplePin, G) SET_BITMASK_TO(PORTG, SIMPLE_PIN_VALUE(simplePin), state); \
}
#define is_pin_set(simplePin) \
( \
(SIMPLE_PORT_CHECK(simplePin, A) ? IS_BITMASK_SET(PINA, SIMPLE_PIN_VALUE(simplePin)) : \
(SIMPLE_PORT_CHECK(simplePin, B) ? IS_BITMASK_SET(PINB, SIMPLE_PIN_VALUE(simplePin)) : \
(SIMPLE_PORT_CHECK(simplePin, C) ? IS_BITMASK_SET(PINC, SIMPLE_PIN_VALUE(simplePin)) : \
(SIMPLE_PORT_CHECK(simplePin, D) ? IS_BITMASK_SET(PIND, SIMPLE_PIN_VALUE(simplePin)) : \
(SIMPLE_PORT_CHECK(simplePin, E) ? IS_BITMASK_SET(PINE, SIMPLE_PIN_VALUE(simplePin)) : \
(SIMPLE_PORT_CHECK(simplePin, F) ? IS_BITMASK_SET(PINF, SIMPLE_PIN_VALUE(simplePin)) : \
(SIMPLE_PORT_CHECK(simplePin, G) ? IS_BITMASK_SET(PING, SIMPLE_PIN_VALUE(simplePin)) : 0)))))))\
)
*/
===== Anwendungsbeispiel =====
#include
#include "pinops.h"
#define LED1 PORTPIN(C, 1)
int main(void)
{
unsigned char x;
setup_output_pin(LED1);
set_pin(LED1);
clear_pin(LED1);
set_pin_to(LED1, 1);
toggle_pin(LED1);
get_pin_value(LED1, x);
}