Hallo
Ich möchte derzeit eine Ganganzeige mit einer Sieben Segment Anzeige für ein Motorrad bauen. Ich hab das ganze im Grunde auch schon zum laufen bekommen ich habe aber wohl noch Probleme mit der Eingangsspannung und der Spannung am AD Wandler.
In dem Motorrad ist ein Gangsensor dessen Widerstand sich nun ändert je nach dem wlecher Gang eingelegt ist. Die Spannung die über diesem Widerstand anliegt werte ich mit dem AD Wandler aus.
Jetzt hab ich das Problem dass sich der Controller des öfteren selber resetet. Das liegt denke ich an der "verseuchten" Eingangsspannung. Ich habe schon versucht das ganze mit einem großen (2000µ) und einen kleinen (100n) Kondensator zu verbessern leider fast ohne erfolg.
Das zweite Problem das ich habe ist eine wohl nicht ganz saubere Spannung am AD Wandler. Auch das habe ich versucht mit einem 100n Kondensator gegen Masse zu lösen, leider auch ohne Erfolg. Die Kombination aus Spule und Kondensator an der Versorgungsspannung des AD-Wandlers ist eingebaut (wie im Datenblatt).
Habt ihr da irgendwelche Ideen wie ich die beiden Probleme lösen kann?
Hier mal mein Code:
Wie ihr seht hab ich schon einiges versucht um den AD Wandler "langsamer" zu machen um mir nicht allzu viele Störungen einzuhandeln.Code:#include <avr/io.h> #include <inttypes.h> #include <util/delay.h> #include <avr/interrupt.h> #define F_CPU = 2000000UL void ADC_init(void); uint16_t ADC_einlesen(void); void Anzeige_init(void); void long_delay(uint16_t ms); void gangAnzeigen(void); void print_1(void); void print_2(void); void print_3(void); void print_4(void); void print_5(void); void print_6(void); void print_L(void); int main(void) { DDRC &= ~(1<<DDC5); //Pin C5 als eingang deklarieren (Leerlauf) PORTC |= (1<<PC5); //Pull Up aktivieren DDRD = (1<<DDD7)|(1<<DDD6)|(1<<DDD5)|(1<<DDD4); //Pins für 7 Segmentanzeige als Ausgang PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten DDRC = (1<<DDC2)|(1<<DDC3)|(1<<DDC4); //Pins für 7 Segmentanzeige als Ausgang PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); sei(); //Interrupts freigeben TIMSK |= (1<<TOIE0); //TimerOverflow Interrupt freigeben TCCR0 |= (1<<CS01); //Timer initialisieren und einschalten ADC_init(); //Anzeige_init(); while(1) { } } void gangAnzeigen(void) { uint16_t gang; gang = ADC_einlesen(); if ((gang<371) & (gang>367)) { print_1(); } else if ((gang<469) & (gang>465)) { print_2(); } else if ((gang<617) & (gang>613)) { print_3(); } else if ((gang<760) & (gang>756)) { print_4(); } else if ((gang<901) & (gang>897)) { print_5(); } else if ((gang<969) & (gang>965)) { print_6(); } else if (gang>971) { print_L(); } } ISR(TIMER0_OVF_vect) { gangAnzeigen(); } void ADC_init(void) { ADCSRA = (1<<ADEN) | (1<<ADPS0) | (1<<ADPS2); ADMUX = (!(1<<MUX0)) | (!(1<<MUX1)) | (!(1<<MUX2)); ADMUX &= ~((1<<REFS1)); ADMUX &= ~((1<<REFS0)); ADCSRA |= (1<<ADSC); while(ADCSRA & (1<<ADSC)); } uint16_t ADC_einlesen(void) { uint16_t result=0; //Variable für Ergebiss anlegen uint8_t i; //Variable für Schleife anlegen ADCSRA = (1<<ADEN); for (i=0; i<4; i++) { ADCSRA |= (1<<ADSC); while(ADCSRA & (1<<ADSC)); result += ADC; } ADCSRA &= ~(1<<ADEN); result /= 4; return result; } void Anzeige_init(void) { int i; for(i=0; i<2; i++) { PORTD &= ~((1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7)); //alle LED`s einschalten PORTC &= ~((1<<PC2)|(1<<PC3)|(1<<PC4)); //alle LED`s einschalten long_delay(1000); long_delay(1000); PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten print_1(); long_delay(1000); long_delay(1000); print_2(); long_delay(1000); long_delay(1000); print_3(); long_delay(1000); long_delay(1000); print_4(); long_delay(1000); long_delay(1000); print_5(); long_delay(1000); long_delay(1000); print_6(); long_delay(1000); long_delay(1000); print_L(); long_delay(1000); long_delay(1000); } } void long_delay(uint16_t ms) { for(; ms>0; ms--) _delay_ms(1); } void print_1(void) { PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten PORTD &= ~((1<<PD5)|(1<<PD6)); //LED`s für c und b einschalten } void print_2(void) { PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten PORTD &= ~((1<<PD4)|(1<<PD6)|(1<<PD7)); //LED`s für a,b,c einschalten PORTC &= ~((1<<PC2)|(1<<PC4)); //LED`s für e,g einschalten } void print_3(void) { PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten PORTD &= ~((1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7)); //LED`s für a,b,c,d einschalten PORTC &= ~((1<<PC4)); //LED`s für g einschalten } void print_4(void) { PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten PORTD &= ~((1<<PD5)|(1<<PD6)); //LED`s für b,c einschalten PORTC &= ~((1<<PC3)|(1<<PC4)); //LED`s für f,g einschalten } void print_5(void) { PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten PORTD &= ~((1<<PD4)|(1<<PD5)|(1<<PD7)); //LED`s für a,c,d einschalten PORTC &= ~((1<<PC3)|(1<<PC4)); //LED`s für f,g einschalten } void print_6(void) { PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten PORTD &= ~((1<<PD4)|(1<<PD5)|(1<<PD7)); //LED`s für a,b,c einschalten PORTC &= ~((1<<PC2)|(1<<PC3)|(1<<PC4)); //LED`s für e,f,g einschalten } void print_L(void) { PORTD |= (1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4); //LEDs ausschalten PORTC |= (1<<PC2)|(1<<PC3)|(1<<PC4); //LEDs ausschalten PORTD &= ~((1<<PD4)); //LED`s für d einschalten PORTC &= ~((1<<PC2)|(1<<PC3)); //LED`s für e,f einschalten }
Die nächsten ideen wären die Schleifendurchläufe in der AD-Wandlerroutine zu erhöhen, den AD Eingang zu entstören und den Controller generell etwas langsamer zu machen. Im Moment läuft er mit 8MHz (intern).
Welche Maßnahmen denkt ihr wären am hilfreichsten? Habt ihr mir weitere Ideen wie ich den AD-Eingang Hardwaremäßig entstören kann?
Vielen Dank im Voraus!
Mr Bean







Zitieren

Lesezeichen