Forum: Mikrocontroller und Digitale Elektronik ESP32 Timer-Zähler


von Levi (Gast)


Lesenswert?

Guten Morgen Zusammen,

ich habe mir ein Programm für den Arduino Mega geschrieben, welches den 
Timer-Stand TCNT1 abfragt und bei gegebener Zahl resettet.

So ist es mir möglich durch verschiedene Zählerabfragen mehrere 
PWM-Signale, auf verschiedenen PINS, Phasenversetzt, mit bis zu 60 kHz 
zu erzeugen.

Da der Arduino Mega leider nur eine 16 Mhz Glock hat, wollte ich auf den 
ESP32 umsteigen (liegt noch daheim rum). Nach einem Tag Recherche habe 
ich leider immer noch nicht herausgefunden, wie es möglich ist, beim 
ESP32 den Zähler abzufragen.

Ich weiß es gibt die mcpwm und ledc Funktion, würde es aber gerne wieder 
mit einer einfachen Timerabfrage und "löschen" des Prescalers umsetzten.

Eventuell weis ja jemand was.

Viele Grüße

: Bearbeitet durch Admin
von Joerg W. (joergwolfram)


Lesenswert?

Der ESP32 hat auch neben PWM und LEDC noch zwei Timerblöcke mit u.a. je 
zwei Zählern, die kann man auch auslesen. Ob das mit den 
Arduino-Bibliotheken geht, kann ich aber nicht sagen. Aber man könnte ja 
auch direkt auf die Register zugreifen, was der Geschwindigkeit 
sicherlich nicht abträglich ist.

Andererseits bieten auch MCPWM und LEDC die Möglichkeit phasenversetzter 
PWM Signale, da kommt es dann auf Deine Anforderungen an. Beim LEDC 
lässt sich z.B. die Phase über die HPOINT Register unabhängig von Duty 
einstellen.

Jörg

von Levi (Gast)


Lesenswert?

Hi Jörg,

das mit den Timerblöcken ist mir bewusst, jedoch habe ich noch nicht 
gefunden wie man den Zähler beim ESP32 auslesen kann. Es gibt mehrere 
Anwendungsbeispiele mit Interrupts, das ist aber für meinen 
Anwendungsfall nicht das richtige.
Beim Arduino Mega war das sehr geschickt, da man den Zähler auslesen 
kann (Zählt mit Glock-Geschwindigkeit) und ab einem Wert beliebig 
löschen kann.

Hast du mir eventuell ein Minimalbeispiel für den Phasenversatz bei 
LEDC?
Mein Anwendungsfall ist eigentlich relativ simpel. Ich habe 2 
PWM-Signale mit 50 kHz erzeugt, eines davon muss ich jetzt um 180° also 
50% verschieben (nicht invertieren!).

Das Internet spuckt dazu leider nicht viel, bzw. für mich 
unverständliches aus.

Viele Grüße

von John P. (brushlesspower)


Lesenswert?


von Joerg W. (joergwolfram)


Lesenswert?

Passenden Code kann ich leider keinen liefern, da ich erst dabei bin, 
meine eigene HAL-Bibliothek an den ESP32 anzupassen.

Laut Doku liegt das LEDC_HSCH0_HPOINT_REG bei 0x3FF59020 und das für 
Kanal 1  bei 0x3FF59030, HPOINT liegt in den untersten 20 Bits. Daher 
sollte es für Kanal 1 so gehen:
1
    volatile uint32_t *pointer;
2
3
    pointer = 0x3FF59030;
4
    *pointer = phase;

Ohne Garantie, denn das Refmanual vom ESP32 enthält leider eine Menge 
Fehler oder Uneindeutigkeiten. Phase ist natürlich auch noch von der 
Frequenz (genutzte Bitbreite) abhängig.

Jörg

von Levi (Gast)


Lesenswert?

Hi John,

wie kann ich damit dann weiter verfahren?
uint64_t timerRead(hw_timer_t *timer);

Alles was ich benötige ist ein simples:

If(timer >= 256){
..
..
timer = 0; }

..
Es muss doch so auf irgendeine Art und Weiße der Zählerstand abgefragt 
werden können?

von Levi (Gast)


Lesenswert?

Ich möchte gerne 80 MHz / 30.000 = 2666

Also meine Auflösung beträgt 2666 Bit bei 30 kHz.
Hast du mir da eventuell die vollständige Implementierung? Ich bin nicht 
tief in der ESP32 Thematik drin.

Grüße

von John P. (brushlesspower)


Lesenswert?

Levi schrieb:
> Ich möchte gerne 80 MHz / 30.000 = 2666
>
> Also meine Auflösung beträgt 2666 Bit bei 30 kHz.
> Hast du mir da eventuell die vollständige Implementierung? Ich bin nicht
> tief in der ESP32 Thematik dri

Das heißt du hast noch garkeine Timer beim ESP32 initialisiert?
Dann solltest du das mal tun, Beispiele gibt es genug.

Levi schrieb:
> wie kann ich damit dann weiter verfahren?
> uint64_t timerRead(hw_timer_t *timer);
>
> Alles was ich benötige ist ein simples:
>
> If(timer >= 256){
> ..
> ..
> timer = 0; }
>
> ..
> Es muss doch so auf irgendeine Art und Weiße der Zählerstand abgefragt
> werden können?

timer = timerRead(TIMER1);
if(timer >= 256){

}


und so weiter. Eigentlich ganz einfach.

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.