📄 hzmmimain18.c
字号:
if(nv_c.code==0x23)
{//召唤MMI数据命令
if(nv_c.data[0]==0x06)
{//召唤MMI版本号
NV_ram_buf[1]=nv_c.s_node_addr & 0x0f;
NV_ram_buf[2]=EEPROMread(eep_node_id);
NV_ram_buf[3]=0x32;
csprintf(&NV_ram_buf[4],VERSION2,TYPE_CODE);
i=strlen(&NV_ram_buf[4]);
NV_ram_buf[0]=i+4+2;
NV_ram_buf[5+i]=0x0d;
NV_ram_buf[6+i]=0x0a;
net_out(1);
}
else
if(nv_c.data[0]==0x05)
{//调取MMI中报告
if(pointer1()==FALSE)
{//MMI没有报告
ans_nva(0x16);
return;
}
temp1=eep_ptr;//结尾
if(pointer3(1)==FALSE)
{//MMI没有报告
ans_nva(0x16);
return;
}
temp2=eep_ptr;//最老的报告起点
eep_ptr=temp1;
if(pointer3(0)==FALSE)
{//MMI没有报告
ans_nva(0x16);
return;
}
temp3=eep_ptr;//最新的报告起点
if(temp1>temp2)
temp3=temp1-temp2;
else
temp3=(MAX_REPORT_EEP/17)-temp2+temp1;
if(temp3==1)
{//MMI只有一个报告
memcpy_e(disp_buffer1,(byte*)(0x4000+eep_rpt_buf+eep_ptr*17),16);
disp_buffer1[16]=0;
tran_rpt();
net_send(1,strlen(disp_buffer1),(nv_c.s_node_addr&0x0f),
0x32,2|0x80,0,disp_buffer1);
return;
}
RX_A:
disp_buffer1[0]=0;
eep_ptr=temp2;
temp1=(nv_c.s_node_addr&0x0f);
for(k=1;k<=temp3;k++)
{//从eeprom里取数据拷贝到网络缓冲区
memcpy_e(disp_buffer,(byte*)(0x4000+eep_rpt_buf+eep_ptr*17),16);
disp_buffer[16]=0;
strcat(disp_buffer1,disp_buffer);
if((EEPROMread(eep_rpt_buf+eep_ptr*17+16)==0x0a)
||(strlen(disp_buffer1)>=32)||(k==temp3))
{
key=(k==temp3)?0x32:0xb2;
tran_rpt();
net_send(1,strlen(disp_buffer1),temp1,key,2|0x80,0,disp_buffer1);
if(k==temp3)
{
net_send(0,0,0,0,0,0,0);
return;
}
disp_buffer1[0]=0;
key=net_wait();
if(key==0x03)
goto RX_A;
else
if(key!=0x02)
{
net_send(0,0,0,0,0,0,0);
return;
}
}
eep_rpt_inc(eep_ptr);
}
return;
}
}
}
}
void set_quit_key(void)
{
cstrcpy(disp_buffer,"按SET键确认\r 按QUIT键退出");
str_hz(3*16,2,disp_buffer);
}
//串口接收数据有效性判断
byte poll_good(void)
{
rcv_cnt=com_i;
if(rcv_cnt==0)
goto CPU_alm;
if(rcv_cnt==1) //只收到一个数
goto RECV;
if(chk_sum(rcv_cnt)!=0)
{//校验和不对
comm_timer=COM_TIMEOUT/6;//要求短时间内重发
rcv_cnt=com_rcv(0x03);
if(rcv_cnt==0)
goto CPU_alm;
if(rcv_cnt==1)
goto RECV;
if(chk_sum(rcv_cnt)!=0)
goto CPU_alm;
}
RECV://接收成功
if(EEPROMread(eep_COMERR_CNT+poll_seq)!=0)
{
if(EEPROMread(eep_COMERR_CNT+poll_seq)>=ALM_NUMBER)
init_disp();
EEPROMwrite(eep_COMERR_CNT+poll_seq,0);
}
return TRUE;
//没收到或两次接受的校验和都不对,则cpu板出错的次数加1,
//当所有的CPU板通讯出错次数达到最大次数时复位
CPU_alm:
if(EEPROMread(eep_COMERR_CNT+poll_seq)<ALM_NUMBER)
{
byte i;
EEPROMwrite(eep_COMERR_CNT+poll_seq,EEPROMread(eep_COMERR_CNT+poll_seq)+1);
for(i=1;i<=TOTAL_CPU_NUMBER;i++)
if((EEPROMread(eep_CPU_NUB+i))&&
(EEPROMread(eep_COMERR_CNT+i)<ALM_NUMBER))
break;
if(i>TOTAL_CPU_NUMBER)
application_restart();//所有的CPU板通讯出错次数达到最大次数时复位
return FALSE;
}
else
if(menu_in==FALSE)
{//如果cpu板通讯出错的次数大于允许值时则告警
csprintf(disp_buffer,"与CPU%d通信出错!",poll_seq);
mediacy_hz(2*16,disp_buffer);
}
alarm();
return FALSE;
}
void poll_out(void)
{
if(EEPROMread(eep_COMERR_CNT+poll_seq)>=ALM_NUMBER)
comm_timer=COM_TIMEOUT/3;//cpu板多次通讯不正常,则简短测试
else
comm_timer=COM_TIMEOUT;
poll_rcv(0x00);
return;
}
void poll_clr()
{
for(;poll_com==1;)
comm_with_lon();
poll_com=0;
}
//轮巡cpu板,对送上来的报文,根据报文的第一个字节决定是否显示、是否向网络转发
void poll_timer_routine (void)
{
byte i,j,key;
if((ctl_data&COM_SEL)!=COM_SEL)//如果与PC通讯则不轮巡
return;
if(poll_com==1)
return;
if(poll_com==2)
{
poll_com=0;
if(poll_good()!=FALSE)
goto deal_com;
else
return;
}
for(i=1,j=0;i<=TOTAL_CPU_NUMBER;i++)
if(EEPROMread(eep_CPU_NUB+i))
j++;
if(j==0)
{//如果cpu板的个数为0,返回;
if(menu_in==FALSE)
{
cstrcpy(disp_buffer,"请设置CPU!");
cls();
mediacy_hz(2*16,disp_buffer);
}
rcv_cnt=0;
return;
}
if(keep_timer)
{//在不应期内
if((keep_timer==2)&&(sampleCPU!=0))
{//装置启动后,采样CPU板有采样值送上来,第一次送上来的值存于0x400处
//在不应期结束前不轮巡采样CPU板
//在不应期即将结束时将其输出打印,并将以后的轮巡锁定在采样CPU板上
i=menu_in;
menu_in=TRUE;
cls();//彻底清屏
menu_in=i;
STATUS_WORD=5;//打印期间避免键盘干扰
cstrcpy(disp_buffer,"正在打印..");
disp_prt(1*16+8);
net_send(1,commu_buf[1+400]-5,commu_buf[3+400],
commu_buf[5+400],2,0,&commu_buf[6+400]);
poll_seq=sampleCPU-1;
keep_timer=1;
}
else
if((keep_timer==1)&&(sampleCPU!=0))
poll_seq=sampleCPU-1;//将轮巡锁定在采样CPU板上,直至sampleCPU被清0
else
{
keep_timer--;
if(keep_timer==0)
if(STATUS_WORD==5)
{
STATUS_WORD=0;
cls();
}
}
}
if((STATUS_WORD==1)||(STATUS_WORD==2))
poll_seq=(clz_prt&0x0e0)>>5;
else
if(EEPROMread(eep_CPU_NUB+0)==0)
{//含有非CPU1板则逐一点名
for(;;)
{
if(poll_seq<TOTAL_CPU_NUMBER)
poll_seq++;
else
poll_seq=1;
if((keep_timer>1)&&(sampleCPU==poll_seq)&&(j>1))
continue;//不应期结束前,不对采样CPU点名
if(EEPROMread(eep_CPU_NUB+poll_seq))
break;
}
}
else
poll_seq=1;
CPU_ID=poll_seq<<5;
poll_out();
poll_timer_f=TRUE;
return;
deal_com:
// disp_comm(rcv_cnt);//调试用
i=8;//case 0x91:和case 0xB1:用
switch(commu_buf[0])
{//用第一个字节判断功能
case 0x80://无报文
if(Q_KEY[poll_seq]==0xaa)
{
if((word)CTL_DOT_CPU[poll_seq].str==0x0001)//录波CPU
com_byte(CPU_ID|0x04);//请求结束
if((STATUS_WORD!=1)||(CPU_ID!=(clz_old&0x0e0)))
Q_KEY[poll_seq]=0;
}
if((keep_timer==1)&&(sampleCPU==poll_seq))
{
static cnt=0;
cnt++;
if(cnt>4)
{
sampleCPU=0;//采样CPU板已停止送采样,则sampleCPU清0
if(STATUS_WORD==5)
STATUS_WORD=0;
cnt=0;
}
}
break;
case 0x81://送当地显示
if(Q_KEY[poll_seq]==0xaa)
{//请求退出状态
com_byte(CPU_ID|0x04);//请求结束
if(STATUS_WORD==1)
{
if(CPU_ID==(clz_old&0x0e0))
{
STATUS_WORD=0;
Q_KEY[poll_seq]=0;
}
}
else
{
STATUS_WORD=0;
Q_KEY[poll_seq]=0;
}
return;
}
if((menu_in!=FALSE)&&(commu_buf[2]==0x09)&&(PT_RST!=FALSE))
{//请求退出状态
com_byte(CPU_ID|0x04);//请求结束
return;
}
com_byte(CPU_ID | 0x02);//接收成功确认
j=commu_buf[1]-2;
for(;;)
{//分析是否属于查看模拟量的报文
char DzStrBuf[20];
byte *iindex;
const byte *cpp;
if((STATUS_WORD!=1)&&(STATUS_WORD!=2))
break;
if((commu_buf[2]&0x01)==0)
break;
if((STATUS_WORD==2)&&(commu_buf[1]!=0x0d))
return;
if(clz_order!=FALSE)
{//调取新模拟量时,第一次来的数不要
clz_order=FALSE;
return;
}
if(STATUS_WORD==1)
{
memcpy(disp_buffer,&commu_buf[3],j);
disp_buffer[j]=0;
memcpy(DzStrBuf,&commu_buf[3],3);
DzStrBuf[3]=0;
cstrcpy(DzStrBuf+10,"ON:"); //判是否是开入查看
i=strcmp(DzStrBuf,DzStrBuf+10);
if(i!=0)
{
cstrcpy(DzStrBuf+10,"DI:"); //判是否是开入查看
i=strcmp(DzStrBuf,DzStrBuf+10);
}
if(i==0)
{//是开入查看
commu_buf[j+3]=0;
commu_buf[j+4]=0;
iindex=strchr(commu_buf+6,'T');//判是否含跳位
{//先显示开入端子号,接着显示跳位,然后把后面的数据接上来显示
if((iindex!=0)&&(*(iindex+1)=='W'))
{
*iindex=0;
csprintf(disp_buffer,"开入端子号:\r %s跳位%s",commu_buf+6,iindex+2);//On:
}
else
if((iindex!=0)&&(*(iindex+1)=='Y'))
{
*iindex=0;
csprintf(disp_buffer,"开入端子号:\r %s停用%s",commu_buf+6,iindex+2);//On:
}
else
csprintf(disp_buffer,"开入端子号:\r %s",commu_buf+6);//On:
}
LCD_display(16,0);
return;
}
if(clz_old<clz_di)
{//一般的零漂刻度都是0x09,只有开入以后的项目是0x01
if((commu_buf[2]!=0x0d)
&&(commu_buf[2]!=0x09)
&&(commu_buf[2]!=0x08))
break;
}
}
{
cls();
disp_buffer[0]=0;
if(EEPROMread(eep_CPU_NUB+0)==0)
csprintf(disp_buffer,"CPU%d的",(clz_old&0x0e0)>>5);
if(STATUS_WORD==2)
cpp="对点:";
else
if((clz_old&0x1f)==0x11)
cpp="零漂:";
else
if((clz_old&0x1f)==0x10)
cpp="刻度:";
else
if((clz_old&0x1f)==0x12)
cpp="阻抗:";
cstrcpy(disp_buffer1,cpp);
strcat(disp_buffer,disp_buffer1);
mediacy_hz(16,disp_buffer);
memcpy(disp_buffer,&commu_buf[3],j);
disp_buffer[j]=0;
if(STATUS_WORD==2)
DZBchinese(disp_buffer,j,2);
else
floatchinese(disp_buffer,j,32);
}
return;
}
if(j>32)
j=32;
if(commu_buf[2] & 0x10) //点亮运行灯
PORTD|=RUN_LAMP;
else
PORTD&=~RUN_LAMP;
if(commu_buf[2] & 0x04) //告警
alarm();
if(commu_buf[2] &0x08) //保存在ram中
{
if(RPT_TIME[0]==0xa5)
{
rpt_ram_clr();
memcpy(rpt_ram_buf,&RPT_TIME[2],15);
rpt_ram_buf[15]=' ';
ram_ptr++;
RPT_TIME[0]=0xa0;
CYCLE_FLAG=TRUE;
STATUS_WORD=0;
}
ram_save(j,0x81);
}
if(RPT_TIME[0]!=0xb5)
if(commu_buf[2] & 0x02) //保存在eeprom中
{
pointer1();
eep_save(j,0x81);
}
if((commu_buf[2] & 0x01)&&(CYCLE_FLAG==FALSE)&&(ATTENTION==FALSE)
&&(STATUS_WORD==0)&&(menu_in==FALSE))
{//滚屏显示0x81报文
memcpy(disp_buffer,&commu_buf[3],j);
disp_buffer[j]=0;
if(desk_pause==0)//不暂停
{
deskchinese(j);//翻屏(桌面)文字
for(j=0;j<50;j++)
{
out_rst24();
if(has_key&0x80)
break;
dlyms(10);
}
if(has_key==(KEY_UP|0x80))
{
has_key&=0x7f;
desk_pause=10;
}
}
}
break;
case 0x91://要求MMI以NVA转发报文
i=0;
case 0xB1://以NVB转发报文
if(i==0)
i=1;//以NVA转发报文
else
i=2;//以NVB转发报文
com_byte(CPU_ID | 0x02);//向cpu板发确认命令
if(commu_buf[4]==0x33)
{
j=2;//0x33报文,多帧发送时有两字节为头
if(commu_buf[5]==0x09)
j=1;
}
else
if(commu_buf[4]==0x30)
j=1;//0x30报文,多帧发送时有一字节为头
else
j=0;//其它报文
net_send(i,commu_buf[1]-4,commu_buf[2],commu_buf[4],0,j,&commu_buf[5]);
break;
case 0xA1:
com_byte(CPU_ID | 0x02);
return;
break;
case 0xC1://送当地显示,同时以NVA向网络转发
if(Q_KEY[poll_seq]==0xaa)
{//请求停止发送
com_byte(CPU_ID | 0x04);//发送请求停止命令
if(STATUS_WORD==1)
{
if(CPU_ID==(clz_old&0x0e0))
{
STATUS_WORD=0;
Q_KEY[poll_seq]=0;
}
}
else
{
STATUS_WORD=0;
Q_KEY[poll_seq]=0;
}
return;
}
com_byte(CPU_ID | 0x02);//确认收齐一帧数据
rcv_cnt=commu_buf[1]-5;
if(rcv_cnt>32)
rcv_cnt=32;
if(keep_timer!=1)
if(PT_RST!=FALSE)
{//如果在不应期内,延长不应期,为每个CPU读六次的时间
keep_timer=0;
for(i=1;i<=TOTAL_CPU_NUMBER;i++)
{
if(EEPROMread(eep_CPU_NUB+i))
keep_timer++;
}
keep_timer*=6;
}
if(RPT_TIME[0]!=0xb5)
if(commu_buf[2]&0x02)
{//数据要求存EEPROM
pointer1();
if((ATTENTION==FALSE)&&(PT_RST==FALSE))
{//没有关注且在不应期之外
report_time_lock();//取当前时间
sampleCPU=0;
if((STATUS_WORD==3)||(STATUS_WORD==4))
{//如果是测试时产生的报文
STATUS_WORD=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -