// // Jeffery Durand // DC_board_buttons_v01: each button makes the motor // go in a different direction. // Pressing both buttons will toggle the motor speed // // Used parts of Neil Gershenfeld's code // #include // basic library #include /* Functions to waste time */ #include // contains the booleans // Certain functions are the same in fact but conceptually different hance the different names // pin x is always one bit shifted x times // DDRx manipulation #define output(directions,pin) (directions |= pin) // set port direction for output (make 1) #define input(directions,pin) (directions &= (~pin)) // set port direction for input, default (make 0) // PORTx manipulation #define set(port,pin) (port |= pin) // set port pin #define clear(port,pin) (port &= (~pin)) // clear port pin #define all_set(port) (port = 0xff) // set all port pins, not recommended as different names may be given to same port #define all_clear(port) (port = 0x00) // clear all port pins // PINx reading #define pin_test(pins,pin) (pins & pin) // test for port pin #define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set // PROGRAM SPECIFIC // variables #define on_delay() _delay_ms(1) // PWM on time #define power_levels 15 // different levels of power // COMPONENTS // H-bridge output #define bridge_port PORTA // H-bridge port #define bridge_direction DDRA // H-bridge direction #define IN1 (1 << PA3) // IN1 #define IN2 (1 << PA2) // IN2 // button input #define button_port PORTB #define button_direction DDRB #define button_pins PINB #define button1 (1 << PB0) #define button2 (1 << PB1) int main(void) { static bool both_pressed = false; // both buttons just got pressed? static uint8_t delay = 0; // delay where the motor is inactive static uint8_t count_delay = 0; // variable for loop iteration static uint8_t count_power = 0; // the current power level selected (0 is highest, power_levels is lowest) // // set clock divider to /1 // CLKPR = (1 << CLKPCE); CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); // // initialize H-bridge pins // clear(bridge_port, IN1); output(bridge_direction, IN1); clear(bridge_port, IN2); output(bridge_direction, IN2); // // initialize button pins // set(button_port, button1); // want pull up resistors for the buttons input(button_direction, button1); set(button_port, button2); input(button_direction, button2); // // main loop // while (1) { // button 1 only pressed: turn forward! if (pin_test (button_pins, button1) == 0 && pin_test (button_pins, button2) != 0){ both_pressed = false; // both buttons not pressed (in case just released one button) clear(bridge_port, IN1); // set direction // make go forward set(bridge_port, IN2); on_delay(); // pause clear(bridge_port, IN2); for (count_delay = 0; count_delay < delay; count_delay++) { on_delay(); } } // button 2 only pressed: turn reverse if (pin_test (button_pins, button1) != 0 && pin_test (button_pins, button2) == 0){ both_pressed = false; // both buttons not pressed (in case just released one button) clear(bridge_port, IN2); // set direction // make go backwards set(bridge_port, IN1); on_delay(); // pause clear(bridge_port, IN1); for (count_delay = 0; count_delay < delay; count_delay++) { on_delay(); } } // both buttons pressed if (pin_test (button_pins, button1) == 0 && pin_test (button_pins, button2) == 0){ // turn motor off clear(bridge_port, IN1); clear(bridge_port, IN2); if (both_pressed == false){ // change delay (speed of motor) count_power = (count_power + 1) % power_levels; delay = count_power; // both_pressed is true (so the variable only changes once) both_pressed = true; } } // no buttons pressed if (pin_test (button_pins, button1) != 0 && pin_test (button_pins, button2) != 0){ // stop running clear(bridge_port, IN1); clear(bridge_port, IN2); // both_pressed back to false both_pressed = false; } } return 0; }