wie kann man die Hardware Timer im Prozessor ansprechen?

Hallo liebe Arduinofreunde,

ich habe schon in anderen ATMEGA Umgebungen gearbeitet und bin von den Prozessoren ziemlich angetan. Nun möchte ich die Arduinoumgebung kennenlernen (derzeit Nano). Dabei bin ich auf ein vermeintliches Problem gestoßen: der Zugriff auf die Hardwaretimer des Prozessors.

Ich benötige für meine Programierung (PWM bei 38 kHz für Infrarot LED) den Zugriff auf zwei der Timer auf dem Atmel Prozessor und habe für Timer1 die Lib TimerOne.h gefunden. Wie kann ich z.B. auf Timer3 zugreifen? Gibt es eine generelle und dauerhaft gepflegte Library für den Zugriff auf mehr als einen Timer?

Besten Dank
Exacompta

PS Ich weiß, dass die Timer teilweise für andere Zwecke (tone, PWM etc) genutzt werden, die Querbeziehungen würde ich bei der Programmierung berücksichtigen.

exacompta:
Ich benötige für meine Programierung (PWM bei 38 kHz für Infrarot LED) den Zugriff auf zwei der Timer auf dem Atmel

Oder vielleicht benötigst Du ja auch nur eine fertige IRemote-Library? Z.B.:

exacompta:
Wie kann ich z.B. auf Timer3 zugreifen?

Alle verschiedenen Betriebsarten und diversen Funktionen und Register der Timer/Counter werden im jeweiligen vollständigen Datenblatt des Controllers erklärt. Beim Nano mit dem Atmega328 wäre das dieser Wälzer mit fast 700 Seiten:

Laut Datenblatt kannst Du bei einem Atmega328 überhaupt nicht auf einen "Timer3 zugreifen" wie Du es ausdrückst. Der Atmega328 hat zwar drei Timer, aber diese werden Timer0, Timer1 und Timer2 durchgezählt (wovon Timer0 bereits von der Arduino-Software verwendet wird, z.B. um den millis()-Zeitzähler bereitzustellen).

Google ist dein Freund
Hier ist auch nochmal einiges.
http://www.wrightflyer.co.uk/Using%20AVR%20Counter.pdf
Gruß
Der Dani

Timer3 und höher gibt es nur auf dem Mega

Wenn du wie gesagt nach "AVR Timer" oder "Arduino Timer" googelst, findest du da eine Menge Tutorials. Wobei aber viele nur die Standard-Modi behandeln, und PWM etwas außen vor lassen. Aber erst mal z.B. CTC zu verstehen hilft auch sich in die Timer einzuarbeiten.

Hallo liebe Arduinofreunde,

vielen Dank fuer das Feedback.
@jurs:

  • Ja, das mit der IR Lib ist ein guter Tipp, jedoch brauch ich nur ein ganz minimales Codeschnipsel zum Ansteuern der LED.
  • AVR Doku: ist mir ein bisschen lang.
  • Timer Nummerierung: Du hast natuerlich Recht: Die Timer werden von 0 bis 2 durchgezaehlt, Timer2 ist also der dritte Timer, sorry.

@serenifly:
Ja es gibt viele Tutorials, dachte aber, dass das in der Basisimplementierung zum Mega enthalten waere und dass ich es nur nicht gefunden haette. Danke!

@volvodani: Danke für den Hinweis, das Tutorial ist ziemlich klar geschrieben. Habe das ganze aber dann wie folgt gelöst (s.u.).

Dank an alle, exacompta

Aufgabe war eine LED mit 38 kHz anzusteuern und einen Puls mit 600 Mikrosekunden HIGH und 600 Mikrosekunden LOW darueberzulegen. Hat bisher gut geklappt. Bin enthusiasmiert. Nano HW ist auch ziemlich nett.

Code ist:

/*
Programm IR-Sender mit timer1 und tone-funktion
Eine LED an PIN 13 wird mit 38 kHz angesteuert
und mit einer Pulslaenge von 600 Mikrosekunden ausgetastet
Dutycycle ist 50%
*/

#include "TimerOne.h"

boolean toggle=0;
const int outputpin=13; // PIN 13 testweise als Outputpin
const int traegerfrequenz=38000; // 38 kHz Traegerfrequenz
const int pulslaenge=600; // Pulslaenge sind 600 Mikrosekunden

long int z=0; // Testzwecke

void setup()
{
Serial.begin(9600);
starte_sender();
};

void starte_sender()
{
Timer1.initialize(pulslaenge);
Timer1.attachInterrupt(ISR_burst);
};

void ISR_burst() // schaltet Traegersignal ein und aus
{
if (toggle==0) {tone(outputpin, traegerfrequenz); toggle=1; z=z+1;} else {noTone(outputpin); toggle=0;z=z+1;};
};

void loop(){

// Test: in 600 Millisekunden wird die LED ziemlich genau 500 mal hell und 500 mal dunkel gesteuert
Serial.println(z);
delay(600);

// todo: Auswertung des reflektierten Signals mit TSOP 4838

};

exacompta:

  • AVR Doku: ist mir ein bisschen lang.

Du musst ja nicht alles auf einmal lesen. Man sucht sich immer den Abschnitt zum aktuellen Problem und liest den relevanten Teil durch. Oder immerhin die Register-Beschreibung.

Und denke daran, dass du Variablen, die innerhalb und außerhalb von Interrupts verwendest als volatile deklarierst!