Hallo Zusammen
Um die Geschwindigkeit eines Modellautos zu messen arbeite ich mit einem Weg-Impuls-Geber.
Nun habe ich jedoch noch einige Probleme mit der Software. Das folgende Modul funktioniert ganz gut, muss jedoch irgendwo noch einen Bug haben, da es in zufälligen Abständen (zwischen wenigen hunder Millisekunden und einigen Minuten) zu Fehlauswertungen kommt. freqGet() liefert dann irgend einen komisch Wert, welcher am häufigsten 0 ist. Dabei wird die Frequenz zurzeit noch von einem Rechteckgenerator geliefert. An diesem sollte es also nicht liegen.
Damit man den Code schneller versteht hier ein paar grundsätzliche Dinge:
Das Signal liegt am Analogkomperator, welcher mit einem Kondensator noch einwenig geglättet wird. Getriggert wird bei 2.5V. Das Signal ist ein Rechteck von 0-5V.
Um zusätzlich noch entprellen zu können wird der Analog Comparator Interrupt beim auftreten eines Interrupts kurz deaktiviert und einwenig später vom Timer wieder aktiviert.
timGet() liefert ein DWord (32 Bit langer unsigned Typ). Dieses zählt auf dem Systemtakt hoch und überläuft nach ca. 9min einfach.
Ich komme bei diesem Problem schon seit geraumer Zeit nicht weiter. Finden vielleicht jemand von euch den Fehler?
Danke für eure Hilfe!Code:/// includes -------------------------------------------------------------------- #include <normlib.h> #include <interrupt.h> #include "avr.h" #include "tim.h" #include "out.h" #include "dataTable.h" #include "data.h" #include "freq.h" // global variables ------------------------------------------------------------ byte freqPulsLedFlag; byte freqEnable; // local definitions ----------------------------------------------------------- // local variables ------------------------------------------------------------- static word actFreq; static dword t0,tI1; //timestamp of last puls static dword dt; //delta t static byte signal; static byte preload; static dword pLedTime; // global function implementation ---------------------------------------------- void freqInit(){ TCCR0=BV(CS02)|BV(CS00); // activate Timer 0, prescaler /1024 preload=dataGetByte(DATATABLE_AC_TCNT0); //preload of Timer0 // Enable Analog Comparator, Enable Analog Comparator Interrupt if(dataGetByte(DATATABLE_AC_EDGE)) ACSR=BV(ACIS0)|BV(ACIS1); //rising Edge else ACSR=BV(ACIS1); //falling Edge cbi(ACSR,ACD); //Enable Analog Comparator sbi(ACSR,ACIE); //Enable Analog Comparator Interrupt actFreq =0; signal =FALSE; freqPulsLedFlag=TRUE; freqEnable =TRUE; pLedTime =(F_CPU/1000)*dataGetWord(DATATABLE_PULS_LED_FREQ); } word freqGet(){ return actFreq; } void freqUpdate(){ if(!freqEnable) return; cli(); dword t1=tI1; sei(); if(t0!=t1){ signal=TRUE; if(t1<t0) dt=-t0+t1; else dt=t1-t0; if(dt<((dword)(10*F_CPU/0xFFFF))) actFreq=0xFFFF; else actFreq=(word)((dword)(10*F_CPU)/dt); t0=t1; if(freqPulsLedFlag) outClear(OUT_PULS); } if(!signal){ actFreq=0; return; } if(t0==t1){ dword t2=timGet(); dword dtN; if(t2<t0) dtN=-t0+t2; else dtN=t2-t0; if(dtN>dt){ actFreq=(word)((dword)(10*F_CPU)/dtN); } } if(timReached((dword)F_CPU,t0)) signal=FALSE; if(freqPulsLedFlag&&timReached(pLedTime,t0)) outSet(OUT_PULS); } // interrupt routines ---------------------------------------------------------- ISR(ANA_COMP_vect){ tI1=timGet(); cbi(ACSR,ACIE); //disable Analog Comparator Interrupt TCNT0=preload; //preload Timer0 sbi(TIMSK,TOIE0);//enable Timer 0 Interrupt } ISR(TIMER0_OVF_vect){ sbi(ACSR,ACI); //clear Analog Comparator Interrupt Flag sbi(ACSR,ACIE); //enable Analog Comparator Interrupt cbi(TIMSK,TOIE0);//disable Timer 0 Overflow Interrupt } // EOF -------------------------------------------------------------------------
Gruss
cumi







Zitieren

Lesezeichen