更新:

1、编程输出:阶跃,完成;
2、主界面:测量值溢出时显示“+”号;
This commit is contained in:
吴俊潮 2025-06-05 11:44:15 +08:00
parent 98f3e7f035
commit 26e34b5cf0
13 changed files with 21201 additions and 20930 deletions

View File

@ -34,9 +34,6 @@ extern uint8_t scr_main_set_flag;
//闪烁次数上限
#define TWINKLE_CNT_MAX 10
//数码管闪烁功能使能
#define NIXIE_CUBE_ENABLE 0
//EEPROM状态监控
#define EEPROM_MONITOR_ENABLE 1

View File

@ -73,7 +73,8 @@ typedef enum
MODBUS_MASTER_TRX, //modbus主站收发选项选择
MODBUS_MASTER_TRX_MODIFY, //modbus主站收发选项修改
PROG_OUT_CONFIG_1, //编程输出配置页面1输出方式、输出模式、循环次数、下一步
PROG_OUT_CONFIG_2 //阶跃、三角波
PROG_OUT_CONFIG_2, //阶跃、三角波的参数配置界面
PROG_OUT_PROCESSING //编程输出执行中
}OPERATIONS;
typedef enum
@ -128,11 +129,7 @@ typedef struct
SIG_FUNCTIONS_TYPE input_mode_type; //当前输入模式的类型
SIG_FUNCTIONS output_mode; //当前的输出模式
SIG_FUNCTIONS_TYPE output_mode_type; //当前输出模式的类型
#if NIXIE_CUBE_ENABLE
uint8_t twk_flag; //闪烁使能标志
uint8_t twk_flip; //0-1变量用于控制显示内容翻转显示/不显示)
uint8_t twk_cnt; //闪烁计数,计数达到上限后闪烁停止
#endif
uint8_t sign_flag_in; //输入信号符号位标志0->不显示1->显示负号
uint8_t sign_flag_out; //输出信号符号位标志0->不显示1->显示负号

View File

@ -3,10 +3,15 @@
#include "apps_gather.h"
//输出方式
#define PROG_OUT_V 0
#define PROG_OUT_MA 1
//输出模式
#define PROG_OUT_STEP 0
#define PROG_OUT_TRIANGLE 1
//最大循环次数
#define CIRCULATIONS_MAX 10
//CONFIG1
@ -25,6 +30,14 @@
#define CONF2_FALLING_PERCENT 6
#define CONF2_PERIOD 7
typedef enum
{
PROGOUT_WAITING = 0,
PROGOUT_START,
PROGOUT_RUNNING,
PROGOUT_END
}PROGRAM_OUT_PROCESS;
typedef struct
{
uint8_t output_unit;
@ -37,6 +50,11 @@ typedef struct
uint8_t rising_percent;
uint8_t falling_percent;
uint16_t period;
PROGRAM_OUT_PROCESS process;
int16_t out_max;
int16_t out_min;
uint8_t out_percent; //当前输出百分比
}PROGRAM_OUT_DATA;
extern PROGRAM_OUT_DATA progout_data;
@ -66,4 +84,16 @@ void text_update_conf2(uint8_t con);
//修改config2右列值
void val_modify_conf2(int8_t step);
//执行编程输出流程
void program_out_run(void);
//执行编程输出,阶跃
void program_out_step(void);
//执行编程输出,三角波
void program_out_triangle(void);
//百分比转化为数值输出, perc:[0, 100]
void percent2val_out(float32 perc);
#endif

View File

@ -13,6 +13,8 @@ extern int twk_1000ms_flag;
extern int twk_1000ms_cnt;
extern int input_500ms_flag;
extern uint16_t sig2slave_current_tick;
extern uint8_t progout_tick_flag;
extern int progout_tick;
void duty_tim3(void);
void duty_tim6(void);

View File

