本帖最后由 lylam 于 2019-10-21 08:09 编辑

硬件平台  新UFUN开发板-STM32F103RC
360截图16171112125545.jpg
硬件电路新UFUN开发板是共阳RGB彩灯,(没有仔细看原理图,下代码之前一直以为是共阴极)
360截图16171112317464.jpg
▲新UFUN开发板RGB彩灯硬件原理图
RGB原理
度娘有话说:RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。
20190322162042589.jpg
RGB色彩
在电脑中,RGB的所谓“多少”就是指亮度,并使用整数来表示。通常情况下,RGB各有256级亮度,按照计算,256级的RGB色彩总共能组合出约1678万种色彩,即256×256×256=16777216。通常也被简称为1600万色或千万色。也称为24位色(2的24次方)。
好了,知道这些就够了!!!!!

设计思路
RGB LED简单一组或两组组合亮灭,可以实现7种色彩,这种方式色彩分界线明显
控制1组:红、蓝、绿,
控制两组:红+=青,红+绿=黄,
三组:红++绿=白,共七色
RGB.jpg
RGB组合图,UFUN的颜色与上图方向相反,顺时针颜色分别是:红→绿
如果50%+50%绿=黄,那么20%+80%=???什么颜色,红黄?橙???好吧不知道也没关系
本篇介绍,通过用RGB通过PWM实现更多颜色渐变的实现(有多少种没算过),变化过程种很多色实际上肉眼可能反应不过来奥
实现代码:

360截图16171112145747.jpg
UFUN开发板RGB彩灯的控制引脚时PA0,PA1,PA2
复用功能分别是TIM2CH1/TIM5CH1,TIM2CH1/TIM5CH1,TIM2CH2/TIM5CH2TIM2CH3/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)
        {        
        }
}

仿真图
360截图16171112287161.jpg
360截图16171112064939.jpg
360截图16171112075040.jpg

视频效果图
说实话灯光的视频不太好拍,不知能不能看出效果(测试亮瞎了我24K黄金眼)