car firmware: finished pwm drive and lights switching

Sun, 22 Dec 2013 00:08:46 +0100

author
Malte Bayer <mbayer@neo-soft.org>
date
Sun, 22 Dec 2013 00:08:46 +0100
changeset 148
08cb88614d69
parent 147
f66c5b3b3ed2
child 149
1c3425af9aa0

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);
+        */
 
 
 

mercurial