Nos ocupamos del módulo PWM en tms320

Buenas tardes. Hace un tiempo leí que alguien quería profundizar en la pregunta sobre el módulo ePWM en el mk tms320f28xxx, así que decidí por qué no escribir un artículo sobre este tema en el que intentaré masticar este módulo en detalle usando el ejemplo de tms320f28335 ...



Capacidades del módulo EPWM



  • Las salidas de epwmA epwmB pueden funcionar como:

    • operación de un solo borde
    • operación simétrica de doble filo
    • operación asimétrica de doble filo
  • El tiempo muerto se puede configurar
  • El evento TZ se puede configurar y se puede configurar el estado lógico de las salidas HI y LO.
  • Se puede configurar un evento de interrupción o un evento SOC para el ADC.


Acerquémonos a los bloques principales: en qué consiste el módulo ePWM y a qué está conectado.







Como puede ver en la figura, no hay muchos bloques en el módulo ePWM. Por lo tanto, tiene sentido considerar de qué es responsable cada módulo y comenzar con las señales.



  • Las señales EPWMxA y EPWMxB son probablemente la señal de salida más obvia. El estado lógico normal es HI o LO, dependiendo de cómo esté configurada la acción de salida
  • TZ1 — TZ6 — . , , , . , EPWMxA EPWMxB . , , - , , . . , .
  • EPWMxSYNCI EPWMxSYNCO — , , .
  • Señales EPWMxSOCA y EPWMxSOCB : aquí todo está más que claro por el nombre. Estos eventos pueden configurar eventos SOC para el ADC.
  • Señales EPWMxTZINT y EPWMxINT - aquí un evento de interrupción en TZ y en eventos relacionados con el PWM mismo, por ejemplo, generando una interrupción en el período PWM.


Ahora pasemos a los



módulos de base de tiempo (TB) : el módulo es responsable de la hora del evento de cada módulo ePWM. No entraremos en todas las configuraciones de este módulo, creo que es suficiente con prestar atención al hecho de que hay 3 modos de funcionamiento del contador:



  • Modo de conteo ascendente y descendente
  • Modo de conteo ascendente
  • Modo de cuenta regresiva






Y también hay una configuración de sincronización del temporizador al configurar el



módulo de bits de comparación de contador (CC) TBCLKSYNC ; a través de él, simplemente configuramos nuestro ciclo de trabajo.

Módulo Action-Qualifier (AQ) : a través de él puede configurar el estado de un evento. Y para las salidas, puede configurar las siguientes acciones:



  • Establecer en estado HI
  • Establecer en estado LO
  • Realizar inversión de estado
  • Nada que hacer


Módulo de submódulo de banda muerta (DB) : este módulo se puede utilizar para establecer bandas muertas para canales PWM. No será un secreto para nadie que las llaves de transistor no cambian instantáneamente, y para evitar una situación en la que la llave de medio puente superior no tiene tiempo de cerrarse y la inferior ya está abierta, establecen un retraso para cambiar al estado HI y antes para cambiar al estado LO.



Módulo de submódulo de zona de disparo (TZ) : como se mencionó anteriormente, este módulo está asociado con el manejo de condiciones de emergencia. Aquí podemos elegir 1 de 4 acciones.



  • Establecer en estado HI
  • Establecer en estado LO
  • Establecer estado de alta impedancia
  • Nada que hacer


El evento que desencadena la acción del módulo TZ puede ser desencadenado tanto por software como por hardware. Además, se proporciona una llamada de interrupción.



Pasemos ahora de las palabras a la práctica.



Primero, debe configurar GPIO para una función epwm alternativa



EALLOW;
//  pull-up
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0x000;  
GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0x000;  
//  GPIO   EPWM1A
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0x001;   
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0x001;  

EDIS;


A continuación, cuando ya tengamos configurado el GPIO, podemos proceder con las distintas configuraciones. Para configurar el funcionamiento de PWM, debe decidir qué queremos obtener. Comencemos con la frecuencia TBCLK. Está determinado por la fórmula:



TBCLK=SYSCLKOUT/(HSPCLKDIV×CLKDIV)



Aquí hay que prestar atención al hecho de que CLKDIV es 1 por defecto, con HSPCLKDIV todo es diferente, por defecto es 2. Esto debe tenerse en cuenta, ya que hay ocasiones en las que la gente lo olvida. Al cargar un programa en la RAM, a menudo HSPCLKDIV = 1, respectivamente, este problema no se nota de inmediato.



Hemos decidido la frecuencia de reloj de TBCLK. Pero tendríamos que elegir cómo funcionará el mostrador para nosotros. Por recesión, por aumento, y tal vez de esta o aquella forma, para ello es necesario configurar el registro adecuado, por ejemplo:



 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
 


En el futuro, para que nadie se sienta intimidado por las macros, determinaremos de dónde vienen. Estas definiciones se definen en un archivo llamado DSP2833x_EPwm_defines.h.



Luego, debe decidir cómo reaccionarán nuestros GPIO para alcanzar ciertos valores de TBCTR. Hay opciones más que suficientes. Se muestran en la siguiente tabla:







