⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nsawhws1.c

📁 一种电度表的通讯程序,实际中已使用
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -