📄 nsawhws1.c
字号:
#define WH_SD 0 //ShuDa
#define WH_WS 1 //WeiSheng
#define WH_HT 2 //HenTong
#define WH_JH 3 //JinHa
#define WH_KD 4 //KeDa
#define WH_KX 5 //KeXing
#define WH_DTF 6 //LeiQing DTF
#define WH_DX 7 //DaXing
#define WH_SWIT 8 //Swithland
//checked with VB on 24,March,1999
/*-------------------------------------------------------------------
#define WH_WS 1 //WeiSheng
WeiSheng:
Suml=Addr^...^Data
Sumh=Addr+...+Data
From Wh Pkt:Addr,0x8B,0xD6,nbytes,data,Suml,Sumh,0x0D:total 38 bytes
To Wh Pkt:Addr,0xB8,0x6D,0x0F,0x00,0x00,Suml,Sumh,0x0D:total 9 bytes
-----------------------------------------------------------------------*/
#include <time.h>
#include <dos.h>
#include <stdio.h>
#include "nsa.h"
#define LIMIT_WH_T1 5 /*WH prescribe 5s*/
#define LIMIT_WH_T LIMIT_WH_T1*5+1
#define LIMIT_WH_ERR_TIMES 3
void WhTimeProc();
WORD ToWhProc(WORD UartNo);
void ToWh(WORD UartNo);
void FindWhSync(WORD UartNo);
void FindWhSyncListen(WORD UartNo);
void ReadWhHead(WORD UartNo);
void ReadWhData(WORD UartNo);
void FromWh(WORD UartNo);
void FromWhProc(WORD UartNo);
void RecordWhRecvData(WORD UartNo);
void RecordWhRecvDataListen(WORD UartNo);
WORD CheckWhPkt(WORD UartNo);
void ReadNoByteFromWh(WORD UartNo);
void ReadNoByteFromWhListen(WORD UartNo);
void ClearWhBuff(WORD UartNo);
WORD WhWsBuffInit(WORD GroupNo);
WORD ToWhWsProc(WORD UartNo,ULONG Addr);
int FromWhWsProc(WORD UartNo);
int CalFromWhWsPktNbytes();
WORD CheckWhWsPkt(WORD UartNo);
WORD CalWhWsCheckSum(BYTE Buf[],WORD nbytes);
MyFunS FunWhBuffInitProc[]={
{0,WH_WS, WhWsBuffInit} //1
};
MyFunS FunToWhProc[]={
{0,WH_WS, ToWhWsProc} //1
};
MyFunS FunFromWhProc[]={
{0,WH_WS, FromWhWsProc} //1
};
MyFunS FunCalFromWhPktNbyts[]={
{0,WH_WS, CalFromWhWsPktNbytes} //1
};
MyFunS FunCheckWhPkt[]={
{0,WH_WS, CheckWhWsPkt} //1
};
#define TXDT_POLL_WH 0
#define TXDT_POLL_ONE_WH 1
static TxDtS TxDt[]={
{0,3,OFF}, //17:wh:ask all wh interval
{0,2,OFF}, //18:one_wh interval
{0,13,OFF}, //17:wh:ask all wh interval
{0,4,OFF}, //18:one_wh interval
};
#define TXDT_NUM_PER_WH_UNIT 2
///llh 2001.3.27,for zj
#define MAX_COMMAND 4
static WORD ComByte[MAX_COMMAND]={0x1001,0x1006,0x100B,0x1010};
//正向总有功,正向总感性无功,正向总容性无功,反向总有功//
///if want to get other val extend the combyte and in whaddr.tab file fill in val offset
// WORD YmOffset[4]; in struct OnePwStru must extend along with val no, add scanf in function ReadWhAddrTab();
static BYTE ComNum[2]={0,0},AddrNo[2]={0,0} ;
//static BYTE SendFlag[0]={0,0};
static time_t lastSendTime[2]={0,0},nowtime; //time_t 2001.3.29
static BYTE SendFlg[2]={0,0};
static BYTE pktbuf[256],pkbuf[256];
///end
static BYTE debug ;
static WORD GroupNo;
WhS *Whp;
void FromToWh(WORD UartNo){
WORD i,OrgMark,Check,nbytes,Type,UnitNo,Comd,ScadaNo;
BYTE *p,len,sum,xgx;
WORD ms,dms,xgxYmoff;
WORD PktIsOver,PktOverMs;
BYTE XHex[4];
ULONG SUMHex[1];
GroupNo=Uart[UartNo].SameFunNo;
//llh
if( GroupNo>=2) return;
///llh
//if(Lib.WhBanRun[GroupNo][0]==ON||Lib.WhBanRun[GroupNo][1]==ON)return;//delete by llh
//WhTimeProc();delete by llh
if ( (Whp= (WhS __far *)_vload( VmhWh[GroupNo], _VM_DIRTY)) == NULL ){
printf("FromToWh vload error\n");
_vheapterm();
exit( -1 );
}
debug=DispDat[UartNo];
//llh
{
// printf("+++++++++++ Total pwMeter=%d+++++++++++++++\n", ZjPw.pwNum);//delete if debug pk
if(ZjPw.pwNum<=64){
mytime(&nowtime);
if(SendFlg[GroupNo]>2 && DiffTime(&nowtime,&lastSendTime[GroupNo])>=1)//rev return pkt ,delay one second after send inqury pkt or first time
{
len=RecvUart(UartNo,&pkbuf[0],5);//receive 4 bytes head//pktbuf-->pktbuf 2001.3.29
if(pkbuf[1]==0xaa)// correct无报警
{
//len=RecvUart(UartNo,&pktbuf[0],pktbuf[4]+6);//receive all bytes
len=RecvUart(UartNo,&pkbuf[5],6);
//SendFlg[GroupNo]=5;//set inqury flag
if(len==6)//receive byte count==bytes in head ?????????????
{
if(len>=2)//not NULL pkt and error pkt ,correct pkt len=7
{
sum=0;
for(i=0;i<10;i++) sum+=pkbuf[i]; //接收校验和
if(sum==pkbuf[9] && pkbuf[10]==0x0d)// sum and end code right
{
UnitNo=pkbuf[0];//addr
sum=255;
for(i=0;i<ZjPw.pwNum;i++)//total meter
{ if(UnitNo==ZjPw.onePw[i].addr && GroupNo==ZjPw.onePw[i].port)// addr and port equal
{ sum=i;
xgx=i;
break;
}
}
if(sum<ZjPw.pwNum)
{ UnitNo=sum;//find index in struct
sum=MAX_COMMAND+5;
Comd=pkbuf[3]*256+pkbuf[2];// command word
for(i=0;i<MAX_COMMAND;i++)
if(Comd==ComByte[i]) {sum=i;break;}
XHex[0]=pkbuf[5];
XHex[1]=pkbuf[6];
XHex[2]=pkbuf[7];
XHex[3]=pkbuf[8];
xgxYmoff=xgx*4+sum;
SUMHex[0]=XHex[0]*0.001+XHex[1]*0.256+XHex[2]*65.536+XHex[3]*16777.2;
if(sum<MAX_COMMAND) //correct ret command code
{
//PutYmInLib(UartNo,ZjPw.onePw[UnitNo].YmOffset[sum],&pktbuf[5],4);
PutYmInLib(UartNo,xgxYmoff,&SUMHex[0],sizeof(SUMHex[0]));
Lib.Bj3UnitYmReceived=ON;
}
}
}
}
}
else
len=RecvUart(UartNo,&pkbuf[0],11);//read other bytes
}
else
len=RecvUart(UartNo,&pkbuf[0],11);//read other bytes
}
if(DiffTime(&nowtime,&lastSendTime[GroupNo])>5||SendFlg[GroupNo]<2)//need send a inqury pkt
{ i=0;
while(i<ZjPw.pwNum)//find next addr in this port
{ AddrNo[GroupNo]++;
if(AddrNo[GroupNo]>=ZjPw.pwNum)
{
AddrNo[GroupNo]=0;
ComNum[GroupNo]++;//next command type
if(ComNum[GroupNo]>MAX_COMMAND) ComNum[GroupNo]=0;
}
/*yl del if(ZjPw.onePw[AddrNo[GroupNo]].port==GroupNo)break;
i++;
}*/
pktbuf[0]=ZjPw.onePw[AddrNo[GroupNo]].addr;//meter addr
pktbuf[1]=0x55;//fill in pkt to send
pktbuf[2]=ComByte[ComNum[GroupNo]]%256;//command code
pktbuf[3]=ComByte[ComNum[GroupNo]]/256;
pktbuf[4]=0; //数据长度
pktbuf[5]=0; //校验和
for(i=0;i<5;i++)
pktbuf[5]+=pktbuf[i];
pktbuf[6]=0x0d;
SendUart(UartNo,&pktbuf[0],7);
lastSendTime[GroupNo]=nowtime;
SendFlg[GroupNo]=5;//set inqury flag
if(ZjPw.onePw[AddrNo[GroupNo]].port==GroupNo)break;
i++;
} //while
}//if
}//<=64
return;
}
//llh
if(Whp->OrgPktStat==ON){
OrgMark=ToWhProc(UartNo);
if(OrgMark==ON){
UnitNo=Whp->DnUnitNo;
nbytes=Whp->OrgBytes;
p=&Whp->ToBuff[0];
if(Whp->SendPkt[0]==OFF)Whp->SendPkt[0]=MONI_S22;/*send pkt */
if(Whp->SendPkt[1]==OFF)Whp->SendPkt[1]=MONI_S22;/*send pkt */
Lib.WhBanRun[GroupNo][0]=OrgUnitMoniPkt(0,UartNo,UnitNo,p,nbytes,&Whp->SendPkt[0],&Whp->RecvPkt[0]);
Lib.WhBanRun[GroupNo][1]=OrgUnitPanelPkt(1,UartNo,UnitNo,p,nbytes,&Whp->SendPkt[1],&Whp->RecvPkt[1]);
Whp->OrgPktStat=OFF;
Whp->SendPktStat=ON;
SetRts(UartNo,ON); /*for sending*/
if(Lib.WhBanRun[GroupNo][0]==ON||Lib.WhBanRun[GroupNo][1]==ON)return;
}
}
if(Whp->SendPktStat==ON){
ToWh(UartNo);
if(Whp->SendBytes>=Whp->OrgBytes){
FlushRecvBuff(UartNo);
UioCntlAsm[UartNo].PktIsOver=0x12;//for int routine(常规的) sets RTS to OFF
Whp->SendBytes=0;
Whp->SendPktStat=OFF;
Whp->JudgePktIsOver=ON;
}
}
if(Whp->JudgePktIsOver==ON){
GetPktOverTime(UartNo,&PktIsOver,&PktOverMs);
if(PktIsOver==ON){
Whp->JudgePktIsOver=OFF;//need to answer from Wh
Whp->ReadNeed=ON;
Whp->RecvData=OFF;
mytime(&Whp->OnePktSendTime);
// printf("1:Whp->OnePktSendTime=%d\n",Whp->OnePktSendTime);
}
}
if(Whp->ReadNeed==ON){
if(Whp->SyncFull==OFF)FindWhSync(UartNo);
if(Whp->SyncFull==ON&&Whp->HeadFull==OFF)ReadWhHead(UartNo);
if(Whp->HeadFull==ON&&Whp->DataFull==OFF)ReadWhData(UartNo);
if(Whp->DataFull==ON||Whp->PktIsTimeOut==ON){
p=&Whp->FromBuff[0];
nbytes=Whp->RecvByteNum;
if(debug)printf("\nRWh%d:",UartNo);
if(debug)for(i=0;i<nbytes;i++)printf("%02x ",p[i]);
if(Whp->RecvPkt[0]==OFF)Whp->RecvPkt[0]=MONI_S23;/*all received pkt*/
if(Whp->RecvPkt[1]==OFF)Whp->RecvPkt[1]=MONI_S23;/*all received pkt*/
UnitNo=Whp->UpUnitNo; //start from 0
Lib.WhBanRun[GroupNo][0]=OrgUnitMoniPkt(0,UartNo,UnitNo,p,nbytes,&Whp->SendPkt[0],&Whp->RecvPkt[0]);
Lib.WhBanRun[GroupNo][1]=OrgUnitPanelPkt(1,UartNo,UnitNo,p,nbytes,&Whp->SendPkt[1],&Whp->RecvPkt[1]);
}
if(Whp->DataFull==ON){
Check=CheckWhPkt(UartNo);
if(Check==ON)FromWhProc(UartNo);
}
if(Whp->DataFull==ON||Whp->PktIsTimeOut==ON){
ClearWhBuff(UartNo);
Whp->PktIsTimeOut=OFF;
}
}
}
void FromWh(WORD UartNo){
WORD i,OrgMark,nbytes,Type,UnitNo,Addr,cmd,ScadaNo,Clear;
BYTE *p;
WORD ms,dms;
WORD PktIsOver,PktOverMs;
GroupNo=Uart[UartNo].SameFunNo;
if (Lib.WhBanRun[GroupNo][0]==ON||Lib.WhBanRun[GroupNo][1]==ON)return;
if ( (Whp= (WhS __far *)_vload( VmhWh[GroupNo], _VM_DIRTY)) == NULL ){
printf("FromToWh vload error\n");
_vheapterm();
exit( -1 );
}
debug=DispDat[5];
Whp->ReadNeed=ON;
if (Whp->ReadNeed==ON){
if(Whp->SyncFull==OFF)FindWhSync(UartNo);
if(Whp->SyncFull==ON&&Whp->HeadFull==OFF)ReadWhHead(UartNo);
if(Whp->HeadFull==ON&&Whp->DataFull==OFF)ReadWhData(UartNo);
if(Whp->DataFull==ON){
if(CheckWhPkt(UartNo)==ON)FromWhProc(UartNo);/*may modify RecvPkt[0]*/
}
if(Whp->DataFull==ON||Whp->PktIsTimeOut==ON){
Whp->RecvPkt[0]=MONI_S23;/*all received pkt*/
Whp->RecvPkt[1]=MONI_S23;/*all received pkt*/
p=&Whp->FromBuff[0];
nbytes=Whp->RecvByteNum;
UnitNo=Whp->FromBuff[0];
Lib.WhBanRun[GroupNo][0]=OrgUnitMoniPkt(0,UartNo,UnitNo,p,nbytes,&Whp->SendPkt[0],&Whp->RecvPkt[0]);
Lib.WhBanRun[GroupNo][1]=OrgUnitPanelPkt(1,UartNo,UnitNo,p,nbytes,&Whp->SendPkt[1],&Whp->RecvPkt[1]);
ClearWhBuff(UartNo);
Whp->PktIsTimeOut=OFF;
}
}
}
void ToWh(WORD UartNo){
WORD nbytes,i;
BYTE *p;
nbytes=Whp->OrgBytes-Whp->SendBytes;
p=&Whp->ToBuff[Whp->SendBytes];
nbytes=SendUart(UartNo,p,nbytes);
//for(i=0;i<nbytes;i++)printf("%02x ",p[i]);
Whp->SendBytes+=nbytes;
if (Whp->SendBytes>=Whp->OrgBytes){
if(debug)printf("\nTWh%d:",UartNo);
if(debug)for(i=0;i<Whp->OrgBytes;i++)printf("%02x ",Whp->ToBuff[i]);
// FlushRecvBuff(UartNo);
}
}
WORD ToWhProc(WORD UartNo){
WORD CurUnitNo,OrgMark=OFF;
ULONG Addr;
WORD offset;
offset=GroupNo*TXDT_NUM_PER_WH_UNIT;
if(TxDt[offset+TXDT_POLL_WH].Occur==ON&&TxDt[offset+TXDT_POLL_ONE_WH].Occur==ON){//10 minutes ,2 seconds
CurUnitNo=Whp->CurOrgPktUnitNo;//start from 0
Whp->DnUnitNo=CurUnitNo;
Addr = Lib.AddrTab[CurUnitNo];
OrgMark=(*( FunToWhProc[0].Fun))(UartNo,Addr);
CurUnitNo++;
if(CurUnitNo>=Uart[UartNo].LimitNum+Uart[UartNo].StartNo){/*only poll Wh in this Rs485*/
CurUnitNo=Uart[UartNo].StartNo; //start from 0
TxDt[offset+TXDT_POLL_WH].Occur=OFF;
}
Whp->CurOrgPktUnitNo=CurUnitNo;
TxDt[offset+TXDT_POLL_ONE_WH].Occur=OFF;
}
return(OrgMark);
}
void FromWhProc(WORD UartNo){
WORD UpUnitNo,addr;
UpUnitNo=Whp->UpUnitNo;//UnitNo according to Addr of Wh[].FromBuff[],start from 0
addr=UpUnitNo-Whp->MinNo;
Lib.WhStat[addr]=NORMAL;
(*( FunFromWhProc[0].Fun))(UartNo);
}
WORD CheckWhPkt(WORD UartNo){//start from 0
WORD Check=OFF;
Check=(*( FunCheckWhPkt[0].Fun))(UartNo);
return(Check);
}
WORD WhCalUnitNo(WORD UartNo,ULONG Addr){//start from 0
WORD UnitNo,i;
UnitNo=0xFF;
for(i=0;i<Lib.WhAddrTabNum;i++)//LimitUnitNum:total wh meter num in 2 lines
if(Addr==Lib.AddrTab[i]){UnitNo=i;break;}
return(UnitNo);
}
/*
void FindWhSync(WORD UartNo){
WORD i,j,k,m,nbytes,UnitNo,Stat,ms,pos,RecvData=OFF;
BYTE *p;
BYTE sync;
//printf("in findwhsync..");
if(Lib.Listen==ON){FindWhSyncListen(UartNo);return;}
for(i=0;i<5;i++){ // loop return when nbytes=0 or finding
pos=Whp->RecvByteNum;
nbytes=sizeof(Wh[0].FromBuff)-Whp->RecvByteNum;
p=&Whp->FromBuff[pos];
nbytes=RecvUart(UartNo,p,nbytes);
if(nbytes==0)continue;
Whp->RecvByteNum+=nbytes;
RecvData=ON;
if(debug)for(j=0;j<nbytes;j++)printf("s:%02x ",p[j]);
for(j=0;j<nbytes;j++){
if(p[j]==Whp->SynCode[Whp->RecvSyncNum]){//SynCode is filled at OrgPkt
Whp->RecvSyncNum++;
if(debug)printf("RecvSyncNum=%d,SynBytes=%d\n",Whp->RecvSyncNum,Whp->SynBytes);
if(Whp->RecvSyncNum==Whp->SynBytes){
Whp->RecvSyncNum=0;
Whp->SyncFull=ON;
m=(&p[j]-&Whp->FromBuff[0]+1)-Whp->SynBytes;
Whp->RecvByteNum=Whp->RecvByteNum-m;
for(k=0;k<Whp->RecvByteNum;k++)
Whp->FromBuff[k]=Whp->FromBuff[m+k];
if(debug)printf("Find sync\n");
break;
}
}
else if(Whp->RecvSyncNum>=1){
Whp->RecvSyncNum=0;
}
}
if(Whp->SyncFull==ON)break;//case if break from inner for loop
}
if(RecvData==OFF)ReadNoByteFromWh(UartNo);
else{
RecordWhRecvData(UartNo);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -