cancel
Showing results for 
Search instead for 
Did you mean: 

Variable Color Generation with PWM signals and RGB led.

RicardoDuarte
Associate II

Hello everybody.

I tried to develop a simple application, using a RGB led to produce variable colors in a continous way along the time and I still not have succeeded completely. Let me explain what is happening:

1) I used STM32CubeMX 5.3.0 to configure PWM3 (Channel2), PWM4 (Channel 1) and PWM1 (Channel 1N) to control PWM signals respectively in PC7 (Red), PB6 (Blue) and PA7 (Green). These GPIOs are fixed and linked to the RGB led terminals mounted in a commercial shield. I´m using STM32 Nucleo for F1 Board (STM32F103RB MCU).

2) I configured STM32CubeMX clock tree with PB1 and PB2 Timer Clocks with 0.0625 MHz (62500 KHz). My intention is to generate a PWM 500 Hz frequency with resolution value equal to 125.

3) My initial configuration of the PWM channels in STM32CubeMX was:

TIM4 (Channel1 = PWM Generation CH1; Clock Source: Internal Clock; Prescaler = 0; Counter Period = 125; Pulse = 62);

TIM3 (Channel2 = PWM Generation CH2; Clock Source: Internal Clock; Prescaler = 0; Counter Period = 125; Pulse = 62);

TIM1 (Channel1 = PWM Generation CH1N; Clock Source: Internal Clock; Prescaler = 0; Counter Period = 125; Pulse = 62);

4) I generated the Code to SW4STM. I included the code below in the infinite loop:

 /* Infinite loop */

 /* USER CODE BEGIN WHILE */

 while (1)

 {

  /* USER CODE END WHILE */

  /* USER CODE END WHILE */

//  setPWM(htim1, TIM_CHANNEL_1, 125, 1);

 for(int i=0; i<125; i++){

 setPWM(htim3, TIM_CHANNEL_2, 125, i+=2); // Sinal R

 for(int j=0; j<125; j++){

 setPWM(htim4, TIM_CHANNEL_1, 125, j+=2); // Sinal B

 for(int k=0; k<125; k++){

 setPWM(htim1, TIM_CHANNEL_1, 125, k+=2); // Sinal G

 }

 }

 }

  /* USER CODE BEGIN 3 */

 }

5) My setPWM function is described below:

/* USER CODE BEGIN 4 */

void setPWM(TIM_HandleTypeDef timer, uint32_t channel, uint16_t period, uint16_t pulse)

{

HAL_TIM_PWM_Stop(&timer, channel); // stop generation of pwm

TIM_OC_InitTypeDef sConfigOC;

timer.Init.Period = period; // set the period duration

HAL_TIM_PWM_Init(&timer); // reinititialise with new period value

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = pulse; // set the pulse duration

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

HAL_TIM_PWM_ConfigChannel(&timer, &sConfigOC, channel);

HAL_TIM_PWM_Start(&timer, channel); // start pwm generation

}

/* USER CODE END 4 */

6) I tested the code and what is happening?

TIM3 (Signal Red) and TIM4 (signal Blue) varies color along the time as expected.

TIM1 (Signal Green) remains off all the time.

Fact: I´ve already test and I verified that Green Led is working properly.

What I suspect after that?

My TIM1 is not configured properly and/or I´m not using TIM1 in a correct manner, or both.

I appreciate if you could provide me a clue or point me where I can solve my question.

If you need the complete code to have a better analysis, ask me that I can post on this thread question.

Best wishes.

Ricardo

1 ACCEPTED SOLUTION

Accepted Solutions

Hi Ricardo, I am not using F1xx series but you are using N output.

PWM channel can be enabled/stopped with first line, PWMN output require second line.

Please check if this solve your issue, I am not familair to F103

      HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);

      HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);

      HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);

      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);

Channel update using start and configure result in PWM noise, try use

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, PWM_Value);

Regards

View solution in original post

5 REPLIES 5

TIM1 is an advanced timer, you need to explicitly enable pin outputs.