@ -54,13 +54,6 @@ void main_data_init(void)
//绘图数据初始化
plot_data_init();
#if NIXIE_CUBE_ENABLE
menu_data.twk_flag = 0; //0停止闪烁1开始闪烁
menu_data.twk_flip = 0; //0显示1不显示
menu_data.twk_cnt = 0; //闪烁计数
#endif
}
//绘图数据初始化
@ -260,13 +253,6 @@ void scr_main_run(void)
//当前输入值/测量值显示
input_value_show(); //500ms
#if NIXIE_CUBE_ENABLE
//数值闪烁
num_twinkle(); //1000ms
#endif
}
#if EEPROM_MONITOR_ENABLE
@ -438,7 +424,7 @@ void set_nixie_cube_sign(uint8_t on2off, uint8_t sg)
{
case 0:
{
//熄灭负号
//熄灭显示NULL
menu_data.sign_flag_in = 0;
lv_img_set_src(guider_ui.screen_main_ani_in_sign, screen_main_ani_in_sign_imgs[0]);
}
@ -446,12 +432,18 @@ void set_nixie_cube_sign(uint8_t on2off, uint8_t sg)
case 1:
{
//显示负号
//显示减号(负)
menu_data.sign_flag_in = 1;
lv_img_set_src(guider_ui.screen_main_ani_in_sign, screen_main_ani_in_sign_imgs[1]);
}
break;
case 2:
{
//显示加号(正)
lv_img_set_src(guider_ui.screen_main_ani_in_sign, screen_main_ani_in_sign_imgs[2]);
}
default:
break;
}
@ -489,7 +481,9 @@ void set_nixie_cube_sign(uint8_t on2off, uint8_t sg)
}
}
//设置数码管显示值io_slc-输入/输出pos-第几个数字(99代表全部)num->(可正可负)实际数值
uint8_t input_overflow_flag = 0;
void set_nixie_cube(uint8_t io_slc, uint8_t pos, int32_t num)
{
switch (io_slc)
@ -511,6 +505,8 @@ void set_nixie_cube(uint8_t io_slc, uint8_t pos, int32_t num)
set_nixie_cube_sign(IO_INPUT, 0);
}
if(input_overflow_flag == 1) set_nixie_cube_sign(IO_INPUT, 2);
//负数转正数
num = ( num >= 0 )?(num):(0 - num);
@ -792,16 +788,16 @@ void input_value_show(void)
//获取输入值
pltdata.yreal_scd_value = mux2real(mux_signal.data_pv);
if( MY_ABS(pltdata.yreal_scd_value - pltdata.yreal_scd_value_prv) < (float32)0.01)
{
//变化值过小的情况下不更新显示内容
return;
}
else
{
//记录前一时刻的值,用于计算变化量
pltdata.yreal_scd_value_prv = pltdata.yreal_scd_value;
}
// if( MY_ABS(pltdata.yreal_scd_value - pltdata.yreal_scd_value_prv) < (float32)0.01)
// {
// //变化值过小的情况下不更新显示内容
// return;
// }
// else
// {
// //记录前一时刻的值,用于计算变化量
// pltdata.yreal_scd_value_prv = pltdata.yreal_scd_value;
// }
int32_t pvi = 0;
@ -809,14 +805,17 @@ void input_value_show(void)
if(pltdata.yreal_scd_value >= pltdata.yreal_scd_up)
{
pvi = pltdata.yreal_scd_up*1000;
input_overflow_flag = 1;
}
else if (pltdata.yreal_scd_value <= pltdata.yreal_scd_low)
{
pvi = pltdata.yreal_scd_low*1000;
input_overflow_flag = 1;
}
else
{
pvi = (int32_t)(pltdata.yreal_scd_value*1000); //副轴用于绘制实时输入测量值
input_overflow_flag = 0;
}
set_nixie_cube(IO_INPUT, 99, pvi);
@ -953,51 +952,6 @@ void scr_main_chart_update(void)
set_obj_color(guider_ui.screen_main_label_area_OUT, tabdata.item1_page0_color_output);
}
#if NIXIE_CUBE_ENABLE
//数值闪烁
void num_twinkle(void)
{
if(menu_data.twk_flag == 0)
{
//不需要闪烁的情况下直接返回
//防止空白残留
set_nixie_cube(IO_OUTPUT, menu_data.io_cursor, menu_data.o_numbers[ menu_data.io_cursor ]);
return;
}
else
{
if(twk_1000ms_flag)
{
twk_1000ms_flag = 0;
//闪烁指定位置 menu_data.io_cursor
if(menu_data.twk_flip)
{
set_nixie_cube(IO_OUTPUT, menu_data.io_cursor, menu_data.o_numbers[ menu_data.io_cursor ]);
menu_data.twk_flip = 0;
}else
{
set_nixie_cube(IO_OUTPUT, menu_data.io_cursor, 10);
menu_data.twk_flip = 1;
}
menu_data.twk_cnt++;
}
}
if(menu_data.twk_cnt > TWINKLE_CNT_MAX) // TWINKLE_CNT_MAX秒无动作上、下、左、右无按下后停止闪烁
{
menu_data.twk_cnt = 0;
menu_data.twk_flip = 0;
menu_data.twk_flag = 0;
menu_data.io_cursor_prv = menu_data.io_cursor;
//防止空白残留
set_nixie_cube(IO_OUTPUT, menu_data.io_cursor, menu_data.o_numbers[ menu_data.io_cursor ]);
}
}
#endif
//实时曲线绘制
//将实际值线性转换成绘图值
void plot_drawing(void)
@ -1009,9 +963,9 @@ void plot_drawing(void)
//输出曲线
//{
//将独立数字转换成实际值
if(mux_signal.data_sv == 0)
if( (current_operation == PROG_OUT_PROCESSING)||(menu_data.io_on2off == IO_OFF) )
{
pltdata.yreal_pri_value = 0;
pltdata.yreal_pri_value = mux_signal.data_sv;
}
else
{
@ -1025,7 +979,7 @@ void plot_drawing(void)
pltdata.y_pri_value = ( pltdata.y_pri_up - pltdata.y_pri_low ) * \
( pltdata.yreal_pri_value - pltdata.yreal_pri_low ) / ( pltdata.yreal_pri_up - pltdata.yreal_pri_low );
if( MY_ABS(pltdata.y_pri_value - pltdata.y_pri_value_prv) < 1 )
if( MY_ABS(pltdata.y_pri_value - pltdata.y_pri_value_prv) < 0.5 )
{
//变化幅度小的情况下不更新显示值
//等待一段时间后不再更新
@ -1062,7 +1016,7 @@ void plot_drawing(void)
pltdata.y_scd_value = ( pltdata.y_scd_up - pltdata.y_scd_low ) * \
( pltdata.yreal_scd_value - pltdata.yreal_scd_low ) / ( pltdata.yreal_scd_up - pltdata.yreal_scd_low );
if( MY_ABS(pltdata.y_scd_value - pltdata.y_scd_value_prv) < 1 )
if( MY_ABS(pltdata.y_scd_value - pltdata.y_scd_value_prv) < 0.5 )
{
//变化幅度小的情况下不更新显示值
//等待一段时间后不再更新
@ -1151,14 +1105,6 @@ void set_working_mode(SIG_FUNCTIONS mode, SIG_FUNCTIONS_TYPE type)
menu_data.io_cursor_prv = 3;
set_cursor_position();
#if NIXIE_CUBE_ENABLE
//闪烁参数清零
menu_data.twk_flag = 0; //闪烁中止
menu_data.twk_cnt = 0; //闪烁计数清零
menu_data.twk_flip = 0; //0显示1不显示
#endif
switch (mode)
{
//电压

View File

@ -604,13 +604,6 @@ void scr_setting_run(void) //详细设置界面
//处理复位事件
deal_data_reset();
if(tabdata.modbus_master_send_flag == 1)
{
tabdata.modbus_master_send_flag = 0;
modbus_rtu_master_load();
modbus_rtu_master_send();
}
}
//执行保存功能

View File

@ -395,6 +395,8 @@ void sig_channel_select(uint8_t io, SIG_FUNCTIONS_TYPE type)
//更新设定值根据ON\OFF状态
void sig_sv_update(void)
{
if(progout_data.process == PROGOUT_WAITING)
{
switch (menu_data.io_on2off)
{
case IO_ON:
@ -412,6 +414,14 @@ void sig_sv_update(void)
default:
break;
}
}
else
{
if(menu_data.io_on2off == IO_ON)
{
program_out_run();
}
}
}
//数据转换,将输入热电偶电压值转换为实际温度值℃

View File

@ -369,17 +369,36 @@ void key_config_update(OPERATIONS ope)
case PROG_OUT_CONFIG_2:
{
//使能上、下、左、右、确认OK、返回
//使能上、下、左、右、确认OK、返回、OUT
key_config(KEY_UP, KEY_STATUS_ENABLE);
key_config(KEY_DOWN, KEY_STATUS_ENABLE);
key_config(KEY_LEFT, KEY_STATUS_ENABLE);
key_config(KEY_RIGHT, KEY_STATUS_ENABLE);
key_config(KEY_OK, KEY_STATUS_ENABLE);
key_config(KEY_BACK, KEY_STATUS_ENABLE);
key_config(KEY_OUT, KEY_STATUS_ENABLE);
//不使能其他按键
key_config(KEY_IN, KEY_STATUS_DISABLE);
key_config(KEY_SOURCE, KEY_STATUS_DISABLE);
key_config(KEY_MENU, KEY_STATUS_DISABLE);
key_config(KEY_SWITCH, KEY_STATUS_DISABLE);
}
break;
case PROG_OUT_PROCESSING:
{
//使能确认OK、返回
key_config(KEY_OK, KEY_STATUS_ENABLE);
key_config(KEY_BACK, KEY_STATUS_ENABLE);
//不使能其他按键
key_config(KEY_UP, KEY_STATUS_DISABLE);
key_config(KEY_DOWN, KEY_STATUS_DISABLE);
key_config(KEY_LEFT, KEY_STATUS_DISABLE);
key_config(KEY_RIGHT, KEY_STATUS_DISABLE);
key_config(KEY_OUT, KEY_STATUS_DISABLE);
key_config(KEY_IN, KEY_STATUS_DISABLE);
key_config(KEY_SOURCE, KEY_STATUS_DISABLE);
key_config(KEY_MENU, KEY_STATUS_DISABLE);
key_config(KEY_SWITCH, KEY_STATUS_DISABLE);

View File

@ -89,10 +89,6 @@ void key_functions_main(void)
return;
}
#if NIXIE_CUBE_ENABLE
menu_data.twk_flag = 1; // 上、下、左、右 任意一个键按下后,闪烁开始
menu_data.twk_cnt = 0; //每次按下后闪烁计数清零
#endif
keyset_output(1);
}
break;
@ -196,13 +192,6 @@ void key_functions_main(void)
return;
}
#if NIXIE_CUBE_ENABLE
// menu_data.twk_flag = 1; //上、下、左、右 任意一个键按下后,闪烁开始
// menu_data.twk_cnt = 0; //每次按下后闪烁计数清零
//避免游标移动的瞬间,前一刻的数值处于闪烁熄灭的状态,移动游标前重新显示一次当前数值
set_nixie_cube(IO_OUTPUT, menu_data.io_cursor, menu_data.o_numbers[menu_data.io_cursor]);
#endif
menu_data.io_cursor_prv = menu_data.io_cursor;
menu_data.io_cursor = (menu_data.io_cursor <= 0)?(6):(menu_data.io_cursor - 1);
set_cursor_position();
@ -219,10 +208,16 @@ void key_functions_main(void)
if(menu_data.io_on2off == IO_ON)
{
menu_data.io_on2off = IO_OFF;
//编程输出时暂停计数
if(current_operation == PROG_OUT_PROCESSING) progout_tick_flag = 0;
}
else
{
menu_data.io_on2off = IO_ON;
//编程输出时继续计数
if(current_operation == PROG_OUT_PROCESSING) progout_tick_flag = 1;
}
io_on2off_status(); //更新ON/OFF/IN/OUT状态指示
@ -238,13 +233,6 @@ void key_functions_main(void)
return;
}
#if NIXIE_CUBE_ENABLE
menu_data.twk_flag = 1; // 上、下、左、右 任意一个键按下后,闪烁开始
menu_data.twk_cnt = 0; //每次按下后闪烁计数清零
//避免游标移动的瞬间,前一刻的数值处于闪烁熄灭的状态,移动游标前重新显示一次当前数值
set_nixie_cube(IO_OUTPUT, menu_data.io_cursor, menu_data.o_numbers[menu_data.io_cursor]);
#endif
menu_data.io_cursor_prv = menu_data.io_cursor;
menu_data.io_cursor = (menu_data.io_cursor >= 6)?(0):(menu_data.io_cursor + 1);
set_cursor_position();
@ -397,19 +385,19 @@ void key_functions_main(void)
return;
}
#if NIXIE_CUBE_ENABLE
menu_data.twk_flag = 1; // 上、下、左、右 任意一个键按下后,闪烁开始
menu_data.twk_cnt = 0; //每次按下后闪烁计数清零
#endif
keyset_output(-1);
}
break;
case KEY_BACK: //闲置,预留
case KEY_BACK:
{
key = 0;
key_char2struct();
if(current_operation == PROG_OUT_PROCESSING)
{
progout_data.process = PROGOUT_END;
}
}
break;

