|
|
@ -1,37 +1,52 @@ |
|
|
|
#include "main.h" |
|
|
|
|
|
|
|
#include <stdbool.h> //定义布尔 |
|
|
|
#define TIMING_TICK 20000 |
|
|
|
#define INTERVAL_PERIOD 10000 |
|
|
|
|
|
|
|
#include "board.h" |
|
|
|
|
|
|
|
/*********************************************************************************************************************** |
|
|
|
* =====================================================函数声明====================================================== * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
void onkey(zkey_t *key, zkey_state_t key_state); |
|
|
|
/*********************************************************************************************************************** |
|
|
|
* =====================================================全局变量====================================================== * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
bool starting_up_state = false; //开关机标志位 |
|
|
|
|
|
|
|
bool timing_function_enable_falg = false; //定时功能使能标志位 |
|
|
|
static uint32_t s_timing_shutdown_begin_ticket = 0; //定时开始时,此时的系统时间 |
|
|
|
static uint32_t s_timing_time; //定时时间 |
|
|
|
static zkey_t s_keys[] = { |
|
|
|
ZKEY_INIT("timerkey", port_gpio_get_timer_key_state), |
|
|
|
ZKEY_INIT("gearskey", port_gpio_get_gears_key_state), |
|
|
|
ZKEY_INIT("intervalkey", port_gpio_get_interval_key_state), |
|
|
|
ZKEY_INIT("switchkey", port_gpio_get_switch_key_state), |
|
|
|
}; |
|
|
|
zkey_module_t key_module = ZMODULE_INIT(s_keys, onkey); |
|
|
|
|
|
|
|
static uint32_t s_interval_period = 0; //间歇功能的周期 |
|
|
|
static uint8_t s_now_interval_duty = 0; //间歇功能的占空比 |
|
|
|
static uint8_t s_intervalkey_press_count = 0; //间歇按键按下的次数 |
|
|
|
uint8_t rgb_ticket_count = 3; |
|
|
|
/*********************************************************************************************************************** |
|
|
|
* =====================================================全局状态====================================================== * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
static bool error_even_trigger_after_stop_ozone_work_state; //错误事件触发后停止臭氧工作标志位 |
|
|
|
|
|
|
|
WORK_LEVEL_T now_level; //现在的档位 |
|
|
|
WORK_LEVEL_T shutdown_before_level; //关机前的档位 |
|
|
|
// 设置 |
|
|
|
bool g_setting_interval_work_flag = false; //现在的档位 |
|
|
|
WORK_LEVEL_T g_setting_level = WORK_LEVEL_LOW; //关机前的档位 |
|
|
|
|
|
|
|
error_state_t error_state; //哪个错误事件 |
|
|
|
static bool error_even_trigger_after_stop_ozone_work_state; //错误事件触发后停止臭氧工作标志位 |
|
|
|
//标志位 |
|
|
|
bool g_power_flag = false; //开关机标志位 |
|
|
|
static int g_error_num; |
|
|
|
bool g_auto_shutdown_flag = false; //定时功能使能标志位 |
|
|
|
static uint32_t g_auto_shutdown_countdown_s; //定时时间 |
|
|
|
|
|
|
|
//其他 |
|
|
|
static bool pwm_modble_enable_falg; //硬件pwm使能标志位 |
|
|
|
//####################### HOOK实现 ################################// |
|
|
|
|
|
|
|
/*********************************************************************************************************************** |
|
|
|
* =======================================================HOOK======================================================== * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
void HOOK_pwm_module_set_pwm_duty(uint32_t frequency, uint32_t duty) { |
|
|
|
set_pwm_modbul_freq_duty(frequency, duty); |
|
|
|
port_fan_set(true); //打开风扇 |
|
|
|
pwm_modble_enable_falg = true; |
|
|
|
printf("work\r\n"); |
|
|
|
} |
|
|
|
|
|
|
|
void HOOK_pwm_stop(void) { |
|
|
|
set_pwm_modbul_freq_duty(1, 0); //关闭PWM输出 |
|
|
|
port_fan_set(false); //风扇结束工作 |
|
|
@ -39,316 +54,66 @@ void HOOK_pwm_stop(void) { |
|
|
|
printf("rest\r\n"); |
|
|
|
} |
|
|
|
bool HOOK_pwm_is_enable(void) { return pwm_modble_enable_falg; } |
|
|
|
//####################### 间歇功能 ################################// |
|
|
|
void process_intervalkey_press_even(void) { |
|
|
|
s_intervalkey_press_count++; |
|
|
|
if (s_intervalkey_press_count == 1) { |
|
|
|
//间歇功能开启后rgb亮三秒灭一秒,为了让用户更快的知道间歇功能已经开启,所以rgb_ticket_count设置3,先让rgb灭1s |
|
|
|
rgb_ticket_count = 3; |
|
|
|
update_interval_period_duty(50); |
|
|
|
} else { |
|
|
|
update_interval_period_duty(100); // 调用update_interval_period_duty(100)后将s_intervalkey_press_count=0 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @brief |
|
|
|
* |
|
|
|
*/ |
|
|
|
void update_interval_period_duty(uint8_t interval_duty) { |
|
|
|
if (interval_duty == 100) { //占空比设置100一直工作 |
|
|
|
printf("duty 100\r\n"); |
|
|
|
s_interval_period = 0; |
|
|
|
s_now_interval_duty = 100; |
|
|
|
s_intervalkey_press_count = 0; |
|
|
|
ozone_pwm_control_disable(); |
|
|
|
restore_the_mode_before_intermittent_work(); |
|
|
|
} else if (interval_duty == 50) { |
|
|
|
printf("duty 50\r\n"); |
|
|
|
s_interval_period = INTERVAL_PERIOD; |
|
|
|
s_now_interval_duty = 50; |
|
|
|
ozone_pwm_control_enable(); |
|
|
|
} |
|
|
|
ozone_pwm_control_module_set_pwm_output_1(s_interval_period, s_now_interval_duty); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @brief 恢复间歇工作前的工作档位 |
|
|
|
* |
|
|
|
*/ |
|
|
|
void restore_the_mode_before_intermittent_work(void) { |
|
|
|
if (now_level == WORK_LEVEL_LOW) { |
|
|
|
light_module_set_rgb_mode(RGB_COLOR_GERRN); |
|
|
|
set_pwm_modbul_freq_duty(1, 25); |
|
|
|
port_fan_set(true); //打开风扇 |
|
|
|
} else if (now_level == WORK_LEVEL_MIDDLE) { |
|
|
|
light_module_set_rgb_mode(RGB_COLOR_BLUE); |
|
|
|
set_pwm_modbul_freq_duty(1, 50); |
|
|
|
port_fan_set(true); //打开风扇 |
|
|
|
} else if (now_level == WORK_LEVEL_HIGHT) { |
|
|
|
light_module_set_rgb_mode(RGB_COLOR_RED); |
|
|
|
set_pwm_modbul_freq_duty(1, 100); |
|
|
|
port_fan_set(true); //打开风扇 |
|
|
|
} |
|
|
|
} |
|
|
|
/** |
|
|
|
* @brief 间歇功能开启时,rgb亮3s灭1s |
|
|
|
* |
|
|
|
*/ |
|
|
|
void process_rgb_flicker(void) { |
|
|
|
static uint32_t rgb_ticket = 0; |
|
|
|
if (port_haspassedms(rgb_ticket) > 1000) { |
|
|
|
rgb_ticket = get_sys_ticket(); |
|
|
|
if (rgb_ticket_count < 3) { |
|
|
|
if (now_level == WORK_LEVEL_LOW) { |
|
|
|
light_module_set_rgb_mode(RGB_COLOR_GERRN); |
|
|
|
} else if (now_level == WORK_LEVEL_MIDDLE) { |
|
|
|
light_module_set_rgb_mode(RGB_COLOR_BLUE); |
|
|
|
} else if (now_level == WORK_LEVEL_HIGHT) { |
|
|
|
light_module_set_rgb_mode(RGB_COLOR_RED); |
|
|
|
} |
|
|
|
} else { |
|
|
|
light_module_set_rgb_mode(RGB_CLOSE); |
|
|
|
rgb_ticket_count = 0; |
|
|
|
} |
|
|
|
rgb_ticket_count++; |
|
|
|
} |
|
|
|
} |
|
|
|
int hook_get_autoshutdown_timecount() { return g_auto_shutdown_countdown_s; } |
|
|
|
|
|
|
|
/*********************************************************************************************************************** |
|
|
|
* =======================================================按键======================================================== * |
|
|
|
* =================================================INTERNAL_FUNCTION================================================= * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
static zkey_t s_keys[] = { |
|
|
|
ZKEY_INIT("timerkey", port_gpio_get_timer_key_state), |
|
|
|
ZKEY_INIT("gearskey", port_gpio_get_gears_key_state), |
|
|
|
ZKEY_INIT("intervalkey", port_gpio_get_interval_key_state), |
|
|
|
ZKEY_INIT("switchkey", port_gpio_get_switch_key_state), |
|
|
|
}; |
|
|
|
|
|
|
|
zkey_module_t key_module = ZMODULE_INIT(s_keys, onkey); |
|
|
|
void onkey(zkey_t *key, zkey_state_t key_state) { |
|
|
|
/** |
|
|
|
* @brief 判断每个按键触发的状态 |
|
|
|
* |
|
|
|
* @param key |
|
|
|
* @param key_state |
|
|
|
*/ |
|
|
|
if (starting_up_state) { //开机中 |
|
|
|
if (error_state.fan_error_status == false && error_state.way_circuit_error_status == false) { //设备无异常 |
|
|
|
if (key == &s_keys[0] && //定时按键 |
|
|
|
key->cur_state == zks_keep && //长按 |
|
|
|
!key->hasProcessed && //没有被处理过 |
|
|
|
key->keep_state_count >= POWER_KEY_TRIGGER_TIME / KEY_SCAN_PERIOD) //按下持续时间大于3s |
|
|
|
{ |
|
|
|
key->hasProcessed = true; |
|
|
|
} else if (key == &s_keys[0] && //定时按键 |
|
|
|
key->cur_state == zks_falling_edge && //下降沿触发 |
|
|
|
!key->hasProcessed && key->keep_state_count <= POWER_KEY_TRIGGER_TIME / KEY_SCAN_PERIOD) //小于3s |
|
|
|
{ |
|
|
|
key->hasProcessed = true; |
|
|
|
printf("key0 zks_falling_edge\r\n"); |
|
|
|
update_timing_time(); |
|
|
|
updae_led_light_mode(); |
|
|
|
} else if (key == &s_keys[1] && //高低档位选择 |
|
|
|
key->cur_state == zks_rising_edge && // |
|
|
|
!key->hasProcessed && // |
|
|
|
key->keep_state_count <= POWER_KEY_TRIGGER_TIME / KEY_SCAN_PERIOD) { |
|
|
|
key->hasProcessed = true; |
|
|
|
printf("key1 zks_rising_edge\r\n"); |
|
|
|
process_gearskey_press_even(); |
|
|
|
} else if (key == &s_keys[2] && //间歇功能设置选择 |
|
|
|
key->cur_state == zks_rising_edge && // |
|
|
|
!key->hasProcessed && // |
|
|
|
key->keep_state_count <= POWER_KEY_TRIGGER_TIME / KEY_SCAN_PERIOD) { |
|
|
|
key->hasProcessed = true; |
|
|
|
printf("key2 zks_rising_edge\r\n"); |
|
|
|
process_intervalkey_press_even(); |
|
|
|
} else if (key == &s_keys[3] && //开关按键 |
|
|
|
key->cur_state == zks_rising_edge && // |
|
|
|
!key->hasProcessed && // |
|
|
|
key->keep_state_count <= POWER_KEY_TRIGGER_TIME / KEY_SCAN_PERIOD) { |
|
|
|
key->hasProcessed = true; |
|
|
|
printf("key2 zks_rising_edge\r\n"); |
|
|
|
shutdown(); |
|
|
|
} |
|
|
|
} else if (error_state.fan_error_status == true || error_state.way_circuit_error_status == true) { //设备存在异常 |
|
|
|
if (key == &s_keys[3] && //开关按键 |
|
|
|
key->cur_state == zks_rising_edge && // |
|
|
|
!key->hasProcessed && // |
|
|
|
key->keep_state_count <= POWER_KEY_TRIGGER_TIME / KEY_SCAN_PERIOD) { |
|
|
|
key->hasProcessed = true; |
|
|
|
printf("key2 zks_rising_edge\r\n"); |
|
|
|
shutdown(); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { //关机中 |
|
|
|
if (key == &s_keys[3] && //开关按键 |
|
|
|
key->cur_state == zks_rising_edge && // |
|
|
|
!key->hasProcessed && // |
|
|
|
key->keep_state_count <= POWER_KEY_TRIGGER_TIME / KEY_SCAN_PERIOD) { |
|
|
|
key->hasProcessed = true; |
|
|
|
printf("key zks_rising_edge\r\n"); |
|
|
|
starting_up(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @brief 上电臭氧工作情况,设备中有开关机按键,所以外部上电后,不让设备工作 |
|
|
|
* |
|
|
|
*/ |
|
|
|
void power_on_ozone_working_status(void) { |
|
|
|
update_ozone_work_gears(WORK_LEVEL_CLOSE); |
|
|
|
light_module_set_timing_light_mode(CLOSE_ALL_LED); |
|
|
|
port_fan_set(false); //关闭风扇 |
|
|
|
} |
|
|
|
|
|
|
|
//####################### 档位设置 #######################/ |
|
|
|
/** |
|
|
|
* @brief 根据档位设置pwm输出,rgb的颜色 |
|
|
|
* |
|
|
|
* @param gears |
|
|
|
*/ |
|
|
|
void update_ozone_work_gears(WORK_LEVEL_T level) { |
|
|
|
void update_ozone_work_level(bool interval_work, WORK_LEVEL_T level) { |
|
|
|
printf("update_ozone_work_level(interval_work:%d,level:%d)\n", interval_work, level); |
|
|
|
rgb_light_mode_t lightmode; |
|
|
|
int duty = 0; |
|
|
|
|
|
|
|
if (level == WORK_LEVEL_CLOSE) { |
|
|
|
ozone_pwm_control_module_set_pwm_output_2(1, 0, s_interval_period, s_now_interval_duty); |
|
|
|
light_module_set_rgb_mode(RGB_CLOSE); |
|
|
|
duty = 0; |
|
|
|
lightmode = RGB_CLOSE; |
|
|
|
} else if (level == WORK_LEVEL_LOW) { |
|
|
|
ozone_pwm_control_module_set_pwm_output_2(1, 25, s_interval_period, s_now_interval_duty); |
|
|
|
light_module_set_rgb_mode(RGB_COLOR_GERRN); |
|
|
|
duty = 25; |
|
|
|
lightmode = RGB_COLOR_GERRN; |
|
|
|
} else if (level == WORK_LEVEL_MIDDLE) { |
|
|
|
ozone_pwm_control_module_set_pwm_output_2(1, 50, s_interval_period, s_now_interval_duty); |
|
|
|
light_module_set_rgb_mode(RGB_COLOR_BLUE); |
|
|
|
duty = 50; |
|
|
|
lightmode = RGB_COLOR_BLUE; |
|
|
|
} else if (level == WORK_LEVEL_HIGHT) { |
|
|
|
ozone_pwm_control_module_set_pwm_output_2(1, 100, s_interval_period, s_now_interval_duty); |
|
|
|
light_module_set_rgb_mode(RGB_COLOR_RED); |
|
|
|
duty = 100; |
|
|
|
lightmode = RGB_COLOR_RED; |
|
|
|
} |
|
|
|
now_level = level; |
|
|
|
} |
|
|
|
void process_gearskey_press_even(void) { |
|
|
|
static uint8_t gearskey_press_count; |
|
|
|
gearskey_press_count++; |
|
|
|
if (gearskey_press_count == 1) { |
|
|
|
update_ozone_work_gears(WORK_LEVEL_MIDDLE); |
|
|
|
} else if (gearskey_press_count == 2) { |
|
|
|
update_ozone_work_gears(WORK_LEVEL_LOW); |
|
|
|
} else if (gearskey_press_count == 3) { |
|
|
|
gearskey_press_count = 0; |
|
|
|
update_ozone_work_gears(WORK_LEVEL_HIGHT); |
|
|
|
} |
|
|
|
} |
|
|
|
//####################### 开机关机 #######################/ |
|
|
|
void shutdown(void) { |
|
|
|
ozone_pwm_control_disable(); |
|
|
|
error_state.fan_error_status = false; |
|
|
|
error_state.way_circuit_error_status = false; |
|
|
|
s_intervalkey_press_count = 0; |
|
|
|
shutdown_before_level = now_level; |
|
|
|
starting_up_state = false; |
|
|
|
update_ozone_work_gears(WORK_LEVEL_CLOSE); |
|
|
|
light_module_set_timing_light_mode(CLOSE_ALL_LED); |
|
|
|
port_fan_set(false); //关闭风扇 |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @brief 开机后,根据关机时的档位进行设置,如果关机时档位为关闭则设置为高档工作 |
|
|
|
* |
|
|
|
*/ |
|
|
|
void starting_up(void) { |
|
|
|
//开机没有间歇功能所以设置占空比为100 |
|
|
|
update_interval_period_duty(100); |
|
|
|
//开机没有定时功能所以将 timing_function_enable_falg = false; s_timing_time = 0; |
|
|
|
timing_function_enable_falg = false; |
|
|
|
s_timing_time = 0; |
|
|
|
starting_up_state = true; |
|
|
|
if (shutdown_before_level == WORK_LEVEL_CLOSE) { |
|
|
|
update_ozone_work_gears(WORK_LEVEL_HIGHT); |
|
|
|
if (interval_work) { |
|
|
|
ozone_pwm_control_module_set_pwm_output_2(1, 0, INTERVAL_WORK_DUTY, INTERVAL_WORK_PERIOD_MS); |
|
|
|
} else { |
|
|
|
update_ozone_work_gears(shutdown_before_level); |
|
|
|
} |
|
|
|
port_fan_set(true); //打开你风扇 |
|
|
|
} |
|
|
|
|
|
|
|
void process_switchkey(void) { |
|
|
|
static bool switchkey_press_count = 0; |
|
|
|
switchkey_press_count = !switchkey_press_count; |
|
|
|
if (switchkey_press_count) { //开机 |
|
|
|
starting_up(); |
|
|
|
} else { //关机 |
|
|
|
shutdown(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//####################### 定时功能 #######################/ |
|
|
|
/** |
|
|
|
* @brief 根据现在的时间进行更改 |
|
|
|
* |
|
|
|
*/ |
|
|
|
void updae_led_light_mode(void) { |
|
|
|
if ((s_timing_time / TIMING_TICK) == 0) { |
|
|
|
light_module_set_timing_light_mode(CLOSE_ALL_LED); |
|
|
|
} else if ((s_timing_time / TIMING_TICK) == 1) { |
|
|
|
light_module_set_timing_light_mode(OPEN_ONE_LED); |
|
|
|
} else if ((s_timing_time / TIMING_TICK) == 2) { |
|
|
|
light_module_set_timing_light_mode(OPEN_TWO_LED); |
|
|
|
} else if ((s_timing_time / TIMING_TICK) == 3) { |
|
|
|
light_module_set_timing_light_mode(OPEN_THREE_LED); |
|
|
|
} else if ((s_timing_time / TIMING_TICK) == 4) { |
|
|
|
light_module_set_timing_light_mode(OPEN_FOUR_LED); |
|
|
|
set_pwm_modbul_freq_duty(1, duty); |
|
|
|
} |
|
|
|
light_module_set_rgb_mode(lightmode); |
|
|
|
light_module_set_rgb_flicker_mode(interval_work); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @brief 每次按键按下时间timing_time=timing_time+TIMING_TICK |
|
|
|
* 当timing_time==timing_time = 4 * TIMING_TICK; |
|
|
|
* timing_time = 0; |
|
|
|
* |
|
|
|
* @brief 关机 |
|
|
|
*/ |
|
|
|
void update_timing_time(void) { |
|
|
|
s_timing_shutdown_begin_ticket = get_sys_ticket(); //更新定时关机开始的时间 |
|
|
|
update_begin_ticket(); //更新间歇开始的时间 |
|
|
|
timing_function_enable_falg = true; //使能定时功能 |
|
|
|
if (s_timing_time == 0) { |
|
|
|
s_timing_time = 1 * TIMING_TICK; |
|
|
|
} else if ((s_timing_time / TIMING_TICK) == 1) { |
|
|
|
s_timing_time = 2 * TIMING_TICK; |
|
|
|
} else if ((s_timing_time / TIMING_TICK) == 2) { |
|
|
|
s_timing_time = 3 * TIMING_TICK; |
|
|
|
} else if ((s_timing_time / TIMING_TICK) == 3) { |
|
|
|
s_timing_time = 4 * TIMING_TICK; |
|
|
|
} else if ((s_timing_time / TIMING_TICK) == 4) { |
|
|
|
s_timing_time = 0 * TIMING_TICK; |
|
|
|
timing_function_enable_falg = false; |
|
|
|
update_interval_period_duty(100); |
|
|
|
} |
|
|
|
printf("timing time:%d\r\n", s_timing_time); |
|
|
|
} |
|
|
|
void shutdown(void) { |
|
|
|
printf("shutdown\n"); |
|
|
|
g_power_flag = false; |
|
|
|
g_error_num = 0; |
|
|
|
g_auto_shutdown_flag = false; |
|
|
|
g_auto_shutdown_countdown_s = 0; |
|
|
|
|
|
|
|
/** |
|
|
|
* @brief 定时每过TIMING_TICK timing_time=timing_time-TIMING_TICK |
|
|
|
* 当TIMING_TICK==0的时候关机 |
|
|
|
* |
|
|
|
*/ |
|
|
|
void try_shutdown(void) { |
|
|
|
if (port_haspassedms(s_timing_shutdown_begin_ticket) > TIMING_TICK) { |
|
|
|
s_timing_shutdown_begin_ticket = get_sys_ticket(); |
|
|
|
printf("time minus %dms", TIMING_TICK); |
|
|
|
s_timing_time -= TIMING_TICK; |
|
|
|
updae_led_light_mode(); |
|
|
|
} |
|
|
|
if (s_timing_time == 0) { //定时时间到 |
|
|
|
timing_function_enable_falg = false; //失能定时功能 |
|
|
|
shutdown(); |
|
|
|
} |
|
|
|
update_ozone_work_level(false, WORK_LEVEL_CLOSE); |
|
|
|
port_fan_set(false); //关闭风扇 |
|
|
|
light_module_close_all_light(); |
|
|
|
} |
|
|
|
bool timing_function_is_enable(void) { return timing_function_enable_falg; } |
|
|
|
|
|
|
|
/*********************************************************************************************************************** |
|
|
|
* ======================================================看门狗======================================================= * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
void iwdt_init(void) { |
|
|
|
/** |
|
|
|
* @brief 看门狗介绍:当计数到0时,窗口计数器+1 |
|
|
|
* 当窗口计数为“2”的时候,产生中断 |
|
|
|
* 当窗口计数器为“4”的之前没有进行喂狗操作,产生复位 |
|
|
|
* |
|
|
|
*/ |
|
|
|
IWDT_InitStruType x; |
|
|
|
|
|
|
@ -357,165 +122,99 @@ void iwdt_init(void) { |
|
|
|
x.WDT_Rst = Enable; /* IWDT复位使能 */ |
|
|
|
x.WDT_Clock = IWDT_CLOCK_WDT; /* LRC */ |
|
|
|
IWDT_Init(&x); |
|
|
|
|
|
|
|
/* 使能IWDT */ |
|
|
|
IWDT_Enable(); |
|
|
|
} |
|
|
|
|
|
|
|
void feed_iwdt(void) { |
|
|
|
//喂狗 |
|
|
|
if (0x01 == IWDT_GetFlagStatus()) //产生中断 |
|
|
|
{ |
|
|
|
if (0x01 == IWDT_GetFlagStatus()) { |
|
|
|
IWDT_Clear(); |
|
|
|
// printf("喂狗\r\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void process_error_even(void) { |
|
|
|
if (error_state.fan_error_status == false && error_state.way_circuit_error_status == false) { //没有错误 |
|
|
|
return; |
|
|
|
} else { |
|
|
|
if (!error_even_trigger_after_stop_ozone_work_state) { |
|
|
|
error_even_trigger_after_stop_ozone_work_state = true; |
|
|
|
set_pwm_modbul_freq_duty(1, 0); |
|
|
|
light_module_set_rgb_mode(RGB_CLOSE); |
|
|
|
light_module_set_timing_light_mode(CLOSE_ALL_LED); |
|
|
|
port_fan_set(false); //关闭风扇 |
|
|
|
} |
|
|
|
if (error_state.fan_error_status == true) { //电扇电压异常 |
|
|
|
static uint32_t error_even_fan_ticket = 0; |
|
|
|
static uint8_t one_led_flicker_state = 1; |
|
|
|
if (port_haspassedms(error_even_fan_ticket) > 500) { |
|
|
|
error_even_fan_ticket = get_sys_ticket(); |
|
|
|
one_led_flicker_state = !one_led_flicker_state; |
|
|
|
port_led0_set(one_led_flicker_state); |
|
|
|
} |
|
|
|
} else if (error_state.way_circuit_error_status == true) { //总电路电压异常 |
|
|
|
static uint32_t error_even_way_circuit = 0; |
|
|
|
static uint8_t two_led_flicker_state = 1; |
|
|
|
if (port_haspassedms(error_even_way_circuit) > 500) { |
|
|
|
error_even_way_circuit = get_sys_ticket(); |
|
|
|
two_led_flicker_state = !two_led_flicker_state; |
|
|
|
port_led0_set(two_led_flicker_state); |
|
|
|
port_led1_set(two_led_flicker_state); |
|
|
|
} |
|
|
|
void onkey(zkey_t *key, zkey_state_t key_state) { |
|
|
|
if (key->hasProcessed) return; |
|
|
|
/** |
|
|
|
* @brief 关机时,只处理电源按键 |
|
|
|
*/ |
|
|
|
if (!g_power_flag) { |
|
|
|
if (key == &s_keys[3] && key->cur_state == zks_falling_edge) { |
|
|
|
key->hasProcessed = true; |
|
|
|
printf("key zks_rising_edge\r\n"); |
|
|
|
/** |
|
|
|
* @brief 开机 |
|
|
|
* 1.设置标志位 |
|
|
|
* 2.打开风扇 |
|
|
|
* 3.打开臭氧并打开相应的指示灯 |
|
|
|
*/ |
|
|
|
|
|
|
|
g_power_flag = true; //开关机标志位 |
|
|
|
g_error_num = 0; |
|
|
|
g_auto_shutdown_flag = false; //定时功能使能标志位 |
|
|
|
g_auto_shutdown_countdown_s = 0; //定时时间 |
|
|
|
|
|
|
|
port_fan_set(true); //打开你风扇 |
|
|
|
update_ozone_work_level(g_setting_interval_work_flag, g_setting_level); |
|
|
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/*********************************************************************************************************************** |
|
|
|
* =======================================================测试======================================================== |
|
|
|
** |
|
|
|
***********************************************************************************************************************/ |
|
|
|
void test_adc(void) { |
|
|
|
while (1) { |
|
|
|
ADC_InitStruType x; |
|
|
|
GPIO_InitSettingType y; |
|
|
|
y.Signal = GPIO_Pin_Signal_Analog; //模拟 |
|
|
|
y.Dir = GPIO_Direction_Input; //输入 |
|
|
|
y.Func = GPIO_Reuse_Func0; |
|
|
|
// x.CHS设置adc采集的通道每个引脚对应一个通道 |
|
|
|
GPIO_Init(GPIO_Pin_A2, &y); |
|
|
|
|
|
|
|
//经过分频以后Tadclk=1/(PCLK/4)约等于0.083us |
|
|
|
x.CLKS = ADC_CLKS_PCLK; |
|
|
|
x.CLKDIV = ADC_CLKDIV_1_32; /* ADC时钟源预分频 */ |
|
|
|
|
|
|
|
//采集到的模拟量*3.3/4096=现在的电压 |
|
|
|
|
|
|
|
x.VREF_SEL = ADC_VREF_SEL_0; /* 内部参考电压2.048v,仅设置内部参考电压为多少 */ |
|
|
|
x.VREFP = ADC_VREFP_VDD; /* 选择芯片的工作电压VDD,这个是设置adc具体是要哪个电压来做参考adc的参考电压为多少 */ |
|
|
|
x.VREFN = ADC_VREFN_VSS; /* 负向参考电压选择 */ |
|
|
|
x.CHS = ADC_CHS_AIN8; |
|
|
|
x.SMPS = ADC_SMPS_SOFT; /* AD采样模式为软件控制 */ |
|
|
|
//采样时间st*2+1(个Tadclk)=1.743us |
|
|
|
x.ST = 10; /* AD硬件采样时间选择 */ |
|
|
|
x.BITSEL = ADC_BITSEL_12; /* AD分辨率12位 */ |
|
|
|
ADC_Init(&x); |
|
|
|
uint32_t pa2_adc_val = 0; |
|
|
|
ADC_SoftStart(); |
|
|
|
ADC_SoftStop(); |
|
|
|
//正在转换 |
|
|
|
while (ADC_GetConvStatus() != RESET) |
|
|
|
; |
|
|
|
pa2_adc_val = ADC_GetConvValue(); |
|
|
|
printf("%d\r\n", pa2_adc_val); |
|
|
|
printf("pa2_adc_valpa2_val:%lf\r\n", pa2_adc_val * 3.3 / 4096); |
|
|
|
|
|
|
|
y.Signal = GPIO_Pin_Signal_Analog; //模拟 |
|
|
|
y.Dir = GPIO_Direction_Input; //输入 |
|
|
|
y.Func = GPIO_Reuse_Func0; |
|
|
|
// x.CHS设置adc采集的通道每个引脚对应一个通道 |
|
|
|
GPIO_Init(GPIO_Pin_B8, &y); |
|
|
|
|
|
|
|
//经过分频以后Tadclk=1/(PCLK/4)约等于0.083us |
|
|
|
x.CLKS = ADC_CLKS_PCLK; |
|
|
|
x.CLKDIV = ADC_CLKDIV_1_32; /* ADC时钟源预分频 */ |
|
|
|
|
|
|
|
//采集到的模拟量*3.3/4096=现在的电压 |
|
|
|
|
|
|
|
x.VREF_SEL = ADC_VREF_SEL_0; /* 内部参考电压2.048v,仅设置内部参考电压为多少 */ |
|
|
|
x.VREFP = ADC_VREFP_VDD; /* 选择芯片的工作电压VDD,这个是设置adc具体是要哪个电压来做参考adc的参考电压为多少 */ |
|
|
|
x.VREFN = ADC_VREFN_VSS; /* 负向参考电压选择 */ |
|
|
|
x.CHS = ADC_CHS_AIN3; |
|
|
|
x.SMPS = ADC_SMPS_SOFT; /* AD采样模式为软件控制 */ |
|
|
|
//采样时间st*2+1(个Tadclk)=1.743us |
|
|
|
x.ST = 10; /* AD硬件采样时间选择 */ |
|
|
|
x.BITSEL = ADC_BITSEL_12; /* AD分辨率12位 */ |
|
|
|
ADC_Init(&x); |
|
|
|
uint32_t pb8_adc_val = 0; |
|
|
|
ADC_SoftStart(); |
|
|
|
ADC_SoftStop(); |
|
|
|
//正在转换 |
|
|
|
while (ADC_GetConvStatus() != RESET) |
|
|
|
; |
|
|
|
pb8_adc_val = ADC_GetConvValue(); |
|
|
|
printf("pb8_adc_val%d\r\n", pb8_adc_val); |
|
|
|
printf("pb8_val:%lf\r\n", pb8_adc_val * 3.3 / 4096); |
|
|
|
Delayms(1000); |
|
|
|
} |
|
|
|
} |
|
|
|
void test(void) { |
|
|
|
port_fan_set(false); |
|
|
|
Delayms(10000); |
|
|
|
port_fan_set(true); |
|
|
|
printf("open\r\n"); |
|
|
|
Delayms(10000); |
|
|
|
while (1) { |
|
|
|
// unused_gpio_init(); |
|
|
|
// gpio_init(); |
|
|
|
// port_fan_set(false); |
|
|
|
// printf("close\r\n"); |
|
|
|
// Delayms(30000); |
|
|
|
// port_fan_set(true); |
|
|
|
// printf("open\r\n"); |
|
|
|
// Delayms(10000); |
|
|
|
/** |
|
|
|
* @brief 发生异常时,除了电源按键外,所有按键失效。 |
|
|
|
*/ |
|
|
|
if (g_error_num != 0) { //设备存在异常 |
|
|
|
if (key == &s_keys[3] && key->cur_state == zks_falling_edge) { |
|
|
|
key->hasProcessed = true; |
|
|
|
printf("process key[2] event\r\n"); |
|
|
|
/** |
|
|
|
* @brief 关机 |
|
|
|
*/ |
|
|
|
shutdown(); |
|
|
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
error_state.way_circuit_error_status = true; |
|
|
|
error_state.fan_error_status = true; |
|
|
|
// while (1) { |
|
|
|
// port_fan_set(true); //测试关闭风扇 |
|
|
|
// printf("open\r\n"); |
|
|
|
// Delayms(50000); |
|
|
|
// port_fan_set(false); //测试关闭风扇 |
|
|
|
// printf("close\r\n"); |
|
|
|
// Delayms(50000); |
|
|
|
// port_do_debug_light_state(); |
|
|
|
// printf("Initialization completed\r\n"); |
|
|
|
// } |
|
|
|
|
|
|
|
// while (1) { |
|
|
|
// port_do_debug_light_state(); |
|
|
|
// printf("Initialization completed\r\n"); |
|
|
|
// } |
|
|
|
if (key == &s_keys[0] && key->cur_state == zks_falling_edge) //小于3s |
|
|
|
{ |
|
|
|
printf("process key[0] event\r\n"); |
|
|
|
/** |
|
|
|
* @brief 处理定时按键事件 |
|
|
|
*/ |
|
|
|
if (!g_auto_shutdown_flag) { |
|
|
|
g_auto_shutdown_flag = true; |
|
|
|
g_auto_shutdown_countdown_s = 0; |
|
|
|
} |
|
|
|
g_auto_shutdown_countdown_s += AUTO_SHUTDOWN_ONE_LIGHT_EQ_TIME_S; |
|
|
|
} else if (key == &s_keys[1] && key->cur_state == zks_falling_edge) { |
|
|
|
/** |
|
|
|
* @brief 处理等级按键 |
|
|
|
*/ |
|
|
|
printf("process key[1] event\r\n"); |
|
|
|
if (g_setting_level == WORK_LEVEL_HIGHT) { |
|
|
|
update_ozone_work_level(g_setting_interval_work_flag, WORK_LEVEL_LOW); |
|
|
|
} else if (g_setting_level == WORK_LEVEL_MIDDLE) { |
|
|
|
update_ozone_work_level(g_setting_interval_work_flag, WORK_LEVEL_HIGHT); |
|
|
|
} else if (g_setting_level == WORK_LEVEL_LOW) { |
|
|
|
update_ozone_work_level(g_setting_interval_work_flag, WORK_LEVEL_MIDDLE); |
|
|
|
} |
|
|
|
} else if (key == &s_keys[2] && key->cur_state == zks_falling_edge) { |
|
|
|
printf("process key[2] event\r\n"); |
|
|
|
/** |
|
|
|
* @brief 处理间歇按键事件 |
|
|
|
*/ |
|
|
|
g_setting_interval_work_flag = !g_setting_interval_work_flag; |
|
|
|
update_ozone_work_level(g_setting_interval_work_flag, g_setting_level); |
|
|
|
} else if (key == &s_keys[3] && key->cur_state == zks_falling_edge) { |
|
|
|
printf("process key[2] event\r\n"); |
|
|
|
/** |
|
|
|
* @brief 关机 |
|
|
|
*/ |
|
|
|
shutdown(); |
|
|
|
} |
|
|
|
} |
|
|
|
/** |
|
|
|
* @brief 间歇功能使能后,rgb闪烁 |
|
|
|
* |
|
|
|
*/ |
|
|
|
/*********************************************************************************************************************** |
|
|
|
* ======================================================主函数======================================================= |
|
|
|
** |
|
|
|
***********************************************************************************************************************/ |
|
|
|
int main(void) { |
|
|
|
HRC_Config(Enable, SCU_HRC_48M, Enable); //时钟源SCU_CLK_HRC |
|
|
@ -523,50 +222,89 @@ int main(void) { |
|
|
|
DeviceClockAllEnable(); //打开所有外设时钟 |
|
|
|
User_SysTickInit(); //滴答定时器初始化为(配置为1ms中断) |
|
|
|
SysTick_Enable(); |
|
|
|
|
|
|
|
// all_gpio_reset(); |
|
|
|
//硬件初始化 |
|
|
|
unused_gpio_init(); |
|
|
|
gpio_init(); |
|
|
|
|
|
|
|
uart0_init(); |
|
|
|
zkey_init(&key_module); |
|
|
|
t16_pa4_init(); |
|
|
|
// iwdt_init(); |
|
|
|
power_on_ozone_working_status(); |
|
|
|
|
|
|
|
//模块初始化 |
|
|
|
zkey_init(&key_module); |
|
|
|
|
|
|
|
//上电默认关机 |
|
|
|
shutdown(); |
|
|
|
|
|
|
|
//启动结束 |
|
|
|
printf("Initialization completed\r\n"); |
|
|
|
// test(); |
|
|
|
// test_adc(); |
|
|
|
|
|
|
|
while (true) { |
|
|
|
/******************************************************************************************************************* |
|
|
|
* ==================================================调试指示灯=================================================== * |
|
|
|
*******************************************************************************************************************/ |
|
|
|
port_do_debug_light_state(); |
|
|
|
// feed_iwdt(); |
|
|
|
static uint32_t keylastprocess = 0; |
|
|
|
if (port_haspassedms(keylastprocess) > 40) { |
|
|
|
keylastprocess = get_sys_ticket(); |
|
|
|
zkey_do_loop_in_each_period(NULL); |
|
|
|
|
|
|
|
/*********************************************************************************************************************** |
|
|
|
* =================================================按键模块调度代码================================================== * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
{ |
|
|
|
static uint32_t keylastprocess = 0; |
|
|
|
if (port_haspassedms(keylastprocess) > KEY_PERIOD) { |
|
|
|
keylastprocess = get_sys_ticket(); |
|
|
|
zkey_do_loop_in_each_period(NULL); |
|
|
|
} |
|
|
|
} |
|
|
|
if (starting_up_state) { //开机中 |
|
|
|
port_do_debug_light_state(); |
|
|
|
process_error_even(); |
|
|
|
try_adc_gather(); |
|
|
|
if (timing_function_is_enable()) { //定时功能是开启的 |
|
|
|
try_shutdown(); |
|
|
|
/*********************************************************************************************************************** |
|
|
|
* ===============================================灯光控制模块调度代码================================================ * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
light_module_schedule(); |
|
|
|
|
|
|
|
/*********************************************************************************************************************** |
|
|
|
* ===============================================臭氧控制模块调度代码================================================ * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
ozone_pwm_control_module_loop(); |
|
|
|
|
|
|
|
/*********************************************************************************************************************** |
|
|
|
* ===================================================自动关机逻辑==================================================== * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
// |
|
|
|
if (g_power_flag && g_auto_shutdown_flag) { |
|
|
|
static uint32_t ticket = 0; |
|
|
|
ticket = get_sys_ticket(); |
|
|
|
// |
|
|
|
if (port_haspassedms(ticket) > 1000) { |
|
|
|
ticket = get_sys_ticket(); |
|
|
|
if (g_auto_shutdown_countdown_s > 0) { |
|
|
|
g_auto_shutdown_countdown_s -= 1; |
|
|
|
} else { |
|
|
|
g_auto_shutdown_flag = false; |
|
|
|
/** |
|
|
|
* @brief 触发定时关机 |
|
|
|
*/ |
|
|
|
shutdown(); |
|
|
|
} |
|
|
|
} |
|
|
|
if (ozone_pwm_control_is_enable() == true) { |
|
|
|
ozone_pwm_control_module_loop(); |
|
|
|
process_rgb_flicker(); |
|
|
|
// |
|
|
|
} |
|
|
|
/*********************************************************************************************************************** |
|
|
|
* ===================================================定时指示灯显示逻辑==================================================== |
|
|
|
***********************************************************************************************************************/ |
|
|
|
updae_timing_light_state(); |
|
|
|
/*********************************************************************************************************************** |
|
|
|
* ===================================================异常监控逻辑==================================================== |
|
|
|
***********************************************************************************************************************/ |
|
|
|
{ |
|
|
|
static uint32_t ticket = 0; |
|
|
|
if (port_haspassedms(ticket) > EXCEPTION_CHECK_PERIOD) { |
|
|
|
ticket = get_sys_ticket(); |
|
|
|
|
|
|
|
/** |
|
|
|
* @brief |
|
|
|
* 这里检测ADC的数值是否超出规定范围 |
|
|
|
*/ |
|
|
|
if (false) { |
|
|
|
} |
|
|
|
} |
|
|
|
} else { //关机中 |
|
|
|
} |
|
|
|
// End.................................. |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 上电工作状态设置测试通过 |
|
|
|
* 开关机按键测试通过 |
|
|
|
* 定时按键测试通过 |
|
|
|
* 间歇按键闪烁测试通过 |
|
|
|
* 档位按键测试通过 |
|
|
|
* 模拟风扇错误触发后led0闪烁测试通过 |
|
|
|
* 模拟总电路错误触发后led0,led1闪烁测试通过 |
|
|
|
* 注意:需要加个逻辑,如果总电路电压异常,则风扇电压异常不触发,这个逻辑之后再加 |
|
|
|
*/ |
|
|
|
} |