You'd also need to completely fill out all the fields in the TIM_OC_InitTypeDef , and timer structures. In auto/local variables make sure you completely clear the structures, otherwise they will contain random junk, and break downstream usage.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
RicardoDuarte
Associate II

Hello Clive.

First thank you for your attention and prompt response.

I agree with you that the pin outputs must be explicity enabled when TIM 1 is used.

I suppose that I did this correctly.

First I configured the Green terminal as PWM Generation CH1N fixed associated to PA7 pin of STM32F103RB.

Then I verified in the project file (main.h) the correct association:

#define Sinal_G_Pin GPIO_PIN_7

#define Sinal_G_GPIO_Port GPIOA

Then I also verified in project file (stm32f1xx_hal_msp.c) the correct initiation of the GPIO_InitStruct. As you see in the code bellow:

void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)

{

 GPIO_InitTypeDef GPIO_InitStruct = {0};

 if(htim->Instance==TIM1)

 {

 /* USER CODE BEGIN TIM1_MspPostInit 0 */

 /* USER CODE END TIM1_MspPostInit 0 */

  __HAL_RCC_GPIOA_CLK_ENABLE();

  /**TIM1 GPIO Configuration   

  PA7   ------> TIM1_CH1N 

  */

  GPIO_InitStruct.Pin = Sinal_G_Pin;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

  HAL_GPIO_Init(Sinal_G_GPIO_Port, &GPIO_InitStruct);

  __HAL_AFIO_REMAP_TIM1_PARTIAL();

 /* USER CODE BEGIN TIM1_MspPostInit 1 */

 /* USER CODE END TIM1_MspPostInit 1 */

 }

Therefore I think that the correct pin output PA7 is correctly and explicit associated with TIM 1 PWM Channel CH1N.

Following your suggestion I wrote a new function dedicated exclusively to reconfigure TIM 1 PWM CH1N, filling out all the fields in TIM_OC_InitTypeDef and timer structures. See the code function bellow:

void setPWM_TIM1(TIM_HandleTypeDef timer, uint32_t channel, uint16_t period, uint16_t pulse)

{

HAL_TIM_PWM_Stop(&timer, channel); // stop generation of pwm

TIM_OC_InitTypeDef sConfigOC;

timer.Init.Period = period; // set the period duration

HAL_TIM_PWM_Init(&timer); // reinititialise with new period value

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = pulse;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

HAL_TIM_PWM_ConfigChannel(&timer, &sConfigOC, channel);

HAL_TIM_PWM_Start(&timer, channel); // start pwm generation

}

In the infinite loop I called the new function in the innermost for statement (see bellow):

 while (1)

 {

  /* USER CODE END WHILE */

  /* USER CODE END WHILE */

 for(int i=0; i<125; i++){

 setPWM(htim3, TIM_CHANNEL_2, 125, i+=2); // Sinal R

 for(int j=0; j<125; j++){

 setPWM(htim4, TIM_CHANNEL_1, 125, j+=2); // Sinal B

 for(int k=0; k<125; k++){

 setPWM_TIM1(htim1, TIM_CHANNEL_1, 125, k+=2); // Sinal G

 }

 }

 }

  /* USER CODE BEGIN 3 */

I built the project and tested again with your suggestions, but the behavior remains the same as before.

I still have a suspection that the problem is related with some aditional configuration with TIM 1 - CH1N.

I appreciate any further clues.

Best regards.

Ricardo

Hi Ricardo, I am not using F1xx series but you are using N output.

PWM channel can be enabled/stopped with first line, PWMN output require second line.

Please check if this solve your issue, I am not familair to F103

      HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);

      HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);

      HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);

      HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);

Channel update using start and configure result in PWM noise, try use

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, PWM_Value);

Regards

RicardoDuarte
Associate II

Hi rromano001.

You got it what was happenning.

Now it works properly.

Thanks for the clue about the macro __HAL_TIM_SET_COMPARE use.

Best wishes.

Ricardo

Hi Ricardo, thank for Best selection.

Everyone get in trouble, sometimes solution is simple other is hidden or in front of us and we don't see for various reason.

The macro was suggested from someone here in the forum, I found some good text but still a complete guide to HAL/LL library and CubeMx is missing.

Regards