#include <inttypes.h> #include <avr/io.h> #include <avr/interrupt.h> #define __DELAY_BACKWARD_COMPATIBLE__ #include <util/delay.h> #include <stdlib.h> #define LED_L (1 << PORTC0) #define LED_R (1 << PORTC2) #define MOTOR_ON (0<<PORTB1) #define MOTOR_OFF (1<<PORTB1) static void init_leds(void){ //enable LED channels as output DDRC |= (1 << PORTC0) | (1 << PORTC1) | (1 << PORTC2) | (1 << PORTC3); // both LEDs off PORTC &= ~((1 << PORTC0) | (1 << PORTC1) | (1 << PORTC2) | (1 << PORTC3)); return; } static void inline led_on(int leds){ PORTC |= leds; } static void inline led_off(int leds){ PORTC &= ~leds; return; } static void inline buzzr_off(void){ PORTC &= ~(1 << PORTC5); PORTB &= ~(1 << PORTB2); } static void init_buzzr(void){ //its on B2 and C5, for reasons DDRC |= (1 << PORTC5); DDRB |= (1 << PORTB2); //switch it off buzzr_off(); return; } static void buzzr_up(void){ PORTC &= ~(1 << PORTC5); PORTB |= (1 << PORTB2); return; } static void buzzr_down(void){ PORTC |= (1 << PORTC5); PORTB &= ~(1 << PORTB2); } static void buzzr_inv(void){ PORTC ^= (1 << PORTC5); PORTB ^= (1 << PORTB2); } static void init_motor(void) { /* vibration motor on B1, initially off: */ DDRB |= (1 << PORTB1); PORTB &= ~( 1<<PORTB1); return; } static void set_motor(int val){ PORTB = ~(val); PORTB = PORTB; return; } static void init_switch(void){ DDRD &= ~( (1 << PORTD1) | (1<<PORTD0)); PORTD |= (1 << PORTD1) | (1<<PORTD0); //Pullups FTW return; } static void blinkrattlebeep(void){ led_off(LED_L|LED_R); _delay_ms(100); led_on(LED_L); _delay_ms(100); led_off(LED_L); led_on(LED_R); _delay_ms(100); led_off(LED_R); set_motor(MOTOR_ON); _delay_ms(200); set_motor(MOTOR_OFF); buzzr_up(); for (int i=0; i<100; i++){ _delay_ms(2); buzzr_inv(); }; buzzr_off(); } static void mode_motortest(void) { set_motor(MOTOR_ON); _delay_ms(400); set_motor(MOTOR_OFF); _delay_ms(500); return; } static void mode_blinktest(void) { led_off(LED_L|LED_R); _delay_ms(100); led_on(LED_L); _delay_ms(100); led_off(LED_L); led_on(LED_R); _delay_ms(100); led_off(LED_R); return; } static void mode_beeptest(void) { buzzr_up(); for (int i=0; i<100; i++){ _delay_ms(2); buzzr_inv(); }; buzzr_off(); return; } static void flashleds(int leds) { led_off(LED_L|LED_R); for (int i=0; i<10; i++){ led_on(leds); _delay_ms(10); led_off(LED_L|LED_R); _delay_ms(90); }; return; } int main(void) { /* hardware initialisation: */ init_motor(); init_buzzr(); init_leds(); init_switch(); uint8_t mode = 0; for(;;) /* ever */ { //do something switch(mode){ case 1: mode_blinktest(); break; case 2: mode_motortest(); break; case 3: mode_beeptest(); break; default: //mode=0; blinkrattlebeep(); } //check switches and change mode switch( PIND & 0b00000011){ case 0b00000010: //left switch pressed mode--; if (mode > 3) mode =3; flashleds(LED_L); break; case 0b00000001: //right switch pressed mode++; if (mode > 3) mode = 0; flashleds(LED_R); break; case 0b00000000: //both switches pressed flashleds(LED_R|LED_L); break; } } /* never return 0; */ return 0; }