What is the minimum frequency we can get in SCT 16 bit counter

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

What is the minimum frequency we can get in SCT 16 bit counter

1,146 Views
angiey0017
Contributor III

Hi,

I need to generate 0.5hz[with SCTtimer sample code] frequency in lp845 controller, with the sample code using

16 bit counter SCT, least frequency i'm getting is 0.9hz, not getting lesser then this,

how to get 0.5hz ,kindly advice, below is the calculation done:

For 30Mhz clock-->500[count value] * 30Mhz[sctimer clock] /1000 = 15Mhz

So for say 3hz its = 15M/3 = 5000000[this value is substituted in matchvalue]

Similarly for 0.5hz...but not getting as expected..suggest me is the above method

is correct and how to get 0.5hz using scttimer counter.

Thank you

Labels (1)
5 Replies

995 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Angiey,

From theory, the SCTimer is a clock divider, if you use 30MHz system clock, and set the UNIFY bit in SCTimer/PWM configuration register, the counter is 32bits counter, the divider is 2**32, you can get at least 30MHz/(2**32) =0.007Hz signal. So it is okay to get 0.5HZ signal if you set the match register as 60 000 000.

As an alternative, you can use input 4 as the SCTimer clock signal, which can be 12MHz FRO, but you have to use 32bits counter by setting the UNIFY bit in SCTimer/PWM configuration register.

pastedImage_1.png

Hope it can help you

BR

XiangJun rong

0 Kudos

995 Views
angiey0017
Contributor III

Hi,

Thank you for your response.

By default SCTtimer configuration was in 16 bit so for 32 bit the boolean

value is *true *and set the

match register to 60000000 but still not getting the 0.5hz signal,

is there any other configuration to be changed.

Thank you

On Mon, Jul 15, 2019 at 1:56 PM xiangjun.rong <admin@community.nxp.com>

0 Kudos

995 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Angiey,

This is an example code I copied from SDK. 

SCTIMER_GetDefaultConfig(&sctimerInfo);

sctimerInfo.enableCounterUnify = true; /* SCT operates as a unified 32-bit counter */

    /* Initialize SCTimer module */
    SCTIMER_Init(SCT0, &sctimerInfo);

    /* Configure first PWM with frequency 1HZ from first output */
    pwmParam.output = DEMO_FIRST_SCTIMER_OUT;
    pwmParam.level = kSCTIMER_HighTrue;
    pwmParam.dutyCyclePercent = 50;
    if (SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, 1U, sctimerClock, &event) == kStatus_Fail)
    {
        return -1;
    }

If you use above code, can you get 1HZ PWM signal?

If you can get 1HZ PWM signal, you can use the code to get 0.5HZ PWM signal I suppose.

/* SCT operates as a unified 32-bit counter */

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

BR

Xiangjun Rong

0 Kudos

995 Views
angiey0017
Contributor III

Thanks for the response..I tried with the above changes but not getting the

require frequency of 0.5hz, with the reference of SDK code tried initially by

changing the configuration of unifiy bit to 32 bit counter too,I have attach the

latest change code, is anything need to be changed..?kindly suggest on this.

void SCT_Detection_Callback(void)
{
        GPIO_PortToggle(GPIO, BLUE_LED_PORT, 1u << BLUE_LED_PIN);
        widths = SCT0->COUNT;

        SCT0->CTRL |= (1<<19);//clear counter

        uint32_t CTRL_Enable_Event = SCT0->CTRL;
        CTRL_Enable_Event &= (~(SCT_CTRL_HALT_H_MASK) ); //clear halt H bit
        CTRL_Enable_Event |= SCT_CTRL_STOP_H_MASK; //set stop H bit
//   SCT0->CTRL = CTRL_Enable_Event; //Write both changes at once
}

/*******************************************************************************
 * Code
 ******************************************************************************/
/*!
 * @brief Main function
 */
