This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

3-phase sinusoidal PWM signal generation issues with TMSF28027

Other Parts Discussed in Thread: CONTROLSUITE, TMS320F2802, TMS320F28035

Hello,

I'm trying to generate a 3-phase Sinusoidal PWM signals for an ACIM control. I'm requested to use a potentiometer to variate the output voltage (from 0 to 3V) and the frequency (from 1 to 60 Hz) to satisfy the V/f equation for speed control; when the voltage increases, the frequency must increase as well. So far, I've managed to modify the output voltage using the PWM chopping sub-module and reading the potentiometer values with the ADC module, but I still can't control de frequency values because I haven't found which PWM parameter I should modify. I've attached the code that has worked to me so far, in which I succesfuly change the output voltage values for PWM1 with the potentiometer but haven't figured out yet how to do it with the output frequency. I would really appreciate it if someone could give me hand on this! Thanks in advance.

void InitEPwm1()
{
EPwm1Regs.PCCTL.bit.CHPFREQ = 1;
EPwm1Regs.PCCTL.bit.CHPEN = 1;

EPwm1Regs.TBPRD = TB_PRD; // Set timer period
EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
EPwm1Regs.TBCTR = 0x0000; // Clear counter

// Setup TBCLK
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm1Regs.TBCTL.bit.HSPCLKDIV = HSPCLK_DIV; // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = CLK_DIV;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; //Generar una señal cuando CTR = 0. Esto hace al PWM1 como el maestro.

EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

// Setup compare
EPwm1Regs.CMPA.half.CMPA = TB_PRD;

// Set actions
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;


EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;

// Active Low PWMs - Setup Deadband
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
EPwm1Regs.DBRED = DEAD_BAND;
EPwm1Regs.DBFED = DEAD_BAND;

EPwm1Regs.ETSEL.bit.INTEN = 1; // Habilitar interrupción por evento.
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRD_CMPA;
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; //Interrupt on first event.
}

interrupt void adc_isr(void)
{

Duty = (0.001481481*AdcResult.ADCRESULT0);
EPwm1Regs.PCCTL.bit.CHPDUTY = Duty;
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Clear ADCINT1 flag reinitialize for next SOC
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE

return;
}

