PWM desde C en simulink

#1
Buenas. Necesito algo de ayuda, después de dar muchas vueltas, muchas búsquedas y largo etcétera no he logrado lo siguiente:

Tengo que implementar un PWM en Simulink a partir de un código en C de un dsPIC 30f2010. Se necesita para una simulación de un convertidor CC/CA basado en Push-Pull con un PIC generando el PWM. ¿Alguna sugerencia? Gracias de antemano.

El código en C programado en el PIC es el siguiente:



// Dos señales semiciclo SPWM desfasada 180º
#include "p30f2010.h" // DTCON1:poner deat time de 3 microsegundos entre pwm1 y pwm2 con DTCON1 o tabla(matriz)
#include "pwm.h" // Borrar todo lo que sobra, (//)
//BITS DE CONFIGURACIÓN // PWMCON1: Configurar como salidas PWM1 y PWM2, sin modo complementar
_FOSC(XT_PLL8); //PLLx16 y modo XT
_FWDT(WDT_OFF); //WatchDog timer OFF


#define Fcy 96000000/4 // Frecuencia de instruccion
#define Fpwm 20000 // Frecuencia del PWM

//TABLA PWM PARA 230V
int PWMTable230[]__attribute__((far,section(".const,r")))=
{16,48,80,112,145,177,209,241,272,304,336,368,399,431,462,493,525,556,587,617,648,678,708,739,768,798,828,857,
886,915,944,972,1000,1028,1056,1083,1110,1137,1164,1190,1216,1242,1267,1292,1317,1342,1366,1389,1413,1436,1459,
1481,1503,1525,1546,1567,1587,1608,1627,1647,1665,1684,1702,1720,1737,1754,1770,1786,1801,1817,1831,1845,1859,
1872,1885,1897,1909,1920,1931,1942,1952,1961,1970,1979,1987,1994,2001,2008,2014,2019,2024,2029,2033,2036,2039,
2042,2044,2045,2046,2047,2047,2046,2045,2044,2042,2039,2036,2033,2029,2024,2019,2014,2008,2001,1994,1987,1979,
1970,1961,1952,1942,1931,1920,1909,1897,1885,1872,1859,1845,1831,1817,1801,1786,1770,1754,1737,1720,1702,1684,
1665,1647,1627,1608,1587,1567,1546,1525,1503,1481,1459,1436,1413,1389,1366,1342,1317,1292,1267,1242,1216,1190,
1164,1137,1110,1083,1056,1028,1000,972,944,915,886,857,828,798,768,739,708,678,648,617,587,556,525,493,462,431,
399,368,336,304,272,241,209,177,145,112,80,48,16,
16,48,80,112,145,177,209,241,272,304,336,368,399,431,462,493,525,556,587,617,648,678,708,739,768,798,828,857,
886,915,944,972,1000,1028,1056,1083,1110,1137,1164,1190,1216,1242,1267,1292,1317,1342,1366,1389,1413,1436,1459,
1481,1503,1525,1546,1567,1587,1608,1627,1647,1665,1684,1702,1720,1737,1754,1770,1786,1801,1817,1831,1845,1859,
1872,1885,1897,1909,1920,1931,1942,1952,1961,1970,1979,1987,1994,2001,2008,2014,2019,2024,2029,2033,2036,2039,
2042,2044,2045,2046,2047,2047,2046,2045,2044,2042,2039,2036,2033,2029,2024,2019,2014,2008,2001,1994,1987,1979,
1970,1961,1952,1942,1931,1920,1909,1897,1885,1872,1859,1845,1831,1817,1801,1786,1770,1754,1737,1720,1702,1684,
1665,1647,1627,1608,1587,1567,1546,1525,1503,1481,1459,1436,1413,1389,1366,1342,1317,1292,1267,1242,1216,1190,
1164,1137,1110,1083,1056,1028,1000,972,944,915,886,857,828,798,768,739,708,678,648,617,587,556,525,493,462,431,
399,368,336,304,272,241,209,177,145,112,80,48,16};
int PWMPtrCntMax = 400;
int PWMPtrCntHalf = 200;
int PWMPtrCnt;


void Config_PWM(void); // Initialization for PWM at 20kHz, Center aligned,
// Complementary mode with 1 us of deadtime

void __attribute__((__interrupt__)) _PWMInterrupt (void)
{
IFS2bits.PWMIF = 0; // Borra bandera de interrupcion
PTCONbits.PTEN = 1;
if (PWMPtrCnt < PWMPtrCntHalf){ //Semiciclo positivo
PDC2 = 0;
PDC1 = PWMTable230[PWMPtrCnt];
}
else{ //Semiciclo negativo
PDC1 = 0;
PDC2 = PWMTable230[PWMPtrCnt];
}

PWMPtrCnt += 1;
if (PWMPtrCnt>=PWMPtrCntMax) PWMPtrCnt=0;

return;
}



int main (void){

Config_PWM(); //Inicializa a 20KHz la señal PWM y el DEAD TIME
PWMPtrCnt = 0;
while (1){
IEC2bits.PWMIE = 1;
// PTCONbits.PTEN = 1;
}

}

void Config_PWM(void)
{
PDC1 = 0; // setup duty cycle for PWM1
PDC2 = 0; // setup duty cycle for PWM2


PWMCON1= 0B0000000000110011; //Configura PWM1L,PWM2L,PWM1H, PWM2H como salidas PWM funcionando en modo complementario
PTPER = ((Fcy/Fpwm)- 1); //Según ecuación 15-1 del documento "dsPIC30F Family Reference Manual"
//PTCON = 0; //Operación en modo "free running". Base de tiempo para PWM es Tcy, sin "postcaler". En modo de espera del micro, el reloj del PWM sigue contando
PTCONbits.PTMOD= 0;
PTCONbits.PTEN = 1;
DTCON1 = 0B0010010000100100; //Dead time igual a 36 veces Tcy tanto para la PWM1 como PWM2
// IEC2bits.PWMIE = 1; //Habilitar interrupción PWM (desborde del registro PTMR)
// IFS2bits.PWMIF = 0; //Borrar bandera de interrupción


return;

// TRISE = 0; // PWM pins como salidas
// PTPER = (Fcy/Fpwm - 1) >> 1; // Compute Period based on CPU speed and
// //required PWM frequency (see defines)
// OVDCON = 0x0000; // Disable all PWM outputs.
// DTCON1 = 0B0010010000100100; //Dead time igual a 36 veces Tcy tanto para la PWM1 como PWM2
// PWMCON1 = 0B0000000000110011; //Configura PWM1L,PWM2L,PWM1H, PWM2H como salidas PWM funcionando en modo complementario
// //complementary mode
// PDC1 = PTPER; // Initialize as 0 voltage
// PDC2 = PTPER; // Initialize as 0 voltage
// PDC1 = 0;
// PDC2 = 0;
//
// PWMCON2 = 0x0F02; // 16 postscale values, for achieving 20 kHz
// PTCON = 0x8002; // start PWM as center aligned mode
//
// IEC2bits.PWMIE = 1; //Habilitar interrupción PWM (desborde del registro PTMR)
// IFS2bits.PWMIF = 0; //Borrar bandera de interrupción
// return;
}
 

Temas similares

Arriba