Sodele. Der Sharp läuft, und zeigt auch _brauchbare_ Werte an, aber:
Es gibt ein neues Problem.
Offenbar verträgt sich _diese_ ADC-Routine nicht mit der, die mir die Akkuspannung ermittelt.![]()
Konkret sieht es so aus, dass beim "hochfahren" so ziemlich als erstes mal die Akkuspannung ermittelt wird, wenn der einen bestimmten Wert unterschreitet, machts keinen Sinn, weiterzumachen.
So weit klappt das auch, dann wird das Schwenkservo mal kurz getestet und dann der Sharp abgefragt.
Keinerlei Probleme, bis dahin.
Nun will ich aber, Timergesteuert, von Zeit zu Zeit den Akku immer wieder mal prüfen, und _dann_ hängt _diese_ Routine sich auf.
Lasse ich den periodischen Aufruf von Batterie() weg, klappt alles hervorragend.Code://----------------------------------------- Sharp-IR-Sensor --------------------------------------- int Sharp(void) { ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);// Frequenzvorteiler: setzen auf 128 (16 MHz / 128kHz = 125 kHz) und ADC aktivieren ADMUX = 0x03; // Kanal waehlen (ADC3) ADMUX |= (1<<REFS1); // interne Referenzspannung nutzen ADCSRA |= (1<<ADSC); // eine ADC-Wandlung while ( ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten sharpResult = ADCW; // Wert abholen lcd_setCursor(0,1); // Ausgabe ADC-Wert printf("Sharp: %4d",sharpResult); return 0; } //----------------------------------------- Spannungsüberwachung ---------------------------------- int Batterie(void) { led_set(LED_L_RD,1); // blitzt bei jeder Messung kurz auf unsigned char temp1,temp2; while ((ADMUX & 0x07) != 0x04); cli(); while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete ADCSRA |= (1 << ADIF); // clear ADCIF temp1 = ADCSRA; // Registerinhalte retten temp2 = ADMUX; ADMUX = (1 << REFS0) | (1 << REFS1) | ANALOG_VOLT; //interne Referenzspannung m. externem Kondensator // ADCSRA löschen und neu setzen ADCSRA = 0; ADCSRA |= ((1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0)); // ADC clock = Clock/128 ADCSRA |= (1 << ADEN); // Enable ADC (das aktiviert die 2.56V Referenz) // Warten bis Kondensator an ARef = 2.56V hat // Messung an ARef ergab 1,2msec delay(6); // = ca. 5*Tau // 1. ADC Wandlung starten und Ergebnis ignorieren ADCSRA |= (1 << ADSC); // Start conversion while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete ADCSRA |= (1 << ADIF); // clear ADCIF // 2. ADC Wandlung starten und Ergebnis übernehmen ADCSRA |= (1 << ADSC); // Start conversion while (!(ADCSRA & (1 << ADIF))); // wait for conversion complete ADCSRA |= (1 << ADIF); // clear ADCIF akkuResult = ADCL + (ADCH << 8); // Registerinhalte wiederherstellen ADMUX = temp2; ADCSRA = temp1 & ~(1 << ADSC); // Warten bis Kondensator an ARef = AVcc hat // Messung ergab sehr steile Flanke delay(2); // nicht notwendig, nur zur Sicherheit ADCSRA |= (1 << ADSC); // Start conversion sei(); .....hier kommt noch ein bisschen Rechnerei und die Displayausgabe
Die Routine Sharp() wird im Hauptprogramm in einer Endlosschleife praktisch ununterbrochen aufgerufen, nebenbei zählt ein Timer hoch und löst, bei einem bestimmten Wert (so alle 15s) die Routine Batterie() auf.
Die LED (sie wird später, während der Umrechnung des ADC-Wertes in brauchbares wieder ausgeschalten) bleibt an, daher _muss_ der Punkt, an dem sich das Programm aufhängt, irgendwo in Batterie() liegen.
Alleine (wenn ich Sharp() _nicht_ aufrufe) funktioniert Batterie() einwandfrei.
Weiss jemand Rat?







Zitieren

Lesezeichen