呼吸灯控制方法

呼吸灯控制方法

指示灯枚举

typedef enum{
	LED_LIGHT_WHITE_AUTO = 0,
	LED_LIGHT_RED_AUTO,
}EnumLedLight;

指示灯灯效枚举

typedef enum{
	LED_STATE_STABLE = 0,
	LED_STATE_FLASH,//闪烁
	LED_STATE_BREASH,//呼吸
	LED_STATE_RES,
	LED_STATE_FADE_UP,//渐亮
	LED_STATE_FADE,
}EnumLedState;

灯效控制

typedef struct{
	EnumLedState mode;//灯效模式
	uint32_t gpio;
	uint16_t pin;
	uint32_t value;
	uint8_t max_brightness_percent;//变化的最亮值
	float brightness_percent;//亮度控制,每步只能亮这么长时间
	float brightness_percent_step;//控制亮度用,亮度增加的步长
	uint8_t isledOn;//拉高-1;拉低-0
	uint32_t period_tick;//计时
	uint32_t period_step;//改变亮度周期,计时到这个时间改brightness_percent
	uint32_t period_change;//记录brightness_percent改变的时间点
	uint32_t period_half;//点亮或熄灭半个周期的时长
	uint32_t period_all;//点亮或熄灭整个周期的时长
	uint8_t fade_end;
}LedControlInfo;
#define LIGHT_NUM_MAX 2
LedControlInfo Lights[LIGHT_NUM_MAX];

**//registerGpioLedLight在GPIO.c中完成初始化**
void registerGpioLedLight(EnumLedLight light, uint32_t gpio_periph, uint16_t pin){
	if(light >= LIGHT_NUM_MAX)return;
	LedControlInfo *info = lights + light;   //lights表示第一个结构体,light表示结构体指针偏移
	info ->gpio = gpio_periph;
	info -> pin =pin;
	info ->mode = LED_STATE_STABLE;
	info -> value = 0;
	info -> max_brightness_percent =100;
}

