欧博How to select a timer in ESP32 Arduino API 3.0

bdrmachine:

Where do I select the timer number?

an ESP32 has 4 timers - you check the return from timerBegin() - if it is NULL it failed
this uses 4 timers to generate three phase square waves

// ESP32 three phase square wave variable duty cycle using timers #define phase1 16 // signal output pins #define phase2 18 #define phase3 17 unsigned long int period = 10000; // timer interval in uSec unsigned long duty_cycle = 50; // percentage unsigned long pulse_width = period * duty_cycle / 100; // * 50 / 100; hw_timer_t *timerperiod = NULL; // hardware timer hw_timer_t *timerPhase1 = NULL; // hardware timer hw_timer_t *timerPhase2 = NULL; // hardware timer hw_timer_t *timerPhase3 = NULL; // hardware timer // interrupt service routine to generate HIGH levels volatile int counter = 0; // interrupt counter void ARDUINO_ISR_ATTR onTimer() { static byte state = 0; // determines which phase to generate switch (state) { case 0: digitalWrite(phase1, HIGH); // set phase output HIGH timerWrite(timerPhase1, 0); // clear timer timerAlarm(timerPhase1, pulse_width, false, 0); // generate one shot break; case 1: digitalWrite(phase2, HIGH); timerWrite(timerPhase2, 0); timerAlarm(timerPhase2, pulse_width, false, 0); // generate one shot break; case 2: digitalWrite(phase3, HIGH); timerWrite(timerPhase3, 0); timerAlarm(timerPhase3, pulse_width, false, 0); // generate one shot break; } if (++state >= 3) state = 0; // reset state ? counter++; } // interrupt service routines to generate LOW levels void ARDUINO_ISR_ATTR onTimerPhase1() { digitalWrite(phase1, LOW); // set phase output LOW } void ARDUINO_ISR_ATTR onTimerPhase2() { digitalWrite(phase2, LOW); } void ARDUINO_ISR_ATTR onTimerPhase3() { digitalWrite(phase3, LOW); } void setup() { Serial.begin(115200); delay(2000); Serial.println("\n\nESP32 timer three phase square wave with duty Cycle"); pinMode(phase1, OUTPUT); // enable phase outputs pinMode(phase2, OUTPUT); pinMode(phase3, OUTPUT); digitalWrite(phase3, 1); // setup timer interrupts for 1KHz three phase if ((timerperiod = timerBegin(10000000)) == NULL) // Set timer frequency to 10Mhz Serial.println("ERROR! timer period initialisation failed"); else Serial.println("Timer period initialization OK"); if ((timerPhase1 = timerBegin(10000000)) == NULL) // Set timer frequency to 10Mhz Serial.println("ERROR! timer Phase 1 initialisation failed"); else Serial.println("Timer Phase 1 initialization OK"); if ((timerPhase2 = timerBegin(10000000)) == NULL) // Set timer frequency to 10Mhz Serial.println("ERROR! timer Phase 2 initialisation failed"); else Serial.println("Timer Phase 2 initialization OK"); if ((timerPhase3 = timerBegin(10000000)) == NULL) // Set timer frequency to 10Mhz Serial.println("ERROR! timer Phase 3 initialisation failed"); else Serial.println("Timer Phase 3 initialization OK"); timerAttachInterrupt(timerperiod, &onTimer); // Attach timer ISR for period timing timerAttachInterrupt(timerPhase1, &onTimerPhase1); // attch timers ISR for pulse timing timerAttachInterrupt(timerPhase2, &onTimerPhase2); timerAttachInterrupt(timerPhase3, &onTimerPhase3); // Set alarm to call onTimer function every second (value in 10 microseconds). // Repeat the alarm (third parameter) with unlimited count = 0 (fourth parameter). timerAlarm(timerperiod, period / 3, true, 0); Serial.println("period increment > (* by 10) decrement < (/ by 10)"); Serial.println(" duty cycle enter 1 (for 10%) to 9 (for 90%)\n"); } // display interrupt coun ter every seconds void loop() { static unsigned long int unit = 10000; // check if updated period or duty cycle entered while (Serial.available()) { // if characters entered read them char ch = Serial.read(); if (!isprint(ch)) continue; if (ch == '>') { period += unit; if (period / unit >= 10) unit *= 10; } // < decrement value by 1 unit - minimum is 1 ? if (ch == '<' && period != 1) { if (period == unit) unit = unit / 10; period -= unit; } // * increment value by 10 ? if (ch == '*') { period = unit = unit * 10; } // / decrement value by 10 - minimum is 1 if (ch == '/' && period != 1) { if (period == unit) unit = unit / 10; period = unit; } if ((ch >= '1') && (ch <= '9')) duty_cycle = (ch - '0') * 10; // set duty cycle // duty_cycle=50; pulse_width = period * duty_cycle / 100; Serial.print("period = "); Serial.print(period); Serial.print(" frequency = "); Serial.print(10000000.0 / (period)); Serial.print(" dutyCycle "); Serial.print(duty_cycle); Serial.print(" pulse width "); Serial.println(pulse_width); timerAlarm(timerperiod, period / 3, true, 0); } // every second print interupt counter static unsigned long timert = millis(); if (millis() - timert >= 1000) { Serial.println(counter); counter = 0; timert = millis(); } }

output

1KHz_three_phase_square_wave

1KHz_three_phase_square_wave320×240 28 KB


probably more efficient to use the Remote Control Transceiver (RMT)
however, if generating multiple signals the the ESP32 does not support the sync manager - use an ESP32S3?

2026-01-03 14:44 点击量:0