cancel
Showing results for 
Search instead for 
Did you mean: 

Generate PWM with two duty cycles simultaneously

$AK
Associate III

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

12 REPLIES 12

Hello @Erwan YVIN​,

Thanks for your suggestion, but the MCU I'm using doesn't support DMA.

I just solved the above stated issue by using SPI interface by converting a single bit to a byte of data in SPI in 6.4MHz clock.

I 'am running SPI data with 6.4MHz speed, where the time for sending 8bits of data is 1.25us.

To send data for WS2812/13 Addressable LED data should be passed in 400/800kbps (2.5us/1.25us).

0693W000008y4t8QAA.jpg 

Regards,

AK

Erwan YVIN
ST Employee

good news ,

i spoke about SPC560B54 - Dis 

Nice to see that WS2812/13 Addressable LED data is working with SPC560B54

Good work

Erwan

Thanks,

SPC560B54 MCU had DMA, but the actual MCU was SPC560B50 which doesnt support DMA feature.

Regards,

AK