📄 hdlctest.~cp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "hdlctest.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "MSCommLib_OCX"
#pragma resource "*.dfm"
TForm1 *Form1;
int SavePointer=0;//数据存储指针
int rvbuf[1024]; /* receive RS-232 data buffer */
int sdbuf[1024];/* send RS-232 data buffer */
int sdbt; /* sending buffer tail pointer */
int sdbh; /* sending buffer head pointer */
int rvbt;/* receive buffer tail pointer */
int rvbh;/* receive buffer head pointer */
int RVBUF[1024]; /* receive RS-232 data buffer */
int sd_frame[262];//帧结构
int NS, NR, VS, VR;
int TBL, TBF, TCB, TEC; /* TEC: TRANSMIT END FLAG COUNT */ //TEC:发送终止标志位
int RBS, RV_ERR;
int RCB;
int RVBH;
int Bytenum;
int jishu;
int jishu1;
int ceshi;
int timenum;
int rej1;
int rej2;
int rej3;
int asd;
int asdf[1024];
int edc;
OleVariant TxBuff;
OleVariant RxBuff;
int rv_state;
/////////////////////////////
void send_sdbuf(int j,int send_data[]);
void ProcessData();
void SaveData(int RCount, int pbVal[]);
void rr_frame();
void rej_frame();
void info_frame();
void decmd();
void Transmitt();
void sim_frame();
void sim_frame() //初始化
{
sd_frame[0]=sd_frame[1]=0xee;
sd_frame[2]=sd_frame[3]=0x07;
sd_frame[4]=sd_frame[5]=0x77;
TCB=sd_frame[2];
TBF=0;
NS=0; NR=0; VS=0; VR=0;
TBL=6;
Transmitt();//发送
}
void rej_frame() //拒绝
{
sd_frame[0]=sd_frame[1]=0xee;
sd_frame[2]=sd_frame[3]=0x9+(VR<<5); //9代表拒绝帧(只能加奇数(非信息帧最后一位为1))
sd_frame[4]=sd_frame[5]=0x77;
TCB=sd_frame[2];
TBF=0;
TBL=6;
Transmitt();
jishu++;
jishu=jishu&0xffff;
Form1->Label2->Caption = IntToStr(jishu);
}
void rr_frame() //准备好帧
{
sd_frame[0]=sd_frame[1]=0xee;//0:起始标志位 1:地址位
sd_frame[2]=sd_frame[3]=1+(VR<<5);//2:控制字 3:信息位 最低位为1
sd_frame[4]=sd_frame[5]=0x77;//4,5:结束标志位
TCB=sd_frame[2];
TBF=0;
TBL=6;
Transmitt();
}
void decmd() //解帧
{
int check;
if(RV_ERR) //如果接收错误 非信息帧时2、3字节一样,使RV_ERR=0;
//信息帧时2、3字节不同,使RV_ERR=1;
{
if(TBF==1)
sdbh=(sdbh-TBL+TEC+6)%1024; //定位上次帧指针位置
rej_frame(); //发拒绝帧
rej1++;
Form1->Label9->Caption = IntToStr(rej1);
RV_ERR=0;
}
else if (!(RCB&1))/* INF frame */ //接收正确时判断为何种帧
{
check=0;
for( int zjd=rvbt;zjd!=RBS;)
{
check=(check+rvbuf[zjd])&0xff;//信息帧时求校验和
zjd=(zjd+1)&0x3ff; //3ff=1024 防止越界
}
check=(check+RCB)&0xff;
NS=((RCB>>1)&0x7); //次站所发帧
NR=RCB>>5; //次站所等帧
check=check&0xff;
asd = rvbuf[RBS];
if(check!=rvbuf[RBS]) // 比较接收到的校验和及计算所得的校验和
{
rej_frame();
rej2++;
Form1->Label10->Caption = IntToStr(rej2);
}
else if((NR==((VS+1)&7))&&(NS==VR))//正常传输
{
VS=((VS+1)&7);
VR=((VR+1)&7);
rvbt=RBS;//RBS:接收缓冲器起始地址寄存器,存储上次信息的头指针;
if(sdbt!=sdbh)//头尾指针不同
info_frame();
else rr_frame();
}
else if((NR==VS)&&(NS==VR))
{
VR=((VR+1)&7);
rvbt=RBS;
if(TBF==1)
Transmitt();
else if (sdbt!=sdbh)
info_frame();
else rr_frame();
}
else if((NR!=VS)&&(NR!=((VS+1)&7))&&(NS==VR))
{
VS=0;
VR=((VR+1)&7);
rvbt=RBS;
if(TBF==1)
sdbh=(sdbh+TEC+6-TBL)%1024;
sim_frame();
}
else if((NR==((VS+1)&7))&&(NS!=VR))
{
VS=((VS+1)&7);
rej_frame();
rej3++;
Form1->Label11->Caption = IntToStr(rej3);
}
else if((NR==VS)&&(NS!=VR))
{
if(TBF==1)
sdbh=(sdbh+TEC+6-TBL)%1024;
VR=0;
sim_frame();
}
else
{
if(TBF==1)
sdbh=(sdbh+TEC+6-TBL)%1024;
NS=0;
NR=0;
sim_frame();
}
}
else
{
switch(RCB&0xf) //RCB为次站发来的第二个字节(何种帧)
{
case 0x07://低4位为0x07为初始化帧
sim_frame();
break;
case 0x01: /* RR 接收准备好 S */
{
NR=(RCB>>5);
if(NR==((VS+1)&7))
{
VS=((VS+1)&7);
if(sdbt==sdbh) //发送BUFFER头尾指针相同发准备好帧
rr_frame();
else //不同发信息帧
{
info_frame();
}
}
else if(NR==VS)
{
if(TBF)
Transmitt();
else
{
if (sdbh!=sdbt)
info_frame();
else
rr_frame();
}
}
else
{
sim_frame();
}
}
break;
case 0x09: /* REJ 拒绝 S */
{
jishu1++;
jishu1=jishu1 & 0xffff;
Form1->Label3->Caption = IntToStr(jishu1);
if ((TCB&0xf)==0x9)
{
rr_frame();
}
else Transmitt();
}
break;
case 0x03:/* UA 响应初始化 U */
{
rr_frame();
}
break;
default: break;
}
}
}
void SaveData(int RCount, int pbVal[])
{
int i,a;
AnsiString p;
p = "";
for(i=0;i<RCount;i++)
{
a=(SavePointer+i)&0x3ff;
RVBUF[a]=pbVal[i];//将收到的数据存入临时接收缓冲区
p = p + IntToStr(pbVal[i]) + ",";
}
Form1->Label1->Caption=p;
SavePointer+=RCount;
SavePointer=(SavePointer&0x3ff);
if(RCount>0)
{
ProcessData();//处理收到的数据
}
}
void ProcessData() //用来滤掉帧标志
{ int i=0;
for(i=RVBH;i!=SavePointer;)
{
switch(rv_state)
{
case 0:
if(RVBUF[i]==0xee)
{
rv_state=1;
}
break;
case 1:
if(RVBUF[i]==0xee)
{
rv_state=2;
}
else rv_state=0;
break;
case 2:
RCB=RVBUF[i];//控制字
if(!(RCB&1)) //最低位为0时为信息帧/* information frame */
{
rv_state=3;
RBS=rvbt;//RBS:信息部分头指针,rvbt:上次信息的尾指针
}
else rv_state=5; /* S and U frame 最低位为1时为非信息帧 */
break;
case 3: //信息帧时转case 3,4
if(RVBUF[i]==0x77) //在读信息帧过程中如果出现0x77转case 4
rv_state=4;
rvbuf[RBS]=RVBUF[i];//存储信息部分
RBS=((RBS+1)&0x3ff);
break;
case 4:
if(RVBUF[i]==0x77)//连续0x77时认为帧结束
{
RBS=(RBS-2)&0x3ff;//信息部分的尾指针后退两位,不要校验和,77
rv_state=0; //滤掉两个0x77
decmd(); //解帧
}
else
rv_state=3; //如果为0转 case 3
break;
case 5: //2,3一样时为非信息帧转到case 5,6
if(RVBUF[i]!=RCB) //RCB 为第2个字节内容 i=3;
{
RV_ERR=1; //接收错误
decmd();
}
rv_state=6;
break;
case 6: //非信息帧各位已确定
if(RVBUF[i]==0x77)
rv_state=7;
break;
case 7:
if(RVBUF[i]==0x77)
{
decmd();
rv_state=0;
}
else rv_state=6;
break;
default:rv_state=0;
break;
}
i++;
i=i&0x3ff;
} RVBH = i;
}
void info_frame()//成帧
{
int j,k,l,q;
int check;
sd_frame[0]=sd_frame[1]=0xee; //将主站接收的VS赋给NS,(NS=VR)以备比较
sd_frame[2]=(VS<<1)+(VR<<5); //最低位为0;VS——NR;VR——NS;sd_frame[2]中放置主站收发的信息帧计数;
check=sd_frame[2];
j=3;
TEC=0;
while((sdbh != sdbt) && (j < 200))
{
q = sdbuf[sdbh];
for(k=0;k<q;k++,j++) //命令字以16个字节为单位处理
{
l=(k+sdbh) & 0x3ff;
sd_frame[j]=sdbuf[l]; //将命令字赋给sd_frame
check=(check+sd_frame[j]) & 0xff;
if(sd_frame[j]==0x77)
{
TEC++; //记录插入0的个数;TBL为帧长度
j++;
sd_frame[j]=0;//插0
}
}
sdbh = (sdbh + q)&0x3ff;
}
sd_frame[j++]=check & 0xff;
if(check==0x77)
{
TEC++;
sd_frame[j++]=0;
}
sd_frame[j++]=0x77;
sd_frame[j++]=0x77;
TCB=sd_frame[2];
TBF=1;
TBL=j;//发送长度
Transmitt();
}
void send_sdbuf(int j,int send_data[]) //命令字存于send[16]->send_data[];
{
for(int i=0;i<j;i++)
{
sdbuf[sdbt]=send_data[i];
sdbt=(sdbt+1)&0x3ff;
}
}
//串口发送处理
void Transmitt()
{
int Count=TBL;
TxBuff=VarArrayCreate(OPENARRAY(int,(0,Count-1)),varByte);
for(int i=0;i<Count;i++)
TxBuff.PutElement(sd_frame[i],i);
Form1->MSComm1->Output=TxBuff;
timenum = 0;
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
sim_frame();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
MSComm1->PortOpen=true;
int ii; //
rvbt = 0; //
rv_state = 0; //
for(ii = 0; ii < 262; ii++) //
sd_frame[ii] = 0; //
TBF = 0; // //
TBL = 0; // //
NS = 0; //
NR = 0; //
VR = 0; //
VS = 0; //
TEC = 0;
jishu = 0;
jishu1 = 0; //
for(ii = 0;ii<1024;ii++) //
{ //
sdbuf[ii]=0; //
rvbuf[ii]=0; //
RVBUF[ii]=0;
asdf[ii] = 0;
} //
sdbt = 0; //
rvbt = 0; //
sdbh = 0; //
rvbh = 0; //
RVBH = 0;
ceshi =0;
rej1=0;
rej2=0;
rej3=0;
timenum = 0;
asd = 0;
edc=0;
Timer1->Enabled = true;
Label2->Caption = IntToStr(jishu);
Label3->Caption = IntToStr(jishu1);
Label8->Caption = IntToStr(ceshi);
Label9->Caption = IntToStr(rej1);
Label10->Caption = IntToStr(rej2);
Label11->Caption = IntToStr(rej3); //
}
//---------------------------------------------------------------------------
void __fastcall TForm1::MSComm1Comm(TObject *Sender)
{
int BuffPtr=0; //接收数据
int buffr[256];
int knum;
knum=MSComm1->InBufferCount;
if (MSComm1->InBufferCount>0)
{
RxBuff=VarArrayCreate(OPENARRAY(int,(0,knum-1)),varByte);
RxBuff=MSComm1->Input;
for(int i=0;i<knum;i++)
{
buffr[BuffPtr++]=RxBuff.GetElement(i);
}
SaveData(knum,buffr);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
int send[256];
int i,j;
for( i=0;i<256;i=i+4)
{
send[i]=4;
for(j=1;j<4;j++)
send[j+i]=j;
}
send_sdbuf(i,send);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
timenum++;
if(timenum>60)
{
timenum=0;
ceshi++;
ceshi=ceshi&0xffff;
Label8->Caption=IntToStr(ceshi);
sim_frame();
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form1->Label1->Caption = "";
jishu = 0;
jishu1 = 0;
ceshi = 0;
timenum = 0;
rej1=0;
rej2=0;
rej3=0;
Form1->Label2->Caption = IntToStr(jishu);
Form1->Label3->Caption = IntToStr(jishu1);
Form1->Label8->Caption = IntToStr(ceshi);
Form1->Label9->Caption = "0";
Form1->Label10->Caption = "0";
Form1->Label11->Caption = "0";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
int send[9];
int i;
send[0] = 0x09;
send[1] = 0x20;
for( i=2;i<9;i++)
send[i]=0xff;
send_sdbuf(i,send);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
int send[9];
int i;
send[0] = 0x09;
send[1] = 0x20;
for( i=2;i<9;i++)
send[i]=0xff;
send_sdbuf(i,send);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer3Timer(TObject *Sender)
{
int send[256];
int i,j;
for( i=0;i<256;i=i+4)
{
send[i]=4;
for(j=1;j<4;j++)
send[j+i]=j;
}
send_sdbuf(i,send);
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -