如果LED闪烁(玩转单片机之智能车小露——LED闪烁实战)不能满足你,那么七彩LED呼吸灯绝对可以给你带来足够的乐趣。
七彩LED呼吸灯一般都需要PWM进行调光,所以编程有无限的灵活性。本文七彩呼吸灯可以实现彩虹单色显示、RGB任意颜色显示、单色亮度呼吸、七彩颜色转换呼吸:
//呼吸灯模式:关闭呼吸、单色呼吸、七彩转换呼吸
#define BLED_MODE_OFF 0X00
#define BLED_MODE_SINGLE 0X01
#define BLED_MODE_COLOR 0X02//颜色:关闭及RGB组合彩虹颜色
#define BLED_COLOR_OFF 0X00
#define BLED_COLOR_RED 0X01
#define BLED_COLOR_ORANGE 0X02
#define BLED_COLOR_YELLOW 0X03
#define BLED_COLOR_GREEN 0X04
#define BLED_COLOR_CYAN 0X05
#define BLED_COLOR_BLUE 0X06
#define BLED_COLOR_PURPLE 0X07
#define BLED_COLOR_WHITE 0X08//亮度:0x0100~0x1000;
#define BLED_BRIGHT 0x0fffvoid BLEDTurnOn(unsigned char color);
void BLEDDisplayColor(unsigned char red,unsigned char green,unsigned char blue);
void BLEDBreath(unsigned char mode,unsigned char color);
void BLEDTurnOff(void);
STC32G单片机PWM初始化
控制七彩LED前先要初始化PWM(GPIO设置、PWM设置、端口切换):
void BLEDInit(void){GPIO_InitTypeDef gpio;PWMx_InitTypeDef pwm;gpio.Mode = GPIO_OUT_PP;gpio.Pin = GPIO_Pin_LOW;GPIO_Inilize(GPIO_P2,&gpio);pwm.PWM_Mode = CCMRn_PWM_MODE1;pwm.PWM_Duty = 0x0000;pwm.PWM_EnoSelect = ENO5P;PWM_Configuration(PWM5, &pwm);pwm.PWM_EnoSelect = ENO6P;PWM_Configuration(PWM6, &pwm);pwm.PWM_EnoSelect = ENO7P;PWM_Configuration(PWM7, &pwm);pwm.PWM_Period = 0x1000; pwm.PWM_DeadTime = 0;pwm.PWM_MainOutEnable= ENABLE;pwm.PWM_CEN_Enable = ENABLE; PWM_Configuration(PWMB, &pwm);PWM5_SW(PWM5_SW_P20);PWM6_SW(PWM5_SW_P21);PWM7_SW(PWM5_SW_P22);NVIC_PWM_Init(PWMB,DISABLE,Priority_0);
}
彩虹单色显示
为简化代码,彩虹颜色的显示使用二维数组记录RGB占空比,通过color参数直接定位到ColorRaw数组中对应颜色的占空比。
unsigned char BLEDBreathMode;
unsigned char BLEDColor;
unsigned int BLEDScanCycle;unsigned int code ColorRaw[9][3] = {{0x0000,0x0000,0x0000}, //OFF{BLED_BRIGHT,0x0000,0x0000}, //RED{BLED_BRIGHT,BLED_BRIGHT >> 2,0x0000}, //ORANGE{BLED_BRIGHT,BLED_BRIGHT,0x0000}, //YELLOW{0x0000,BLED_BRIGHT,0x0000}, //GREEN{0x0000,BLED_BRIGHT,BLED_BRIGHT}, //CYAN{0x0000,0x0000,BLED_BRIGHT}, //BLUE{BLED_BRIGHT,0x0000,BLED_BRIGHT}, //PURPLE{BLED_BRIGHT,BLED_BRIGHT,BLED_BRIGHT}}; //WHITEvoid BLEDTurnOn(unsigned char color){unsigned int *pDuty;BLEDColor = color;BLEDBreathMode = BLED_MODE_OFF;pDuty = ColorRaw[color];PWMB_Duty5(pDuty[0]);PWMB_Duty6(pDuty[1]);PWMB_Duty7(pDuty[2]);
}
RGB任意颜色显示
RGB任意颜色显示也很简单,将RGB颜色三个分量参数(0x00~0xFF)缩放到占空比量程后直接输出:
void BLEDDisplayColor(unsigned char red,unsigned char green,unsigned char blue){PWMB_Duty5((unsigned int)red << 4);PWMB_Duty6((unsigned int)green << 4);PWMB_Duty7((unsigned int)blue << 4);
}
单色亮度呼吸和七彩颜色转换呼吸
呼吸思路仍然是在定时中断中按呼吸相应的呼吸规律更新RGB三种颜色的PWM占空比。
单色亮度呼吸熄灭效果不佳所以呼吸周期内只降低到最低亮度(0x0100)不会全熄。
七彩颜色转换呼吸按红->黄->绿->青->蓝->紫->红...依次循环转换。
void BLEDBreath(uint8 mode,uint8 color){BLEDColor = color;BLEDBreathMode = mode;BLEDScanCycle = 0;
}//Systick callback(20ms)
void SystickCallbackBLED(void){unsigned int *pDuty;if(BLEDBreathMode == BLED_MODE_SINGLE){pDuty = ColorRaw[BLEDColor];if(++BLEDScanCycle > 128)BLEDScanCycle = 0;if(BLEDScanCycle < 64){PWMB_Duty5(pDuty[0] - ((BLED_BRIGHT - 0x0100) >> 6) * BLEDScanCycle);PWMB_Duty6(pDuty[1] - ((BLED_BRIGHT - 0x0100) >> 6) * BLEDScanCycle);PWMB_Duty7(pDuty[2] - ((BLED_BRIGHT - 0x0100) >> 6) * BLEDScanCycle);}else{PWMB_Duty5(pDuty[0] - ((BLED_BRIGHT - 0x0100) >> 6) * (128 - BLEDScanCycle));PWMB_Duty6(pDuty[1] - ((BLED_BRIGHT - 0x0100) >> 6) * (128 - BLEDScanCycle));PWMB_Duty7(pDuty[2] - ((BLED_BRIGHT - 0x0100) >> 6) * (128 - BLEDScanCycle));}}else if(BLEDBreathMode == BLED_MODE_COLOR){if(++BLEDScanCycle > 448)BLEDScanCycle = 0;if(BLEDScanCycle < 64){PWMB_Duty5(BLED_BRIGHT);PWMB_Duty6((BLED_BRIGHT >> 6) * BLEDScanCycle);PWMB_Duty7(0x0000);}else if(BLEDScanCycle < 128){PWMB_Duty5(BLED_BRIGHT - (BLED_BRIGHT >> 6) * (BLEDScanCycle-64));PWMB_Duty6(BLED_BRIGHT);PWMB_Duty7(0x0000);}else if(BLEDScanCycle < 192){PWMB_Duty5(0x0000);PWMB_Duty6(BLED_BRIGHT);PWMB_Duty7((BLED_BRIGHT >> 6) * (BLEDScanCycle-128));}else if(BLEDScanCycle < 256){PWMB_Duty5(0x0000);PWMB_Duty6(BLED_BRIGHT - (BLED_BRIGHT >> 6) * (BLEDScanCycle-192));PWMB_Duty7(BLED_BRIGHT);}else if(BLEDScanCycle < 320){PWMB_Duty5((BLED_BRIGHT >> 6) * (BLEDScanCycle-256));PWMB_Duty6(0x0000);PWMB_Duty7(BLED_BRIGHT);}else if(BLEDScanCycle < 384){PWMB_Duty5(BLED_BRIGHT);PWMB_Duty6(0x0000);PWMB_Duty7(BLED_BRIGHT - (BLED_BRIGHT >> 6) * (BLEDScanCycle-320));}}elseBLEDScanCycle = 0;
}
- 本文采用的单片机为STC32G系列,感兴趣的朋友可以参考测试,或去Gitee上下载例程。
- 下载地址:https://gitee.com/loganxiang/lgxsmartcar ,参考breathled.h/breathled.c。
