Generate slow 5Hz PWM with SCTimer

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Generate slow 5Hz PWM with SCTimer

Jump to solution
1,904 Views
krisbellemans
Contributor II

How do I generate a slow 5Hz PWM using the SCTimer on a LPC546xx?

I use the main clock as clock source at 12MHz. I can't get the frequency lower than 184Hz.

Labels (1)
Tags (2)
1 Solution
1,524 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Kris,

I recommend you to use the example sctimer_simple_pwm  provided in the SDK. If you want 5Hz then you will need to modify some things of the example. Inside the main you need to set the output frequency to 5Hz.

if (SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, 5U, sctimerClock, &event) == kStatus_Fail)
{
    return -1;
}‍‍‍‍‍‍‍‍‍‍‍‍

After you can comment all the configurations for the second PWM with different duty cycle.

    /* Configure second PWM with different duty cycle but same frequency as before */
/*    pwmParam.output = kSCTIMER_Out_2;
    pwmParam.level = kSCTIMER_LowTrue;
    pwmParam.dutyCyclePercent = 20;
    if (SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, 10000U, sctimerClock, &event) == kStatus_Fail)
    {
        return -1;
    }*/‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Finally in the file fsl_sctimer.c inside the next function: 

status_t SCTIMER_CreateAndScheduleEvent(SCT_Type *base,
                                        sctimer_event_t howToMonitor,
                                        uint32_t matchValue,
                                        uint32_t whichIO,
                                        sctimer_counter_t whichCounter,
                                        uint32_t *event)‍‍‍‍‍‍‍‍‍‍‍‍

You have the next else condition: 

    else if (combMode == 0x1U)
    {
        /* Return an error if we have hit the limit in terms of number of number of match registers */
        if (s_currentMatch >= FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE)
        {
            return kStatus_Fail;
        }

        currentCtrlVal |= SCT_EVENT_CTRL_MATCHSEL(s_currentMatch);
        /* Use Counter_L bits if counter is operating in 32-bit mode or user wants to setup the L counter */
        if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L))
        {
            base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_L(matchValue);
            base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_L(matchValue);
        }
        else
        {
            /* Select the counter, no need for this if operating in 32-bit mode */
            currentCtrlVal |= SCT_EVENT_CTRL_HEVENT(whichCounter);
            base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_H(matchValue);
            base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_H(matchValue);
        }
        base->EVENT[s_currentEvent].CTRL = currentCtrlVal;
        /* Increment the match register number */
        s_currentMatch++;
    }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

You need to change the two statements inside the next if condition:

if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L))
{
    //base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_L(matchValue);
    //base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_L(matchValue);
    base->SCTMATCH[s_currentMatch] = matchValue;
    base->SCTMATCHREL[s_currentMatch] = matchValue;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The example is working with a unify counter of 32 bits, if you leave the two statements like they are in the if condition then you will discard the higher part of the counter so this won't work for low frequencies. That's why you have to make the change. This will be fixed in future releases of the SDK. Once you make these changes you get the 5Hz PWM as shown in the image attach. 

Hope it helps!

Victor.

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

4 Replies
1,524 Views
krisbellemans
Contributor II

Hi Victor,

Thank you for your answer!

Applying the changes in fsl_sctimer.c made it work.

Kris.

1,524 Views
gerhardk
Contributor II

Kris,

With all due respect to the NXP response, I'd rather use the 8-bit prescaler of a 16-bit SCT counter to bring the PWM frequency down. This way you leave the other 50% of SCT free for something else.

Gerd

0 Kudos
1,524 Views
krisbellemans
Contributor II

Hi Gerd,

Thanks! I'll keep it in mind.

Kris.

0 Kudos
1,525 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Kris,

I recommend you to use the example sctimer_simple_pwm  provided in the SDK. If you want 5Hz then you will need to modify some things of the example. Inside the main you need to set the output frequency to 5Hz.

if (SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, 5U, sctimerClock, &event) == kStatus_Fail)
{
    return -1;
}‍‍‍‍‍‍‍‍‍‍‍‍

After you can comment all the configurations for the second PWM with different duty cycle.

    /* Configure second PWM with different duty cycle but same frequency as before */
/*    pwmParam.output = kSCTIMER_Out_2;
    pwmParam.level = kSCTIMER_LowTrue;
    pwmParam.dutyCyclePercent = 20;
    if (SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, 10000U, sctimerClock, &event) == kStatus_Fail)
    {
        return -1;
    }*/‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Finally in the file fsl_sctimer.c inside the next function: 

status_t SCTIMER_CreateAndScheduleEvent(SCT_Type *base,
                                        sctimer_event_t howToMonitor,
                                        uint32_t matchValue,
                                        uint32_t whichIO,
                                        sctimer_counter_t whichCounter,
                                        uint32_t *event)‍‍‍‍‍‍‍‍‍‍‍‍

You have the next else condition: 

    else if (combMode == 0x1U)
    {
        /* Return an error if we have hit the limit in terms of number of number of match registers */
        if (s_currentMatch >= FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE)
        {
            return kStatus_Fail;
        }

        currentCtrlVal |= SCT_EVENT_CTRL_MATCHSEL(s_currentMatch);
        /* Use Counter_L bits if counter is operating in 32-bit mode or user wants to setup the L counter */
        if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L))
        {
            base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_L(matchValue);
            base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_L(matchValue);
        }
        else
        {
            /* Select the counter, no need for this if operating in 32-bit mode */
            currentCtrlVal |= SCT_EVENT_CTRL_HEVENT(whichCounter);
            base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_H(matchValue);
            base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_H(matchValue);
        }
        base->EVENT[s_currentEvent].CTRL = currentCtrlVal;
        /* Increment the match register number */
        s_currentMatch++;
    }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

You need to change the two statements inside the next if condition:

if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L))
{
    //base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_L(matchValue);
    //base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_L(matchValue);
    base->SCTMATCH[s_currentMatch] = matchValue;
    base->SCTMATCHREL[s_currentMatch] = matchValue;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The example is working with a unify counter of 32 bits, if you leave the two statements like they are in the if condition then you will discard the higher part of the counter so this won't work for low frequencies. That's why you have to make the change. This will be fixed in future releases of the SDK. Once you make these changes you get the 5Hz PWM as shown in the image attach. 

Hope it helps!

Victor.

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------