Jorge Flores

  • Jorge,

    To be honest I don't think you are going about this in the right way.  The chopper module inside the PWM is not intended for this purpose.  What you're doing here is setting the PWM permanently high and replying on the chopper to produce PWM for you.  It won't work because the achievable PWM frequencies will be far too high, with too coarse resolution, and you'll have no way to produce 3-phase patterns.

    To control a 3-phase machine you need three complementary pair PWMs synchronized in phase.  You do this by configuring the phase shift and CMPA & B registers within three separate modules.  The PC block is not needed.

    Scalar control (V/f)  control is typically achieved through a space vector block which takes V & f terms as inputs and modulates the PWM patterns accordingly.  I recommend you look at the ACI scalar example in controlSUITE which has open source code for the SV and V/f blocks.  They will do everything you need.

    If you have installed controlSUITE in the default location you will find the files at:

    C:\ti\controlSUITE\development_kits\HVMotorCtrl+PfcKit_v2.1\HVACI_Scalar

    I hope this helps.

    Regards,

    Richard

  • Hi Richard,

    Thank you very much for your answer. I have controlSUITE in my computer and I've already opened the example you've mentioned; however, the target in this example is the TMS320F2803 DSP's and I'm currently using a TMS320F2802 MCU; is there an example designed for this family? Or how should I migrate from one target to the other?

    Thanks again.

    Regards,

    Jorge
  • Hi Jorge,

    The motor control macros I mentioned don't care which platform they run on.

    I don't see a separate example for '02x but these devices are very similar.  The scalar ACIM project does contain a "DevInit" initilisation file for the F2802x also so I think if you just change over those files in the project (i.e. exclude one and include the other) it will work.  

    Regards,

    Richard

  • Richard,

    I've seen the Devint initilisation file for the F2802x and it actually runs and doesn't present any problem to debug, however, I can't seem to visualize with the oscilloscope the generated PWM signals, as if the controller didn't do anything. I first thought it could be the motor-control driver files, since they are all for the F2803x family, but the controlSUITE does not provide the F2802x ones.

    Also I read that these controlSUITE programs take into account a full kit for motor control provided by TI. The thing is that I only have the MCU and I wish to use my own inverter, but I don't know if, since the program doesn't detect the kit plugged into the MCU, that could be the reason why it seems do nothing (this happened to me while I was trying to use the InstaSPIN-FOC solution with the same microcontroller: since I didn't have any motor control kit, the MCU seemed to do nothing). Do you think one of these could be the problem?

    Thank you very much for your help and advices.

    Regards,

    Jorge
  • Hi Jorge,

    The F2803x library macros will work on the F2802x too.  Those devices are very similar.  

    I think we need to go back a step: you say "the program doesn't detect the kit plugged into the MCU".  Can you elaborate please?  Are you able to connect to the MCU and load code?  If so, can you run the device specific examples in controlSUITE to confirm you have emulator communication with the target and the device is working.  In controlSUITE there are several such examples at:

    C:\ti\controlSUITE\device_support\f2802x\v230\f2802x_examples_structs\gpio_toggle

    Can you try, for example, the adc_soc example and verify the device is functioning correctly?  Then move on to one of the ePWM examples and check the right patterns are generated.  That will tell us if there's any hardware issue.

    Regards,

    Richard

  • Hi Richard,

    My device works fine using the controlSUITE examples such as ePWM signal generation for F2802x. However, when I try to run HVACI_Scalar example I have no PWM signals whatsoever. On the debugging console, I get the the following warning: 

    C28xx: Loader: One or more sections of your program falls into a memory region that is not writable. These regions will not actually be written to the target. Check your linker configuration and/or memory map.

    Also, in the PDF explanation file it says that I should check on a variable called IsrTicker, that should tell me when the system interrupt is reached. On my whatch window, the IsrTicker value says: 

    IsrTicker unknown Error: Memory map prevented reading 0x00009B5E@Data

    And finally, I connect the oscilloscope on the ePWM1A (as I did with the previous examples) and no signal is registered.

    I'm pretty sure I know what the problem is but I just don't know how to adress it! Could you help me on this?

    Thank you very much.

    Regards

    Jorge

  • Hi Jorge,

    Please can you let me know the exact part number of the device you are using?

    Also, can you please attach the linker command file(s) from your project?  Thanks.

    Regards,

    Richard

  • Hi Richard,

    I'm using the TMSF28027F.

    The linker command file:

    /*==================================================================================*/
    /* User specific Linker command file for running from RAM */
    /*==================================================================================*/
    /* FILE: F28035_RAM_HVACI_Scalar.CMD */
    /* */
    /* Description: Linker command file for User custom sections targetted to run */
    /* from RAM. */
    /* */
    /* Target: TMS320F28035 device */
    /* */
    /* Version: 1.00 */
    /* */
    /*----------------------------------------------------------------------------------*/
    /* Copyright Texas Instruments © 2009 */
    /*----------------------------------------------------------------------------------*/
    /* Revision History: */
    /*----------------------------------------------------------------------------------*/
    /* Date | Description */
    /*----------------------------------------------------------------------------------*/
    /* 10/24/08 | Release 1.0 New release. */
    /*----------------------------------------------------------------------------------*/

    /* Define the memory block start/length for the DSP2803x
    PAGE 0 will be used to organize program sections
    PAGE 1 will be used to organize data sections

    Notes:
    Memory blocks on F28035 are uniform (ie same
    physical memory) in both PAGE 0 and PAGE 1.
    That is the same memory region should not be
    defined for both PAGE 0 and PAGE 1.
    Doing so will result in corruption of program
    and/or data.

    L0 block is mirrored - that is it
    can be accessed in high memory or low memory.
    For simplicity only one instance is used in this
    linker file.

    Contiguous SARAM memory blocks can be combined
    if required to create a larger memory block.
    */

    MEMORY
    {
    PAGE 0 :
    /* Note that the memory allocation below does not create sections as necessary for
    the CLA on the F2803x.
    */

    BEGIN : origin = 0x000000, length = 0x000002
    BOOT_RSVD : origin = 0x000002, length = 0x00004E
    RAMM0 : origin = 0x000050, length = 0x0003B0

    progRAM : origin = 0x008000, length = 0x001800

    IQTABLES : origin = 0x3FE000, length = 0x000B50 /* IQ Math Tables in Boot ROM */
    IQTABLES2 : origin = 0x3FEB50, length = 0x00008C /* IQ Math Tables in Boot ROM */
    IQTABLES3 : origin = 0x3FEBDC, length = 0x0000AA /* IQ Math Tables in Boot ROM */

    RESET : origin = 0x3FFFC0, length = 0x000002
    BOOTROM : origin = 0x3FF27C, length = 0x000D44


    PAGE 1 :

    RAMM1 : origin = 0x000480, length = 0x000380

    dataRAM : origin = 0x009800, length = 0x000800

    CLA_CPU_MSGRAM : origin = 0x001480, length = 0x000080
    CPU_CLA_MSGRAM : origin = 0x001500, length = 0x000080
    }


    SECTIONS
    {
    codestart : > BEGIN, PAGE = 0
    ramfuncs : > RAMM0, PAGE = 0

    .text : > progRAM, PAGE = 0

    .cinit : > RAMM0, PAGE = 0
    .pinit : > RAMM0, PAGE = 0
    .switch : > RAMM0, PAGE = 0
    .reset : > RESET, PAGE = 0, TYPE = DSECT

    .stack : > RAMM1, PAGE = 1

    .ebss : > dataRAM, PAGE = 1
    .econst : > dataRAM, PAGE = 1

    .esysmem : > RAMM1, PAGE = 1

    IQmath : > progRAM, PAGE = 0
    IQmathTables : > IQTABLES, PAGE = 0, TYPE = NOLOAD

    Cla1ToCpuMsgRAM : > CLA_CPU_MSGRAM, PAGE = 1
    CpuToCla1MsgRAM : > CPU_CLA_MSGRAM, PAGE = 1

    /* Uncomment the section below if calling the IQNexp() or IQexp()
    functions from the IQMath.lib library in order to utilize the
    relevant IQ Math table in Boot ROM (This saves space and Boot ROM
    is 1 wait-state). If this section is not uncommented, IQmathTables2
    will be loaded into other memory (SARAM, Flash, etc.) and will take
    up space, but 0 wait-state is possible.
    */
    /*
    IQmathTables2 : > IQTABLES2, PAGE = 0, TYPE = NOLOAD
    {

    IQmath.lib<IQNexpTable.obj> (IQmathTablesRam)

    }
    */
    /* Uncomment the section below if calling the IQNasin() or IQasin()
    functions from the IQMath.lib library in order to utilize the
    relevant IQ Math table in Boot ROM (This saves space and Boot ROM
    is 1 wait-state). If this section is not uncommented, IQmathTables2
    will be loaded into other memory (SARAM, Flash, etc.) and will take
    up space, but 0 wait-state is possible.
    */
    /*
    IQmathTables3 : > IQTABLES3, PAGE = 0, TYPE = NOLOAD
    {

    IQmath.lib<IQNasinTable.obj> (IQmathTablesRam)

    }
    */

    }


    SECTIONS
    {
    DLOG: > dataRAM,PAGE=1
    }

    I tried using a linker command file specificaly for F2802x devices, but the program won't compile this way due to memory space issues, that's way I switched back to the original linker command file that came for the example.

    Thank you very much for your help!

    Kind regards,

    Jorge
  • Jorge,

    The issue is you're using a project built for the F28035 on a part with much less memory.  I've tried juggling the memory sections to make it fit, but the F28027 part just doesn't have enough memory to run everything from RAM.  I think the main reason is the memory allocated to data logging.  

    I see two alternatives: The simplest solution is to move to an F28035 part to run this example as it stands.  Otherwise what you can do is use a flash based F28027 linker file (you'll find "F28027.cmd" in the same directory as "28027_RAM_lnk.cmd").  You'll be able to build and load the project, but you'll be limited to only two hardware breakpoints to debug any code. 

    Regards,

    Richard

  • Hi, I am trying to do the same using a launchpad, will this example run on the launchxl-F28069 launchpad?

    Thanks.