#include "main.h" #include //定义布尔 #define TIMING_TICK 20000 #define INTERVAL_PERIOD 10000 /*********************************************************************************************************************** * =====================================================全局变量====================================================== * ***********************************************************************************************************************/ 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 uint32_t s_interval_period = 0; //间歇功能的周期 static uint8_t s_now_interval_duty = 0; //间歇功能的占空比 static uint8_t s_intervalkey_press_count = 0; //间歇按键按下的次数 WORK_LEVEL_T now_level; //现在的档位 WORK_LEVEL_T shutdown_before_level; //关机前的档位 error_state_t error_state; //哪个错误事件 static bool error_even_trigger_after_stop_ozone_work_state; //错误事件触发后停止臭氧工作标志位 static bool pwm_modble_enable_falg; //硬件pwm使能标志位 //####################### 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); //风扇结束工作 pwm_modble_enable_falg = false; 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) { 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; static uint8_t rgb_ticket_count = 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++; } } /*********************************************************************************************************************** * =======================================================按键======================================================== * ***********************************************************************************************************************/ 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) { 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); } 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); } 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); } 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); } 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); } 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); } } /** * @brief 每次按键按下时间timing_time=timing_time+TIMING_TICK * 当timing_time==timing_time = 4 * TIMING_TICK; * timing_time = 0; * */ 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); } /** * @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(); } } bool timing_function_is_enable(void) { return timing_function_enable_falg; } void iwdt_init(void) { /** * @brief 看门狗介绍:当计数到0时,窗口计数器+1 * 当窗口计数为“2”的时候,产生中断 * 当窗口计数器为“4”的之前没有进行喂狗操作,产生复位 * */ IWDT_InitStruType x; x.WDT_Tms = 4000; x.WDT_IE = Enable; /* IWDT中断使能 */ 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()) //产生中断 { 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 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); } 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"); // } } /** * @brief 间歇功能使能后,rgb闪烁 * */ /*********************************************************************************************************************** * ======================================================主函数======================================================= ** ***********************************************************************************************************************/ int main(void) { HRC_Config(Enable, SCU_HRC_48M, Enable); //时钟源SCU_CLK_HRC SystemInit(); 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(); printf("Initialization completed\r\n"); //test(); while (true) { port_do_debug_light_state(); // feed_iwdt(); static uint32_t keylastprocess = 0; if (port_haspassedms(keylastprocess) > 20) { 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(); } if (ozone_pwm_control_is_enable() == true) { ozone_pwm_control_module_loop(); process_rgb_flicker(); } } else { //关机中 } } } /** * 上电工作状态设置测试通过 * 开关机按键测试通过 * 定时按键测试通过 * 间歇按键闪烁测试通过 * 档位按键测试通过 * 模拟风扇错误触发后led0闪烁测试通过 * 模拟总电路错误触发后led0,led1闪烁测试通过 * 注意:需要加个逻辑,如果总电路电压异常,则风扇电压异常不触发,这个逻辑之后再加 */