硬件平台: 新UFUN开发板-STM32F103RC
硬件电路:新UFUN开发板是共阳RGB彩灯,(没有仔细看原理图,下代码之前一直以为是共阴极)
▲新UFUN开发板RGB彩灯硬件原理图
RGB原理:
度娘有话说:RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。
▲RGB色彩
在电脑中,RGB的所谓“多少”就是指亮度,并使用整数来表示。通常情况下,RGB各有256级亮度,按照计算,256级的RGB色彩总共能组合出约1678万种色彩,即256×256×256=16777216。通常也被简称为1600万色或千万色。也称为24位色(2的24次方)。
好了,知道这些就够了!!!!!
设计思路:
RGB LED简单一组或两组组合亮灭,可以实现7种色彩,这种方式色彩分界线明显
控制1组:红、蓝、绿,
控制两组:红+蓝=青,红+绿=黄,
三组:红+蓝+绿=白,共七色
▲RGB组合图,新UFUN的颜色与上图方向相反,顺时针颜色分别是:红→绿→蓝
如果50%红+50%绿=黄,那么20%红+80%=???什么颜色,红黄?橙???好吧不知道也没关系
本篇介绍,通过用RGB通过PWM实现更多颜色渐变的实现(有多少种没算过),变化过程种很多色实际上肉眼可能反应不过来奥
实现代码:
新UFUN开发板RGB彩灯的控制引脚时PA0,PA1,PA2
复用功能分别是TIM2CH1/TIM5CH1,TIM2CH1/TIM5CH1,TIM2CH2/TIM5CH2,TIM2CH3/TIM5CH3,TIM2与TIM5的通道引脚一模一样
端口初始化函数
void LED_GPIO_Init(void) //端口初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //端口时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_2; //配置端口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //配置模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出速率
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
TIM配置函数
void PWM_Init(u16 per,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //开启定时器时钟
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //开启GPIO 时钟
TIM_TimeBaseInitStructure.TIM_Period=per;//装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc;//预分频
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OC1Init(TIM2,&TIM_OCInitStructure);
TIM_OC2Init(TIM2,&TIM_OCInitStructure);
TIM_OC3Init(TIM2,&TIM_OCInitStructure);
//配置 NIVC中断
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM2,ENABLE); //使能ARR
TIM_Cmd(TIM2,ENABLE);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //设置了中断类型(溢出中断)并使能
}
void LED_Move(char user_mode,char user_colour,unsigned int user_RPower)
{
if(user_mode>0)
{
LED.dir=CW; //红 绿 蓝
LED.mode=user_mode;
}
else
{
LED.dir=CCW; //红 蓝 绿
LED.mode=-user_mode;
}
LED.colour=user_colour;
LED.RPower=user_RPower;
PWM_Init(user_RPower,1);
}
中断函数
void TIM2_IRQHandler(void)
{
//static int AAA=3000;
//static unsigned int R,G,B;
unsigned int R_delay=0;
unsigned int G_delay=0;
unsigned int B_delay=0;
static unsigned int count=0;
if (TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
{
switch(LED.mode) //模式
{
case 2:
switch(LED.dir) //方向
{
case CW:
switch(LED.colour) //状态
{
case R:
count++;
R_delay=LED.RPower-count;
G_delay=count;
if(count>=LED.RPower)
{
LED.colour=G;
count=0;
}
break;
case G:
count++;
G_delay=LED.RPower-count;
B_delay=count;
if(count>LED.RPower)
{
LED.colour=B;
count=0;
}
break;
case B:
count++;
B_delay=LED.RPower-count;
R_delay=count;
if(count>=LED.RPower)
{
LED.colour=R;
count=0;
}
break;
}
}
break;
/* case CCW:
switch(LED.colour) //状态
{
case 'R':
count++;
R=LED.RPower-count;
B=LED.RPower+count;
if(count>=LED.RPower)
{
LED.state=B_G;
count=0;
}
break;
case 'B':
count++;
B=LED.RPower-count;
G=LED.RPower+count;
if(count>=LED.RPower)
{
LED.state=G_R;
count=0;
}
break;
case 'G':
count++;
G=LED.RPower-count;
R=LED.RPower+count;
if(count>=LED.RPower)
{
LED.state=R_B;
count=0;
}
break;
}
break;
*/
/*
case 3:
switch(LED.dir) //方向
{
case CW:
switch(LED.colour) //状态
{
case 'R':
count++;
R=LED.RPower-count;
G=LED.RPower+count;
if(count>=LED.RPower)
{
LED.state=G_B;
count=0;
}
break;
case 'G':
count++;
G=LED.RPower-count;
B=LED.RPower+count;
if(count>=LED.RPower)
{
LED.state=G_R;
count=0;
}
break;
case 'B':
count++;
G=LED.RPower-count;
B=LED.RPower+count;
if(count>=LED.RPower)
{
LED.state=R_G;
count=0;
}
break;
}
break;
}
break;
*/
}
/*
case R_G_B:
R-=2;
G++;
B++;
if(0.3)
{
LED.state=LED_off;
}
break;
*/
/*
TIM2->ARR=3000;
//TIM2->CCER|=1<<0;
TIM2->ARR=3000;
//TIM2->CCER|=1<<4;
TIM2->ARR=3000;
//TIM2->CCER|=1<<8;
*/
}
TIM2->CCR1=G_delay;
TIM2->CCR2=B_delay;
TIM2->CCR3=R_delay;
TIM2->CCER|=1<<0; //使能电平
TIM2->CCER|=1<<4;
TIM2->CCER|=1<<8;
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志
}
主函数int main()
{
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组
LED_GPIO_Init(); //配置并初始引脚
LED_Move(2,R,20000);
//delay_ms(1000);
while(1)
{
}
}
仿真图
视频效果图
说实话灯光的视频不太好拍,不知能不能看出效果(测试亮瞎了我24K黄金眼)
红、某红、某黄红、某黄、某绿黄、叫不上名的绿、绿、某绿、某青绿、某青、某青蓝、叫不上名的蓝等等吧..................
由于时间有限,我并没有来得及做三色的叠加,原理很简单,代码也不复杂,有兴趣可以试一下
理论上可以产生: 3^(分辨率)次方种颜色,具体我不太会算|╮(╯_╰)╭
绛红、大红、朱红、嫣红、深红、水红、橘红、杏红、粉红、桃红、玫瑰红、玫瑰茜红、茜素深红、土红、铁锈红、浅珍珠红、壳黄红、橙红、浅粉红
豆绿、浅豆绿、橄榄绿、茶绿、葱绿、苹果绿、原野绿、森林绿、洋蓟绿、苔藓绿、草地绿/草绿水草绿、深草绿、灰湖绿、水绿、海水绿、酸性绿、水晶绿柠檬黄、淡黄、中黄、土黄、铬黄、桔黄、橙黄、铋黄、基黄、撒哈拉黄、拿坡里黄 中国画颜色:藤黄、石黄、鹅黄、鸭黄、雄黄、杏黄、姜黄、柳黄群青、普蓝、钴蓝、湖蓝、靛蓝、碧蓝、蔚蓝、宝蓝、藏蓝、黛蓝、孔雀蓝、天蓝、深蓝、淡蓝、瓦蓝、冰蓝、水蓝、蓝黑,简直是万紫千红一片色~~~