I´m using 2 mcpwm with up and down counter and could make 2 symmetric complementary wave forms with deadtime, this is ok!
But how to change the duty cycle to affect the up and down cycle?
I try to create a interrupt at the start of timer and change the dutyCycle before it start.
But it's only changing at the down part of duty cycle.
I tried with TEP,TEZ isr interrupt events and had the same results.
The TEP interrupt (in yellow, occur when it goes up or down) activate a change of duty cycle that occur before High PWM (blue), but it only work after the middle at the down part of timer. The code call a sequence of 4 cycles of 20% and 4 cycles of 60%. It have high frequency but with pwm_config.frequency = 30 has the same result.
I tried to put the mcpwm_set_duty at the interrupt, but gave this exception:
Guru Meditation Error: Core 0 panic'ed (Coprocessor exception)
This is a simplified version to test the code, and was called from arduino setup() with
xTaskCreatePinnedToCore(loopPWM, "loopPWM", 8192, NULL, 1, NULL, 0);
I could create the full example on GitHub if it helps.
Code: Select all
#include <MotorPWM.h>
#include <driver/mcpwm.h>
#include <Arduino.h>
#include <soc/mcpwm_struct.h>
static mcpwm_dev_t *MCPWM[2] = {&MCPWM0, &MCPWM1};
float acelteste = 0;
bool mudou=false;
uint8_t stg1=0;
uint32_t mcpwm_intr_status;
bool ltest = 0;
static void IRAM_ATTR isr_handler(void *arg){
mcpwm_intr_status = MCPWM[MCPWM_UNIT_0]->int_st.val;
if(mcpwm_intr_status > 0){
digitalWrite(17, ltest);
mudou = true;
}
MCPWM[MCPWM_UNIT_0]->int_clr.val = mcpwm_intr_status;
}
mcpwm_config_t pwm_config;
void setupPWM(){
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, 16);
pinMode(17, OUTPUT);//to debug isr call
pwm_config.frequency = 30000;//15Khz * 2 for up down counter
pwm_config.cmpr_a = 0; //% duty cycle of PWMxA
pwm_config.cmpr_b = 0; //% duty cycle of PWMxb
pwm_config.counter_mode = MCPWM_UP_DOWN_COUNTER;
pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config); //Configure PWM0A & PWM0B with above settings
MCPWM[MCPWM_UNIT_0]->int_ena.timer0_tep_int_ena = true;//A PWM timer 0 TEP event will trigger this interrupt
mcpwm_isr_register(MCPWM_UNIT_0, isr_handler, NULL, ESP_INTR_FLAG_IRAM, NULL); //Set ISR Handler
}
void loopPWM(void*z)
{
disableCore0WDT();//Feeding wdt was not working
delay(500);
setupPWM();
Serial.printf("\nloop2() em core: %d", xPortGetCoreID());
delay(500);
Serial.printf("start!");
delay(500);
while (1)
{
delayMicroseconds(0); //to isr can be called
if(mudou){
mudou = false;
mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, (acelteste));
stg1++;
if(stg1 <= 4)
acelteste = 20;
else
if(stg1 <= 8)
acelteste = 60;
if(stg1 == 8)
stg1 = 0;
ltest = !ltest;
}
}
}