Я пытаюсь управлять преобразователем H-моста, используя один генератор ШИМ для каждой диагонали (в моем случае ШИМ1 и ШИМ4).
Я хочу иметь возможность контролировать как частоту, так и рабочий цикл. Для этого я генерирую триггерное прерывание в начале периода PWM4, а затем обновляю регистры для периода, фазы и рабочего цикла для обоих каналов PWM.
Проблема в том, что когда происходит это обновление, в течение одного периода или около того наблюдается какое-то непредвиденное поведение. См. Картинку.
PWM4 - голубой, PWM1 - пурпурный, а желтый переключается, когда происходит прерывание запуска для PWM4.
Кажется, что PWM1 (пурпурный) обновляется до более медленной частоты (как и должно), но PWM4 продолжает работать на старой в течение другого периода. Также PWM1 выдает еще один короткий импульс. Я измерил время, необходимое для обновления значений регистров периода, режима работы и фазы, и оно составляет около 1 мкс, так что это не должно быть проблемой. Вот конфигурации ШИМ:
void PWM4Config() {
ANSELEbits.ANSE6 = 0;
ANSELEbits.ANSE7 = 0;
TRISEbits.TRISE6 = 0;
TRISEbits.TRISE7 = 0;
PTPER = 7002; //period je 50us
PTCON2bits.PCLKDIV = 0b000; //1:1
//fazni stavovi
PHASE4 = 0;
SPHASE4 = 0;
//duty
PDC4 = 3501;
SDC4 = 3501;
//dead time
DTR4 = 0;
//set PWM mode to independent, active high
IOCON4bits.PENH = 1;
IOCON4bits.PENL = 1;
IOCON4bits.POLH = 0;
IOCON4bits.POLL = 0;
IOCON4bits.PMOD = 0b11;
IOCON4bits.OVRENH = 0;
IOCON4bits.OVRENL = 0;
IOCON4bits.OVRDAT = 0b00;
IOCON4bits.FLTDAT = 0b00;
IOCON4bits.CLDAT = 0b00;
IOCON4bits.SWAP = 0;
IOCON4bits.OSYNC = 0;
//set primary time base, edge aligned, independent duty cycles
PWMCON4 = 0x0000;
//PWMCON4bits.IUE = 1; //privremeno
//config faults
FCLCON4 = 0x0003;
//config trigger & interrupt
IFS6bits.PWM4IF = 0;
IEC6bits.PWM4IE = 1;
TRGCON4 = 0x0000; //triger at every period of pwm
TRIG4 = 0x0000; //triger at start of pwm period
PWMCON4bits.TRGIEN = 0;
}
void PWM1Config() {
ANSELEbits.ANSE0 = 0;
ANSELEbits.ANSE1 = 0;
TRISEbits.TRISE0 = 0;
TRISEbits.TRISE1 = 0;
PTPER = 7002; //period je 50us
PTCON2bits.PCLKDIV = 0b000; //1:1
//fazni stavovi
PHASE1 = 3051;
SPHASE1 = 3501;
//duty
PDC1 = 3501;
SDC1 = 3501;
//dead time
DTR1 = 0;
//set PWM mode to independent, active high
IOCON1bits.PENH = 1;
IOCON1bits.PENL = 1;
IOCON1bits.POLH = 0;
IOCON1bits.POLL = 0;
IOCON1bits.PMOD = 0b11;
IOCON1bits.OVRENH = 0;
IOCON1bits.OVRENL = 0;
IOCON1bits.OVRDAT = 0b00;
IOCON1bits.FLTDAT = 0b00;
IOCON1bits.CLDAT = 0b00;
IOCON1bits.SWAP = 0;
IOCON1bits.OSYNC = 0;
//set primary time base, edge aligned, independent duty cycles
PWMCON1 = 0x0000;
//PWMCON1bits.IUE = 1; //privremeno
//config faults
FCLCON1 = 0x0003;
//config trigger & interrupt
//IFS5bits.PWM1IF = 0;
//IEC5bits.PWM1IE = 1;
//TRGCON1 = 0x0000; //triger na svakom periodu pwm-a
//TRIG1 = 0x0000; //triger je na pocetku pwm-a
//PWMCON1bits.TRGIEN = 0;
}
Они установлены в независимый режим с использованием основной временной развертки.