Der folgende Code vereinfacht Operationen mit den AVR Pins.
// // 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)))))))\ ) */
#include <avr/io.h> #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); }