Forum: Mikrocontroller und Digitale Elektronik Arduino Micro OCR1A Frequenz messen


von Black D. (Gast)


Lesenswert?

Moin, ich versuche grad die eingestellte Frequenz meines Timer1 zu 
messen. Meine erste Idee war den Pin 8 bei jedem Durchlauf des 
Interrputs high und low zu setzten. Da komme ich aber nur auf eine 
Frequenz von 57kHz. Also scheint das nicht zu funktionieren. Habt ihr da 
noch andere Ideen?
1
pinMode(8,OUTPUT);
2
3
//Timer1 instalisieren
4
TCCR1A = 0;                     //Register definiert zurücksetzten
5
TCCR1B = 0;                     //zuerst Register definiert zurücksetzen
6
TCNT1 = 0;                      //Zählerwert zurücksetzten
7
8
OCR1A = 199;                    //Timer1 80kHZ einstellen
9
TCCR1B |= (1 << WGM12);         //CTC mode
10
//TCCR1B |= (0 << CS12) | (0 << CS11) | (1 >> CS10); //kein Prescale
11
TCCR1B |= (1 << CS10);          // clk/1 prescale 1024
12
TIMSK1 |= (1 << OCIE1A);        //Aktivieren des Timer-Vergleichs-Interrupt
13
}
14
15
ISR(TIMER1_COMPA_vect){         //Interrupt
16
digitalWrite(8,HIGH);
17
digitalWrite(8,LOW);
18
}

von Falk B. (falk)


Lesenswert?

Black D. schrieb:
> Moin, ich versuche grad die eingestellte Frequenz meines Timer1 zu
> messen. Meine erste Idee war den Pin 8 bei jedem Durchlauf des
> Interrputs high und low zu setzten.

Kann man so machen, wenn gleich die Funktion digitalWrite() ein wenig 
lahm ist. Die dauert ca. 8us.

Du musst die Register nicht vorher auf Null setzen. Erstens sind die 
nach dem Reset definiert auf Null, zweitens man einen kompletten, neuen 
Wert rein. Nur beim Interrupt-Enable setzt man ein einzelnes Bit, weil 
man dort andere Bits nicht verändern will udn auch nicht weiß, was dort 
drin steht.
Warum meinst du, einen Vorteiler von 1024 zu brauchen, um 80kHz zu 
erzeugen? Schon mal gerechnet?

F_PWM = F_CPU / (PRESCALER * OCR1A + 1) = 16e6 / (1024 * 199 +1) = 
78,125

Man rechnet das so. Bei gewünschten 80kHz sind das 200, aber mit 
Prescaler 1!
Wie mißt du denn das SIignal? Mit einem Oszi? Oder einem billigen 
Multimeter mit Frequenzmeßfunktion? Man kann es auch leichter machen, 
indem man im Interrupt das IO-Pin umschaltet (neudeutsch, toggeln). Dann 
hat man zwar nur die halbe Frequenz, die aber mit entspannten 50% 
Tastverhältnis. Das kann man einfacher messen. F_CPU wird schon von der 
Arduino IDE definiert.
1
#define F_TIMER 80000L
2
#define PRESCALER 1
3
#define RELOAD (F_CPU / ( F_TIMER * PRESCALER) - 1)
4
5
pinMode(8,OUTPUT);
6
//Timer1 einstellen
7
OCR1A = RELOAD;
8
TCCR1A = 0;
9
TCCR1B = (1 << WGM12) | (1<<CS10);         //CTC mode, prescaler 1
10
TIMSK1 |= (1 << OCIE1A);        //Aktivieren des Timer-Vergleichs-Interrupt
11
}
12
13
ISR(TIMER1_COMPA_vect) {         //Interrupt
14
  digitalWrite(!digitalRead(8));  // umschalten, -> halbe ISR-Frequenz am IO-Pin
15
}

von EAF (Gast)


Lesenswert?

Falk B. schrieb:
> digitalWrite(!digitalRead(8));  // umschalten, -> halbe ISR-Frequenz
> am IO-Pin

57kHz, mehr sind so wohl nicht zu erreichen.

Man verwende dort direkte Portzugriffe.
Und evtl die Tooglefähigkeit des Pins

von Falk B. (falk)


Lesenswert?

EAF schrieb:
> 57kHz, mehr sind so wohl nicht zu erreichen.

Hmm, stimmt. 80 kHz sind 12,5us Periodendauer. Das wird SEHR eng mit dem 
Interrupt, welcher VIELE Register sichern muss (wegen dem 
Funktionsaufruf) und den beiden lahmen Arduino-Funktionen.

Alles in allem sind 80 kHz ISR-Frequenz so oder so schon SEHR hoch und 
nix für Anfänger.

von EAF (Gast)


Lesenswert?

Falk B. schrieb:
> (wegen dem
> Funktionsaufruf) und den beiden lahmen Arduino-Funktionen.
Yes!

OCR1A hat einen Pin zur direkten Ausgabe der Frequenz.
Eigentlich ist so gar keine ISR nötig.

von Falk B. (falk)


Lesenswert?

EAF schrieb:
> OCR1A hat einen Pin zur direkten Ausgabe der Frequenz.
> Eigentlich ist so gar keine ISR nötig.

Er will vermutlich was anderes damit machen.

von EAF (Gast)


Lesenswert?

Falk B. schrieb:
> Er will vermutlich was anderes damit machen.

Durchaus möglich.
Aber so ließe sich der Timer selber (und seien Einstellung) unabhängig 
von dem ISR Code testen.

von m.n. (Gast)


Lesenswert?

Frequenz, Periode, Drehzahl mit einem Arduino: 
http://mino-elektronik.de/fmeter/fm_software.htm#bsp7
Ein bisschen oberhalb stehen weitere Erklärungen zu Schaltung/Programm.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

wenn man mit Arduino setup/loop verwendet, was hier der Fall ist, sonst 
würde digitalWrite usw. nicht kompilieren, dann muss man vor eigener 
Timer Konfiguration die Register nullen. Zumindestens die die man nicht 
ändert. Weil die sonst mit Standardwerten für analogWrite (PWM) 
vorbelegt sind und dann der Timer nicht so konfiguriert ist wie man 
denkt.

Und mit Prescaler 1 muss der Compare Wert für 80kHz 199 oder 99 sein, je 
nachdem ob wirklich die Timerfrequenz oder die Signalfrequenz gemeint 
ist.
CTC Mode:
1
OCRnA = (F_CPU / 2 / PRESCALER / fOCnA) - 1

: Bearbeitet durch User
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
Noch kein Account? Hier anmelden.