|
|
#include "main.h"
#include <stdbool.h> //定义布尔
#include "board.h"
#define PWM_FREQHZ 25000 //硬件pwm频率
/***********************************************************************************************************************
* =====================================================函数声明====================================================== * ***********************************************************************************************************************/ void onkey(zkey_t *key, zkey_state_t key_state); /***********************************************************************************************************************
* =====================================================全局变量====================================================== * ***********************************************************************************************************************/
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);
extern uint32_t target_frequencyhz; extern uint32_t target_duty; /***********************************************************************************************************************
* =====================================================全局状态====================================================== * ***********************************************************************************************************************/ static bool error_even_trigger_after_stop_ozone_work_state; //错误事件触发后停止臭氧工作标志位
// 设置
bool g_setting_interval_work_flag = false; //现在间歇工作状态
WORK_LEVEL_T g_setting_level = WORK_LEVEL_HIGHT; //关机前的档位
//标志位
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使能标志位
bool fan_control_by_ozone_pwm_falg = false; //风扇由大周期控制
/***********************************************************************************************************************
* =======================================================HOOK======================================================== * ***********************************************************************************************************************/ void HOOK_pwm_module_set_pwm_duty(uint32_t frequencyhz, uint32_t duty) { set_pwm_modbul_freq_duty(frequencyhz, duty); pwm_modble_enable_falg = true; } void HOOK_pwm_stop(void) { set_pwm_modbul_freq_duty(1, 0); //关闭PWM输出
pwm_modble_enable_falg = false; } bool HOOK_pwm_is_enable(void) { return pwm_modble_enable_falg; } int hook_get_autoshutdown_timecount() { return g_auto_shutdown_countdown_s; }
/***********************************************************************************************************************
* =================================================INTERNAL_FUNCTION================================================= * ***********************************************************************************************************************/
/**
* @brief * * @param freq * @param us */
int get_duty_by_freq_and_valid_time(uint32_t freq, uint32_t us) { uint16_t period = 1000000 / freq; int duty = us * 100 / period; return duty; }
/**
* @brief 根据档位设置pwm输出,rgb的颜色 * * @param gears */ 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; uint32_t pwm_freqhz = 0;
if (level == WORK_LEVEL_CLOSE) { pwm_freqhz = 1; duty = 0; lightmode = RGB_CLOSE; } else if (level == WORK_LEVEL_LOW) { pwm_freqhz = 10000; duty = get_duty_by_freq_and_valid_time(pwm_freqhz, 8); lightmode = RGB_COLOR_BLUE; } else if (level == WORK_LEVEL_HIGHT) { pwm_freqhz = 25000; duty = get_duty_by_freq_and_valid_time(pwm_freqhz, 8); lightmode = RGB_COLOR_RED; }
if (interval_work) { ozone_pwm_control_module_set_pwm_output_2(pwm_freqhz, duty, INTERVAL_WORK_PERIOD_MS, INTERVAL_WORK_DUTY); } else { set_pwm_modbul_freq_duty(pwm_freqhz, duty); } light_module_set_rgb_mode(lightmode); light_module_set_rgb_flicker_mode(interval_work); }
/**
* @brief 关机 */ 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; g_setting_interval_work_flag = false;
update_ozone_work_level(false, WORK_LEVEL_CLOSE); g_setting_level = WORK_LEVEL_HIGHT;
port_fan_set(false); //关闭风扇
light_module_close_all_light(); ozone_pwm_control_module_stop_pwm(); } /***********************************************************************************************************************
* ======================================================看门狗======================================================= * ***********************************************************************************************************************/ 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");
} }
/**
* @brief 取消定时关机 * */ void cancel_autoshutdown(void) { g_auto_shutdown_countdown_s = 0; g_auto_shutdown_flag = false; light_module_set_autoshutdown_indicator_light(false); }
/**
* @brief 开机 * */ void starting_up(void) { 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(false, WORK_LEVEL_HIGHT); }
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.打开臭氧并打开相应的指示灯 */
starting_up(); } return; }
/**
* @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; }
if (key == &s_keys[0] && key->cur_state == zks_falling_edge) //小于3s
{ printf("process key[0] event\r\n"); /**
* @brief 处理定时按键事件 */ if (g_setting_interval_work_flag == true) { // g_setting_interval_work_flag=true现在是间歇工作
ozone_pwm_control_module_stop_pwm(); g_setting_interval_work_flag = false; // 取消间歇工作
update_ozone_work_level(g_setting_interval_work_flag, g_setting_level); fan_control_by_ozone_pwm_falg = false; pwm_modble_enable_falg = false; //硬件pwm使能标志位,这个标志位只在间歇功能下做逻辑了,所以取消间歇功能后将pwm_modble_enable_falg = false;
port_fan_set(true); //打开风扇
} if (!g_auto_shutdown_flag) { g_auto_shutdown_flag = true; g_auto_shutdown_countdown_s = 0; light_module_set_autoshutdown_indicator_light(true); } g_auto_shutdown_countdown_s += AUTO_SHUTDOWN_ONE_LIGHT_EQ_TIME_S; if (g_auto_shutdown_countdown_s > AUTO_SHUTDOWN_ONE_LIGHT_EQ_TIME_S * 4) { cancel_autoshutdown(); }
} 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) { g_setting_level = WORK_LEVEL_LOW; update_ozone_work_level(g_setting_interval_work_flag, WORK_LEVEL_LOW); } else if (g_setting_level == WORK_LEVEL_LOW) { g_setting_level = WORK_LEVEL_HIGHT; update_ozone_work_level(g_setting_interval_work_flag, WORK_LEVEL_HIGHT); } } else if (key == &s_keys[2] && key->cur_state == zks_falling_edge) { printf("process key[2] event\r\n"); /**
* @brief 处理间歇按键事件 */ if (g_auto_shutdown_flag) { //处于定时关机模式
cancel_autoshutdown(); } g_setting_interval_work_flag = !g_setting_interval_work_flag; // fan_control_by_ozone_pwm_falg为true时风扇由大周期控制
fan_control_by_ozone_pwm_falg = !fan_control_by_ozone_pwm_falg; 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(); } }
#define DO_IT_EACH_MS(time) \
{ \ static uint32_t __ticket = 0; \ if (port_haspassedms(__ticket) > time) { \ __ticket = get_sys_ticket();
#define END() \
} \ }
/**
* @brief 间歇模式下臭氧发生时灯闪烁,没有发生时灯为常绿 * */ void process_interval_rgb_mode(void) { static bool last_pwm_modble_enable_falg_2; if (ozone_pwm_control_is_enable() == false) { return; } if (last_pwm_modble_enable_falg_2 != pwm_modble_enable_falg) { if (pwm_modble_enable_falg == true) { close_green_led(); last_pwm_modble_enable_falg_2 = pwm_modble_enable_falg; light_module_set_rgb_flicker_mode(true); } else if (pwm_modble_enable_falg == false) { // light_module_set_rgb_mode(RGB_CLOSE);
// DO_IT_EACH_MS(1000) {
open_green_led(); last_pwm_modble_enable_falg_2 = pwm_modble_enable_falg; light_module_set_rgb_flicker_mode(false); // }
// END();
} } }
/**********************************************************************************************************************
* =======================================================风扇======================================================= * **********************************************************************************************************************/ void fan_module_schedule(void) { static bool last_pwm_modble_enable_falg = false; if (!fan_control_by_ozone_pwm_falg) { return; } else if (fan_control_by_ozone_pwm_falg && last_pwm_modble_enable_falg != pwm_modble_enable_falg) { if (pwm_modble_enable_falg == false) { //代表硬件pwm没有输出
last_pwm_modble_enable_falg = pwm_modble_enable_falg; port_fan_set(false); } else if (pwm_modble_enable_falg == true) { //代表硬件pwm有输出
last_pwm_modble_enable_falg = pwm_modble_enable_falg; port_fan_set(true); } } }
/***********************************************************************************************************************
* ======================================================主函数======================================================= ***********************************************************************************************************************/ int main(void) { HRC_Config(Enable, SCU_HRC_48M, Enable); //时钟源SCU_CLK_HRC
SystemInit(); DeviceClockAllEnable(); //打开所有外设时钟
User_SysTickInit(); //滴答定时器初始化为(配置为1ms中断)
SysTick_Enable(); //硬件初始化
unused_gpio_init(); gpio_init(); uart0_init();
//模块初始化
zkey_init(&key_module); // while (1) {
// }
//上电默认开机并高档工作
starting_up();
//启动结束
printf("Initialization completed\r\n");
//测试
// set_pwm_modbul_freq_duty(25000, 10);
// while (1) {
// }
while (true) { /*******************************************************************************************************************
* ==================================================调试指示灯=================================================== * *******************************************************************************************************************/ DO_IT_EACH_MS(200) { static uint8_t debug_led_state = 1; debug_led_state = !debug_led_state; port_debug_set(debug_led_state); } END() /***********************************************************************************************************************
* =================================================按键模块调度代码================================================== * ***********************************************************************************************************************/ DO_IT_EACH_MS(KEY_PERIOD) { zkey_do_loop_in_each_period(NULL); } END(); /***********************************************************************************************************************
* ===============================================灯光控制模块调度代码================================================ * ***********************************************************************************************************************/ light_module_schedule();
/***********************************************************************************************************************
* ===============================================臭氧控制模块调度代码================================================ * ***********************************************************************************************************************/ ozone_pwm_control_module_loop(); /*******************************************************************************************************************
* ==================================================风扇的调度=================================================== * *******************************************************************************************************************/ fan_module_schedule(); /*******************************************************************************************************************
* ==============================================间歇模式下的rgb模式============================================== * *******************************************************************************************************************/ process_interval_rgb_mode(); /*******************************************************************************************************************
* ==================================================PWM均匀增加================================================== * *******************************************************************************************************************/ DO_IT_EACH_MS(PWM_CHANGE_PERIOD) { set_pwm_modbul_freq_duty(target_frequencyhz, target_duty); } END(); /***********************************************************************************************************************
* ===================================================自动关机逻辑==================================================== * ***********************************************************************************************************************/
//
DO_IT_EACH_MS(1000) { if (g_power_flag && g_auto_shutdown_flag) { if (g_auto_shutdown_countdown_s > 0) { g_auto_shutdown_countdown_s -= 1; printf("auto shutdown countdown %d\n", g_auto_shutdown_countdown_s); } else { g_auto_shutdown_flag = false; /**
* @brief 触发定时关机 */ shutdown(); } } } END(); /***********************************************************************************************************************
* ===================================================异常监控逻辑==================================================== ***********************************************************************************************************************/ DO_IT_EACH_MS(EXCEPTION_CHECK_PERIOD) { /**
* @brief * 这里检测ADC的数值是否超出规定范围 */ if (false) { } } END(); // End..................................
} }
|