📄 hzmmimain18.c
字号:
#define __main__
#include "hzmmi18.h"
//-------------- CONSTANTS -----------------------//
#define ALM_NUMBER 3 //与CPU板通讯失败告警前失败的次数
#define TOTAL_CPU_NUMBER 6 //最大cpu个数
#define MAX_LON_BUF 7 //LON网输入缓冲区大小,必须是2的n次方减1
#define MAX_NV_O 27 //LON网络输出变量数据区长度
#define MAX_NV_I 26 //LON网络输入变量数据区长度
#define COM_TIMEOUT 1200 //与CPU板通讯时限
#define LON_WAITTIME 2000 //等待LON网应答时限
#define POLL_PERIOD 500; //每500ms轮巡各CPU板
#define PC_DETECT 180; //与pc机通讯状态空置时间
#define CYCLE_PERIOD 3; //每3s报告滚屏
//--------------- FUNCTION PROTOTYPES ----------------//
byte EEPROMread(word location);
byte EEPROMwrite(word location,byte byte);
byte net_send(byte,byte,byte,byte,byte,byte,byte *);
void event_routine(void);
void comm_with_lon(void);
void reset_routine(void);
void trigger_routine(void);
void poll_timer_routine(void);
void nv_update_routine(void);
void key_routine(void);
void clock_timer_routine(void);
void cycle_timer_routine(void);
byte get_clock_setting(byte item,byte *tm_str,byte);
byte lb_set(void);
void set_time(void);
byte display_menu(const byte*);
void rpt_ram_clr(void);
void ram_save(byte,byte);
void eep_save(byte,byte);
void alarm (void);
void send_time (void);
void init_disp(void);
void set_cursor_position(byte,byte,const byte *);
byte get_key (void);
void poll_rcv(byte);
word com_rcv(byte);
void disp_prt(byte rol);
void disp_wait(byte rol);
void set_quit(void);
void net_rst(void);
void LCD_display(byte,byte);
byte fun_key_idx(byte);
byte sel_idx(byte,byte);
byte sel_idx2(byte,byte,byte,byte);
byte sel_data_idx(byte,byte);
byte sel_setting_idx(byte,byte);
byte setting_process(byte *,word);
byte send_setting(byte*,word);
void net_out(byte);
byte cpu_nmb(void);
byte select_menu(const byte*);
byte sf_hidden_code(void);
byte ts_hidden_code(void);
byte hidden_code(void);
byte rmtc_op(byte,byte);
void ans_nva(byte);
byte anx_menu(byte*,byte,byte);
void press_rst_key(void);
void out_rst24(void);
void poll_clr(void);
byte net_wait(void);
byte pointer1(void);
byte pointer3(byte);
void report_time_lock(void);
void eep_ram(void);
int FindString(const DaiMa *,char *);
void DZBchinese(char *,byte,byte);
void deskchinese(byte);
void floatchinese(char *,byte,byte);
byte reportchinese(byte,byte);
void prt_set(void);
void tran_rpt(void);
void clr_CYCLE_FLAG(void);
byte WORK_SETTING_AREA; //当前定值区标记数(标记符)
byte TOTAL_SETTING_AREA; //最大定值区号
word work_mode; //工作模式。不同装置的不同处理,由此区分。
byte clz_order; //零漂刻度新命令下达标志
word clz_old; //零漂刻度当前指针
word clz_di; //零漂刻度开入指针,其后的刻度选项特别处理
word clz_bzd; //零漂刻度对点指针,UP,DOWN键选择时越过去
word clz_prt; //零漂刻度打印指针,UP,DOWN键选择时越过去
word clz_total; //零漂刻度总数指针
word clz_total_num; //零漂刻度总数
byte sampleCPU; //装置启动后,主动上送采样值的CPU板号
byte CPU_ID; //cpu点名标示位
byte poll_seq; //cpu点名序号
byte cpu_name; //菜单选择的cpu板序号
byte cpu_set_flag; //cpu定值修改标志
byte STATUS_WORD; //桌面显示所处的状态:0,循环显示;1,零漂刻度;2,对点;3,4,准备接收报告
byte PC_QUIT; //KEY_QUIT标记,PC通讯标记
word waiting; //关注时的等待时间
word rcv_cnt; //收到的字符长度
word s_count;
byte ram_ptr,eep_ptr,cycle_ptr,head_line,frist_line;//与报告相关的指针
byte RPT_TIME[18]; //报告时间暂存
byte Q_KEY[7]; //各cpu板响应KEY_QUIT的纪录
byte ATTENTION,PT_RST,CYCLE_FLAG;//关注标志,不应期标志,循环标志
int S_EEP; //当前显示的报告位于EEPROM中的位置
byte rpt_ram_buf[MAX_REPORT_RAM+16];//ram报告缓冲区
byte NV_ram_buf[MAX_NV_O+4]; //网络数据缓冲区
byte yb_bgn; //各cpu板软压板名在数组中的位置
byte GPS_en; //GPS的工作方式及当前状态
byte net_err; //LON网芯片状态
extern byte time_str[]; //当前时间串
extern word mstimer2; //时间串后的毫秒数值
extern word ms_val; //GPS脉宽
typedef struct {
byte lenth; //长度
byte o_node_addr; //目标地址
byte s_node_addr; //源地址
byte code; //代码
byte data[MAX_NV_O]; //数据
}NV_def1;
typedef struct {
byte lenth;
byte o_node_addr;
byte s_node_addr;
byte code;
byte data[MAX_NV_I];
byte asfdjk1; //防治出错附加的预留
byte asfdjk2; //防治出错附加的预留
}NV_def2;
byte ALM_WORD_att; //告警状态字
byte menu_in; //进入主菜单标记
byte time_setting; //正在修改时间标记
NV_def2 nv_c;
NV_def2 nv_cb[MAX_LON_BUF+1]; //临时网络缓冲区
byte endpoint; //临时网络缓冲区尾指针
byte bgnpoint; //临时网络缓冲区头指针
#define eep_sbxh 0x0000 //0x0000,设备选型
#define eep_GPS 0x0001 //0x0001,GPS工作方式
#define eep_test 0x0002 //0x0002,面板测试设定
#define eep_node_id 0x0003 //0x0003,装置地址
#define eep_CPU_NUB 0x0004 //0x0004--0x000b//[8],CPU板投退
#define eep_COMERR_CNT 0x000c //0x000c--0x0013//[7],与CPU通讯出错次数纪录
#define eep_lb_r 0x0014 //0x0014,录波报告出处
#define eep_lb_d 0x0015 //0x0015,录波报告数据类型
#define eep_lb_u 0x0016 //0x0016,录波报告电压比例
#define eep_lb_i 0x0017 //0x0017,录波报告电流比例
#define eep_rpt_buf 0x0020 //0x0020--0x0fff//[MAX_REPORT_EEP=4064]
#define eep_rpt_inc(x) {if((x)>=(MAX_REPORT_EEP/17-1))x=0;else x++;}
#define eep_rpt_dec(x) {if((x)==0)x=(MAX_REPORT_EEP/17-1);else x--;}
#define value_inc(value,min,max) {if((value)<(max))value++;else value=min;}
#define value_dec(value,min,max) {if((value)>(min))value--;else value=max;}
void ram_ptr_inc(void);
byte trigger; //100
word poll_timer; //500
byte cycle_timer; //3
byte trigger_t; //100
word poll_timer_t; //500
byte cycle_timer_t; //3
byte trigger_f;
byte poll_timer_f;
byte clock_timer_f;
byte cycle_timer_f;
word wait_synch_timer; //250,1700
word synch_timer; //250,1700
word comm_timer; //6000
word detect_timer; //180
byte lamp_last_timer; //200
byte key_timer; //30
byte ATTENTION_timer; //60
byte keep_timer; //36,18
byte desk_pause; //10
void disp_face(void);
void test_face(void);
//主程序调用了上电复位进程,键盘进程,事件进程;
void main(void)
{
reset_routine();
if(EEPROMread(eep_test)=='t')
test_face();
else
disp_face();
for(;;)
{
key_routine();
event_routine();
}
}
//MMI程序校验子程序
word chk_prg_sum(void)
{
byte tmp;
word sum,j;
sum=0; //sum=r16r17
tmp=RAMPZ;
asm("push R0");
asm("mov R30,R16"); //sum=R16R17,z=sum
asm("mov R31,R17");
for(j=0x8000;j!=0;j--)//前64KROM
{
asm("lpm"); //r0=(z)
asm("eor R16,R0"); //sum=sum^(j)
asm("subi R30,255");//z=z+1
asm("sbci R31,255");
asm("lpm"); //r0=(z)
asm("eor R17,R0"); //sum=sum^(j)
asm("subi R30,255");//z=z+1
asm("sbci R31,255");
}
RAMPZ=1;
for(j=0x8000;j!=0;j--)//后64KROM
{
asm("elpm"); //r0=(z)
asm("eor R16,R0"); //sum=sum^(j)
asm("subi R30,255");//z=z+1
asm("sbci R31,255");
asm("elpm"); //r0=(z)
asm("eor R17,R0"); //sum=sum^(j)
asm("subi R30,255");//z=z+1
asm("sbci R31,255");
}
asm("pop R0");//恢复R0
RAMPZ=tmp;
return sum;
}
//事件进程中包含了时钟进程,poll事件进程,trigger事件进程,网络处理事件进程
//报告滚屏显示进程;
void event_routine(void)
{
{
comm_with_lon();
if(cycle_timer_f!=FALSE) //每3s钟滚屏显示从MMI或cpu来的报告;
{
cycle_timer_f=FALSE;
cycle_timer_routine();
}
if(clock_timer_f!=FALSE) //1秒钟刷新一次时间
{
clock_timer_f=FALSE;
clock_timer_routine();
}
if(poll_timer_f!=FALSE) //500ms轮巡一次主cpu送上来的数据;
if(poll_com!=1)
{
poll_timer_f=FALSE;
poll_timer_routine();
}
if(trigger_f!=FALSE) //100ms钟查循一次主cpu送上来的故障信息;
{
trigger_f=FALSE;
trigger_routine();
}
if(nv_update!=FALSE) //网络发来数据
{
nv_update=FALSE;
nv_update_routine();
}
}
}
void init(void);
void init_disp(void);
void init_net(void);
void disp_time(byte);
void dlyms(word);
char *cstrcpy(char *dst,const char *src);
void memcpy_e(byte *d,byte *s,byte num);
void time_str_wr(char *tm_str);
void com_byte(char );
void application_restart(void);
void cls(void);
void disp_GPS(void);
void mediacy_hz(byte,byte*);
void str_hz(byte,byte,byte*);
void str_sasc(byte,byte,byte*);
void com_snd(byte *,word);
int csprintf(char *buf, const char *fmt,...);
void sscanf(char *,char *,unsigned short *);
void LCD_display(byte,byte);
void net_bgn(void);
void net_end(void);
byte net_read(void);
void net_handshake(void);
void net_write(byte);
const char* cstrchr(const char *str,char chr);
void cmemcpy(char *der,const char *ser,unsigned short len);
byte time_sec_rd(void);
extern word ms_val;
const byte *face_str;
//开始运行时的脸面
void disp_face(void)
{
byte i;
menu_in=TRUE;
rebgn:
cstrcpy(disp_buffer,"欢迎您使用");
cls();
mediacy_hz(0,disp_buffer);
if(face_str[0]&&face_str)
cstrcpy(disp_buffer,face_str);
else
cstrcpy(disp_buffer,"四方装置汉化面板");
mediacy_hz(24,disp_buffer);
cstrcpy(disp_buffer,"装置:");
cstrcpy(disp_buffer+strlen(disp_buffer),sbxh[EEPROMread(eep_sbxh)].AscCode);
mediacy_hz(48,disp_buffer);
key_timer=3;
i=get_key();//按任意键退出
cls();
menu_in=FALSE;
GPS_en=EEPROMread(eep_GPS);
return;
}
/*面板的烤机测试
要求硬件作如下配合:连接+5V,+12V,+24V电源;UPTX与UPRX相连;TXD与RXD相连;
/RST-SIGNALS与/ATTENTION、DZ1、DZ2相连;/ALARM2与DZ3、DN1、DN2相连。*/
const CSTR err_str[]=
{"net ","com ","txd ","rst ","dz1 ","dz2 ","dz3 ","dn1 ","dn2 ","att "};
void test_face(void)
{
byte i;
word tmp;
word err_code,err_sum;
word net_tm;
if((time_str[5]==0)&&(time_str[4]==0x12)&&(time_str[3]<10))
if(EEPROMread(eep_test)!='t')
EEPROMwrite(eep_test,'t');
PORTD&=~(RUN_LAMP|ALARM2);
PORTD|=RST_SIGN;
err_sum=0;
net_tm=s_count;
cls();
i=0;
for(;;)
{
if((time_str[5]==0)&&(time_str[4]==0x12)&&(time_str[3]<10))
;
else
{
EEPROMwrite(eep_test,0xff);
application_restart();
}
Q_KEY[1]=0;
CYCLE_FLAG=TRUE;
key_routine();
if(Q_KEY[1]==0xaa)
{
PORTD&=~(RUN_LAMP|ALARM2);
PORTD|=RST_SIGN;
key_timer=10;
menu_in=TRUE;
time_setting=TRUE;
if(ts_hidden_code()!=FALSE)
{
EEPROMwrite(eep_test,0xff);
application_restart();
}
cls();
time_setting=FALSE;
menu_in=FALSE;
err_sum=0;
}
GPS_en=0;
comm_with_lon();
if(nv_update!=FALSE)
{ //网络发来数据
nv_update=FALSE;
net_tm=s_count;
if(nv_c.code==0x3f)
err_code=err_sum=0;
else
if(nv_c.code==0x3d)
nv_update_routine();
}
i++;
if(clock_timer_f!=FALSE) //1秒钟刷新一次时间
{
PORTD^=RUN_LAMP;
cstrcpy(disp_buffer,"欢迎您测试");
mediacy_hz(1*16,disp_buffer);
if(face_str[0]&&face_str)
cstrcpy(disp_buffer,face_str);
else
cstrcpy(disp_buffer,"四方装置汉化面板");
mediacy_hz(2*16,disp_buffer);
err_code=0;
if((s_count-net_tm)>200)//网络通讯检测
err_code|=0x0200;
if(i==0xff)
i=0;
if((com_rcv(i)==0)||((i|CPU_ID)!=commu_buf[0]))//串口通讯检测
err_code|=0x0100;
PORTB^=TXD1;
dlyms(5);
if((!(PINB&RXD1))!=(!(PORTB&TXD1)))
err_code|=0x080;
PORTD^=RST_SIGN;
dlyms(5);
if((!(PINF&ATTN))!=(!(PORTD&RST_SIGN)))
err_code|=0x040;
if((!(PINF&RST_24))!=(!(PORTD&RST_SIGN)))
err_code|=0x020;
if((!(PIND&DZ1))!=(!(PORTD&RST_SIGN)))
err_code|=0x010;
if((!(PIND&DZ2))!=(!(PORTD&RST_SIGN)))
err_code|=0x008;
PORTD^=ALARM2;
dlyms(5);
if((!(PIND&DZ3))!=(!(PORTD&ALARM2)))
err_code|=0x004;
if((!(PIND&DN1))!=(!(PORTD&ALARM2)))
err_code|=0x002;
if((!(PIND&DN2))!=(!(PORTD&ALARM2)))
err_code|=0x001;
if(((EEPROMread(eep_node_id)&0xf0)>0x50)
||((EEPROMread(eep_node_id)&0x0f)>0x09))
EEPROMwrite(eep_node_id,time_str[0]);
err_sum|=err_code;
ctl_data^=LCD_LED;
if(err_sum==0)
{
cstrcpy(disp_buffer,"本面板工作正常");
mediacy_hz(3*16,disp_buffer);
memset(disp_buffer,' ',40);
disp_buffer[40]=0;
str_sasc(4*16,0,disp_buffer);
}
else
{
cstrcpy(disp_buffer,"本面板有错误:");
mediacy_hz(3*16,disp_buffer);
disp_buffer[0]=0;
tmp=err_sum;
for(i=0;i<10;i++)
{
if(tmp&0x0200)
{
cstrcpy(disp_buffer1,err_str[i].str);
strcat(disp_buffer,disp_buffer1);
}
tmp<<=1;
}
memset(disp_buffer1,' ',40);
disp_buffer1[40]=0;
strcat(disp_buffer,disp_buffer1);
disp_buffer[40]=0;
str_sasc(4*16,0,disp_buffer);
}
clock_timer_f=FALSE;
clock_timer_routine();
if(time_str[0]==EEPROMread(eep_node_id))
if((time_str[1]^EEPROMread(eep_node_id))&1)
{
NV_ram_buf[0]=0x09;
NV_ram_buf[1]=0x0f;
NV_ram_buf[2]=EEPROMread(eep_node_id);
NV_ram_buf[3]=0x30;
NV_ram_buf[4]=0x07;
NV_ram_buf[5]=0x01;
NV_ram_buf[6]=err_code;
NV_ram_buf[7]=err_code/256;
NV_ram_buf[8]=err_sum;
NV_ram_buf[9]=err_sum/256;
net_out(1);
}
else
{
NV_ram_buf[0]=0x0a;
NV_ram_buf[1]=0x0f;
NV_ram_buf[2]=EEPROMread(eep_node_id);
NV_ram_buf[3]=0x30;
NV_ram_buf[4]=0x07;
NV_ram_buf[5]=0x01;
NV_ram_buf[6]=err_code;
NV_ram_buf[7]=err_code/256;
NV_ram_buf[8]=err_sum;
NV_ram_buf[9]=err_sum/256;
NV_ram_buf[10]=0xff;
net_out(2);
}
}
}
return;
}
//初始化进程,完成液晶,网络的初始化,修正eeprom中不合理的数值
void reset_routine(void)
{
byte i;
init(); //对控制输出口的初始化;
PORTD&=~RUN_LAMP;
ctl_data|=LCD_LED;
menu_in=TRUE;
init_disp(); //对液晶显示的初始化;
menu_in=FALSE;
init_net(); //对网络的初始化
bgnpoint=0;
endpoint=0;
time_setting=FALSE;
ATTENTION=FALSE;
PT_RST=CYCLE_FLAG=FALSE;
S_EEP=0;
rpt_ram_clr();
poll_timer=POLL_PERIOD;
cycle_timer=CYCLE_PERIOD;
cpu_set_flag=FALSE;
trigger=100;
GPS_en=0;
if(EEPROMread(eep_GPS)>2)
EEPROMwrite(eep_GPS,2);
for(i=0;i<TOTAL_SB_NUMBER;i++)
if(sbxh[i].AscCode==0)
break;
if(EEPROMread(eep_sbxh)>=i)
EEPROMwrite(eep_sbxh,0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -