Sun, 22 Dec 2013 00:08:46 +0100
car firmware: finished pwm drive and lights switching
car004f/main.c | file | annotate | diff | comparison | revisions |
--- a/car004f/main.c Sat Dec 21 21:01:55 2013 +0100 +++ b/car004f/main.c Sun Dec 22 00:08:46 2013 +0100 @@ -16,8 +16,12 @@ #define PULSE_PORT PORTD #define PULSE_BIT PD2 -#define RESPONSE_PORT PORTC -#define RESPONSE_PIN PC1 +typedef struct { + uint8_t slot; + uint8_t light; + unsigned program:1; // programming mode active +} config_t; + volatile uint16_t data = 0; volatile uint8_t data_len = 0; @@ -25,11 +29,14 @@ volatile uint16_t bitbuf = 0; volatile uint8_t car_speed[8]; volatile uint8_t car_switch[8]; -volatile uint8_t my_id; // Die ID des Autos! + +volatile uint8_t timeout = 0; +volatile uint8_t brake_timeout = 0; + uint8_t my_switch; uint8_t my_speed; -uint8_t light_mode; +config_t config; ISR ( INT0_vect ) { GICR &= ~_BV(INT0) ; // Disable INT0 @@ -94,10 +101,13 @@ } } -ISR (TIMER1_OVF_vect) { +ISR (INT1_vect) { } -ISR (INT1_vect) { +ISR (TIMER0_OVF_vect) { + TCNT0 = 100; // TIMER0 vorladen mit 100 + if (brake_timeout > 1) brake_timeout--; + if (timeout > 1) timeout--; } #define LIGHT_PORT PORTC @@ -107,15 +117,31 @@ #define IR_PORT PORTB #define IR_LED 3 +#define BRAKE_PORT PORTB +#define BRAKE 0 #define LIGHT_MODES 1 // anzahl der lichtmodi (ohne den modus "aus") +void config_save(void) { + eeprom_write_block( (void*)&config, 0, sizeof(config) ); +} + + +void brake_on(void) { + LIGHT_PORT |= _BV(LIGHT_BRAKE); // brake light on + BRAKE_PORT |= _BV(BRAKE); // brake on + brake_timeout = 50; +} + +void brake_off(void) { + LIGHT_PORT &= ~_BV(LIGHT_BRAKE); // brake light off + BRAKE_PORT &= ~_BV(BRAKE); // brake off + brake_timeout = 0; +} int main(void) { - uint8_t car0_state, car1_state; - // setup data bit timer2 TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match OCR2 = TIMER2_50US; @@ -126,35 +152,68 @@ MCUCR = _BV(ISC00) | _BV(ISC01) | _BV(ISC10) | _BV(ISC11); // INT0/1 rising edge GICR = _BV(INT0) | _BV(INT1) ; // Enable INT0 + INT1 - // oscillator calibration - // atmega8@1mhz = 0xac - // @4mhz = ca 0xa0 - //OSCCAL = 0xa0; - //OSCCAL = 0x9A; - //OSCCAL = 0xa0; // internal oscillator @ 4 mhz.... doesnt work accurate! + + DDR(LIGHT_PORT) |= _BV(LIGHT_FRONT) | _BV(LIGHT_BRAKE); + DDR(BRAKE_PORT) |= _BV(BRAKE); + + // config (from eeprom!) + eeprom_read_block( (void*)&config, (const void*)0, sizeof(config) ); + + + TCCR1A = (1<<WGM10)|(1<<COM1A1) // Set up the two Control registers of Timer1. + |(1<<COM1B1); // Wave Form Generation is Fast PWM 8 Bit, + + TCCR1B = (1<<WGM12)|(1<<CS10); // OC1A and OC1B are cleared on compare match + // and set at BOTTOM. Clock Prescaler is 1. + + + //OCR1A = 63; // Dutycycle of OC1A = 25% + //OCR1B = 127; // Dutycycle of OC1B = 50% + OCR1A = 0; + OCR1B = 0; + + // configure TIMER0 to overflow every 10ms at 4 MHz + TIMSK = _BV(TOIE0); // Timer0 Overflow INT erlauben + TCNT0 = 100; // TIMER0 vorladen mit 100 + TCCR0 = _BV(CS02) ; // Vorteiler auf 256, ab hier läuft der TIMER0 + sei(); - DDR(LIGHT_PORT) |= (_BV(LIGHT_FRONT) | _BV(LIGHT_BRAKE)); - //defaults (from eeprom!) - my_id = 1; - light_mode = 0; +config.slot = 1; while (1) { // main loop + if (brake_timeout == 1) { + DDRB &= ~_BV(2); // PB2 PWM Output disable + brake_off(); + } + + if (my_speed != car_speed[config.slot]) { + my_speed = car_speed[config.slot]; + OCR1B = (int) ((float)0xff * (float)((float)my_speed / (float)15)); + if (my_speed == 0) { + DDRB &= ~_BV(2); // PB2 PWM Output disable + brake_on(); + } else { + brake_off(); + DDRB |= _BV(2); // PB2 PWM Output enable + } + } + // Light cycle if switch pressed without speed - if (my_speed == 0) { - if (my_switch != car_switch[my_id]) { - my_switch = car_switch[my_id]; + if (car_speed[config.slot] == 0) { + if (my_switch != car_switch[config.slot]) { + my_switch = car_switch[config.slot]; if (my_switch != 0) { // cycle light - if (light_mode == LIGHT_MODES) light_mode = 0; else light_mode++; + if (config.light == LIGHT_MODES) config.light = 0; else config.light++; } } } - switch (light_mode) { + switch (config.light) { case 0: LIGHT_PORT &= ~_BV(LIGHT_FRONT); // switch lights off break; @@ -163,11 +222,11 @@ break; } - _delay_ms(100); - LIGHT_PORT |= _BV(LIGHT_BRAKE); // brake light on + + /* _delay_ms(100); - LIGHT_PORT &= ~_BV(LIGHT_BRAKE); // brake light off - + _delay_ms(100); + */