#include <reg52.h>
#include <intrins.h>
// 引脚定义
sbit KEY = P1^0; // 按键输入(低电平有效)
sbit LED_R = P2^0; // 红色LED(共阳极,低电平点亮)
sbit LED_G = P2^1; // 绿色LED
sbit LED_B = P2^2; // 蓝色LED
sbit HEAT = P2^3; // 加热输出(高电平有效)
// 全局变量
volatile unsigned char pwm_cnt = 0; // PWM计数器 0~19
volatile unsigned char pwm_thr_r = 20; // 红色PWM阈值
volatile unsigned char pwm_thr_g = 20;
volatile unsigned char pwm_thr_b = 20;
volatile unsigned char pwm_thr_heat = 0;
volatile unsigned char breath_active = 0; // 呼吸使能
volatile unsigned char breath_factor = 20; // 呼吸亮度因子 0~20
volatile unsigned char breath_dir = 0; // 方向 0:升 1:降
volatile unsigned char breath_cycle_done = 0;// 一次呼吸完成标志
volatile unsigned int breath_step_timer = 0; // 125ms步进计时
volatile unsigned int sys_tick_ms = 0; // 系统毫秒计数器
volatile unsigned char flag_10ms = 0; // 10ms定时标志
// 颜色目标亮度(0~20),对应蓝、绿、黄、橙、红、白
code unsigned char color_table[6][3] = {
{0, 0, 20}, // 蓝
{0, 20, 0}, // 绿
{20, 20, 0}, // 黄
{20, 10, 0}, // 橙(红多绿少)
{20, 0, 0}, // 红
{20, 20, 20} // 白
};
unsigned char color_target_r, color_target_g, color_target_b;
// 档位占空比(%)
code unsigned char duty_percent[6] = {20, 40, 60, 80, 100, 0};
unsigned char duty_idx = 0; // 当前档位索引
// 系统状态
typedef enum {
SYS_OFF,
SYS_STANDBY,
SYS_RUNNING,
SYS_LOWPROTECT
} SysState;
SysState sys_state = SYS_OFF;
// 电压阶段
#define STAGE_LOW 0 // <10.5V
#define STAGE_106_114 1 // 10.6~11.4V
#define STAGE_115_129 2 // 11.5~12.9V
#define STAGE_130_134 3 // 13.0~13.4V
#define STAGE_135PLUS 4 // ≥13.5V
unsigned char current_stage = STAGE_LOW;
// 运行子状态
unsigned char sub_state = 0;
unsigned int sub_timer = 0; // 子状态计时(ms)
unsigned int stage_total = 0; // 阶段累计计时(ms)
// 按键相关
unsigned char key_press_flag = 0;
unsigned int key_press_time = 0;
unsigned char key_long_press = 0;
unsigned char key_short_press = 0;
// 功能控制标志
unsigned char heat_enable = 0;
unsigned char led_on = 0;
// 函数声明
void Timer0_Init(void);
void KeyScan(void);
void UpdatePWMThresholds(void);
void EnterStage(unsigned char stage);
void UpdateRunningSubState(void);
void EnterStandby(void);
void EnterLowProtect(void);
void Activate(void);
unsigned int GetVoltage(void); // 返回mV,需用户实现
unsigned char GetVoltageStage(unsigned int v);
// 定时器0中断(1ms)
void Timer0_ISR() interrupt 1 {
// 重装初值(12MHz,1ms)
TH0 = 0xFC;
TL0 = 0x18;
// PWM计数器更新(周期20ms)
pwm_cnt++;
if (pwm_cnt >= 20) pwm_cnt = 0;
// 输出PWM比较(共阳极:阈值越小越亮)
LED_R = (pwm_cnt < pwm_thr_r) ? 1 : 0;
LED_G = (pwm_cnt < pwm_thr_g) ? 1 : 0;
LED_B = (pwm_cnt < pwm_thr_b) ? 1 : 0;
HEAT = (pwm_cnt < pwm_thr_heat) ? 1 : 0;
// 呼吸步进(每125ms更新一次)
breath_step_timer++;
if (breath_step_timer >= 125) {
breath_step_timer = 0;
if (breath_active) {
if (breath_dir == 0) { // 上升
breath_factor++;
if (breath_factor >= 20) {
breath_factor = 20;
breath_dir = 1;
}
} else { // 下降
breath_factor--;
if (breath_factor == 0) {
breath_factor = 0;
breath_dir = 0;
breath_cycle_done = 1; // 完成一个呼吸周期
}
}
// 更新PWM阈值(呼吸因子变化时)
UpdatePWMThresholds();
}
}
// 系统毫秒计数
sys_tick_ms++;
// 10ms标志
if (sys_tick_ms % 10 == 0) flag_10ms = 1;
}
// 更新PWM阈值
void UpdatePWMThresholds(void) {
unsigned char factor = breath_active ? breath_factor : 20;
if (!led_on) {
pwm_thr_r = 20;
pwm_thr_g = 20;
pwm_thr_b = 20;
} else {
pwm_thr_r = 20 - (color_target_r * factor / 20);
pwm_thr_g = 20 - (color_target_g * factor / 20);
pwm_thr_b = 20 - (color_target_b * factor / 20);
}
// 加热阈值
if (heat_enable) {
unsigned char duty = duty_percent[duty_idx];
pwm_thr_heat = duty * 20 / 100;
} else {
pwm_thr_heat = 0;
}
}
// 获取电压阶段
unsigned char GetVoltageStage(unsigned int v) {
if (v < 10500) return STAGE_LOW;
else if (v < 11500) return STAGE_106_114; // 10.6~11.4
else if (v < 13000) return STAGE_115_129; // 11.5~12.9
else if (v < 13500) return STAGE_130_134; // 13.0~13.4
else return STAGE_135PLUS;
}
// 进入运行阶段(重置计时,初始化子状态)
void EnterStage(unsigned char stage) {
current_stage = stage;
sub_timer = 0;
stage_total = 0;
// 先关闭所有
heat_enable = 0;
led_on = 0;
breath_active = 0;
breath_cycle_done = 0;
breath_factor = 20;
breath_dir = 0;
switch(stage) {
case STAGE_106_114:
heat_enable = 0;
led_on = 1;
breath_active = 1;
breath_factor = 0; // 从暗开始
breath_dir = 0;
sub_state = 0; // 0:呼吸, 1:等待
break;
case STAGE_115_129:
heat_enable = 1;
led_on = 1;
breath_active = 0;
sub_state = 0; // 0:加热, 1:灭灯1, 2:呼吸, 3:灭灯2
break;
case STAGE_130_134:
heat_enable = 1;
led_on = 1;
breath_active = 0;
sub_state = 0; // 0:加热, 1:呼吸等待
break;
case STAGE_135PLUS:
heat_enable = 1;
led_on = 1;
breath_active = 0;
sub_state = 0;
break;
default:
break;
}
UpdatePWMThresholds();
}
// 更新运行子状态(每10ms调用)
void UpdateRunningSubState(void) {
static unsigned char wait_breath_sub = 0; // 用于高阶段呼吸子状态
static unsigned int wait_breath_timer = 0;
switch(current_stage) {
case STAGE_106_114:
// 子状态0:呼吸, 1:等待
if (sub_state == 0) {
if (breath_cycle_done) {
breath_cycle_done = 0;
// 一次呼吸完成
stage_total += 2500; // 累计呼吸时间
if (stage_total >= 7500) { // 3次呼吸完成(每次2.5s)
EnterStandby();
return;
} else {
// 进入等待1秒
sub_state = 1;
sub_timer = 0;
led_on = 0;
breath_active = 0;
UpdatePWMThresholds();
}
}
} else { // 等待
sub_timer += 10;
if (sub_timer >= 1000) {
sub_timer = 0;
sub_state = 0;
led_on = 1;
breath_active = 1;
breath_factor = 0;
breath_dir = 0;
breath_cycle_done = 0;
UpdatePWMThresholds();
}
}
break;
case STAGE_115_129:
// 子状态: 0加热, 1灭灯1, 2呼吸, 3灭灯2
sub_timer += 10;
if (sub_state == 0) { // 加热5s
if (sub_timer >= 5000) {
sub_timer = 0;
sub_state = 1;
heat_enable = 0;
led_on = 0;
breath_active = 0;
UpdatePWMThresholds();
}
} else if (sub_state == 1) { // 灭灯1s
if (sub_timer >= 1000) {
sub_timer = 0;
sub_state = 2;
led_on = 1;
breath_active = 1;
breath_factor = 0;
breath_dir = 0;
breath_cycle_done = 0;
UpdatePWMThresholds();
}
} else if (sub_state == 2) { // 呼吸2.5s
if (breath_cycle_done) {
breath_cycle_done = 0;
sub_timer = 0;
sub_state = 3;
led_on = 0;
breath_active = 0;
UpdatePWMThresholds();
}
} else if (sub_state == 3) { // 灭灯1s
if (sub_timer >= 1000) {
sub_timer = 0;
stage_total += 9500; // 5+1+2.5+1 = 9.5s
if (stage_total >= 60000) {
EnterStandby();
return;
} else {
sub_state = 0;
heat_enable = 1;
led_on = 1;
breath_active = 0;
UpdatePWMThresholds();
}
}
}
break;
case STAGE_130_134:
// 子状态: 0加热2min, 1呼吸等待(持续1min)
sub_timer += 10;
if (sub_state == 0) {
if (sub_timer >= 120000) { // 2分钟
sub_timer = 0;
sub_state = 1;
heat_enable = 0;
led_on = 1;
breath_active = 1;
breath_factor = 0;
breath_dir = 0;
breath_cycle_done = 0;
wait_breath_sub = 0; // 0:呼吸, 1:等待
wait_breath_timer = 0;
UpdatePWMThresholds();
}
} else { // 呼吸+等待循环,持续1分钟
if (wait_breath_sub == 0) { // 呼吸
if (breath_cycle_done) {
breath_cycle_done = 0;
wait_breath_sub = 1;
wait_breath_timer = 0;
led_on = 0;
breath_active = 0;
UpdatePWMThresholds();
}
} else { // 等待1s
wait_breath_timer += 10;
if (wait_breath_timer >= 1000) {
wait_breath_timer = 0;
stage_total += 3500; // 2.5+1
if (stage_total >= 60000) {
EnterStandby();
return;
} else {
wait_breath_sub = 0;
led_on = 1;
breath_active = 1;
breath_factor = 0;
breath_dir = 0;
breath_cycle_done = 0;
UpdatePWMThresholds();
}
}
}
}
break;
case STAGE_135PLUS:
// 持续加热,无需更新
break;
default:
break;
}
}
// 进入待机
void EnterStandby(void) {
sys_state = SYS_STANDBY;
heat_enable = 0;
led_on = 0;
breath_active = 0;
UpdatePWMThresholds();
}
// 进入低电压保护
void EnterLowProtect(void) {
sys_state = SYS_LOWPROTECT;
heat_enable = 0;
led_on = 0;
breath_active = 0;
UpdatePWMThresholds();
}
// 激活(待机或低保护->运行)
void Activate(void) {
unsigned int v = GetVoltage();
unsigned char stage = GetVoltageStage(v);
if (stage == STAGE_LOW) {
// 低于10.5V不允许激活
return;
}
sys_state = SYS_RUNNING;
EnterStage(stage);
}
// 按键扫描(10ms调用)
void KeyScan(void) {
static unsigned char last_key = 1;
static unsigned int press_cnt = 0;
unsigned char cur_key = KEY;
if (cur_key == 0 && last_key == 1) { // 按下
press_cnt = 0;
key_press_flag = 1;
} else if (cur_key == 0 && key_press_flag) {
press_cnt++;
if (press_cnt >= 300) { // 3秒(10ms*300)
key_long_press = 1;
key_press_flag = 0; // 防止重复触发
}
} else if (cur_key == 1 && last_key == 0) { // 释放
if (key_press_flag && press_cnt < 300 && press_cnt > 5) {
key_short_press = 1;
}
key_press_flag = 0;
press_cnt = 0;
}
last_key = cur_key;
}
// 主函数
void main(void) {
// 初始化
Timer0_Init();
// 默认颜色(蓝)
color_target_r = color_table[0][0];
color_target_g = color_table[0][1];
color_target_b = color_table[0][2];
UpdatePWMThresholds();
sys_state = SYS_OFF;
while(1) {
if (flag_10ms) {
flag_10ms = 0;
// 按键扫描
KeyScan();
// 处理按键事件
if (key_long_press) {
key_long_press = 0;
if (sys_state == SYS_OFF) {
// 开机
unsigned int v = GetVoltage();
unsigned char stage = GetVoltageStage(v);
if (stage != STAGE_LOW) {
sys_state = SYS_RUNNING;
EnterStage(stage);
} else {
// 电压过低,不开机
sys_state = SYS_OFF;
}
} else {
// 关机
sys_state = SYS_OFF;
heat_enable = 0;
led_on = 0;
breath_active = 0;
UpdatePWMThresholds();
}
}
if (key_short_press) {
key_short_press = 0;
// 短按:切换档位
duty_idx = (duty_idx + 1) % 6;
color_target_r = color_table[duty_idx][0];
color_target_g = color_table[duty_idx][1];
color_target_b = color_table[duty_idx][2];
UpdatePWMThresholds();
// 待机状态短按激活
if (sys_state == SYS_STANDBY) {
Activate();
}
// 低保护下短按仅调档但不激活(实际上低保护时我们不应调档,这里忽略)
// 若处于低保护,调档无效(可恢复颜色,但无输出)
if (sys_state == SYS_LOWPROTECT) {
// 不激活,但可调档(无输出)
}
}
// 电压检测(每100ms测一次)
static unsigned int vdetect_cnt = 0;
vdetect_cnt++;
if (vdetect_cnt >= 10) { // 100ms
vdetect_cnt = 0;
unsigned int v = GetVoltage();
unsigned char new_stage = GetVoltageStage(v);
// 状态机处理
switch(sys_state) {
case SYS_OFF:
// 不处理
break;
case SYS_LOWPROTECT:
if (new_stage == STAGE_135PLUS) {
Activate();
}
break;
case SYS_STANDBY:
if (new_stage == STAGE_135PLUS) {
Activate();
}
break;
case SYS_RUNNING:
// 防回跳:只允许下降或升到13.5V以上
if (new_stage == STAGE_LOW) {
// 进入低保护
EnterLowProtect();
} else if (new_stage < current_stage) {
// 降到更低阶段
current_stage = new_stage;
EnterStage(new_stage);
} else if (new_stage > current_stage && new_stage == STAGE_135PLUS) {
// 升到正常阶段(13.5以上)
current_stage = new_stage;
EnterStage(new_stage);
}
// 否则保持不变,继续运行子状态
UpdateRunningSubState();
break;
}
}
}
}
}
// 定时器0初始化(1ms)
void Timer0_Init(void) {
TMOD &= 0xF0;
TMOD |= 0x01; // 16位定时器
TH0 = 0xFC;
TL0 = 0x18;
ET0 = 1;
EA = 1;
TR0 = 1;
}
// 模拟ADC读取电压(需根据实际硬件替换)
unsigned int GetVoltage(void) {
// 此处应实现真实ADC转换,返回单位mV
// 例:假设P1.1接电压采样,使用STC内部ADC
// 暂时返回一个固定值用于调试(如12.0V)
return 12000;
} |