sggt/App/MODBUS/Src/modbus_register_process.c

777 lines
23 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}
//如果当前页面存在该内容,则更新文本
if( (menu_data.scr_now == SCREEN_SETTING)&&(tabdata.item_cursor == ITEM_3) ) set_item3_text(LIGHT_STATUS);
}
}
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();
//保持寄存器处理mux输出设定值的修改事件
hold_deal_muxsv();
//保持寄存器,量程类型选择
hold_deal_range_type();
//保持寄存器,处理量程上限的修改事件
hold_deal_range_max();
//保持寄存器,处理量程下限的修改事件
hold_deal_range_min();
//保持寄存器,处理采样间隔修改事件
hold_deal_sample_interval();
//保持寄存器,处理描点数量的修改事件
hold_deal_plot_counts();
//保持寄存器,处理输入曲线&图例颜色修改事件
hold_deal_color_input();
//保持寄存器,处理输出曲线&图例颜色修改事件
hold_deal_color_output();
//保持寄存器,处理语言选择事件
hold_deal_language_select();
}
void hold_deal_set_work_mode(void)
{
//计算当前工作模式的对应编码参照Modbus寄存器配置表excel文件
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 range_max_prv = 0, range_min_prv = 0;
uint16_t phyunit_prv = 0;
uint8_t *p8low = 0, *p8up = 0, *p8low_prv = 0, *p8up_prv = 0;
int16_t *p16low = 0, *p16up = 0, *p16low_prv = 0, *p16up_prv = 0;
void hold_deal_range_type(void)
{
//发生变化时才执行以下操作
if( HoldReg[HOLD_ADDR_PHY_UNIT] == phyunit_prv ) return;
phyunit_prv = HoldReg[HOLD_ADDR_PHY_UNIT];
range_max_prv = 0;
range_min_prv = 0;
//选择指定物理量之后,更新上限和下限的寄存器值
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;
}
}
void hold_deal_range_max(void)
{
//发生改变才执行(只需判断是否变化,不用处理符号)
if(range_max_prv == HoldReg[HOLD_ADDR_PHY_UP])
{
//处理 当前选中的物理量在本地进行了修改 的情况
if(*p8up != *p8up_prv)
{
*p8up_prv = *p8up;
HoldReg[HOLD_ADDR_PHY_UP] = 0x00FF & (*p8up);
}
else if(*p16up != *p16up_prv)
{
*p16up_prv = *p16up;
memcpy(HoldReg + HOLD_ADDR_PHY_UP, p16up, 2);
}
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;
*p8up_prv = *p8up;
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(menu_data.scr_now == SCREEN_SETTING)
{
setting_items_page(ITEM_0, 1);
}
}
else
{
//拒绝修改
HoldReg[HOLD_ADDR_PHY_UP] = range_max_prv;
}
}
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;
*p16up_prv = *p16up;
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);
}
}
else if(menu_data.scr_now == SCREEN_SETTING)
{
setting_items_page(ITEM_0, 1);
}
}
else
{
//拒绝修改
HoldReg[HOLD_ADDR_PHY_UP] = range_max_prv;
}
}
}
void hold_deal_range_min(void)
{
//发生改变才执行(只需判断是否变化,不用处理符号)
if(range_min_prv == HoldReg[HOLD_ADDR_PHY_LOW])
{
//处理 当前选中的物理量在本地进行了修改 的情况
if(*p8low != *p8low_prv)
{
*p8low_prv = *p8low;
HoldReg[HOLD_ADDR_PHY_LOW] = 0x00FF & (*p8low);
}
else if(*p16low != *p16low_prv)
{
*p16low_prv = *p16low;
memcpy(HoldReg + HOLD_ADDR_PHY_LOW, p16low, 2);
}
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(menu_data.scr_now == SCREEN_SETTING)
{
setting_items_page(ITEM_0, 1);
}
}
else
{
//拒绝修改
HoldReg[HOLD_ADDR_PHY_LOW] = range_min_prv;
}
}
else
{
if( (!p16up)|(!p16low) ) return;
int16_t hold_temp16 = 0;
memcpy(&hold_temp16, HoldReg + HOLD_ADDR_PHY_LOW, 2);
if( (rg_min <= hold_temp16)&&(hold_temp16 <= *p16up) )
{
*p16low = 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);
}
}
else if(menu_data.scr_now == SCREEN_SETTING)
{
setting_items_page(ITEM_0, 1);
}
}
else
{
//拒绝修改
HoldReg[HOLD_ADDR_PHY_LOW] = range_min_prv;
}
}
}
//保持寄存器,处理采样间隔修改事件
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];
if( (menu_data.scr_now == SCREEN_SETTING)&&(tabdata.item_cursor == ITEM_1) ) set_item1_text(SAMPLE_INTERVAL);
}
else
{
//拒绝修改
HoldReg[HOLD_ADDR_SAMPLE_INTERVAL] = tabdata.item1_page0_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 = 0x00FF & HoldReg[HOLD_ADDR_PLOT_COUNTS];
if(menu_data.scr_now == SCREEN_MAIN)
{
//更新显示模式,强制归零后自动恢复显示值(曲线只有在显示值变化时才刷新,于是在此处手动发生变化)
scr_main_chart_update();
pltdata.y_pri_value = 0;
pltdata.y_scd_value = 0;
}
else if(menu_data.scr_now == SCREEN_SETTING)
{
set_item1_text(PLOT_NUM);
}
}
else
{
//拒绝修改
HoldReg[HOLD_ADDR_PLOT_COUNTS] = 0x00FF & tabdata.item1_page0_plot_num;
}
}
}
//保持寄存器,处理输入曲线&图例颜色修改事件
void hold_deal_color_input(void)
{
if( HoldReg[HOLD_ADDR_INPUT_COLOR] != (0x00FF & (uint8_t)tabdata.item1_page0_color_input) )
{
if( HoldReg[HOLD_ADDR_INPUT_COLOR] <= 5 )
{
tabdata.item1_page0_color_input = (COLORS)HoldReg[HOLD_ADDR_INPUT_COLOR];
if(menu_data.scr_now == SCREEN_MAIN)
{
scr_main_chart_update();
}
else if( (menu_data.scr_now == SCREEN_SETTING)&&(tabdata.item_cursor == ITEM_1) )
{
set_obj_color(guider_ui.screen_setting_label_21, tabdata.item1_page0_color_input);
}
}
else
{
//拒绝修改
HoldReg[HOLD_ADDR_INPUT_COLOR] = 0x00FF & (uint8_t)tabdata.item1_page0_color_input;
}
}
}
//保持寄存器,处理输出曲线&图例颜色修改事件
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();
}
else if( (menu_data.scr_now == SCREEN_SETTING)&&(tabdata.item_cursor == ITEM_1) )
{
set_obj_color(guider_ui.screen_setting_label_31, tabdata.item1_page0_color_output);
}
}
else
{
//拒绝修改
HoldReg[HOLD_ADDR_OUTPUT_COLOR] = 0x00FF & (uint8_t)tabdata.item1_page0_color_output;
}
}
}
//保持寄存器,处理语言选择事件
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);
}
else
{
//拒绝修改
HoldReg[HOLD_ADDR_LANGUAGE] = 0x00FF & (uint8_t)tabdata.item3_page0_language;
}
}
}
//输入寄存器,上位机只读
void modbus_reg_update_input(void)
{}