Skip to main content
$AK
Associate III
March 10, 2021
Solved

Generate PWM with two duty cycles simultaneously

  • March 10, 2021
  • 2 replies
  • 1944 views

Hello All,

I'm working on PWM on SPC560B54 - Dis by importing and using example source code "SPC560Bxx_RLA PWM-ICU Test Application for Discovery"

I can generate PWM signal with 800kHz and 400kHz frequency but could not change the Pulse width of every pulse I'm generating.

In order to control ws2812 addressable LED, PWM needs to be generated with 60% and 30% duty cycle simultaneously. I tried to generate PWM with two width simultaneously but sometimes one pulse is missed or generated extra. From datasheet ws2812 needs data in 800kHz and 400kHz with 24bits of "1"code(60%) and "0"code(30%) for one led.

/*************************************************************************************************/
#define LED_CNT 1
#define RED 1
#define GREEN 0
#define BLUE 2
 
uint8_t led_buffer[LED_CNT][3],i;
 
 
void glow_led(void)
{
	uint16_t led_no;
	uint8_t led_color,one=1;
	uint8_t bit;
	for(led_no = 0; led_no<LED_CNT; led_no++)
	{
		for(led_color=0; led_color<3; led_color++)
		{
			for(bit = 8; bit>0;bit--)
			{
				if((led_buffer[led_no][led_color]&(one<<(bit-1)))!=0) /*1 Code*/
				{
					pwm_lld_enable_channel(&PWMD5, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD5, 6000), 0);
				}
				else				 								 /*0 Code*/
				{
					pwm_lld_enable_channel(&PWMD5, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD5, 3000), 0);
				}
			}
		}
	}
	 pwm_lld_enable_channel(&PWMD5, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD5, 0), 0); /*Reset code*/
	 microsec_delay(50);
	pwm_lld_disable_channel(&PWMD5, 0);
}
 
void led(uint8_t led_num, uint8_t R, uint8_t G, uint8_t B)
{
	led_buffer[led_num][RED] = R;
	led_buffer[led_num][GREEN] = G;
	led_buffer[led_num][BLUE] = B;
	glow_led();
}
 
 
int main(void) 
{
	/* Initialization of all the imported components in the order specified in
	 the application wizard. The function is generated automatically.*/
	componentsInit();
 
	/* Enable Interrupts */
	irqIsrEnable();
 
	/*
	* Initializes the PWM driver 1.
	*/
	pwm_lld_start(&PWMD5, &pwm_config_emios1);
 
	while(1)
		{
		for(i=0;i<LED_CNT;i++)
			{
				led(i,0,255,255);
				osalThreadDelayMilliseconds(1000);
			}
			for(i=0;i<LED_CNT;i++)
			{
				led(i,0,0,0);
				osalThreadDelayMilliseconds(1000);
			}
		}
}
 
/*************************************************************************************************/

system clock - 64MHz, Peripheral Clock - 32MHz, PWM Frequency - 400kHz/800kHz.

Please guide me with above issue or Is there any other possible way to generate different pulses or to control ws2812.

Regards,

AK

    This topic has been closed for replies.
    Best answer by $AK

    The issue has been resolved in another post

    https://community.st.com/s/question/0D53W00000dOY29SAG/generate-pwm-with-two-duty-cycles-simultaneously

    Regards,

    AK

    2 replies

    $AK
    $AKAuthorBest answer
    Associate III
    April 1, 2021
    Javier1
    Principal
    April 19, 2021
    hit me up in https://www.linkedin.com/in/javiermuñoz/
    $AK
    $AKAuthor
    Associate III
    April 20, 2021

    But my MCU doesn't (SPC560B50L5) support DMA, because of that we have try different methods.

    Now it is solved with SPI.

    https://community.st.com/s/question/0D53W00000dOY29SAG/generate-pwm-with-two-duty-cycles-simultaneously

    Regards,

    AK

    Javier1
    Principal
    April 20, 2021

    its actually the first time i hear about that architecture.

    What do you use it for?

    hit me up in https://www.linkedin.com/in/javiermuñoz/