玩转单片机之智能车小露——七彩LED呼吸灯

如果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				0x0fff

void 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_InitDefine 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(PWM6_SW_P21);
	PWM7_SW(PWM7_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}};	//WHITE
	
void 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){
	BLEDBreathMode = BLED_MODE_OFF;
	
	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] - min(pDuty[0],(((BLED_BRIGHT - 0x0100) >> 6) * BLEDScanCycle)));
			PWMB_Duty6(pDuty[1] - min(pDuty[1],(((BLED_BRIGHT - 0x0100) >> 6) * BLEDScanCycle)));
			PWMB_Duty7(pDuty[2] - min(pDuty[2],(((BLED_BRIGHT - 0x0100) >> 6) * BLEDScanCycle)));
		}
		else{
			PWMB_Duty5(pDuty[0] - min(pDuty[0],(((BLED_BRIGHT - 0x0100) >> 6) * (128 - BLEDScanCycle))));
			PWMB_Duty6(pDuty[1] - min(pDuty[1],(((BLED_BRIGHT - 0x0100) >> 6) * (128 - BLEDScanCycle))));
			PWMB_Duty7(pDuty[2] - min(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));
		}
	}
	else
		BLEDScanCycle = 0;
}
  • 本文采用的单片机为STC32G系列,感兴趣的朋友可以参考测试,或去Gitee上下载例程。
  • 下载地址:https://gitee.com/loganxiang/lgxsmartcar ,参考breathled.h/breathled.c。
posted @ 2025-10-24 22:48  芥子的世界  阅读(27)  评论(0)    收藏  举报