📄 ceshi.cpp.bak
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "ceshi.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "MSCommLib_OCX"
#pragma resource "*.dfm"
TForm1 *Form1;
unsigned char rvbuf[1024];
unsigned char sdbuf[1024];
unsigned char send[256];
unsigned char t_length;
int sdbt;
int sdbh;
int rvbt;
int rvbh;
unsigned char sd_frame[256];
unsigned char NS, NR, VS, VR;
unsigned char TBL, TBF, TCB, TEC;
unsigned char RCB, RV_ERR;
int RBS;
int jishu;
int jishu1;
int ceshi;
int timenum;
unsigned char serial_data;
unsigned char rv_state;
unsigned char asd;
int rej1;
int rej2;
int rej3;
int edc;
bool xianshi;
OleVariant TxBuff;
OleVariant RxBuff;
/////////////////////////////
void send_sdbuf();
void ProcessData();
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() //解帧
{
unsigned char 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 i=rvbt;i!=RBS;)
{
check=(check+rvbuf[i])&0xff;//信息帧时求校验和
i=(i+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 ProcessData() //用来滤掉帧标志
{
switch(rv_state)
{
case 0:
if(serial_data==0xee)
{
rv_state=1;
}
break;
case 1:
if(serial_data==0xee)
{
rv_state=2;
}
else
rv_state=0;
break;
case 2:
RCB=serial_data;//控制字
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(serial_data==0x77) //在读信息帧过程中如果出现0x77转case 4
rv_state=4;
rvbuf[RBS]=serial_data;//存储信息部分
RBS=((RBS+1)&0x3ff);
break;
case 4:
if(serial_data==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(serial_data!=RCB) //RCB 为第2个字节内容 i=3;
{
RV_ERR=1; //接收错误
}
rv_state=6;
break;
case 6: //非信息帧各位已确定
if(serial_data==0x77)
rv_state=7;
break;
case 7:
if(serial_data==0x77)
{
decmd();
rv_state=0;
}
else
rv_state=6;
break;
default:
rv_state=0;
break;
}
}
void info_frame()//成帧
{
int k,l;
unsigned char check,j,q;
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() //命令字存于send[16]->send_data[];
{
for(int i=0;i<t_length;i++)
{
sdbuf[sdbt]=send[i];
sdbt=(sdbt+1)&0x3ff;
}
}
//串口发送处理
void Transmitt()
{
unsigned char 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; // //
for(ii = 0; ii < 256; ii++)
{ //
sd_frame[ii] = 0;
send[ii] = 0;
}
t_length = 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; //
} //
rv_state = 0; //
sdbt = 0; //
rvbt = 0; //
sdbh = 0; //
rvbh = 0; //
ceshi =0;
rej1=0;
rej2=0;
rej3=0;
timenum = 0;
asd = 0;
serial_data = 0;
xianshi = true;
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 data,length;
AnsiString p;
if (MSComm1->CommEvent!=comEvSend)
{
length=MSComm1->InBufferCount;
if (MSComm1->InBufferCount>0)
{
length=MSComm1->InBufferCount;
MSComm1->InputLen=length;
RxBuff=MSComm1->Input;
MSComm1->InBufferCount=0;
p = "";
for(int i=0;i<length;i++)
{
data=RxBuff.GetElement(i);
serial_data = data&0xff;
ProcessData();
p = p + IntToStr(serial_data) + ",";
}
if(xianshi)
{
Form1->Label1->Caption=p;
}
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
unsigned char j;
int i;
for( i=0;i<256;i=i+4)
{
send[i]=4;
for(j=1;j<4;j++)
send[j+i]=j;
}
t_length = i;
send_sdbuf();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
timenum++;
if(timenum>60)
{
timenum=0;
xianshi=false;
ceshi++;
ceshi=ceshi&0xffff;
Label8->Caption=IntToStr(ceshi);
rv_state=0;
rej_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)
{
unsigned char i;
send[0] = 0x09;
send[1] = 0x20;
for( i=2;i<9;i++)
send[i]=0xff;
t_length = i;
send_sdbuf();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
unsigned char j;
int i;
send[0] = 4;
for( i=1;i<4;i++)
send[i]=i;
t_length=i;
send_sdbuf();
send[0] = 0x09;
send[1] = 0x20;
for( i=2;i<9;i++)
send[i]=0xff;
t_length=i;
send_sdbuf();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer3Timer(TObject *Sender)
{
unsigned char j;
int i;
for( i=0;i<256;i=i+4)
{
send[i]=4;
for(j=1;j<4;j++)
send[j+i]=j;
}
t_length=i;
send_sdbuf();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn4Click(TObject *Sender)
{
xianshi=(!xianshi);
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -