LPC55S28 SCTimer PWM issue

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

LPC55S28 SCTimer PWM issue

1,527 Views
AccorMountain
Contributor I

Hello,

I'm testing the SDK example "lpcxpresso55s28_sctimer_pwm_with_dutycyle_change" and successfully generated PWM from pin P0_15(SCT0, OUT2).

But when i use my logic analyzer to see the pulse, i saw there are always an incorrect pulse every 4.17ms, please check my picture. Did anyone meet this issue?2023-12-20_182040.jpg

 

#define SCTIMER_CLK_FREQ        CLOCK_GetFreq(kCLOCK_BusClk)
#define DEMO_FIRST_SCTIMER_OUT  kSCTIMER_Out_2
#define DEMO_SECOND_SCTIMER_OUT kSCTIMER_Out_6

void InitI2C();

// Function to convert a byte to a hex string
void byteToHexString(uint8_t byteValue, char* hexString) {
    sprintf(hexString, "%02X", byteValue);
}

uint8_t OverHeat = 0;

/*******************************************************************************
 * Variables
 ******************************************************************************/
volatile bool sctimerIsrFlag      = false;
volatile bool brightnessUp        = true; /* Indicate LED is brighter or dimmer */
volatile uint8_t updatedDutycycle = 1U;
uint32_t eventNumberOutput;

/*******************************************************************************
 * Code
 ******************************************************************************/
void delay(void)
{
    volatile uint32_t i = 0U;
    for (i = 0U; i < 1000U; ++i)
    {
        __asm("NOP"); /* delay */
    }
}

/* The interrupt callback function is used to update the PWM dutycycle */
void SCTIMER_LED_HANDLER()
{
	/* Start the 32-bit unify timer */
	//SCTIMER_StopTimer(SCT0, kSCTIMER_Counter_U);

    sctimerIsrFlag = true;

    if (brightnessUp)
    {
        /* Increase duty cycle until it reach limited value, don't want to go upto 100% duty cycle
         * as channel interrupt will not be set for 100%
         */
        if (++updatedDutycycle >= 50U)
        {
            updatedDutycycle = 50U;
            brightnessUp     = false;
        }
    }
    else
    {
        /* Decrease duty cycle until it reach limited value */
        if (--updatedDutycycle == 1U)
        {
            brightnessUp = true;
        }
    }

    if (SCTIMER_GetStatusFlags(SCT0) & (1 << eventNumberOutput))
    {
        /* Clear interrupt flag.*/
        SCTIMER_ClearStatusFlags(SCT0, (1 << eventNumberOutput));
    }
}


/*
 * @brief   Application entry point.
 */
int main(void) {

	//PWM
	sctimer_config_t sctimerInfo;
	sctimer_pwm_signal_param_t pwmParam;
	uint32_t event;
	uint32_t sctimerClock;

	//unsigned char i,j;
	//unsigned char caseCnt = 0; //delayModeOn = 0;
	unsigned char brightness = 0x6F;
	uint8_t hddStatus = 0;

    /* Init board hardware. */
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitBootPeripherals();
#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL
    /* Init FSL debug console. */
    BOARD_InitDebugConsole();
#endif

//    InitI2C();
//
//    OLED_Initial_WS0012();
//
//    OLED_ShowStrings(MSG1, MSG2);
//
//    OLED_WriteIns(0x8f);
//
//    AMI_Initial_MG9100();
//
//    AMI_ReadReg(AMI_slvAddr_1, AMI_SLOT_1_STATUS, &hddStatus);

    sctimerClock = SCTIMER_CLK_FREQ;

	/* Print a note to terminal */
	//PRINTF("\r\nSCTimer example to output 2 center-aligned PWM signals\r\n");
	//PRINTF("\r\nProbe the signal using an oscilloscope");

	SCTIMER_GetDefaultConfig(&sctimerInfo);

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

	/* Configure first PWM with frequency 24kHZ from first output */
	pwmParam.output           = DEMO_FIRST_SCTIMER_OUT;
	pwmParam.level            = kSCTIMER_HighTrue;
	pwmParam.dutyCyclePercent = updatedDutycycle;
	if (SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_EdgeAlignedPwm, 24000U, sctimerClock, &eventNumberOutput) == kStatus_Fail)
	{
		return -1;
	}

	/* Enable interrupt flag for event associated with out 4, we use the interrupt to update dutycycle */
	SCTIMER_EnableInterrupts(SCT0, (1 << eventNumberOutput));

	/* Receive notification when event is triggered */
	SCTIMER_SetCallback(SCT0, SCTIMER_LED_HANDLER, eventNumberOutput);

	/* Enable at the NVIC */
	EnableIRQ(SCT0_IRQn);

    /* Start the 32-bit unify timer */
    SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_U);

    /* Force the counter to be placed into memory. */
    //volatile static int i = 0 ;
    /* Enter an infinite loop, just incrementing a counter. */
    while(1) {

    	/* Use interrupt to update the PWM dutycycle on output */
		if (true == sctimerIsrFlag)
		{
			/* Disable interrupt to retain current dutycycle for a few seconds */
			SCTIMER_DisableInterrupts(SCT0, (1 << eventNumberOutput));

			sctimerIsrFlag = false;

			/* Enable interrupt flag to update PWM dutycycle */
			SCTIMER_EnableInterrupts(SCT0, (1 << eventNumberOutput));

			/* Update PWM duty cycle */
			SCTIMER_UpdatePwmDutycycle(SCT0, DEMO_FIRST_SCTIMER_OUT, updatedDutycycle, eventNumberOutput);

			/* Delay to view the updated PWM dutycycle */
			//delay();



		}
0 Kudos
Reply
4 Replies

1,485 Views
AccorMountain
Contributor I

Hi @Alex_Wang 

Thanks for your quick reply. I apologize for not clearly explaining my point. When I use the purely SDK code to generate a pulse, the result is the same as yours, and it works fine. However, when I try to modify the code to generate a different duty cycle for each pulse individually, weird pulses occur frequently. It seems that the more frequently I update the duty cycle, the more frequently these weird pulses occur. I can't figure out why. Should I avoid generating pulses with different duty cycles one by one?

0 Kudos
Reply

1,493 Views
Alex_Wang
NXP Employee
NXP Employee

Hello, @AccorMountain 

Hello, I have repeated the problem you mentioned, and there is no such problem. The SDK version I used is "SDK_2_14_0_LPCXpresso55S28.zip". The SDK example "lpcxpresso55s28_sctimer_pwm_with_dutycyle_change" was tested on the LPC55S28 development board, and the output pulse of pin P0_15(SCT0, OUT2) was checked with a virtual oscilloscope. The pulse was correct. The hardware connection is as follows:

Alex_Wang_0-1703135708653.jpeg

Please see the attachment video for test pulse.

Best regards, Alex.

0 Kudos
Reply

1,464 Views
Alex_Wang
NXP Employee
NXP Employee

Hello, @AccorMountain 

      Hi, I have checked the code and found that "/*Enable interrupt flag to update PWM duty cycle*/" is placed in front of "/* Update PWM duty cycle */", you can modify it and try again, please refer to the following figure:

Alex_Wang_0-1703211227578.png

      You can test the attachment project.

Best regards, Alex.

Tags (2)
0 Kudos
Reply

1,397 Views
AccorMountain
Contributor I

Hi @Alex_Wang ,

I still meet the weird pulse when i use your project and only modify the delay parameter from 80000U to 8000U, the shorter of delay will make weird pulse happen more frequently, could you try to modify the delay time to 8000U and chekc if you also get weird pulse?

2023-12-22_142821.jpg

0 Kudos
Reply