Statistics
| Revision:

## root / trunk / code / projects / colonet / utilities / robot_slave / dio.c @ 13

History | View | Annotate | Download (5.93 KB)

 1 ```/* ``` ```dio.c ``` ```Controls digital input and output ``` ``` ``` ```A general note on how this code works: ``` ```portpin is used to select both the bank and which pin is selected ``` ```6 bits are used (lower 6, ex: 0b00abcdef) ``` ```the first 3 (abc in this example) are used to select the bank ``` ```A = 001 ``` ```B = 010 ``` ```C = 011 ``` ```D = 100 ``` ```E = 101 ``` ```F = 110 ``` ```G = 111 ``` ``` ``` ```the bank can be found by doing portpin >> 3 ``` ``` ``` ```the next 3 (def in this example) are used to select the pin number ``` ```the 3 bits are just the binary representation of the pin number ``` ```0 = 000 ``` ```1 = 001 ``` ```2 = 010 ``` ```3 = 011 ``` ```4 = 100 ``` ```5 = 101 ``` ```6 = 110 ``` ```7 = 111 ``` ``` ``` ```the pin number can be found by doing portping & 0b111 ``` ```*/ ``` ```#include ``` ```#include ``` ```#include ``` ```#include ``` ```/* ``` ``` * digital_input ``` ``` * Reads the value on the selected portpin, returns it as 1 or 0 ``` ``` * see general description (above) for definition of portpin ``` ``` */ ``` ```int digital_input(int portpin){ ``` ``` int pin = portpin & 0x7; ``` ``` int pin_val = 0; ``` ``` ``` ``` switch(portpin >> 3){ ``` ``` case _PORT_A: ``` ``` DDRA &= ~_BV(pin); ``` ``` pin_val = PINA; ``` ``` return (pin_val >> pin) & 1; ``` ``` case _PORT_B: ``` ``` DDRB &= ~_BV(pin); ``` ``` pin_val = PINB; ``` ``` return (pin_val >> pin) & 1; ``` ``` case _PORT_C: ``` ``` DDRC &= ~_BV(pin); ``` ``` pin_val = PINC; ``` ``` return (pin_val >> pin) & 1; ``` ``` case _PORT_D: ``` ``` DDRD &= ~_BV(pin); ``` ``` pin_val = PIND; ``` ``` return (pin_val >> pin) & 1; ``` ``` case _PORT_E: ``` ``` DDRE &= ~_BV(pin); ``` ``` pin_val = PINE; ``` ``` return (pin_val >> pin) & 1; ``` ``` case _PORT_F: ``` ``` if(pin>=4){ ``` ``` MCUSR|=1<<7; ``` ``` MCUSR|=1<<7; ``` ``` } ``` ``` DDRF &= ~_BV(pin); ``` ``` pin_val = PINF; ``` ``` return (pin_val >> pin) & 1; ``` ``` case _PORT_G: ``` ``` DDRG &= ~_BV(pin); ``` ``` pin_val = PING; ``` ``` return (pin_val >> pin) & 1; ``` ``` default: break; ``` ``` } ``` ``` ``` ``` return -1; ``` ```} ``` ```/* ``` ``` digital_pull_up ``` ``` Enables pullup on a pin. if pin is output, it will make it output 1. ``` ```*/ ``` ```void digital_pull_up(int portpin) { ``` ``` int pins = portpin & 0x07; ``` ``` switch(portpin >> 3) { ``` ``` case _PORT_A: ``` ``` PORTA |= _BV(pins); ``` ``` break; ``` ``` case _PORT_B: ``` ``` PORTB |= _BV(pins); ``` ``` break; ``` ``` case _PORT_C: ``` ``` PORTC |= _BV(pins); ``` ``` break; ``` ``` case _PORT_D: ``` ``` PORTD |= _BV(pins); ``` ``` break; ``` ``` case _PORT_E: ``` ``` PORTE |= _BV(pins); ``` ``` break; ``` ``` case _PORT_F: ``` ``` PORTF |= _BV(pins); ``` ``` break; ``` ``` case _PORT_G: ``` ``` PORTG |= _BV(pins); ``` ``` break; ``` ``` } ``` ```} ``` ```/* ``` ``` digital_output ``` ``` ``` ``` sets portpin to the value ``` ``` see general description above for explanation of portpin ``` ``` val can only be 0 for off, nonzero for on ``` ```*/ ``` ```void digital_output(int portpin, int val) { ``` ``` int pins = portpin & 0x07; ``` ``` ``` ``` /* if you want to set to 0... */ ``` ``` if(val == 0) { ``` ``` switch(portpin >> 3) { ``` ``` case _PORT_A: ``` ``` DDRA |= _BV(pins); ``` ``` PORTA &= (0XFF - _BV(pins)); ``` ``` break; ``` ``` case _PORT_B: ``` ``` DDRB |= _BV(pins); ``` ``` PORTB &= (0XFF - _BV(pins)); ``` ``` break; ``` ``` case _PORT_C: ``` ``` DDRC |= _BV(pins); ``` ``` PORTC &= (0XFF - _BV(pins)); ``` ``` break; ``` ``` case _PORT_D: ``` ``` DDRD |= _BV(pins); ``` ``` PORTD &= (0XFF - _BV(pins)); ``` ``` break; ``` ``` case _PORT_E: ``` ``` DDRE |= _BV(pins); ``` ``` PORTE &= (0XFF - _BV(pins)); ``` ``` break; ``` ``` case _PORT_F: ``` ``` DDRF |= _BV(pins); ``` ``` PORTF &= (0XFF - _BV(pins)); ``` ``` break; ``` ``` case _PORT_G: ``` ``` DDRG |= _BV(pins); ``` ``` PORTG &= (0XFF - _BV(pins)); ``` ``` break; ``` ``` } ``` ``` }else { /* ( val == 1) */ ``` ``` switch(portpin >> 3) { ``` ``` case _PORT_A: ``` ``` DDRA |= _BV(pins); ``` ``` PORTA |= _BV(pins); ``` ``` break; ``` ``` case _PORT_B: ``` ``` DDRB |= _BV(pins); ``` ``` PORTB |= _BV(pins); ``` ``` break; ``` ``` case _PORT_C: ``` ``` DDRC |= _BV(pins); ``` ``` PORTC |= _BV(pins); ``` ``` break; ``` ``` case _PORT_D: ``` ``` DDRD |= _BV(pins); ``` ``` PORTD |= _BV(pins); ``` ``` break; ``` ``` case _PORT_E: ``` ``` DDRE |= _BV(pins); ``` ``` PORTE |= _BV(pins); ``` ``` break; ``` ``` case _PORT_F: ``` ``` DDRF |= _BV(pins); ``` ``` PORTF |= _BV(pins); ``` ``` break; ``` ``` case _PORT_G: ``` ``` DDRG |= _BV(pins); ``` ``` PORTG |= _BV(pins); ``` ``` break; ``` ``` } ``` ``` } ``` ```} ``` ```////////////////////////////////////// ``` ```//////////// button1 ////////////// ``` ```////////////////////////////////////// ``` ```/* ``` ``` return 1 if button is pressed, 0 otherwise ``` ```*/ ``` ```int button1_read( void ) ``` ```{ ``` ``` int pin_val; ``` ``` DDRG &= ~_BV(PING0); ``` ``` PORTG|= _BV(PING0); ``` ``` pin_val = PING; ``` ``` return !((pin_val & _BV(PING0))); ``` ``` ``` ```} ``` ```/* similar to button1_read, but hold program until the button is actually ``` ``` * pressed ``` ```*/ ``` ```void button1_wait( void ) ``` ```{ ``` ``` while(!button1_read() ) { ``` ``` delay_ms(15); ``` ``` } ``` ```} ``` ```/* USER LED ``` ``` same as button1_wait ``` ``` However, blink the led while waiting ``` ``` ``` ``` IMPORTANT: This requires that the LED has been initialized ( init_led ) ``` ```*/ ``` ```/* ``` ```void button1_wait_led( void ) ``` ```{ ``` ``` int i = 0; ``` ``` ``` ``` while(!button1_read()){ ``` ``` if(i < 8){ ``` ``` led_user(1); ``` ``` }else{ ``` ``` led_user(0); ``` ``` } ``` ``` //increment i, but restart when i = 15; ``` ``` i = (i+1) & 0xF; ``` ``` delay_ms(15); ``` ``` } ``` ``` ``` ``` led_user(0); ``` ```} ``` ```*/ ``` ```//click waits until the button is realesed to return true ``` ```//return false immediatley ``` ```int button1_click() ``` ```{ ``` ``` if(button1_read()){ ``` ``` while(button1_read()); ``` ``` return 1; ``` ``` }else{ ``` ``` return 0; ``` ``` } ``` ```} ``` ```////////////////////////////////////// ``` ```//////////// button2 ////////////// ``` ```////////////////////////////////////// ``` ```//see button1 functions for descriptions ``` ```//same except for which button is used ``` ```int button2_read( void ) ``` ```{ ``` ``` int pin_val; ``` ``` DDRG &= ~_BV(PING1); ``` ``` PORTG|= _BV(PING1); ``` ``` pin_val = PING; ``` ``` return !((pin_val & _BV(PING1))); ``` ```} ``` ```void button2_wait( void ) ``` ```{ ``` ``` while(!button2_read()){ ``` ``` delay_ms(15); ``` ``` } ``` ```} ``` ```/*USER LED NO LONGER EXISTS ``` ```void button2_wait_led(void) ``` ```{ ``` ``` int i = 0; ``` ``` ``` ``` while(!button2_read()){ ``` ``` if(i < 8){ ``` ``` led_user(1); ``` ``` }else{ ``` ``` led_user(0); ``` ``` } ``` ``` //increment i, but restart when i = 15; ``` ``` i = (i+1) & 0xF; ``` ``` delay_ms(15); ``` ``` } ``` ``` ``` ``` led_user(0); ``` ```} ``` ```*/ ``` ```int button2_click() ``` ```{ ``` ``` if(button2_read()){ ``` ``` while(button2_read()); ``` ``` return 1; ``` ``` }else{ ``` ``` return 0; ``` ``` } ``` ```} ``` ```/* ``` ```// EXTERNAL INTERRUPTS ``` ```/// example code to be used by anyone in need ``` ```/// this example has 2 bump sensors on PE6 and PE7 ``` ``` ``` ```// left touch sensor on PE6 ``` ```SIGNAL (SIG_INTERRUPT6) ``` ```{ ``` ```putcharlcd('6'); ``` ```} ``` ``` ``` ```// right touch sensor on PE7 ``` ```SIGNAL (SIG_INTERRUPT7) ``` ```{ ``` ``` putcharlcd('7'); ``` ```} ``` ```*/ ```