/*************************************** Project : FUP Solar car Version : 1.0 Date : 29.01.2014 Author : Thomas Hasibeder Company : FH-Wels Comments: Dieses Programm misst die Pulsweite von der Fehrnsteuerung und erzeugt ein PWM Signal für den Motortreiber Chip type : ATmega32 Clock frequency : 8,000000 MHz Memory model : Small Internal RAM size: 512 External RAM size: 0 Data Stack size : 128 ***************************************/ #include #include #include #include #define uchar unsigned char #define uint unsigned int //start Timer1 no prescaler //#define START_TIMER TCCR1B |= (1 << CS10) //stop Timer1 //#define STOP_TIMER TCCR1B &= ~(1 << CS10) #define LEDS 0x04 uint pulseStart = 0; uint pulseEnd = 0; uint pulseInUs = 0; uchar edge = 0; uint success = 0; uint failure = 0; uint y = 0; uchar k = 0; void init (void); void wait_us (uint tus); void wait_ms (uint tms); void set_mux (uchar mux); void wr_data (uchar data); void PWM_set (uchar duty); int main (void) { init (); set_mux (LEDS); k=1; wr_data (k); wait_ms (1000); TIMSK |= ((1 << TOIE1) & (1 << TICIE1)); //(0x24)Capture interrupt enable + Overflow Interrupt enabled TCCR1B |= (1 << ICES1); //Steigende Flanke TIFR = 1<= cnt wird }; } // wait_ms wartet tms Millisekunden. Zulässige Werte: 1-65000 void wait_ms (uint tms) { uint ms; for (ms=1; ms<=tms; ms++) { wait_us (1000); }; } // set_mux stellt den Display-Multiplexer auf LEDs, Ampel oder Siebensegmentanzeige void set_mux (uchar mux) { PORTB=mux<<5; } // wr_data schreibt die Daten an die mit set_mux angegebene Anzeigeeinheit void wr_data (uchar data) { PORTC=data; } // init stellt die Anfangszustand des AVR-Boards ein. void init (void) { sei(); //Global interrupt enable // Input/Output Ports initialization // Port B DDRB=0xFC; //Port B ist Output PORTB=0x00; // Port B=0000 0000B, Output Low // Port C DDRC=0xFF; // Port C is Output PORTC=0x00; // Port C=0000 0000B, Output Low // Port D DDRD =0xBF; //PORTD.6 = INPUT (Empfänger INPUT (S3,ICP)) PORTD=0x00; //Timer 1 Register Pulsweitenmodulation TCCR1A=0b00000000; TCCR1B=0b01000001; //Timer 0 Register PWM TCCR0=0b01101001; //Fast PWM + no prescaler + clear OC0 on compare match, set OC0 at Bottom,(non inverting mode) } void PWM_set (uchar duty) { OCR0 = duty; //OCR0 wird mit TCNT0 verglichen, wenn gleich OCO (PWM) } ISR(TIMER1_CAPT_vect) //Interrupt vector Seite 45 (Capture Handler) { if(edge == 0) { k=2; wr_data (k); pulseStart = ICR1; //Kopiren vom Capture Register (Zählwert) in Variable TCCR1B &= ~(1 << ICES1); //Fallende Flanke edge = 1; wait_ms (1000); } else { k=3; wr_data (k); pulseEnd = ICR1; //Kopiren vom Capture Register (Zählwert) in Variable TCCR1B |= (1 << ICES1); //Steigende Flanke edge = 0; TCCR1B &= ~(1 << CS10); //Stop Timer //STOP_TIMER; TCNT1 = 0; //Counter zurücksetzten pulseInUs = pulseEnd - pulseStart; //Differenz success = 1; y=(pulseInUs/44)*2-509; //Geradengleichung zur umskalierung PWM_set(y); wait_ms (1000); } } //Wird unter normalen bedingungen nicht erreicht weil nur bis maximal 16776 gezählt wird!!!! ISR(TIMER1_OVF_vect) //Interrupt vector Seite 45 (overflow Handler) { k=4; wr_data (k); wait_ms (1000); failure = 1; TCCR1B |= (1 << ICES1); //Steigende Flanke TCCR1B &= ~(1 << CS10); //Stop Timer //STOP_TIMER; TCNT1 = 0; //Counter zurücksetzten edge = 0; }