View File

@ -988,8 +988,71 @@ void key_functions_setting(void)
}
break;
case KEY_OUT:
{
key = 0;
key_char2struct();
if( (current_operation == PROG_OUT_CONFIG_2)&&(tabdata.content_focus == 0) )
{
//熄灭游标
setting_contents_check(99, cursor_conf2);
//加载主界面
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;
//当前操作切换至“编程输出执行”,按键配置同步更新
current_operation = PROG_OUT_PROCESSING;
key_config_update(current_operation);
progout_data.process = PROGOUT_START;
switch (progout_data.output_unit)
{
case PROG_OUT_V:
{
sig_channel_select(IO_OUTPUT, VOLTAGE_V);
mux_signal.data_sv = 0;
progout_data.out_min = tabdata.item0_page0_vlow[0];
progout_data.out_max = tabdata.item0_page0_vup[0];
}
break;
case PROG_OUT_MA:
{
sig_channel_select(IO_OUTPUT, CURRENT_MA);
mux_signal.data_sv = 0;
progout_data.out_min = tabdata.item0_page0_clow;
progout_data.out_max = tabdata.item0_page0_cup;
}
break;
default:
break;
}
menu_data.io_on2off = IO_ON;
io_on2off_status();
}
}
break;
case KEY_NONE:
{
key = 0;
key_char2struct();
}
default:

