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.

TMS570LS1224: The problem about PWM duty output control

Part Number: TMS570LS1224

Hello,

I have a problem about PWM output control. We need to control all PWM duty output(0 ~ 100%) in our application.
But it looks failed. So I want to know whether it can be complete control, or there has another way to achieve the goal?

Setting information is as follows : 

Mode: up-down count
Interrupt timing : ZERO & PRD(wave trough & crest) using for setting next execution case
Shadow loading timing : ZERO & PRD
Case Z => P => H => Z => P => H => Z => H => P => Z => H => P => Z
(P = PRD, Z = ZERO, H = HALF)
Case output was controlled by CMPA and AQCTLA register.

PWM1A and PWM2A output to Oscilloscope
PWM1A : output duty
PWM2A : Indicating crests and troughs(output high means at increase interval, low means at decrease interval)

Expected wave :

The case of setting will execute at next interval. For example : setting at increase interval, executing at decrease interval.(first execution case)

Result wave of experiment :

We could see that there were two condition occurs fail. Others were correct. (Red wave form is expected wave)

(1) From increase to decrease interval(execute P to H)

(2) From decrease to increase interval(execute Z to H)

Thanks for your help.

  • Hello Elvis,

    The ePWM module can do it. How do I know when it is "Z", "H", and "P"?

  • You need to change the settings of CAU, CAD, CBU, CBD, PRD and ZRO in AQCTLA register dynamically based on the condition of "Z", "P" and "H".

  • Hello Q J Wang,

    It was dynamically changing the AQCTLA register already.

    I was according to count condition and CMPA value to change the AQCTLA control field.(count condition means that it is up count or down count at the monent)

    After AQCTLA was changed, the compare value would fill in CMPA register. And then it will take effect in next interval.

    But it failed. You can see another same case " P => H " in the picture 2, the output is as expected.( the fifth case to sixth case)

    Thanks for your reply.

  • Hello Elvis,

    Can you post your code which is used to update the duty cycle?

  • Hello QJ,

    OK! Update code of AQCTLA register  is as fallows. Setting in up-count interval will execution at decreasing interval. So up-count should set CAD and PRD.

    We checked the compare value and changed the AQCTLA register first. After that, fill the compare value in CMPA register.

    (compare value means DutyCmp in the code)

    //AQCTLA shift
    #define AQCTLx_CBD_shift                        10U
    #define AQCTLx_CBU_shift                        8U
    #define AQCTLx_CAD_shift                        6U
    #define AQCTLx_CAU_shift                        4U
    #define AQCTLx_PRD_shift                        2U
    #define AQCTLx_ZRO_shift                        0U

    #define CBDHIGH         ((uint16)0x2U << AQCTLx_CBD_shift)
    #define CBUHIGH         ((uint16)0x2U << AQCTLx_CBU_shift)
    #define CADHIGH         ((uint16)0x2U << AQCTLx_CAD_shift)
    #define CAUHIGH         ((uint16)0x2U << AQCTLx_CAU_shift)
    #define PRDHIGH         ((uint16)0x2U << AQCTLx_PRD_shift)
    #define ZROHIGH         ((uint16)0x2U << AQCTLx_ZRO_shift)

    #define CBDLOW          ((uint16)0x1U << AQCTLx_CBD_shift)
    #define CBULOW          ((uint16)0x1U << AQCTLx_CBU_shift)
    #define CADLOW          ((uint16)0x1U << AQCTLx_CAD_shift)
    #define CAULOW          ((uint16)0x1U << AQCTLx_CAU_shift)
    #define PRDLOW          ((uint16)0x1U << AQCTLx_PRD_shift)
    #define ZROLOW          ((uint16)0x1U << AQCTLx_ZRO_shift)

    #define CADNOTHING  ((uint16)0x0U << AQCTLx_CAD_shift)
    #define CAUNOTHING  ((uint16)0x0U << AQCTLx_CAU_shift)
    #define PRDNOTHING  ((uint16)0x0U << AQCTLx_PRD_shift)
    #define ZRONOTHING  ((uint16)0x0U << AQCTLx_ZRO_shift)


    void DutyOutPrcs(PWMGEN *DutyCmp)
    {
        uint16 zRegU                                                     = 0;
        zRegU                                                                = etpwmREG5->AQCTLA;

        if(((etpwmREG5->TBSTS)&0x0001)==1)          //up-count
        {
            if(DutyCmp->PWM1out == C_PWM_PRD)
                    etpwmREG5->AQCTLA                        = CADNOTHING | PRDHIGH  | (zRegU&0xFF33);
            else if(DutyCmp->PWM1out == 0)
                    etpwmREG5->AQCTLA                        = CADNOTHING | PRDLOW   | (zRegU&0xFF33);
            else
                    etpwmREG5->AQCTLA                        = CADHIGH         | PRDLOW   | (zRegU&0xFF33);

        }else                                                                  //down-count
        {
            if(DutyCmp->PWM1out == C_PWM_PRD)
                    etpwmREG5->AQCTLA                        = CAUNOTHING | ZROHIGH  | (zRegU&0xFFCC);
            else if(DutyCmp->PWM1out == 0)
                    etpwmREG5->AQCTLA                        = CAUNOTHING | ZROLOW   | (zRegU&0xFFCC);
            else
                    etpwmREG5->AQCTLA                        = CAULOW          | ZROHIGH  | (zRegU&0xFFCC);
        }
    }

  • Hello Elvis,

    From your code, I don't see all the conditions.

    For example, there are TWO P(high lighted as yellow) when counter is UP. If previous PWM output is Z, the next PWM output should H (first one); if the previous PWM output is H, the next PWM output should be Zero (second one)

    for 1st one, the AQ control setting should be

                    etpwmREG5->AQCTLA  = CADHIGH | PRDLOW  | ZEROLOW | (zRegU&0xFF33);

  • Hello QJ,

    I don't know what the next output is H, P, or Z in our application.

    So the rule in my code is that We should set the CAD and PRD at up-count, and set the CAU and ZERO at down-count.

    (Setting in up-count would execute at down-count interval. So up-count control the PRD(head of interval) and CAD.)

    According to that I don't know what the next output is.

    I found that my experiment miss the six cases for H=>H, P=>P, Z=>Z(*2 start from up or down count condition)

    I did the experiment again for twice.(a total of 19 cases per experiment)

    (1) Picture 1 : original code

    (2) Picture 2 : From your suggest but I just change this.  => etpwmREG5->AQCTLA  = CADHIGH | PRDLOW  | ZEROLOW  | (zRegU&0xFF33);

    But the problem still exists( the left red circle in the picture). Look at picture 1 and 2. I got the same waveform.

  • Hello Elvis,

    I don't have scope at home to do my test. Please check the value of zRegU. What is the purpose to OR zRegU in your instruction?

  • Hello QJ,

    zRegU is used for latching the original AQCTLA register setting for logic calculation.

    zRegU                                                    = etpwmREG5->AQCTLA;

    etpwmREG5->AQCTLA                         = CADNOTHING | PRDHIGH  | (zRegU&0xFF33);

    I found some information in Technical Reference Manual page 735. It doesn't suggest use the PRD or ZERO value for CMPA. So, Is it a limitation of TMS570?

  • Hello Elvis,

    Those are the restrictions:

    1. Load at ZERO: CMPA/B must be >= 1

    2. Load at PRD: CMPA/B must be <= PRD-1

    Otherwise the new value will be delay by one period.

  • QJ Wang said:

    Hello Elvis,

    Those are the restrictions:

    1. Load at ZERO: CMPA/B must be >= 1

    2. Load at PRD: CMPA/B must be <= PRD-1

    Otherwise the new value will be delay by one period.

    Hello QJ,

    Thanks for your help!!