uint8_t isLedControlStateEnd(EnumLedLight  light){
	if(light < LIGHT_NUM_MAX){
		LedControlInfo *info = lights + light; 
		if((info -> mode == LED_STATE_FADE_UP) || (info -> mode == LED_STATE_FADE)){
			return info -> fade_end;
		}
	}
	return 0;
}
/*
1.先关闭LED;
2.如果period_tick是period_step的整数倍,则赋值period_change,如果后者超过period_half,逐步降低亮度,否则增亮
3.确保来个亮度百分比在合理范围内
4.超时点亮LED
*/
**static void lightCtrl_LL(LedControlInfo *info)**
{
	info -> isledOn = 0;
	if((info - > period_tick % info -> period_step) == 0){
		info -> period_change = info -> period_tick;
		if(info -> period_change > info -> period_half){
			info -> brightness_percent -= info -> brightness_percent_step;
		}
		else{
			info -> brightness_percent += info -> brightness_percent_step;
		}
		if(info -> brightness_percent > info -> max_brightness_percent){
			info -> brightness_percent -= info -> max_brightness_percent;
		}
		else if( info -> brightness_percent  < 0){
			info -> brightness_percent = 0;
		}
	}
	if((info -> period_tick - info -> period_change) < info -> brightness_percent ){
		info -> isledOn = 1;
	}
	if(info -> isledOn){
		GPIO_BOP(info -> gpio) = info -> pin;
	}
	else{
		GPIO_BC(info -> gpio) = info -> pin;
	}
	info -> period_tick++;
}
*//将函数放在定时器回调函数中运行即可*
void displaylight(void){
	for(i= 0;i< LIGHT_NUM_MAX;i++){
		LedControlInfo *info = lights +i;
		switch(info -> mode){
			case LED_STATE_STABLE://开关状态
				if(info ->period_tick > info ->period_all){
					info->period_tick = 0;
					info->period_change = 0;
				}
				break;
			case LED_STATE_FLASH://闪烁
				if(info ->period_tick > info ->period_all){
					info->period_tick = 0;
					info->period_change = 0;
				}
				break;
			case LED_STATE_BREATH://呼吸
				if(info ->period_tick > info ->period_all){
					info->period_tick = 0;
					info->period_change = 0;
					info->brightness_percent = 0;
				}
				break;			
			case LED_STATE_FADE_UP://渐亮
				if(info ->period_tick == info ->period_all){
					info->period_tick = info->period_change;
					info->fade_end = 1;
				}
				break;			
			case LED_STATE_FADE://渐暗
				if(info ->period_tick > info ->period_all){
					info->period_tick = info->period_change;
					info->fade_end = 1;
				}
				break;		
			default:
				break;
		}
		**lightCtrl_LL(info);**
	}
}
//setLedLightControlInfo函数作为外部调用接口进行调用,触发不同的灯效
void setLedLightControlInfo(EnumLedLight light,EnumLedState mode,uint32_t value,uint8_t max_value){
	if(light >= LIGHT_NUM_MAX){
		return;
	}
	LedControlInfo *info = lights + light;
	info -> mode = mode;
	info -> value = value;
	info -> isledOn = 0;
	info -> period_tick = 0;
	info -> fade_end = 0; 
	info -> period_change = 0;
	info -> period_step = 100;

	switch(info -> mode){
		case LED_STATE_FLASH:
			info -> period_all = info->period_half * 2;
			info ->period_half = info->value * 100 * 10;
			if((value > 0) && (max_value <= 100)){
				info -> max_brightness_percent = max_value;
				info -> brightness_percent = max_value;
				info -> brightness_percent_step = max_value;
			}
			else{
				info -> max_brightness_percent = 0;
				info ->brightness_percent = 0;
				info ->brightness_percent_step = 0;
			}
			break;
		case LED_STATE_STABLE:
			info -> period_all =100;
			info ->period_half = 100;
			info -> brightness_percent_step = 0;
			if((value > 0)&&(max_value <= 100)){
				info -> max_brightness_percent = max_value;
				info ->brightness_percent = max_value;
			}
			else{
				info -> max_brightness_percent = 0;
				info ->brightness_percent = 0;
			}
			break;
		case LED_STATE_BREATH:
			info -> period_all = info->value *100 * 10 * 2;
			info ->period_half = info->period_all / 2;
			if((value > 0) && (max_value <= 100)){
				info -> max_brightness_percent = max_value;
				info -> brightness_percent = 0;
				info -> brightness_percent_step = (float)info -> max_brightness_percent *100 / info -> period_half;
			}
			else{
				info -> max_brightness_percent = 0;
				info ->brightness_percent = 0;
				info ->brightness_percent_step = 0;
			}
			break;
		case LED_STATE_FADE_UP:
			info -> period_all = info->value *100 * 10;
			info ->period_half = period_all ;
			info -> brightness_percent_step = 0;
			if((value > 0)&&(value <= 100)){
				info -> max_brightness_percent = max_value;
				info -> brightness_percent_step = (float)info -> max_brightness_percent *100 / info -> period_all;
				info ->brightness_percent = 0;
			}
			else{
			    info -> brightness_percent_step = 0;
				info -> max_brightness_percent = 0;
				info -> brightness_percent = 0;
			}
			break;
		case LED_STATE_FADE:
			info -> period_all = info->value *100 * 10;
			info ->period_half = 0;
			info -> brightness_percent_step = 0;
			if((value > 0)&&(value <= 100)){
				info -> max_brightness_percent = max_value;
				info -> brightness_percent_step = (float)info -> max_brightness_percent *100 / info -> period_all;
				info ->brightness_percent = max_value;
			}
			else{
			    info -> brightness_percent_step = 0;
				info -> max_brightness_percent = 0;
				info -> brightness_percent = 0;
			}
			break;
		default:
			break;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值