also ich fasse mich kurz, ich hab eine Schaltung mit der ich Frequenzen bzw Periodendauern messen will... in benutzung: EX0 zum aufnehmen des Pulses! Timer1 zum zählen der Zeit... ( Quarz= 12Mhz) lass ihn von 0 bis 65536 durchlaufen bis ein Puls von EX0 kommt, dabei zeige ich dann nur die Zeit an, in gewissen interwallen, sodala jetzt hab ich allerdings meinen Frequenzgenertor drangehänt und fahre mit einer Konstanten Frequenz die ich messen will... problem: wenn ich eine Periodendauer von 5ms eingestellt habe zeigt er alles mögliche an zwischen 5084 - 4600 an.
Wie lang ist die Zeit bis der Timer durchgelaufen ist? Kommt es zu einem Überlauf oder ist er zu langsam?
16 Bit Timer, wenns nen überlauf gibt dann zählt er eine Variable mit und multipliziert dann mit 65536, TH1 wird mit 256 multipliziert und TL1 wird einfach so addiert ... Beispiel: er hat 9900uS zwischen den Pulsen... zählt aber mal um +150 drüber oder -150 drunter ... er schwankt einfach wie wild ...
setzt du den timer wieder zurück wenn ein Impule an EX0 erfasst wurde? Am besten schreibste mal deine Source in den Thread. mfg
#define WP P1 // Working Port #define AP P3 // Addressierung Port #define uchar unsigned char sbit bTaster = P3^0; // Setz taste für die RPM Shift light sbit bInput = P3^2; // Puls Input, 6 Zylinder, 2 Umdrehungen = 3 Pulse/umdrehung wegen 4-Takt sbit bSL = P3^7; // Shift light uchar disp[4]; // Display Value uchar cTable[] = { 0x0A, // 0 // Werte Tabelle für 7 Segmente 0x9F, // 1 0x29, // 2 0x0D, // 3 0x9C, // 4 0x4C, // 5 0x48, // 6 0x1E, // 7 0x08, // 8 0x0C }; // 9 uchar port; // Welcher gerade Aktiv ist! unsigned long value; // Aktiver Wert! unsigned long time; unsigned int array[10]; uchar overlap; uchar t_overlap; uchar t_high; uchar t_low; uchar counter; uchar temp; // Interrupts void INTEX0(void) interrupt 0 using 2; // Externer Interrupt 0 void INTTIM0(void) interrupt 1 using 2; // Timer0 void INTTIM1(void) interrupt 3 using 2; // Timer1 void setChar( uchar display_value ); // Initialisierungen void init(); // Initialisieren des Timer0 & Externen Interrupts!!! void setBCDport(); void char2display(int input) { disp[0] = input / 1000; input -= disp[0] * 1000; disp[1] = input / 100; input -= disp[1] * 100; disp[2] = input / 10; input -= disp[2] * 10; disp[3] = input; } ////////////////////////////////////// Initialisierungen /////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////// void INTEX0(void) interrupt 0 using 2 { bSL = !bSL; TR1 = 0; // Beide Timer ausschalten! TR0 = 0; t_overlap = overlap; t_high=TH1; t_low =TL1; overlap = 0; TH1 = 0; TL1 = 10; // Mit 10 vorladen! TR1 = 1; // Timer 1 Wieder einschalten!!! TR0 = 1; // Timer 0 Wieder einschalten!! // Wert ausrechnen!!! value = t_overlap*65536+t_high*256+t_low; // Wert Einlesen! } void INTTIM0(void) interrupt 1 using 2 // Ausgelöster Interrupt 1 -> 1ms { TH0 = 0xFC; // 1ms Reload bei 12 MHz TL0 = 0x0F; TF0 = 0; // Interrupt Flag Löschen! TR0 = 1; // Timer0 Einschalten!! counter++; if ( (counter-1)%20 == 0 ) array[(counter-1)%20] = 20000000/value; if (counter == 199) // Neuer wert alle 180ms { counter = 0; time = 0; for (temp=0;temp<10;temp++) time += array[temp]; // time /= 10; // time = 20000000/value; // Bei 15hz is schluss... Reason: 1/x // time = value; if (time>9999) time = 9999; } WP = 0xFF; // Damit keine Randbereiche Rot beleuchtet sind! char2display(time); // Umrechnen auf 4 Bytes! setBCDport(); // Nächste Anzeige Adressieren! setChar(disp[port]); // Zeichen In die Anzeige Legen! } void INTTIM1(void) interrupt 3 using 2 { overlap++; TH1 = 0; // Timer 1 wieder auf 0 zurücksetzen!!! TL1 = 0; TR1 = 1; // Timer 1 Einschalten!!! } void timer_start() { TH0 = 0xFC; // 1ms Reload bei 12 MHz TL0 = 0x0F; TH1 = 0; // Timer 1 auf 0 setzen! TL1 = 0; TR0 = 1; // Timer0 Einschalten!! TR1 = 1; // Timer1 Einschalten!! } void init() { bSL = 1; counter = 0; port = 3; // Port auf 3 setzen! ( start mit 0 ) TCON = 0x00; // Timer0 & Timer1 Aus! TMOD = 0x11; // Timer 0 16 Bit Zähler / Timer 1 16 Bit Zähler! ET0 = 1; // Timer0 Interrupt Enable ET1 = 1; // Timer1 Interrupt Enable bInput = 1; EX0 = 1; // Enable External Interrupt 1 IT0 = 1; // Flankengesteuert! TF0 = 0; IP0 |= 0x01; // Zeitmessung Maximale Priorität!!! INTERRUPT genauigkeit verbessern! IP1 |= 0x01; EAL = 1; // Enable all Interrupts } void setChar( uchar display_value ) { WP = cTable[display_value]; } void setBCDport() { port++; // port shifterei ... if (port == 4) port = 0; AP |= 0x3A; // Alle Adressierungen Löschen! if (port == 0) AP &= 0xFD; if (port == 1) AP &= 0xDF; if (port == 2) AP &= 0xEF; if (port == 3) AP &= 0xF7; } void main() { init(); timer_start(); // Timer Starten und auf ins vergnügen!! while(1) ; }
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.