为了能更好地解决RGB三基色LED灯亮度的调节对颜色影响的问题,通常采用三路
PWM来控制三色灯的每种颜色的导通程度来实现彩色混色,调节亮度如果采用三种
基色同时递加或递减来实现亮度的调节,那么会造成颜色发生偏移问题,为了能解决
此问题,采用HSV空间颜色来实现亮度调节的
首先将RGB空间颜色转换成HSV空间颜色,然后调节V的值,调整之后,再将HSV空间
颜色转回到RGB空间颜色这样就实现了三色灯亮度的调节
在头文件中加入#include "math.h"
定义2个结构体数据类型
//color data struct
typedef struct{
unsigned char R;
unsigned char G;
unsigned char B;
unsigned char l;
}COLOR_RGB;
//hsv data struct
typedef struct{
float H;
float S;
float V;
}COLOR_HSV;
定义一个COLOR_RGB结构体变量rgb_v
COLOR_RGB rgb_v;
定义2个函数,一个求最大数,一个求最小数
/**------------------------------------------------------------------------------------------------
* @brief : This is return a and b of minimum value
* @param : None
* @retval : None
*----------------------------------------------------------------------------------------------*/
static float minValue(float a,float b) //calc minimum value
{
float temp = b;
if(a < temp)
temp = a;
return temp;
}
/**------------------------------------------------------------------------------------------------
* @brief : This is return a and b of maximum value
* @param : None
* @retval : None
*----------------------------------------------------------------------------------------------*/
static float maxValue(float a,float b) //calc maximum value
{
float temp = b;
if(a > temp)
temp = a;
return temp;
}
定义一个RGB空间颜色向HSV空间颜色转变的函数
/**------------------------------------------------------------------------------------------------
* @brief : This is RGB to HSV convert function
* @param : None
* @retval : None
*----------------------------------------------------------------------------------------------*/
static void RGB_TO_HSV(const COLOR_RGB* input,COLOR_HSV* output) // convert RGB value to HSV value
{
float r,g,b,minRGB,maxRGB,deltaRGB;
r = input->R/255.0f;
g = input->G/255.0f;
b = input->B/255.0f;
minRGB = minValue(r,minValue(g,b));
maxRGB = maxValue(r,maxValue(g,b));
deltaRGB = maxRGB - minRGB;
output->V = maxRGB;
if(maxRGB != 0.0f)
output->S = deltaRGB / maxRGB;
else
output->S = 0.0f;
if (output->S <= 0.0f)
{
output->H = 0.0f;
}
else
{
if (r == maxRGB)
{
output->H = (g-b)/deltaRGB;
}
else
{
if (g == maxRGB)
{
output->H = 2.0f + (b-r)/deltaRGB;
}
else
{
if (b == maxRGB)
{
output->H = 4.0f + (r-g)/deltaRGB;
}
}
}
output->H = output->H * 60.0f;
if (output->H < 0.0f)
{
output->H += 360;
}
output->H /= 360;
}
}
定义一个HSV空间颜色向RGB空间颜色转变的函数
/**------------------------------------------------------------------------------------------------
* @brief : This is HSV to RGB convert function
* @param : None
* @retval : None
*----------------------------------------------------------------------------------------------*/
static void HSV_TO_RGB(COLOR_HSV* input,COLOR_RGB* output) //convert HSV value to RGB value
{
float R,G,B;
int k;
float aa,bb,cc,f;
if (input->S <= 0.0f)
R = G = B = input->V;
else
{
if (input->H == 1.0f)
input->H = 0.0f;
input->H *= 6.0f;
k = (int)floor(input->H);
f = input->H - k;
aa = input->V * (1.0f - input->S);
bb = input->V * (1.0f - input->S * f);
cc = input->V * (1.0f -(input->S * (1.0f - f)));
switch(k)
{
case 0:
R = input->V;
G = cc;
B =aa;
break;
case 1:
R = bb;
G = input->V;
B = aa;
break;
case 2:
R =aa;
G = input->V;
B = cc;
break;
case 3:
R = aa;
G = bb;
B = input->V;
break;
case 4:
R = cc;
G = aa;
B = input->V;
break;
case 5:
R = input->V;
G = aa;
B = bb;
break;
}
}
output->R = (unsigned char)(R * 255);
output->G = (unsigned char)(G * 255);
output->B = (unsigned char)(B * 255);
}
定义一个调整亮度函数
/**---------------------------------------------------------------------------
* @brief : This is brightness adjusting function
* @param : None
* @retval : None
*-----------------------------------------------------------------------------*/
void adjustBrightness(int step) //adjust RGB brightness
{
COLOR_HSV hsv_v;
RGB_TO_HSV(&rgb_v,&hsv_v);
rgb_v.l += step;
if(rgb_v.l <= 0)
{
rgb_v.l = 1;
}else if(rgb_v.l >= 100)
{
rgb_v.l = 100;
}
hsv_v.V = rgb_v.l /100.0;
HSV_TO_RGB(&hsv_v,&rgb_v);
}
在main函数中测试RGB亮度调节
/**@brief Application main function.
*/
int main(void)
{
bool erase_bonds;
// Initialize.
// uart_init();
log_init();
timers_init();
buttons_leds_init(&erase_bonds);
power_management_init();
ble_stack_init();
gap_params_init();
gatt_init();
services_init();
advertising_init();
conn_params_init();
// Start execution.
// printf("\r\nUART started.\r\n");
NRF_LOG_INFO("Debug logging for UART over RTT started.");
advertising_start();
// 亮度调节测试
rgb_v.R = 0xef;
rgb_v.G = 0x36;
rgb_v.B = 0x86;
rgb_v.l = 0x64;
adjustBrightness(-30); //亮度减少30%
//打印转换后的RGB值及亮度值
NRF_LOG_INFO("R=%02x,G=%02x,B=%02x,L=%02x\n",rgb_v.R, rgb_v.G ,rgb_v.B,rgb_v.l);
// Enter main loop.
for (;;)
{
idle_state_handle();
}
}
DEMO下载地址:https://download.csdn.net/download/mygod2008ok/11180344