#include "include.h" #include "func.h" #include "app_variable.h" #if TRACE_EN #define TRACE(...) printf(__VA_ARGS__) #else #define TRACE(...) #endif #define FUNC_HR_SIMULATE_DATA_EN 0 #define HR_ANIM_BG_X (GUI_SCREEN_CENTER_X) #define HR_ANIM_BG_Y (GUI_SCREEN_CENTER_Y - 10) #define HR_ANIM_NUM_MAX (8) #define HR_MEASURING_TIME (60) #define HR_ANIM_TICK_SPEED_LOW (240) #define HR_ANIM_TICK_SPEED_NORMAL (180) #define HR_ANIM_TICK_SPEED_FAST (150) #define HR_LOADING_BG_X (GUI_SCREEN_CENTER_X) #define HR_LOADING_BG_Y (GUI_SCREEN_CENTER_Y - 25) #define HR_LOADING_NUM_MAX (13) #define HR_LOADING_TICK_SPEED (160) #define HR_CURR_POS_X (19) #define HR_CURR_POS_Y (207) #define HR_CURR_UNIT_POS_X (HR_CURR_POS_X + 5) #define HR_CURR_UNIT_POS_Y (232) #define HR_RANGE_POS_X (10) #define HR_RANGE_POS_Y (500) #define HR_RANGE_UNIT_POS_X (HR_RANGE_POS_X + 2) #define HR_RANGE_UNIT_POS_Y (525) #define HR_CHART_POS_X (GUI_SCREEN_CENTER_X) // 图表X坐标 #define HR_CHART_POS_Y (400) // 图表Y坐标 #define HR_CHART_BAR_POS_Y (340) // 图表柱子Y坐标 #define HR_CHART_BAR_RADIUS (2) // 图表打点柱子圆角 #define HR_CHART_BAR_WIDTH (4) // 图表柱子宽度 #define HR_CHART_BAR_HEIGHT (92) // 图表柱子高度 #define HR_CHART_BAR_INIT_HEIGHT (115) // 图表默认高度数值 #define HR_CHART_BAR_COLUMN_MAX (24) // 图表打点数据每小时一根 //组件ID; enum { COMPO_ID_PIC_BG = 1, COMPO_ID_TITLE_TIME, COMPO_ID_NUM_HEARTRATE_CUR, COMPO_ID_NUM_HEARTRATE_CUR_UNIT, COMPO_ID_NUM_HEARTRATE_LAST, COMPO_ID_TEXT_HEARTRATE_CUR, COMPO_ID_NUM_HEARTRATE_HISTORY, COMPO_ID_NUM_HEARTRATE_HISTORY_UNIT, COMPO_ID_NUM_HEARTRATE_HISTORY_MAX, COMPO_ID_NUM_HEARTRATE_HISTORY_MIN, /* 图表下方不允许放置ID */ COMPO_ID_CHART }; typedef enum { HR_STA_IDLE = 0, // 空闲 HR_STA_WORKING, // 检测中 HR_STA_NOT_OUTPUT_VALUE, // 持续出值中 } heartrate_status_e; typedef struct f_heartrate_t_ { page_tp_move_t *ptm; heartrate_status_e run_status; u8 hr_history_max; u8 hr_history_min; u8 anim_index; u32 anim_tick; u8 loading_index; u32 loading_tick; u8 measuring_sec; u32 measuring_tick; u8 sec; u32 tick; u32 refresh_tick; } f_heartrate_t; #if FUNC_HR_SIMULATE_DATA_EN static const uint8_t record_max[24] = {88, 111, 98, 78, 60, 125, 126, 111, 111, 144, 109, 89, 98, 198, 78, 98, 135, 88, 111, 78, 89, 69, 99, 80}; static const uint8_t record_min[24] = {40, 72, 58, 62, 46, 80, 50, 80, 40, 80, 84, 78, 89, 68, 56, 51, 76, 48, 41, 66, 51, 60, 66, 60}; #endif static uint8_t hr_max_record_data_get(uint8_t hour) { #if FUNC_HR_SIMULATE_DATA_EN return record_max[hour] > 170 ? 170 : record_max[hour]; #else return SysVariable.heartRateModule.recordMaxHeart[hour] > 170 ? 170 : SysVariable.heartRateModule.recordMaxHeart[hour]; #endif } static uint8_t hr_min_record_data_get(uint8_t hour) { #if FUNC_HR_SIMULATE_DATA_EN return record_min[hour]; #else return SysVariable.heartRateModule.recordMinHeart[hour]; #endif } static u32 func_hr_last_measure_time_get(void) { int time_min = (SysVariable.Rtc.hour * 3600 + SysVariable.Rtc.min * 60) - SysVariable.heartRateModule.heartMeasureTime; /* 数据超出保护 */ if (time_min < 60) time_min = 60; return time_min / 60; } static void func_heartrate_data_init(void) { f_heartrate_t *f_heartrate = (f_heartrate_t *)func_cb.f_cb; /* 初始化历史记录最小最大值 */ for (u8 i = 0; i < 24; i++) { if (hr_max_record_data_get(i) > f_heartrate->hr_history_max) f_heartrate->hr_history_max = hr_max_record_data_get(i); if ((hr_min_record_data_get(i) < f_heartrate->hr_history_min || f_heartrate->hr_history_min == 0) && hr_max_record_data_get(i)) f_heartrate->hr_history_min = hr_min_record_data_get(i); } } static void func_heartrate_last_data_text_get(char *text_buf) { char last_buf[TEXTBOX_TEXT_BUF_LEN] = {0}; if (text_buf == NULL) return; if (SysVariable.heartRateModule.lastHeart && SysVariable.heartRateModule.maxHeart) { if (func_hr_last_measure_time_get() >= 60) sprintf(last_buf, i18n[STR_HOURS_AGO], func_hr_last_measure_time_get() / 60); else sprintf(last_buf, i18n[STR_MINUTE_AGO], func_hr_last_measure_time_get()); #if defined(__LANGUAGE_SM_CHINESE__) if (tjd_Get_Language_Current_Index() == LANGUAGE_TYPE_Chinese) sprintf(text_buf, "%d次/分 %s", SysVariable.heartRateModule.lastHeart, last_buf); else #endif sprintf(text_buf, "%dBPM %s", SysVariable.heartRateModule.lastHeart, last_buf); } else { #if defined(__LANGUAGE_SM_CHINESE__) if (tjd_Get_Language_Current_Index() == LANGUAGE_TYPE_Chinese) sprintf(text_buf, "---次/分"); else #endif sprintf(text_buf, "---BPM"); } } // 创建心率窗体,创建窗体中不要使用功能结构体 func_cb.f_cb compo_form_t *func_heartrate_form_create(void) { char text_buf[TEXTBOX_TEXT_BUF_LEN] = {0}; /* 新建窗体 */ compo_form_t *frm = compo_form_create(true); /*=========================== 测量页面 ===========================*/ compo_picturebox_t *pic = compo_picturebox_create(frm, UI_BUF_HEART_RATE_HR_LOADING_BIN); compo_picturebox_set_pos(pic, HR_LOADING_BG_X, HR_LOADING_BG_Y); compo_picturebox_cut(pic, 0, HR_LOADING_NUM_MAX); compo_setid(pic, COMPO_ID_PIC_BG); /* 测量中 */ compo_textbox_t *txt_title = compo_textbox_create(frm, 20); compo_textbox_set_forecolor(txt_title, make_color(212, 212, 212)); compo_textbox_set_align_center(txt_title, false); compo_textbox_set_pos(txt_title, 19, 175); sprintf(text_buf, "%s...", i18n[STR_MEASURING]); compo_textbox_set(txt_title, text_buf); compo_setid(txt_title, COMPO_ID_TEXT_HEARTRATE_CUR); /* 当前测量心率值 */ compo_textbox_t *txt_val = compo_textbox_create(frm, 3); compo_setid(txt_val, COMPO_ID_NUM_HEARTRATE_CUR); compo_textbox_set_pos(txt_val, HR_CURR_POS_X, HR_CURR_POS_Y); compo_textbox_set_font(txt_val, UI_BUF_0FONT_FONT_NUM_38_BIN); compo_textbox_set_autosize(txt_val, true); compo_textbox_set_align_center(txt_val, false); compo_textbox_set(txt_val, "---"); /* 当前测量心率值单位 */ compo_textbox_t *txt_unit = compo_textbox_create(frm, 6); compo_setid(txt_unit, COMPO_ID_NUM_HEARTRATE_CUR_UNIT); compo_textbox_set_pos(txt_unit, HR_CURR_UNIT_POS_X + widget_text_get_area(txt_val->txt).wid, HR_CURR_UNIT_POS_Y); compo_textbox_set_forecolor(txt_unit, make_color(142, 142, 142)); compo_textbox_set_align_center(txt_unit, false); #if defined(__LANGUAGE_SM_CHINESE__) if (tjd_Get_Language_Current_Index() == LANGUAGE_TYPE_Chinese) compo_textbox_set(txt_unit, "次/分"); else #endif compo_textbox_set(txt_unit, "BPM"); /* 最后测量心率值单位 */ compo_textbox_t *txt_last = compo_textbox_create(frm, 100); compo_setid(txt_last, COMPO_ID_NUM_HEARTRATE_LAST); compo_textbox_set_align_center(txt_last, false); compo_textbox_set_location(txt_last, 22, 264, 188, 28); compo_textbox_set_autoroll_mode(txt_last, TEXT_AUTOROLL_MODE_SROLL_CIRC); compo_textbox_set_forecolor(txt_last, make_color(169, 169, 169)); func_heartrate_last_data_text_get(text_buf); compo_textbox_set(txt_last, text_buf); /*=========================== 详细信息页面 ===========================*/ compo_form_add_image(frm, UI_BUF_HEART_RATE_HR_CHART_BG_BIN, HR_CHART_POS_X, HR_CHART_POS_Y); /* 创建图表 */ for (u8 i = 0; i < HR_CHART_BAR_COLUMN_MAX; i++) { compo_shape_t *vol_bar = compo_radius_shape_create(frm, COMPO_SHAPE_TYPE_ROUNDED_RECTANGLE, HR_CHART_BAR_RADIUS); compo_setid(vol_bar, COMPO_ID_CHART + i); compo_shape_set_align_center(vol_bar, false); compo_shape_set_color(vol_bar, make_color(255, 31, 14)); } compo_textbox_t *txt_history_max = compo_textbox_create(frm, 6); compo_setid(txt_history_max, COMPO_ID_NUM_HEARTRATE_HISTORY_MAX); compo_textbox_set_font(txt_history_max, UI_BUF_0FONT_FONT_CALENDAR_BIN); compo_textbox_set_forecolor(txt_history_max, make_color(255, 31, 14)); compo_textbox_set_right_align(txt_history_max, true); compo_textbox_set_align_center(txt_history_max, false); compo_textbox_set_location(txt_history_max, 195, 337, 26, 18); compo_textbox_t *txt_history_min = compo_textbox_create(frm, 6); compo_setid(txt_history_min, COMPO_ID_NUM_HEARTRATE_HISTORY_MIN); compo_textbox_set_font(txt_history_min, UI_BUF_0FONT_FONT_CALENDAR_BIN); compo_textbox_set_forecolor(txt_history_min, make_color(255, 31, 14)); compo_textbox_set_right_align(txt_history_min, true); compo_textbox_set_align_center(txt_history_min, false); compo_textbox_set_location(txt_history_min, 195, 430, 26, 18); /* 范围 */ txt_title = compo_textbox_create(frm, 6); compo_textbox_set_forecolor(txt_title, make_color(212, 212, 212)); compo_textbox_set_align_center(txt_title, false); compo_textbox_set_pos(txt_title, 10, 472); compo_textbox_set(txt_title, i18n[STR_RANGE]); /* 当前测量心率值 */ txt_val = compo_textbox_create(frm, 8); compo_setid(txt_val, COMPO_ID_NUM_HEARTRATE_HISTORY); compo_textbox_set_pos(txt_val, HR_RANGE_POS_X, HR_RANGE_POS_Y); compo_textbox_set_font(txt_val, UI_BUF_0FONT_FONT_NUM_38_BIN); compo_textbox_set_autosize(txt_val, true); compo_textbox_set_align_center(txt_val, false); compo_textbox_set(txt_val, "00-000"); /* 当前测量心率值单位 */ txt_unit = compo_textbox_create(frm, 6); compo_setid(txt_unit, COMPO_ID_NUM_HEARTRATE_HISTORY_UNIT); compo_textbox_set_align_center(txt_unit, false); compo_textbox_set_pos(txt_unit, HR_RANGE_UNIT_POS_X + widget_text_get_area(txt_val->txt).wid, HR_RANGE_UNIT_POS_Y); compo_textbox_set_forecolor(txt_unit, make_color(142, 142, 142)); #if defined(__LANGUAGE_SM_CHINESE__) if (tjd_Get_Language_Current_Index() == LANGUAGE_TYPE_Chinese) compo_textbox_set(txt_unit, "次/分"); else #endif compo_textbox_set(txt_unit, "BPM"); txt_title = compo_textbox_create(frm, 6); compo_textbox_set_forecolor(txt_title, make_color(152, 152, 152)); compo_textbox_set_align_center(txt_title, false); compo_textbox_set_pos(txt_title, 16, 555); compo_textbox_set(txt_title, i18n[STR_TODAY]); /* 创建标题栏信息 */ memset(text_buf, 0, sizeof(text_buf)); if (SysVariable.deviceInfo.timeType == TIME_TYPE_12_HOUR) sprintf(text_buf, "%02d:%02d%s", get_autoformat_hour(SysVariable.Rtc.hour), SysVariable.Rtc.min, SysVariable.Rtc.hour >= 12 ? "PM" : "AM"); else sprintf(text_buf, "%02d:%02d", SysVariable.Rtc.hour, SysVariable.Rtc.min); compo_textbox_t *txt_time = compo_textbox_create_for_page(frm, frm->page, 8); compo_setid(txt_time, COMPO_ID_TITLE_TIME); compo_textbox_set_align_center(txt_time, false); compo_textbox_set_location(txt_time, 120, 9, 90, 30); compo_textbox_set_right_align(txt_time, true); compo_textbox_set(txt_time, text_buf); return frm; } static void func_heartrate_anim_refresh(void) { f_heartrate_t *f_heartrate = (f_heartrate_t *)func_cb.f_cb; compo_picturebox_t *compo_pic = compo_getobj_byid(COMPO_ID_PIC_BG); /* 测量出值前加载动画 */ if (f_heartrate->run_status == HR_STA_WORKING) { if (compo_pic != NULL) { if (tick_check_expire(f_heartrate->loading_tick, HR_LOADING_TICK_SPEED)) { f_heartrate->loading_tick = tick_get(); f_heartrate->loading_index = (f_heartrate->loading_index + 1) % HR_LOADING_NUM_MAX; compo_picturebox_cut(compo_pic, f_heartrate->loading_index, HR_LOADING_NUM_MAX); } } } /* 测量心跳动画 */ if (f_heartrate->run_status == HR_STA_NOT_OUTPUT_VALUE) { u8 anim_speed = 200; /* 动画速度取决与心率区间 */ if (SysVariable.heartRateModule.heart <= 70) anim_speed = HR_ANIM_TICK_SPEED_LOW; else if (SysVariable.heartRateModule.heart <= 120) anim_speed = HR_ANIM_TICK_SPEED_NORMAL; else if (SysVariable.heartRateModule.heart > 120) anim_speed = HR_ANIM_TICK_SPEED_FAST; if (compo_pic != NULL) { if (tick_check_expire(f_heartrate->anim_tick, anim_speed)) { f_heartrate->anim_tick = tick_get(); compo_picturebox_cut(compo_pic, f_heartrate->anim_index, HR_ANIM_NUM_MAX); /* 除首次从第一张播放起,第二遍从跳动开始循环播放 */ if (f_heartrate->anim_index < HR_ANIM_NUM_MAX - 1) f_heartrate->anim_index++; else f_heartrate->anim_index = 2; } } } } // 刷新心率 static void func_heartrate_refresh(void) { f_heartrate_t *f_heartrate = (f_heartrate_t *)func_cb.f_cb; char text_buf[TEXTBOX_TEXT_BUF_LEN] = {0}; compo_textbox_t *txt_time = compo_getobj_byid(COMPO_ID_TITLE_TIME); compo_textbox_t *compo_hr_val = compo_getobj_byid(COMPO_ID_NUM_HEARTRATE_CUR); compo_textbox_t *compo_hr_unit = compo_getobj_byid(COMPO_ID_NUM_HEARTRATE_CUR_UNIT); compo_textbox_t *compo_hr_txt = compo_getobj_byid(COMPO_ID_TEXT_HEARTRATE_CUR); compo_textbox_t *compo_hr_last = compo_getobj_byid(COMPO_ID_NUM_HEARTRATE_LAST); compo_textbox_t *compo_history_txt = compo_getobj_byid(COMPO_ID_NUM_HEARTRATE_HISTORY); compo_textbox_t *compo_history_unit = compo_getobj_byid(COMPO_ID_NUM_HEARTRATE_HISTORY_UNIT); compo_textbox_t *compo_history_max = compo_getobj_byid(COMPO_ID_NUM_HEARTRATE_HISTORY_MAX); compo_textbox_t *compo_history_min = compo_getobj_byid(COMPO_ID_NUM_HEARTRATE_HISTORY_MIN); compo_picturebox_t *compo_pic = compo_getobj_byid(COMPO_ID_PIC_BG); if (SysVariable.heartRateModule.openStatus == true || f_heartrate->run_status != HR_STA_IDLE) { reset_sleep_delay_all(); } /* 测量过程tick检测 */ if (tick_check_expire(f_heartrate->measuring_tick, 1000) && (f_heartrate->run_status == HR_STA_WORKING || f_heartrate->run_status == HR_STA_NOT_OUTPUT_VALUE)) { f_heartrate->measuring_tick = tick_get(); if (f_heartrate->measuring_sec > 0) f_heartrate->measuring_sec--; if ((SysVariable.heartRateModule.timeOutFlag == true) || (SysVariable.heartRateModule.measureEndFlag == true)) { /* 测量结束 */ bsp_sensor_hr_stop(); /* 更新结束数据显示 */ memset(text_buf, 0, sizeof(text_buf)); func_heartrate_last_data_text_get(text_buf); compo_textbox_set(compo_hr_last, text_buf); compo_textbox_set(compo_hr_txt, i18n[STR_CURRENT]); compo_picturebox_cut(compo_pic, 0, HR_ANIM_NUM_MAX); f_heartrate->run_status = HR_STA_IDLE; sys_cb.motor_flag = 1; set_func_motor(80, 5, 0, 1); } else if (f_heartrate->measuring_sec == HR_MEASURING_TIME - 15) { /* 测量出值阶段 */ f_heartrate->anim_index = 0; f_heartrate->anim_tick = tick_get(); f_heartrate->run_status = HR_STA_NOT_OUTPUT_VALUE; compo_picturebox_set(compo_pic, UI_BUF_HEART_RATE_HR_ANIM_BIN); compo_picturebox_cut(compo_pic, f_heartrate->anim_index, HR_ANIM_NUM_MAX); compo_picturebox_set_pos(compo_pic, HR_ANIM_BG_X, HR_ANIM_BG_Y); } } /* 动画刷新 */ func_heartrate_anim_refresh(); /* 更新数据 */ if (tick_check_expire(f_heartrate->refresh_tick, 100)) { func_heartrate_data_init(); // 更新图表数据 u16 chart_offser_x[HR_CHART_BAR_COLUMN_MAX / 6] = { 0, 3, 7, 10}; u16 temp_max = f_heartrate->hr_history_max < HR_CHART_BAR_INIT_HEIGHT ? HR_CHART_BAR_INIT_HEIGHT : f_heartrate->hr_history_max; u16 bar_hei_uint; if(temp_max - f_heartrate->hr_history_min == 0) bar_hei_uint = (HR_CHART_BAR_HEIGHT * 10); else bar_hei_uint = (HR_CHART_BAR_HEIGHT * 10) / (temp_max - f_heartrate->hr_history_min); if (f_heartrate->hr_history_max) { /* 由于平台不支持浮点运算,故将单位系数放大10倍后续计算后恢复 */ for (u8 i = 0; i < HR_CHART_BAR_COLUMN_MAX; i++) { if (hr_max_record_data_get(i) && hr_min_record_data_get(i)) { u16 chart_y = ((hr_min_record_data_get(i) - f_heartrate->hr_history_min) * bar_hei_uint) / 10; u16 height = ((hr_max_record_data_get(i) - hr_min_record_data_get(i)) * bar_hei_uint) / 10; if (height == 0) height = 1; compo_shape_t *hr_bar = compo_getobj_byid(COMPO_ID_CHART + i); compo_shape_set_location(hr_bar, (21 + chart_offser_x[i / 6]) + (i * 8), (HR_CHART_BAR_POS_Y + (HR_CHART_BAR_HEIGHT - height)) - chart_y, HR_CHART_BAR_WIDTH, height); } } } memset(text_buf, 0, sizeof(text_buf)); sprintf(text_buf, "%d", temp_max); compo_textbox_set(compo_history_max, text_buf); memset(text_buf, 0, sizeof(text_buf)); sprintf(text_buf, "%d", f_heartrate->hr_history_min); compo_textbox_set(compo_history_min, text_buf); // 更新历史范围值 memset(text_buf, 0, sizeof(text_buf)); sprintf(text_buf, "%d-%d", f_heartrate->hr_history_min, f_heartrate->hr_history_max); compo_textbox_set(compo_history_txt, text_buf); compo_textbox_set_pos(compo_history_unit, HR_RANGE_UNIT_POS_X + widget_text_get_area(compo_history_txt->txt).wid, HR_RANGE_UNIT_POS_Y); // 更新测量数据 if (SysVariable.heartRateModule.heart > 0 && f_heartrate->run_status != HR_STA_WORKING) { sprintf(text_buf, "%d", SysVariable.heartRateModule.heart); compo_textbox_set(compo_hr_val, text_buf); compo_textbox_set_pos(compo_hr_unit, HR_CURR_UNIT_POS_X + widget_text_get_area(compo_hr_val->txt).wid, HR_CURR_UNIT_POS_Y); } } /* 更新标题时间 */ static u32 tick = 0; memset(text_buf, 0, sizeof(text_buf)); if (tick_check_expire(tick, 500)) { if (txt_time) { tick = tick_get(); if (SysVariable.deviceInfo.timeType == TIME_TYPE_12_HOUR) sprintf(text_buf, "%02d:%02d%s", get_autoformat_hour(SysVariable.Rtc.hour), SysVariable.Rtc.min, SysVariable.Rtc.hour >= 12 ? "PM" : "AM"); else sprintf(text_buf, "%02d:%02d", SysVariable.Rtc.hour, SysVariable.Rtc.min); compo_textbox_set(txt_time, text_buf); } } } //心率功能事件处理 static void func_heartrate_process(void) { f_heartrate_t *f_heartrate = (f_heartrate_t *)func_cb.f_cb; compo_page_move_process(f_heartrate->ptm); #ifdef TJD_GUI_Remind_slip_wrist_Show //脱腕检测 if (tick_check_expire(f_heartrate->tick, 100)) { f_heartrate->tick = tick_get(); if(++f_heartrate->sec > 30) { if(SysVariable.heartRateModule.is_farway_hand == true){ func_switch_to_assign_screen(FUNC_FARWAY_HAND, false); func_cb.last = FUNC_HEARTRATE; } } } #endif func_heartrate_refresh(); func_process(); } //心率功能消息处理 static void func_heartrate_message(size_msg_t msg) { f_heartrate_t *f_heartrate = (f_heartrate_t *)func_cb.f_cb; switch (msg) { case MSG_CTP_TOUCH: compo_page_move_touch_handler(f_heartrate->ptm); break; case MSG_CTP_CLICK: case MSG_CTP_SHORT_UP: case MSG_CTP_SHORT_DOWN: case MSG_CTP_LONG: break; case MSG_QDEC_BACKWARD: if (func_cb.flag_sort) { //快捷应用状态下不滚动页面 func_message(msg); } else { compo_page_move_set_by_pages(f_heartrate->ptm, -1); } break; case MSG_QDEC_FORWARD: if (func_cb.flag_sort) { func_message(msg); } else { compo_page_move_set_by_pages(f_heartrate->ptm, 1); } break; default: func_message(msg); break; } } //进入心率功能 static void func_heartrate_enter(void) { func_cb.f_cb = func_zalloc(sizeof(f_heartrate_t)); func_cb.frm_main = func_heartrate_form_create(); f_heartrate_t *f_heartrate = (f_heartrate_t *)func_cb.f_cb; f_heartrate->ptm = (page_tp_move_t *)func_zalloc(sizeof(page_tp_move_t)); page_move_info_t info = { .title_used = false, .page_size = GUI_SCREEN_HEIGHT, .page_count = 2, .jump_perc = 10, .quick_jump_perc = 100, .up_over_perc = 0, .down_over_perc = 0, }; compo_page_move_init(f_heartrate->ptm, func_cb.frm_main->page_body, &info); f_heartrate->run_status = HR_STA_WORKING; f_heartrate->measuring_sec = HR_MEASURING_TIME; func_heartrate_data_init(); bsp_sensor_hr_start(MeasureMode_Heart); } //退出心率功能 static void func_heartrate_exit(void) { f_heartrate_t *f_heartrate = (f_heartrate_t *)func_cb.f_cb; if (f_heartrate->ptm) { func_free(f_heartrate->ptm); } bsp_sensor_hr_stop(); } //心率功能 void func_heartrate(void) { printf("%s\n", __func__); func_heartrate_enter(); while (func_cb.sta == FUNC_HEARTRATE) { func_heartrate_process(); func_heartrate_message(msg_dequeue()); } func_heartrate_exit(); }