PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timingprobleme



pyr0skull
17.04.2011, 14:23
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:


#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;
}
}
}
}
}

TobiKa
17.04.2011, 14:35
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?!

pyr0skull
17.04.2011, 14:43
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.

sternst
17.04.2011, 14:50
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.

pyr0skull
17.04.2011, 15:36
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. O:)

lokirobotics
18.04.2011, 08:31
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.

pyr0skull
18.04.2011, 08:34
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.

lokirobotics
18.04.2011, 08:56
Du kannst programmieren, ob er auf fallende, oder steigende Flanke reagieren soll. TCCR1B Bit 6 0=> fallende Flanke, 1=> steigende Flanke.

pyr0skull
18.04.2011, 09:52
Und dann in der ISR jeweils das Bit togglen?

lokirobotics
18.04.2011, 12:39
Genau. Die Methode dürfte noch ein wenig präziser sein.

pyr0skull
18.04.2011, 13:09
Ok, das kann ich auf jeden Fall mal ausprobieren. Problem ist eben, dass ich dadurch einen Timer verlieren und die genauere Erfassung durch Temperaturschwankungen und andere äußere Faktoren direkt wieder aufgehoben wird..

lokirobotics
18.04.2011, 13:30
Brauchst du denn so viele Timer, dass es dann kritisch wird?
"Temperaturschwankungen und andere äußere Faktoren" => Die heben die Genauigkeit, in Bezug auf die andere Lösung, nicht auf, da sie da ebenso drauf Einfluss nehmen.