int main(void)
{
    sctimer_config_t sctimerInfo;
    uint32_t stateNumber;    
        uint32_t eventCounterL, eventCounterH;
        uint32_t sctimerClock;
        uint32_t matchValueL, matchValueH;

    /* Board pin, clock, debug console init */

    /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
    CLOCK_Select(BOARD_DEBUG_USART_CLK_ATTACH);

    BOARD_InitPins();
        BOARD_BootClockFRO30M();
    BOARD_InitDebugConsole();
        
        gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0, };
        GPIO_PortInit(GPIO, BLUE_LED_PORT);                                
        GPIO_PinInit(GPIO, BLUE_LED_PORT, BLUE_LED_PIN, &led_config);
        
        if(SysTick_Config(SystemCoreClock / 100000U))
    {
        while(1)
        {
        }
    }        
        
        LCD_Init();
        LCD_Cmd(_LCD_CURSOR_OFF);
        LCD_Cmd(_LCD_CLEAR);

    sctimerClock = SCTIMER_CLK_FREQ;

    /* Default configuration operates the counter in 32-bit mode */
    SCTIMER_GetDefaultConfig(&sctimerInfo);
        
         /* Switch to 16-bit mode */
    sctimerInfo.enableCounterUnify = true ;//true[for 32 bit]
        sprintf(txta, "%d ", sctimerInfo.enableCounterUnify);
        LCD_Out(1,1,txta);
        
    /* Calculate prescaler and match value for Counter L for 100ms interval */
    matchValueL = MSEC_TO_COUNT(500U, sctimerClock);//changed values
        sprintf(txtb, "%d ", matchValueL);
        LCD_Out(2,1,txtb);
        
    sctimerInfo.prescale_l = matchValueL / 65536;
        
    matchValueL = matchValueL / (sctimerInfo.prescale_l + 1) - 1;
        
    /* Calculate prescaler and match value for Counter H for 200ms interval */
    matchValueH = MSEC_TO_COUNT(500U, sctimerClock);//changed values
    sctimerInfo.prescale_h = matchValueH / 65536;
    matchValueH = matchValueH / (sctimerInfo.prescale_h + 1) - 1;

    /* Initialize SCTimer module */
    SCTIMER_Init(SCT0, &sctimerInfo);

    stateNumber = SCTIMER_GetCurrentState(SCT0);

  /* Schedule a match event for Counter L every 0.1 seconds */
    if (SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_MatchEventOnly, matchValueL, 0, kSCTIMER_Counter_L,
                                       &eventCounterL) == kStatus_Fail)
    {
        return -1;
    }

    /* Toggle first output when Counter L event occurs */
    SCTIMER_SetupOutputToggleAction(SCT0, DEMO_FIRST_SCTIMER_OUT, eventCounterL);

    /* Reset Counter L when Counter L event occurs */
    SCTIMER_SetupCounterLimitAction(SCT0, kSCTIMER_Counter_L, eventCounterL);

    /* Schedule a match event for Counter H every 0.2 seconds */
    if (SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_MatchEventOnly, matchValueH, 0, kSCTIMER_Counter_H,
                                       &eventCounterH) == kStatus_Fail)
    {
        return -1;
    }

    /* Toggle second output when Counter H event occurs */
    SCTIMER_SetupOutputToggleAction(SCT0, DEMO_SECOND_SCTIMER_OUT, eventCounterH);//P1.20 WONT TOGGLE

    /* Reset Counter H when Counter H event occurs */
        SCTIMER_SetupCounterLimitAction(SCT0, kSCTIMER_Counter_H, eventCounterH);

     SCTIMER_SetCallback(SCT0, sctimer_callback_table, eventCounterH);//kSCTIMER_Counter_H

     SCTIMER_EnableInterrupts(SCT0,1<<eventCounterH);//kSCTIMER_Counter_H

     NVIC_EnableIRQ(SCT0_IRQn);

    /* Start the timer, use counter L as we are operating counter in 32-bit mode */
    SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_L);//D6 PIN WONT TOGGLE
    SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_H);//D5 PIN WONT TOGGLE

    while (1)
    {
    }
}

0 Kudos

995 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

The PWM code in SDK is complicated, I develop an example code for the 0.5HZ PWM signal, it is okay when I run it on LPC54114. You have to modify the code yourself based on your application.

BR

Xiangjun Rong

void SCT0_PWM_05Hz(void)
{
    uint32_t clockDiv=2*SystemCoreClock;
    SYSCON->AHBCLKCTRL[1]|=(1<<2); //SET SCT0 bit
    SCT0->CONFIG = (1 << 0) | (1 << 17); // unified 32-bit timer, auto limit
    SCT0->SCTMATCHREL[0] = clockDiv; // match 0 @ 100 Hz = 10 msec
    SCT0->EVENT[0].STATE = 0xFFFFFFFF; // event 0 happens in all states


    //set event1
    SCT0->SCTMATCHREL[1]=0x00;
    SCT0->EVENT[1].STATE = 0xFFFFFFFF; // event 1 happens in all states
    SCT0->EVENT[1].CTRL = (1 << 12)|(1<<0); // match 1 condition only

    //set event2
    SCT0->SCTMATCHREL[2]=(clockDiv)/2;
    SCT0->EVENT[2].STATE = 0xFFFFFFFF; // event 2 happens in all states
    SCT0->EVENT[2].CTRL = (1 << 12)|(2<<0); // match 2 condition only

    //set event3
    SCT0->SCTMATCHREL[3]=(clockDiv)/4;
    SCT0->EVENT[3].STATE = 0xFFFFFFFF; // event 3 happens in all states
    SCT0->EVENT[3].CTRL = (1 << 12)|(3<<0); // match 3 condition only

    //set event4
    SCT0->SCTMATCHREL[4]=3*(clockDiv)/4;
    SCT0->EVENT[4].STATE = 0xFFFFFFFF; // event 4 happens in all states
    SCT0->EVENT[4].CTRL = (1 << 12)|(4<<0); // match 4 condition only

    //PWM output1 signal
    SCT0->OUT[1].SET = (1 << 1); // event 1 will set SCT1_OUT0
    SCT0->OUT[1].CLR = (1 << 2); // event 2 will clear SCT1_OUT0
    SCT0->RES |= (3 << 2); // output 0 toggles on conflict

    //PWM output2 signal
    SCT0->OUT[2].SET = (1 << 3); // event 3 will set SCT1_OUT0
    SCT0->OUT[2].CLR = (1 << 4); // event 4 will clear SCT1_OUT0
    SCT0->RES = (3 << 4); // output 0 toggles on conflict

    //PWM start
    SCT0->CTRL &= ~(1 << 2); // unhalt by clearing bit 2 of the CTRL
}