Hallo zusammen, ich möchte mit meinem Mega16 (@16MHZ)die Schrittweite eines Signals einlesen. 15khz (bei arithm. Mittel=0). Leider will das Ganze nicht so wie ich es will. Hat mir jemand einen Tip woran es liegen könnte? Habe mal das Grundgerüst für das Capture aus meiner Software rausgezogen. Vielen Dank #include <inttypes.h> //Header includen als Bibliotheken #include <avr/io.h> #include <avr/interrupt.h> #include <avr/wdt.h> #include <string.h> #include <avr/eeprom.h> volatile double rising = 0; //Ergibt sich aus den beiden 8bit Variablen risinglow/risinghigh volatile uint8_t risinglow = 0; //8bit Variable zum Register auslesen volatile uint8_t risinghigh = 0; //8bit Variable zum Register auslesen volatile long double risingtemp = 0; volatile double falling = 0; //Ergibt sich aus den beiden 8bit Variablen fallinglow/fallinghigh volatile uint8_t fallinglow = 0; //8bit Variable zum Register auslesen volatile uint8_t fallinghigh = 0; //8bit Variable zum Register auslesen volatile long double fallingtemp = 0; volatile uint16_t Overflows = 0; volatile uchar status=0; volatile uchar fertig=0; int main (void) { //Capture Input PORTD &= ~BIT6; //Pullup aus DDRD &= ~(1<<PD6); //Eingang InitTimer(); // SystemClock sei(); // Freigabe Interrupts if (ModulEingang1) { fertig=0; status=0; //Overflows=0; lcd_cls(); double long countstemp; double long countstemp1; if (fertig==1) { countstemp = (fallingtemp-risingtemp);//Schrittweite countstemp = (countstemp*0.0625); //in Mikrocontrollertakten countstemp1 = (risingtemp-fallingtemp); countstemp1 = (countstemp1*0.0625); //in Mikrocontrollertakten lcd_cls(); lcd_outdouble(countstemp); lcd_outdouble(countstemp1); Overflows=0; wait(10000); fertig=0; status=0; } } ISR(TIMER1_CAPT_vect) { if (fertig==1){return;} if ((PIND & (1<<PIND6))&&(status==0)) { risinglow=ICR1L; risinghigh=ICR1H; rising = risinglow; rising += (risinghigh<<8); risingtemp = (long double)(rising+(Overflows*65536)); //Overflows=0; TCCR1B = 0x81; //on falling edge, noise canceler, @16MHZ status=1; } else { fallinglow=ICR1L; fallinghigh=ICR1H; falling = fallinglow; falling += (fallinghigh<<8); fallingtemp = (long double)(falling+(Overflows*65536)); TCCR1B=0xC1; //Overflows=0; fertig=1; } } ISR(TIMER1_OVF_vect) { Overflows++; } void InitTimer() { TCCR0 = 0x01; // no prescale -->16MHZ TCCR1A = 0x00; TCCR1B = 0xC1; //Noise Canceler on, trigger on rising edge, no prescale (16MHZ) TIMSK |= (1<<TOIE0)|(1<<TICIE1)|(1<<TOIE1); // Timer0 OverFlow Interrupt Enable (BIT0), Timer1:Interrupt wird ausgelöst wenn ICF1 Flag gesetzt wird (edge detector hat rising edge erkannt) }
Bitte beim nächsten Mal den Code richtig formatieren! > PORTD &= ~BIT6; //Pullup aus Das sieht schonmal verdächtig aus. Wie ist "BIT6" definiert? > risinglow=ICR1L; > risinghigh=ICR1H; > rising = risinglow; > rising += (risinghigh<<8); Das ist Murks. Lass die 16-Bit-Zugriffe doch den Compiler machen. Schmeiß die ***low und ***high weg und schreib einfach
1 | rising = ICR1; |
Abgesehen davon kennt der AVR-GCC weder double noch long double (bzw. double kennt er zwar, aber es ist identisch mit float, also nur 32 Bit breit; 64-Bit-Gleitkomma gibt's im AVR-GCC nicht). Schau Dir bitte mal den Artikel zum Thema Festkommaarithmetik an. Ich bin überzeugt davon, dass Du für Dein Vorhaben mit Sicherheit keine Gleitkommaverrenkungen brauchst. Zudem wendest Du Bitschiebe-Operationen auf Deine double-Variablen an. Das geht garantiert schief! Bitschiebereien sind generell nur für Ganzzahl-Werte (integer) definiert.
Fällt mir grad noch auf: Wo ist der Handler (ISR) für den Timer 0 Overflow Interrupt?
Hallo, erstmals tausend dank für die Hilfe. Hier der Timer0 Overflow: ISR(TIMER0_OVF_vect) { SystemClk++; if (SystemClk>=38) { SystemClk=0; DoForEver10ms=1; } // 38 * 256usec @16MHz -> 9,728msec } Bit6 ist wie folgt definiert: #define BIT6 0x40 Ich probier das gleich mal aus - mit dem Register ICR1.... Vielen Dank nochmal....
Marc Ziegl wrote: > Ich probier das gleich mal aus - mit dem Register ICR1.... > Vielen Dank nochmal.... Das mit dem ICR ist aber Dein allerkleinstes Problem...
Marc Ziegl wrote:
> ...wie meinen?
Will sagen, dass das mit dem ICR noch nicht mal für die Funktion der
ganzen Sache relevant ist, weil es so, wie es in Deinem Code steht (bis
auf die double-Geschichten) noch nicht mal ein Fehler ist, sondern
lediglich eine vermeidbare umständliche Vorgehensweise ist. Die
Behandlung der anderen genannten Probleme ist da eindeutig zu
priorisieren.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.