#include "modbus_register_process.h" //处理modbus寄存器值的更新与写入 void modbus_registers_update(void) { //线圈寄存器 modbus_reg_update_coil(); //离散状态寄存器 modbus_reg_update_dis(); //保持寄存器 modbus_reg_update_hold(); //输入寄存器 modbus_reg_update_input(); } //线圈寄存器,读写 void modbus_reg_update_coil(void) { //主界面的ON&OFF控制 coil_deal_ON2OFF(); //照明控制 coil_deal_light(); //配置保存 coil_deal_save(); //配置复位 coil_deal_reset(); //屏幕切换:主界面<->设置界面 coil_deal_screen_switch(); } void set_coil_val(uint8_t addr, uint8_t bit_val) { if( (addr > COIL_ADD_MAX)||(bit_val > 1) ) return; addr -= COIL_ADD_MIN; if( addr > 200 ) return; uint8_t pcoil = addr / 8; //数组的第几个元素, 0-7 uint8_t pbit = addr % 8; //元素的第几位, 0-7 uint8_t fac = 0; //辅助计算的因子 switch (bit_val) { case 0: { fac = ~(1 << pbit); CoilState[pcoil] &= fac; } break; case 1: { fac = 1 << pbit; CoilState[pcoil] |= fac; } break; default: break; } } uint8_t get_coil_val(uint8_t addr) { if( addr > COIL_ADD_MAX ) return 99; addr -= COIL_ADD_MIN; if( addr > 200 ) return 99; uint8_t result = 0; uint8_t pcoil = addr / 8; //数组的第几个元素, 0-7 uint8_t pbit = addr % 8; //元素的第几位, 0-7 result = 0x01 & (CoilState[pcoil] >> pbit); return result; } void coil_deal_ON2OFF(void) { if( (get_coil_val(COIL_ADDR_ON_OFF) != menu_data.io_on2off)&&(get_coil_val(COIL_ADDR_ON_OFF) < 2) ) { //进入此处说明线圈寄存器的值被上位机修改 if( menu_data.scr_now == SCREEN_MAIN ) { //只有在主界面时,修改内容才生效 menu_data.io_on2off = get_coil_val(COIL_ADDR_ON_OFF); io_on2off_status(); } else { //拒绝修改内容 set_coil_val(COIL_ADDR_ON_OFF, menu_data.io_on2off); } } } void coil_deal_light(void) { if( (get_coil_val(COIL_ADDR_LIGHT) != tabdata.item3_page0_lightflag)&&(get_coil_val(COIL_ADDR_LIGHT) < 2) ) { //进入此处说明线圈寄存器的值被上位机修改 tabdata.item3_page0_lightflag = get_coil_val(COIL_ADDR_LIGHT); if(tabdata.item3_page0_lightflag) { LIGHT_ON; } else { LIGHT_OFF; } } } void coil_deal_save(void) { if( (get_coil_val(COIL_ADDR_CONFIG_SAVE) == 1)&&(tabdata.item3_page0_saveflag == 0) ) { if( (menu_data.scr_now == SCREEN_SETTING)&&(tabdata.item3_page0_resetflag != 1) ) { //当前处于设置界面,并且未处于重置过程中,执行保存 tabdata.item3_page0_saveflag = 1; } else { //拒绝修改 set_coil_val(COIL_ADDR_CONFIG_SAVE, 0); } } } void coil_deal_reset(void) { if( (get_coil_val(COIL_ADDR_CONFIG_RESET) == 1)&&(tabdata.item3_page0_resetflag == 0) ) { if( (menu_data.scr_now == SCREEN_SETTING)&&(tabdata.item3_page0_saveflag != 1) ) { //当前处于设置界面,并且未处于保存过程中,执行复位 tabdata.item3_page0_resetflag = 1; } else { //拒绝修改 set_coil_val(COIL_ADDR_CONFIG_RESET, 0); } } } void coil_deal_screen_switch(void) { if( get_coil_val(COIL_ADDR_SCREEN_SWITCH) != ( (uint8_t)menu_data.scr_now - 1 ) ) { switch (menu_data.scr_now) { case SCREEN_INIT: { //拒绝修改,开机动画视作主界面 set_coil_val(COIL_ADDR_SCREEN_SWITCH, 0); } break; case SCREEN_MAIN: { //切换至设置界面; scr_setting_recover(); lv_scr_load(guider_ui.screen_setting); lv_obj_clear_flag(guider_ui.screen_setting, LV_OBJ_FLAG_HIDDEN); //隐藏主界面对象 lv_obj_add_flag(guider_ui.screen_main, LV_OBJ_FLAG_HIDDEN); menu_data.scr_now = SCREEN_SETTING; set_coil_val(COIL_ADDR_SCREEN_SWITCH, 1); } break; case SCREEN_SETTING: { //切换至主界面; if(!scr_main_set_flag) { scr_main_set_flag = 1; setup_scr_screen_main(&guider_ui); delay_cnt(200); } scr_main_recover(); lv_scr_load(guider_ui.screen_main); lv_obj_clear_flag(guider_ui.screen_main, LV_OBJ_FLAG_HIDDEN); //隐藏设置界面对象 lv_obj_add_flag(guider_ui.screen_setting, LV_OBJ_FLAG_HIDDEN); menu_data.scr_now = SCREEN_MAIN; set_coil_val(COIL_ADDR_SCREEN_SWITCH, 0); } break; default: { //拒绝修改,其他界面视作设置界面 set_coil_val(COIL_ADDR_SCREEN_SWITCH, 1); } break; } } } //离散输入寄存器,上位机只读 void modbus_reg_update_dis(void) {} //保持寄存器,读写 void modbus_reg_update_hold(void) { hold_deal_set_work_mode(); hold_deal_muxsv(); hold_deal_range_type(); hold_deal_range_max(); hold_deal_range_min(); } void hold_deal_set_work_mode(void) { uint16_t work_mode_pv = (menu_data.io_mode == IO_INPUT)*( (uint16_t)menu_data.input_mode_type + 1 ) + \ (menu_data.io_mode == IO_OUTPUT)*( (uint16_t)menu_data.output_mode_type + 15 ); //工作模式符合编码的情况下,发生改变才执行以下操作 if( (HoldReg[HOLD_ADDR_SET_WORK_MODE] != work_mode_pv)&&(0 < HoldReg[HOLD_ADDR_SET_WORK_MODE])&&(HoldReg[HOLD_ADDR_SET_WORK_MODE] <= 28) ) { //只有在主界面才接收修改 if(menu_data.scr_now == SCREEN_MAIN) { SIG_FUNCTIONS iom; SIG_FUNCTIONS_TYPE iomt; iomt = (SIG_FUNCTIONS_TYPE)( HoldReg[HOLD_ADDR_SET_WORK_MODE] - 1 - 14 * (HoldReg[HOLD_ADDR_SET_WORK_MODE] > 14) ); switch (iomt) { case 0: iom = SIG_CURRENT; break; case 1: {} //break; case 2: iom = SIG_VOLTAGE; break; case 3: iom = SIG_RESISTANT; break; case 4: iom = SIG_FREQUENCE; break; case 13: iom = SIG_RTD; break; default: iom = SIG_TC; break; } if(HoldReg[HOLD_ADDR_SET_WORK_MODE] > 14) { menu_data.io_mode = IO_OUTPUT; menu_data.output_mode = iom; menu_data.output_mode_type = iomt; } else { menu_data.io_mode = IO_INPUT; menu_data.input_mode = iom; menu_data.input_mode_type = iomt; } set_working_mode(iom, iomt); } else { //拒绝修改 HoldReg[HOLD_ADDR_SET_WORK_MODE] = work_mode_pv; } } } void hold_deal_muxsv(void) { //上位机控制的情况下,设定值跟随保持寄存器的值变化 uint32_t hold_temp = (HoldReg[HOLD_ADDR_MUX_SV_H] << 16) + HoldReg[HOLD_ADDR_MUX_SV_L]; float32 real_hold = 0; memcpy(&real_hold, &hold_temp, 4); if( (real2mux(real_hold) != mux_signal.data_sv)&&get_coil_val(COIL_ADDR_HOLD_SV_CTRL)&&get_coil_val(COIL_ADDR_HOLD_SV_ENSURE) ) { if( (menu_data.scr_now == SCREEN_MAIN)&&(pltdata.yreal_pri_low <= real_hold)&&(real_hold <= pltdata.yreal_pri_up) ) { set_output(real_hold); } else { //拒绝修改 uint32_t mcpy_temp = 0; float32 muxpv_temp = mux2real(mux_signal.data_sv); memcpy(&mcpy_temp, &muxpv_temp, 4); HoldReg[HOLD_ADDR_MUX_SV_H] = mcpy_temp >> 16; HoldReg[HOLD_ADDR_MUX_SV_L] = mcpy_temp & 0x0000FFFF; } //设定一次后清零,等待下次设定 set_coil_val(COIL_ADDR_HOLD_SV_ENSURE, 0); } } int16_t rg_max = 0, rg_min = 0; uint16_t phyunit_prv = 0; uint8_t *p8low = 0, *p8up = 0; int16_t *p16low = 0, *p16up = 0; void hold_deal_range_type(void) { //发生变化时才执行以下操作 if( HoldReg[HOLD_ADDR_PHY_UNIT] == phyunit_prv ) return; phyunit_prv = HoldReg[HOLD_ADDR_PHY_UNIT]; if( HoldReg[HOLD_ADDR_PHY_UNIT] == 0 ) return; //选择指定物理量之后,更新上限和下限的寄存器值 switch (HoldReg[HOLD_ADDR_PHY_UNIT]) { case 1: { HoldReg[HOLD_ADDR_PHY_LOW] = 0x00FF & tabdata.item0_page0_clow; HoldReg[HOLD_ADDR_PHY_UP] = 0x00FF & tabdata.item0_page0_cup; rg_max = CUR.up; rg_min = CUR.low; p8low = &tabdata.item0_page0_clow; p8up = &tabdata.item0_page0_cup; } break; case 2: { memcpy(HoldReg + HOLD_ADDR_PHY_LOW, &tabdata.item0_page0_vlow[0], 2); memcpy(HoldReg + HOLD_ADDR_PHY_UP, &tabdata.item0_page0_vup[0], 2); rg_max = VOL[0].up; rg_min = VOL[0].low; p16low = &tabdata.item0_page0_vlow[0]; p16up = &tabdata.item0_page0_vup[0]; } break; case 3: { memcpy(HoldReg + HOLD_ADDR_PHY_LOW, &tabdata.item0_page0_vlow[1], 2); memcpy(HoldReg + HOLD_ADDR_PHY_UP, &tabdata.item0_page0_vup[1], 2); rg_max = VOL[1].up; rg_min = VOL[1].low; p16low = &tabdata.item0_page0_vlow[1]; p16up = &tabdata.item0_page0_vup[1]; } break; case 4: { memcpy(HoldReg + HOLD_ADDR_PHY_LOW, &tabdata.item0_page1_rlow, 2); memcpy(HoldReg + HOLD_ADDR_PHY_UP, &tabdata.item0_page0_rup, 2); rg_max = RES.up; rg_min = RES.low; p16low = &tabdata.item0_page1_rlow; p16up = &tabdata.item0_page0_rup; } break; case 5: { HoldReg[HOLD_ADDR_PHY_LOW] = 0x00FF & tabdata.item0_page1_flow; HoldReg[HOLD_ADDR_PHY_UP] = 0x00FF & tabdata.item0_page1_fup; rg_max = FRE.up; rg_min = FRE.low; p8low = &tabdata.item0_page1_flow; p8up = &tabdata.item0_page1_fup; } break; case 6: {} //break; case 7: {} //break; case 8: {} //break; case 9: {} //break; case 10: {} //break; case 11: {} //break; case 12: {} //break; case 13: { uint8_t p_temp = HoldReg[HOLD_ADDR_PHY_UNIT] - 6; memcpy(HoldReg + HOLD_ADDR_PHY_LOW, &tabdata.item0_page1_TClow[p_temp], 2); memcpy(HoldReg + HOLD_ADDR_PHY_UP, &tabdata.item0_page1_TCup[p_temp], 2); rg_max = TC[p_temp].up; rg_min = TC[p_temp].low; p16low = &tabdata.item0_page1_TClow[p_temp]; p16up = &tabdata.item0_page1_TCup[p_temp]; } break; case 14: { memcpy(HoldReg + HOLD_ADDR_PHY_LOW, &tabdata.item0_page2_RTDlow, 2); memcpy(HoldReg + HOLD_ADDR_PHY_UP, &tabdata.item0_page2_RTDup, 2); rg_max = RTD.up; rg_min = RTD.low; p16low = &tabdata.item0_page2_RTDlow; p16up = &tabdata.item0_page2_RTDup; } break; default: { HoldReg[HOLD_ADDR_PHY_UNIT] = 0; HoldReg[HOLD_ADDR_PHY_LOW] = 0; HoldReg[HOLD_ADDR_PHY_UP] = 0; rg_max = 0; rg_min = 0; *p8low = 0; *p8up = 0; *p16low = 0; *p16up = 0; } break; } } uint16_t range_max_prv = 0; void hold_deal_range_max(void) { //发生改变才执行 if(range_max_prv == HoldReg[HOLD_ADDR_PHY_UP]) return; range_max_prv = HoldReg[HOLD_ADDR_PHY_UP]; //数据类型不同,电流mA(0-25)和频率KHz(0-100)的数据类型时uint8,其他都是int16 //*p8指向了需要修改的uint8,*p16指向了需要修改的int16 if( (HoldReg[HOLD_ADDR_PHY_UNIT] == 1)|(HoldReg[HOLD_ADDR_PHY_UNIT] == 5) ) { if( (!p8up)|(!p8low) ) return; uint8_t hold_temp8 = 0x00FF & HoldReg[HOLD_ADDR_PHY_UP]; if( (*p8low <= hold_temp8)&&(hold_temp8 <= (uint8_t)rg_max) ) { *p8up = hold_temp8; if(menu_data.scr_now == SCREEN_MAIN) { SIG_FUNCTIONS_TYPE typ = (SIG_FUNCTIONS_TYPE)(menu_data.input_mode_type*(!menu_data.io_mode) + menu_data.output_mode_type*menu_data.io_mode); if( typ == (HoldReg[HOLD_ADDR_PHY_UNIT] - 1) ) { up2down_update(*p8low, *p8up); } } } } else { if( (!p16up)|(!p16low) ) return; int16_t hold_temp16 = 0; memcpy(&hold_temp16, HoldReg + HOLD_ADDR_PHY_UP, 2); if( (*p16low <= hold_temp16)&&(hold_temp16 <= rg_max) ) { *p16up = hold_temp16; if(menu_data.scr_now == SCREEN_MAIN) { SIG_FUNCTIONS_TYPE typ = (SIG_FUNCTIONS_TYPE)(menu_data.input_mode_type*(!menu_data.io_mode) + menu_data.output_mode_type*menu_data.io_mode); if( typ == (HoldReg[HOLD_ADDR_PHY_UNIT] - 1) ) { up2down_update(*p16low, *p16up); } } } } } uint16_t range_min_prv = 0; void hold_deal_range_min(void) { //与hold_deal_range_max相同 if(range_min_prv == HoldReg[HOLD_ADDR_PHY_LOW]) return; range_min_prv = HoldReg[HOLD_ADDR_PHY_LOW]; if( (HoldReg[HOLD_ADDR_PHY_UNIT] == 1)|(HoldReg[HOLD_ADDR_PHY_UNIT] == 5) ) { if( (!p8up)|(!p8low) ) return; uint8_t hold_temp8 = 0x00FF & HoldReg[HOLD_ADDR_PHY_LOW]; if( ((uint8_t)rg_min <= hold_temp8)&&(hold_temp8 <= *p8up) ) { *p8low = hold_temp8; if(menu_data.scr_now == SCREEN_MAIN) { SIG_FUNCTIONS_TYPE typ = (SIG_FUNCTIONS_TYPE)(menu_data.input_mode_type*(!menu_data.io_mode) + menu_data.output_mode_type*menu_data.io_mode); if( typ == (HoldReg[HOLD_ADDR_PHY_UNIT] - 1) ) { up2down_update(*p8low, *p8up); } } } } else { if( (!p16up)|(!p16low) ) return; int16_t hold_temp16 = 0; memcpy(&hold_temp16, HoldReg + HOLD_ADDR_PHY_LOW, 2); if( ((uint8_t)rg_min <= hold_temp16)&&(hold_temp16 <= *p16up) ) { *p16up = hold_temp16; if(menu_data.scr_now == SCREEN_MAIN) { SIG_FUNCTIONS_TYPE typ = (SIG_FUNCTIONS_TYPE)(menu_data.input_mode_type*(!menu_data.io_mode) + menu_data.output_mode_type*menu_data.io_mode); if( typ == (HoldReg[HOLD_ADDR_PHY_UNIT] - 1) ) { up2down_update(*p16low, *p16up); } } } } } //保持寄存器,处理采样间隔修改事件 void hold_deal_sample_interval(void) { if( HoldReg[HOLD_ADDR_SAMPLE_INTERVAL] != tabdata.item1_page0_sample_interval ) { if( (MENU_TASK_PERIOD <= HoldReg[HOLD_ADDR_SAMPLE_INTERVAL])&&(HoldReg[HOLD_ADDR_SAMPLE_INTERVAL] <= SAMPLE_INTERVAL_MAX) ) { tabdata.item1_page0_sample_interval = HoldReg[HOLD_ADDR_SAMPLE_INTERVAL]; } } } //保持寄存器,处理描点数量修改事件 void hold_deal_plot_counts(void) { if( HoldReg[HOLD_ADDR_PLOT_COUNTS] != (0x00FF & tabdata.item1_page0_plot_num) ) { if( (PLOT_NUM_MIN <= HoldReg[HOLD_ADDR_PLOT_COUNTS])&&(HoldReg[HOLD_ADDR_PLOT_COUNTS] <= PLOT_NUM_MAX) ) { tabdata.item1_page0_plot_num = HoldReg[HOLD_ADDR_PLOT_COUNTS]; if(menu_data.scr_now == SCREEN_MAIN) { scr_main_chart_update(); } } } } //保持寄存器,处理输入曲线&图例颜色修改事件 void hold_deal_color_input(void) { if( HoldReg[HOLD_ADDR_INPUT_COLOR] != (0x00FF & (uint8_t)tabdata.item1_page0_color_input) ) { if( HoldReg[HOLD_ADDR_PLOT_COUNTS] <= 5 ) { tabdata.item1_page0_color_input = (COLORS)HoldReg[HOLD_ADDR_PLOT_COUNTS]; if(menu_data.scr_now == SCREEN_MAIN) { scr_main_chart_update(); } } } } //保持寄存器,处理输出曲线&图例颜色修改事件 void hold_deal_color_output(void) { if( HoldReg[HOLD_ADDR_OUTPUT_COLOR] != (0x00FF & (uint8_t)tabdata.item1_page0_color_output) ) { if( HoldReg[HOLD_ADDR_OUTPUT_COLOR] <= 5 ) { tabdata.item1_page0_color_output = (COLORS)HoldReg[HOLD_ADDR_OUTPUT_COLOR]; if(menu_data.scr_now == SCREEN_MAIN) { scr_main_chart_update(); } } } } //保持寄存器,处理语言选择事件 void hold_deal_language_select(void) { if( HoldReg[HOLD_ADDR_LANGUAGE] != (0x00FF & (uint8_t)tabdata.item3_page0_language) ) { if( HoldReg[HOLD_ADDR_LANGUAGE] <= 1 ) { tabdata.item3_page0_language = (LANGUAGES)HoldReg[HOLD_ADDR_LANGUAGE]; setting_laguage_switch(tabdata.item3_page0_language); } } } //输入寄存器,上位机只读 void modbus_reg_update_input(void) {}