Interface RGB LED with STM32

In this tutorial we are going to interface RGB LED with STM32. Basically this is another application of PWM (Pulse Width Modulation) and should work with any microcontroller, that is capable of PWM.
I am using a Common Cathode RGB led i.e. the ground pin is
common and we have to supply voltage to the other individual pins. A CC RGB led looks as picture below
The individual pins represent the following colours
  • 1 –> RED
  • 2 –> GROUND
  • 3 –> GREEN
  • 4 –> BLUE
I have connected them to STM32F446RE as:-
  • 1 –> PA8 (TIM1_CH-1)
  • 2 –> GROUND 
  • 3 –> PA9 (TIM1_CH-2)
  • 4 –> PA10 (TIM1_CH-3)

HOW TO

Before going to the coding part, let’s see How these LEDs works. As we know that RGB stands for Red, Green and Blue and these LEDs can emit all these three colours at the same time. Basically each colour have a range of intensity from 0 to 255 which depends on the voltageprovided to the respective pin. We combine these intensities (0 to 255) of these three colours to produce 16 million (256x256x256) different colours.
In order to vary the voltage across these pins, we need to use PWM and for that I am using TIMER 1 of my STM32F446RE. TIMER is running at 90 MHz and we need to use prescalar and ARR to vary the duty cycle. Duty cycle describes the amount of time, the signal is in HIGH state as a percentage of total time, it takes to complete one cycle. As I mentioned, the intensity value ranges from 0 to 255, so I am going configure the timer in such a way that 100% duty cycle is equivalent to 255. So let’s start
You guys are familiar with the initial setup of cubemx so I am going to jump to TIMER CONFIGURATION section directly

As you can see above that the APB1 timer clock (TIMER1 clock) is running at 90 MHz.

Now as I mentioned, I need to configure timer in such a way that the 100% duty cycle is equivalent to 255 and so I am going to divide the clock by 255 i.e. (90 MHz / 255 = 352941). Next I want the ARR value to be set such that 100% of ARR is 255 again because this is what the timer is going to count upto and as the intensity vary from 0 to 255, it’s better to setup it as 255. So let’s further divide the clock by 255 i.e. (352941/255 = 1384). This (1384) is the value that we need to enter in the prescalar register.

Some Insight into the code

First I am going to write a function to feed the values in the different channels which are connected to the different pins of the RGB led.
void set_rgb (uint8_t red, uint8_t green, uint8_t blue)
{
 htim1.Instance->CCR1 = red;
 htim1.Instance->CCR2 = green;
 htim1.Instance->CCR3 = blue;
}
Next you need to start the respective channels in the main function and than feed in the desired values
int main(void)
{
  HAL_Init();

  SystemClock_Config();


  MX_GPIO_Init();
  MX_TIM1_Init();

  HAL_TIM_PWM_Start (&htim1, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start (&htim1, TIM_CHANNEL_2);
  HAL_TIM_PWM_Start (&htim1, TIM_CHANNEL_3);

  while (1)
  {

   set_rgb (255,0,0);   // red only
   HAL_Delay (1000);

   set_rgb (0,255,0);   // green only
   HAL_Delay (1000);

   set_rgb (0,0,255);  // blue only
   HAL_Delay (1000);

   set_rgb (255,255,0);
   HAL_Delay(1000);

   set_rgb (0,255,255);
   HAL_Delay (1000);

   set_rgb (255,0,255);
   HAL_Delay (1000);

   set_rgb (192,192,192);
   HAL_Delay (1000);


  }

}

Connection

The connections are as follows

To DOWNLOAD THE FULL CODE, VISIT https://www.controllerstech.com/rgb-led-and-stm32/

CHECK OUT THE VIDEO BELOW



Interface RGB LED with STM32 Interface RGB LED with STM32 Reviewed by Controllerstech on February 16, 2019 Rating: 5

1 comment:

  1. Sorry, sir. Can you share the github or any link of this project. I'm learning about stm32 registers, C programming from platformio/stm32duino. So i'm using TIMx_CR1, TIMx_ARR, TIMx_PSC, etc... And i don´t know how to "convert" from HAL functions to C registers, if you share the project complete i can make an idea of how to do the "conversion". Your content of this page and https://controllerstech.com/ is so useful, thank you!!!

    ReplyDelete

Powered by Blogger.