You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
373 lines
16 KiB
373 lines
16 KiB
#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 = kwork_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; //定时时间
|
|
|
|
/***********************************************************************************************************************
|
|
* =======================================================HOOK======================================================== *
|
|
***********************************************************************************************************************/
|
|
bool hook_get_ozone_generator_working_flag() { return ozone_pwm_control_hardware_is_enable(); }
|
|
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 == kwork_level_close) {
|
|
pwm_freqhz = 1;
|
|
duty = 0;
|
|
lightmode = krgb_close;
|
|
} else if (level == kwork_level_low) {
|
|
pwm_freqhz = LOW_LEVEL_PWM_FREQ;
|
|
// duty = 50;
|
|
duty = get_duty_by_freq_and_valid_time(pwm_freqhz, PWM_PULSE_WIDTH_US);
|
|
lightmode = krgb_color_blue;
|
|
} else if (level == kwork_level_hight) {
|
|
pwm_freqhz = HIGH_LEVEL_PWM_FREQ;
|
|
// duty = 10;
|
|
duty = get_duty_by_freq_and_valid_time(pwm_freqhz, PWM_PULSE_WIDTH_US);
|
|
lightmode = krgb_color_red;
|
|
}
|
|
|
|
if (interval_work) {
|
|
ozone_pwm_control_module_set_pwm_output_2(pwm_freqhz, duty, INTERVAL_WORK_PERIOD_MS, INTERVAL_WORK_DUTY);
|
|
} else {
|
|
ozone_pwm_control_module_set_pwm_output_1(pwm_freqhz, duty);
|
|
}
|
|
light_module_set_rgb_mode(lightmode);
|
|
light_module_set_rgb_in_interval_working_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, kwork_level_close);
|
|
g_setting_level = kwork_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, kwork_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");
|
|
|
|
if (g_setting_interval_work_flag == true) { // g_setting_interval_work_flag=true现在是间歇工作
|
|
g_setting_interval_work_flag = false; // 取消间歇工作
|
|
update_ozone_work_level(g_setting_interval_work_flag, g_setting_level);
|
|
}
|
|
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 == kwork_level_hight) {
|
|
g_setting_level = kwork_level_low;
|
|
update_ozone_work_level(g_setting_interval_work_flag, kwork_level_low);
|
|
} else if (g_setting_level == kwork_level_low) {
|
|
g_setting_level = kwork_level_hight;
|
|
update_ozone_work_level(g_setting_interval_work_flag, kwork_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;
|
|
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() \
|
|
} \
|
|
}
|
|
|
|
/**********************************************************************************************************************
|
|
* =======================================================风扇======================================================= *
|
|
**********************************************************************************************************************/
|
|
void fan_module_schedule(void) {
|
|
//风扇效果和PWM输出绑定
|
|
port_fan_set(ozone_pwm_control_hardware_is_enable());
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* ======================================================主函数=======================================================
|
|
***********************************************************************************************************************/
|
|
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();
|
|
t16_pa4_init();
|
|
//模块初始化
|
|
zkey_init(&key_module);
|
|
|
|
//上电默认开机并高档工作
|
|
starting_up();
|
|
|
|
//启动结束
|
|
// printf("Initialization completed\r\n");
|
|
|
|
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();
|
|
/*******************************************************************************************************************
|
|
* ==================================================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..................................
|
|
}
|
|
}
|