-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: Timingprobleme

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.06.2008
    Ort
    Rösrath
    Alter
    33
    Beiträge
    332

    Timingprobleme

    Anzeige

    Ich stehe vor der Herausforderung, die Einspritzzeit eines Ventils in Mikrosekunden zu messen. Die Auflösung beträgt 100 Mikrosekunden, ein Ventil ist i.d.R. ca. 1200 Mikrosekunden geöffnet.

    Als Controller benutze ich einen Atmega168 mit 12MHZ-Quarz. Ich habe also Timer0 mit einem Prescaler von 8 versehen und benutze den CTC-Modus mit einem TOP-Wert von 150. Dadurch sollte rein rechnerisch alle 100 Mikrosekunden ein Interrupt ausgelöst werden.

    Um die Genauigkeit zu überprüfen, hab ich eine simple Uhr programmiert. Diese geht allerdings nach, hochgerechnet etwa 8 Minuten pro Tag. Das ist mir zuviel.

    Die Frage ist jetzt, ist diese Abweichung ein Fehler im Code (siehe unten) oder einfach die Ungenauigkeit des Quarzes (bzw. der Beschaltung)?

    Die Schaltung befindet sich z.Z. auf einer Streifenrasterplatine, ist also von der Leiterbahnlänge am Quarz nicht optimal.

    Hier mal der Code:

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <avr/pgmspace.h>
    #include "dog_glcd.h"
    #include "keypad.h"
    #include "uart.h"
    #include <stdlib.h>
    
    volatile struct {
    	uint8_t hour;
    	uint8_t minute;
    	uint8_t second;
    	uint16_t usec;
    } time;
    
    char temp[40];
    
    int main() {
    	sei();
    
    	DDRD |= _BV(PD6);
    	PORTD |= _BV(PD6);
    
    	// Timer
    	TCCR0A |= _BV(WGM01);
    	TCCR0B |= _BV(CS01);
    	TIMSK0 |= _BV(OCIE0A);
    	OCR0A = 150;
    
    	spi_init();
    	lcd_init();
    	time.hour = 14;
    	time.minute = 28;
    	lcd_clear();
    	while (1) {
    		[Ausgabe auf LCD]
    	}
    	return 1;
    }
    
    ISR(TIMER0_COMPA_vect)
    {
    	time.usec++;
    	if (time.usec == 10000) {
    		time.usec = 0;
    		time.second++;
    		if (time.second == 60) {
    			time.second = 0;
    			time.minute++;
    			if (time.minute == 60) {
    				time.minute = 0;
    				time.hour++;
    				if (time.hour == 24) {
    					time.hour = 0;
    				}
    			}
    		}
    	}
    }
    Deine Signatur ist zu lang.

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.04.2010
    Beiträge
    1.249
    Eine Abweichung von 0,0055% ist doch erstmal nicht so schlecht. Aber 8 min Pro Tag scheinen mir auch recht viel.

    Was ist das für ein Quarz? Du meinst aber nicht den internen RC?!

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.06.2008
    Ort
    Rösrath
    Alter
    33
    Beiträge
    332
    Nein, ist ein "richtiger" Quarz im HC49-Gehäuse. Ich müsste mal ausrechnen, ob die ISR zu lang ist.. Aber das sollte doch eigentlich passen, bei 100 Mikrosekunden.
    Deine Signatur ist zu lang.

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Als Controller benutze ich einen Atmega168 mit 12MHZ-Quarz. Ich habe also Timer0 mit einem Prescaler von 8 versehen und benutze den CTC-Modus mit einem TOP-Wert von 150. Dadurch sollte rein rechnerisch alle 100 Mikrosekunden ein Interrupt ausgelöst werden.
    Nö, für einen alle-100µs-Interrupt muss TOP 149 sein. Du willst 150 Zählerschritte haben, also von 0 bis 149.
    MfG
    Stefan

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.06.2008
    Ort
    Rösrath
    Alter
    33
    Beiträge
    332
    Zitat Zitat von sternst Beitrag anzeigen
    Nö, für einen alle-100µs-Interrupt muss TOP 149 sein. Du willst 150 Zählerschritte haben, also von 0 bis 149.
    Kaum macht man es richtig, schon funktioniert's.. Danke für den Tipp, manchmal sieht man den Wald vor lauter Bäumen nicht.
    Deine Signatur ist zu lang.

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.05.2005
    Ort
    Berlin
    Beiträge
    316
    Wie misst du denn die Ventilöffnungszeit? Mit einem Timer mit Input Capture solltest du die Zeit imho am genauesten messen können. Vorausgesetzt, das Signal kommt von aussen.

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.06.2008
    Ort
    Rösrath
    Alter
    33
    Beiträge
    332
    Mit dem Input Capture wollte ich das zuerst auch machen, dieser spricht aber nur auf eine steigende Flanke an. Da ich aber nicht die Frequenz sondern die Pulslänge brauche, fällt das leider raus..

    Gemessen wird das dann über einen externen Interrupt, je nach Pegel wird ein Counter hochgezählt und der gemessene Wert auf einen 64 Bit Integer addiert (reicht für ein Jahrhundert Dauerbetrieb..). In der Hauptschleife kann ich mir dann einen entsprechenden Literwert zusammenrechnen.
    Deine Signatur ist zu lang.

  8. #8
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.05.2005
    Ort
    Berlin
    Beiträge
    316
    Du kannst programmieren, ob er auf fallende, oder steigende Flanke reagieren soll. TCCR1B Bit 6 0=> fallende Flanke, 1=> steigende Flanke.

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.06.2008
    Ort
    Rösrath
    Alter
    33
    Beiträge
    332
    Und dann in der ISR jeweils das Bit togglen?
    Deine Signatur ist zu lang.

  10. #10
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.05.2005
    Ort
    Berlin
    Beiträge
    316
    Genau. Die Methode dürfte noch ein wenig präziser sein.

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Timer0 und Timingprobleme
    Von rathma im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 10
    Letzter Beitrag: 11.05.2006, 16:01

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •