-
-
Save fabiovila/77c544286e9b0260a5a09823b47ba39f to your computer and use it in GitHub Desktop.
// CHANGE the clock prescale in mcpwm.c file to make possible get 30000hz of pwm frequency (15Khz in center aligned mode) | |
#define MCPWM_BASE_CLK (2 * APB_CLK_FREQ) //2*APB_CLK_FREQ 160Mhz | |
#define MCPWM_CLK_PRESCL 1 //MCPWM clock prescale Original = 15 <--------------------- | |
#define TIMER_CLK_PRESCALE 1 //MCPWM timer prescales Original = 9 <--------------------- | |
#define MCPWM_CLK (MCPWM_BASE_CLK/(MCPWM_CLK_PRESCL +1)) | |
#define MCPWM_PIN_IGNORE (-1) | |
#define OFFSET_FOR_GPIO_IDX_1 6 | |
#define OFFSET_FOR_GPIO_IDX_2 75 |
mcpwm_config_t pwm_config; | |
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_PWM0A_OUT); | |
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, GPIO_PWM0B_OUT); | |
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM1A, GPIO_PWM1A_OUT); | |
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM1B, GPIO_PWM1B_OUT); | |
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM2A, GPIO_PWM2A_OUT); | |
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM2B, GPIO_PWM2B_OUT); | |
Motor.TabelaLimite = 0; | |
// Center aligned pwm mode complementary mode | |
// 15Khz frequency | |
// 95% initial duty cibly | |
pwm_config.frequency = 30000; //frequency | |
pwm_config.cmpr_a = 95.0; // Duty em porcentagem | |
pwm_config.cmpr_b = pwm_config.cmpr_a; | |
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_init(MCPWM_UNIT_0, MCPWM_TIMER_1, &pwm_config); //Configure PWM1A & PWM1B with above settings | |
mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_2, &pwm_config); //Configure PWM2A & PWM2B with above settings | |
// deadtime (see clock source changes in mcpwm.c file) | |
mcpwm_deadtime_enable(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, 80, 80); // 1us deadtime | |
mcpwm_deadtime_enable(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, 80, 80); | |
mcpwm_deadtime_enable(MCPWM_UNIT_0, MCPWM_TIMER_2, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, 80, 80); | |
// TEZ interrupts (TIMERS in ZERO before ascending) | |
MCPWM[MCPWM_UNIT_0]->int_ena.val = BIT(3) | BIT(4) | BIT(5); // /*A PWM timer X TEZ event will trigger this interrupt*/ | |
mcpwm_isr_register(MCPWM_UNIT_0, isr_handler, NULL, ESP_INTR_FLAG_IRAM, NULL); //Set ISR Handler | |
// ------ READ THIS | |
// mcpwm_sync_signal_t is defined only to SYNC0/1/2 that are for GPIO sync | |
// In order to sync Timer1 and Timer2 with Timer0 | |
// Pass 1 to mcpwm_sync_signal_t sync_sig in mcpwm_sync_enable | |
// 1 is equal to "PWM timer0 sync_out" in PWM_TIMER_SYNCI_CFG_REG.PWM_TIMER1/2_SYNCISEL | |
// Phase (last parameter) is zero. | |
mcpwm_sync_enable(MCPWM_UNIT_0, MCPWM_TIMER_1, 1, 0); | |
mcpwm_sync_enable(MCPWM_UNIT_0, MCPWM_TIMER_2, 1, 0); | |
// Timer0 is our sync out. When it is equal to zero and before ascending sync out is triggered, so Timer1 and Timer2 stands in sync_in with Timer0. | |
// When Timer0 is zero Timer1 and Timer2 is forced to phase defined in last parameter in functions above (0). | |
// Make Timer0 sync out in TEZ | |
MCPWM[MCPWM_UNIT_0]->timer[MCPWM_TIMER_0].sync.out_sel = 1; | |
// So: | |
// [TIMER0](When in Zero)->[TIMER1=0] | |
// ->[TIMER2=0] | |
// Ref: | |
// esp32_technical_reference_manual_en.pdf around pages 439 | |
// mcpwm.h | |
// mcpwm_struct.h | |
// try and error!! | |
Marcarleto,
This is like the complete code of the project, it seems to be esp-idf: https://github.com/fabiovila/ESP32ACMotorInverter_Test/blob/master/main/motor.c
Hi. It seems like mcpwm.c is deprecated and now is replaced by mcpwm_prelude.c
Is there any chance you updated your code to be used with ESP-IDF 5.1? I'm struggling to generate 100kHz PWM while maintaining 8 bit resolution.
I'm trying to use MCPWM_UP_DOWN_COUNTER
and my frequency range is 10K - 100K, i know i have to provide double the frequency to generate the center aligned output. but the factor of twice the frequency changes when i above 12K, for instance if i want to generate 100K i'm providing 200K as frequency but the output is 125K instead. I've also tried to make a loop to see the linearity but by decreasing the value 200K then next jumps comes at around 83K and so on...., this only happens in MCPWM_UP_DOWN_COUNTER if i am using the other mode its fine.
The code snippet is attached below, any help would be appreciated. thanks
mcpwm_config_t pwm_configA;
pwm_configA.frequency = 40000; // frequência = 500Hz,
pwm_configA.cmpr_a = 50; // Ciclo de trabalho (duty cycle) do PWMxA = 0
pwm_configA.cmpr_b = 50; // Ciclo de trabalho (duty cycle) do PWMxb = 0
pwm_configA.counter_mode = MCPWM_UP_DOWN_COUNTER; // Para MCPWM assimetrico
pwm_configA.duty_mode = MCPWM_DUTY_MODE_0; // Define ciclo de trabalho em nível alto
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, Pulse_Pin_1);
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, Pulse_Pin_2);
mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_configA); // Define PWM0A & PWM0B com as configurações acima
int DutyCycle = 50;
mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, DutyCycle);
mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_B, 100 - DutyCycle); // Configura a porcentagem do PWM no Operador B (Ciclo de trabalho)
mcpwm_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, MCPWM_DUTY_MODE_0);
mcpwm_set_duty_type(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_B, MCPWM_DUTY_MODE_1);
Is this in Arduino IDE?