View File

@ -530,4 +530,154 @@ void val_modify_conf2(int8_t step)
}
}
void program_out_run(void)
{
switch (progout_data.output_mode)
{
case PROG_OUT_STEP:
{
program_out_step();
}
break;
case PROG_OUT_TRIANGLE:
{
program_out_triangle();
}
break;
default:
break;
}
}
void percent2val_out(float32 perc)
{
if( (perc < 0)||(perc > 100) ) return;
mux_signal.data_sv = perc / (float32)100 * (progout_data.out_max - progout_data.out_min) + progout_data.out_min;
set_output(mux_signal.data_sv);
}
int8_t step_dir = 0;
uint8_t cir_times = 0;
void program_out_step(void)
{
switch (progout_data.process)
{
case PROGOUT_START:
{
if( progout_tick_flag == 0 )
{
//计时开始
progout_tick_flag = 1;
progout_tick = 0;
progout_data.out_percent = progout_data.start_percent;
percent2val_out(progout_data.out_percent);
step_dir = 1;
}
else
{
//到达起点%后等待一段时间
if(progout_tick >= 5000)
{
//计时结束
progout_tick_flag = 0;
progout_tick = 0;
progout_data.process = PROGOUT_RUNNING;
}
}
}
break;
case PROGOUT_RUNNING:
{
if(progout_tick_flag == 0)
{
//计时开始
progout_tick_flag = 1;
progout_tick = 0;
progout_data.out_percent += step_dir * progout_data.step_percent;
if(progout_data.out_percent <= progout_data.start_percent)
{
//向下触底后本次循环结束
progout_data.out_percent = progout_data.start_percent;
step_dir = 1;
cir_times++;
if( progout_data.circulations < 11 )
{
//循环次数达到目标后,跳转至终止步骤
if(cir_times >= progout_data.circulations) progout_data.process = PROGOUT_END;
}
else
{
//无限循环
cir_times = 0;
}
}
else if(progout_data.out_percent >= progout_data.end_percent)
{
//向上触顶后反向
progout_data.out_percent = progout_data.end_percent;
step_dir = -1;
}
percent2val_out(progout_data.out_percent);
}
else
{
if( progout_tick > progout_data.hold_time )
{
//计时结束
progout_tick_flag = 0;
progout_tick = 0;
}
}
}
break;
case PROGOUT_END:
{
step_dir = 0;
cir_times = 0;
menu_data.io_on2off = IO_OFF;
mux_signal.data_sv = 0;
//加载菜单界面
lv_scr_load(guider_ui.screen_setting);
scr_setting_recover();
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; //当前界面为详细设置菜单
tabdata.item_cursor_prv = ITEM_0;
tabdata.item_cursor = ITEM_2;
setting_items_check(tabdata.item_cursor, tabdata.item_cursor_prv);
//返回config2界面
program_out_config2();
current_operation = PROG_OUT_CONFIG_2;
key_config_update(current_operation);
progout_data.process = PROGOUT_WAITING;
}
break;
default:
break;
}
}
void program_out_triangle(void)
{}

View File

@ -10,13 +10,13 @@ int twk_1000ms_flag = 0;
int twk_1000ms_cnt = 0;
int input_500ms_flag = 0;
int input_500ms_cnt = 0;
uint16_t sig2slave_previous_tick = 0;
uint16_t sig2slave_current_tick = 0;
uint8_t progout_tick_flag = 0;
int progout_tick = 0;
void duty_tim3(void)
{
freq_signal.over_cnt++;
}
void duty_tim6(void)
@ -58,6 +58,11 @@ void duty_tim6(void)
input_500ms_flag = 1;
}
if(progout_tick_flag == 1)
{
progout_tick++;
}
//发送完成 或者 已经接收到一部分数据之后开始计时
if( (sig2slave_step == 1)||(mod_master.tx_flag == TX_OK) )
{

File diff suppressed because it is too large Load Diff