Luego, debe decidir qué comportamiento queremos de los puertos A y B, es decir, queremos que estén conectados entre sí o que puedan funcionar de forma independiente. Si queremos que el puerto A sea el maestro, simplemente escribimos acciones para él, por ejemplo (caso para contar hacia arriba):



    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; 
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;


si queremos independencia para el segundo puerto, agreguemos:



    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;
    EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;


Para obtener más detalles sobre la configuración, debe consultar la imagen de arriba para solo una adición, hay un poco más de registros AQCTLA que los que se muestran en la tabla, esto no cambia mucho la imagen, pero solo se introducen detalles sobre en cuyo caso el contador alcanzó el valor deseado, por ejemplo, al contar en arriba o cuenta regresiva. Más brevemente sobre los bits se pueden encontrar en el corte del archivo .h del sistema



struct AQCTL_BITS {            // bits   description
    Uint16 ZRO:2;              // 1:0    Action Counter = Zero
    Uint16 PRD:2;              // 3:2    Action Counter = Period
    Uint16 CAU:2;              // 5:4    Action Counter = Compare A up
    Uint16 CAD:2;              // 7:6    Action Counter = Compare A down
    Uint16 CBU:2;              // 9:8    Action Counter = Compare B up
    Uint16 CBD:2;              // 11:10  Action Counter = Compare B down
    Uint16 rsvd:4;             // 15:12  reserved
};


Si tenemos 2 puertos ePWM que funcionan de forma independiente y queremos establecer el tiempo muerto, entonces necesitamos configurar el registro en el estado deseado, por ejemplo:



EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;


Ahora que hemos decidido la descripción de la periferia, podemos pasar a ejemplos específicos.



Configuración de ePWM en modo de conteo



A continuación se muestra un ejemplo sin tiempo muerto y el puerto A y el puerto B funcionan de forma independiente. Cuando A está activo, B está inactivo.



	EPwm1Regs.TBPRD = 150000 / 5; 	// .  150 / 5000 
    //   50%
    EPwm1Regs.CMPA.half.CMPA = EPwm1Regs.TBPRD / 2;	
    EPwm1Regs.TBPHS.half.TBPHS = 0; 
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; 
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; 
    EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; 
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; 
    EPwm1Regs.AQCTLA.bit.PRD = AQ_CLEAR;
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
    EPwm1Regs.AQCTLB.bit.PRD = AQ_SET;
    EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR;


En el oscilograma puedes ver el resultado obtenido:







Ahora puedes intentar agregar tiempo muerto, para esto agregamos:



    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    EPwm1Regs.DBCTL.all = BP_ENABLE + POLSEL_ACTIVE_HI_CMP;	//  db 
    EPwm1Regs.DBFED = 300;	//   = 150 * 2 = 300
    EPwm1Regs.DBRED = 300; 


El tiempo muerto se cuenta de la misma forma que la frecuencia, según la fórmula:

DB=TBCLKdeadTime;



Y ahora tenemos tiempo muerto tal como lo queríamos







¿Qué pasa si necesitamos desatar el puerto A y el puerto B? Esto también ocurre. Aquí todo es sencillo. Regresamos al primer ejemplo y eliminamos las últimas 4 líneas, y escribimos cada ciclo de trabajo en los siguientes registros.



    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;
    EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;
    EPwm1Regs.CMPA.half.CMPA 	= EPwm1Regs.TBPRD / 2;	//   50%  
    EPwm1Regs.CMPB	= EPwm1Regs.TBPRD / 3;	//   33%  


Ahora tenemos una imagen así. Puede configurar el ciclo de trabajo para cada canal por separado.







Para el modo de caída, todo es aproximadamente igual. Hay una diferencia con la cuenta atrás en el modo de subida y bajada. Aquí la frecuencia de calce se calcula usando la fórmula:

TBPRD=TBCLK/(2Fpwm)



Lo mismo es cierto para Dead Time.



Probablemente lo único importante que no se consideró es la configuración de TZ, bueno, ahora vamos a detenernos en este módulo con un poco más de detalle.



Para activar programáticamente un evento de alarma, basta con configurar los siguientes registros:



    EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
    EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;


La alarma PWM se puede activar y restablecer mediante los siguientes comandos:



    // 
    EALLOW;
        EPwm1Regs.TZFRC.bit.OST = 0x001;
    EDIS;
	
    //  
    EALLOW;
	EPwm1Regs.TZCLR.bit.OST = 0x0001;
    EDIS;


Si queremos llamar a la señal TZ en hardware, entonces todo es aún más fácil, a través del registro TZSEL configuramos la TZ que necesitamos, pero además de esto, necesitamos configurar el GPIO a TZ.



Conclusión



Si alguien encuentra este artículo interesante, entonces puedo escribir un par de artículos más de una manera más o menos acelerada. Planeo considerar el módulo can, me gustaría dma, y ​​tal vez también escribiré un pequeño artículo sobre IQMath de ti con sus bibliotecas.



All Articles