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

📄 secdlink.c

📁 详细介绍了arm7-at91r40008,的开发全过程
💻 C
📖 第 1 页 / 共 3 页
字号:
}

//编辑从动站应答10帧
void EditSec101_2002Fra10(INT8U Port, INT8U Function)
{
    INT8U i, j;
    INT8U *p;

    i = Port - 1;
    if (ComLink[i]->TxdStatus==TXDSEND)
        ComLink[i]->TxdTail=0;
    ComLink[i]->FrameHead=ComLink[i]->TxdTail;
    p=ComLink[i]->TxdBuf+ComLink[i]->FrameHead;
    p[0]=STARTCODE10;
    p[1]=Function;
    ComLink[i]->LastControl=Function;
    p[1]&=(~P101_DFC);
    p[1]&=(~P101_PRM);
    p[1]&=(~P101_DIR);//清方向位,防止干扰。
    p[1]|=ComLink[i]->IEC_DIR;//子站向主站传输,平衡模式为1,非平衡模式为0
    //if(FlagData1&&(!BalanMode)&&(Function!=DLSTATUSOK))//一级数据位
    if(ComLink[i]->FlagData1&&(!ComLink[i]->BalanMode))//一级数据位,为了适应胜利油田在链路过程总再次召唤链路的要求
        p[1]|=P101_ACD;
    else
        p[1]&=(~P101_ACD);
    for(j=0;j<ComLink[i]->LinkAddrSize;j++)
        p[2+j]=((ComLink[i]->SourceNo>>(8*j))&0xff);
    p[2+ComLink[i]->LinkAddrSize]=CheckSum(Port,p);
    p[3+ComLink[i]->LinkAddrSize]=ENDCODE;
    ComLink[i]->TxdTail+=ComLink[i]->FixFrmLength;//移动发送尾指针

    memcpy(ComLink[i]->TxdBuf_Sec,p,ComLink[i]->FixFrmLength);
    ComLink[i]->TxdTail_Sec=ComLink[i]->FixFrmLength;
    
}

/*编辑68帧*/
//Function:链路功能码
//FrameLength:应用层报文长度(从类型标识开始),是应用层调用返回的
void S101_2002EditFra68(INT8U Port, INT8U Function, INT16U FrameLength)
{
    INT8U *p, i;
    INT16U length, j;
    
    i = Port - 1;	
    if (ComLink[i]->TxdStatus==TXDSEND)
        ComLink[i]->TxdTail=0;
    ComLink[i]->FrameHead=ComLink[i]->TxdTail;
    p=ComLink[i]->TxdBuf+ComLink[i]->FrameHead;

    p[0]=p[3]=STARTCODE68;
    p[1]=p[2]=FrameLength+1+ComLink[i]->LinkAddrSize;
    p[4]=Function;
    ComLink[i]->LastControl=Function;
    if ((Function==DLSENDNOCON))
        p[4]&=(~P101_FCV);
    else
        p[4]|=P101_FCV;
    if (p[4]&P101_FCV)
    {
        if (ComLink[i]->TlaConCode&0x20)
        {
            p[4]&=(~P101_FCB);
            ComLink[i]->TlaConCode&=0xDF;
        }
        else
        {
            p[4]|=P101_FCB;
            ComLink[i]->TlaConCode|=0x20;
        }
        ComLink[i]->TlaConCode|=0x10;
    }
    else
    {
        p[4]&=(~P101_FCB);
        ComLink[i]->TlaConCode&=0xEF;
    }
    p[4]|=P101_PRM;
    p[4]&=(~P101_DIR);//清方向位,防止干扰。
    p[4]|=ComLink[i]->IEC_DIR;//子站向主站传输,平衡模式为1,非平衡模式为0。
    for(j=0;j<ComLink[i]->LinkAddrSize;j++)
        p[5+j]=((ComLink[i]->SourceNo>>(8*j))&0xff);
    length=7+ComLink[i]->LinkAddrSize+FrameLength;//全部报文长度
    p[length-2]=CheckSum(Port, p);
    p[length-1]=ENDCODE;
    ComLink[i]->TxdTail+=length;

    memcpy(ComLink[i]->TxdBuf_Pri,p,length);
    ComLink[i]->TxdTail_Pri=length;
}

void EditSec101_2002Fra68(INT8U Port, INT8U Function, INT16U FrameLength)
{
    INT8U *p, i;
    INT16U length, j;

    i = Port - 1;
    if (ComLink[i]->TxdStatus==TXDSEND)
        ComLink[i]->TxdTail=0;
    ComLink[i]->FrameHead=ComLink[i]->TxdTail;

    p=ComLink[i]->TxdBuf+ComLink[i]->FrameHead;
    p[0]=p[3]=STARTCODE68;
    p[1]=p[2]=FrameLength+1+ComLink[i]->LinkAddrSize;
    p[4]=Function;
    ComLink[i]->LastControl=Function;
    if(ComLink[i]->FlagData1&&(!ComLink[i]->BalanMode))
        p[4]|=P101_ACD;
    else
        p[4]&=(~P101_ACD);
    p[4]&=(~P101_DFC);
    p[4]&=(~P101_PRM);
    p[4]&=(~P101_DIR);//清方向位,防止干扰。
    p[4]|=ComLink[i]->IEC_DIR;//子站向主站传输,平衡模式为1,非平衡模式为0。

    for(j=0;j<ComLink[i]->LinkAddrSize;j++)
        p[5+j]=((ComLink[i]->SourceNo>>(8*j))&0xff);

    length=7+ComLink[i]->LinkAddrSize+FrameLength;//全部报文长度
    p[length-2]=CheckSum(Port,p);
    p[length-1]=ENDCODE;

    ComLink[i]->TxdTail+=length;
    memcpy(ComLink[i]->TxdBuf_Sec,p,length);
    ComLink[i]->TxdTail_Sec=length;
}


void SecEditE5(INT8U Port)//编辑E5帧
{
    INT8U i;
    i = Port - 1; 
    if (ComLink[i]->TxdStatus==TXDSEND)
        ComLink[i]->TxdTail=0;
    ComLink[i]->FrameHead=ComLink[i]->TxdTail;
    *(ComLink[i]->TxdBuf+ComLink[i]->FrameHead)=0xe5;
    ComLink[i]->LastControl=0xe5;
    ComLink[i]->TxdTail++;

    *(ComLink[i]->TxdBuf_Sec)=0xe5;
    ComLink[i]->TxdTail_Sec=1;
}



void S101_2002DLSendProc(INT8U Port)
{
    INT8U i;
    i = Port - 1;
    
    if(ComApp[i]->AppCommand&APP_HAVEDATA1)//还有一级数据
    {
        ComLink[i]->FlagData1=TRUE;
        ComApp[i]->AppCommand&=0x7FFF;
    }
    else
        ComLink[i]->FlagData1=FALSE;

    switch(ComApp[i]->AppCommand)
    {
        case APP_APPCON:	//应用层对收到的数据做应答
            EditSec101_2002Fra10(Port, DLCON);
            S101_2002SendDataToMISI(Port);
            break;
        case APP_APPDIABALE:	//应用层无效
            break;
        case APP_SENDCON:	//发送03命令
            S101_2002EditFra68(Port, DLSENDCON,ComApp[i]->LengthOut);
            S101_2002SendDataToMISI(Port);
            ComLink[i]->TimeOutTick_Pri=TimeDelay(Port,ComApp[i]->LengthOut+8+5)+(ComLink[i]->TimeOutValue/100);
            ComLink[i]->DLPriStatus=PRISENDCON;
            ComLink[i]->RetryCount=MAXRETRYNUM;
            break;
        case APP_SENDNOCON:	//发送04命令 平衡模式
            S101_2002EditFra68(Port, DLSENDNOCON,ComApp[i]->LengthOut);
            S101_2002SendDataToMISI(Port);
            ComLink[i]->TimeOutTick_Pri=0;
            break;
        case APP_SENDDATA://发送08命令
            EditSec101_2002Fra68(Port, DLRESDATA,ComApp[i]->LengthOut);
            S101_2002SendDataToMISI(Port);
            break;
        case APP_NODATA://应用层无数据
            if(!ComLink[i]->BalanMode)
            {
                SecEditE5(Port);
                S101_2002SendDataToMISI(Port);
            }
            break;
        case APP_NOJOB://应用层无任务
            if(ComApp[i]->BalanMode&&(ComLink[i]->DLPriStatus==PRIWAITSTATUS))
                CallDLStatus(Port);
            break;
        default:
            break;
    }
}

void CallUData(INT8U Port)//取紧急数据
{
    INT8U i;
    i= Port-1;
    	
    ComApp[i]->LengthIn=0;
    ComApp[i]->DLCommand=DL_CALLUDATA;
    Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                        ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);

    S101_2002EditFra68(Port,DLSENDCON,ComApp[i]->LengthOut);
    S101_2002SendDataToMISI(Port);
    ComLink[i]->TimeOutTick_Pri=TimeDelay(Port, (ComApp[i]->LengthOut+8+5))+(ComLink[i]->TimeOutValue/100);
    ComLink[i]->DLPriStatus=PRISENDCON;
    ComLink[i]->RetryCount=MAXRETRYNUM;
}

//平衡模式的遥控过程
void CallUMsg(INT8U Port)//取遥控消息
{
    INT8U i;
    i = Port-1;
    
    ComApp[i]->LengthIn=0;
    ComApp[i]->DLCommand=DL_CALLDBMSG;
    Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                        ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);

    if(ComApp[i]->LengthOut!=0)
    {
        S101_2002EditFra68(Port,DLSENDCON,ComApp[i]->LengthOut);
        S101_2002SendDataToMISI(Port);
        ComLink[i]->TimeOutTick_Pri=TimeDelay(Port, ComApp[i]->LengthOut+8+5)+(ComLink[i]->TimeOutValue/100);
        ComLink[i]->DLPriStatus=PRISENDCON;
        ComLink[i]->RetryCount=MAXRETRYNUM;
    }
}

void SendDataEnd(INT8U Port)  //发送结束
{
    INT8U i;
    
    i = Port - 1;
    
    if(ComLink[i]->DLPriStatus==PRIENABLE)
    {
        switch(ComLink[i]->LastControl)//最近一次发送的命令
        {
            case DLSENDNOCON://平衡模式,发送04命令后调用应用层服务
            case DLCON:
                ComApp[i]->DLCommand=DL_SCAN1S;
                ComApp[i]->LengthIn=0;
                Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                                    ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
                S101_2002DLSendProc(Port);
                break;
            default:
                break;
        }
    }
}

/*编辑10帧——启动站的10帧*/
void EditFra10(INT8U Port, INT8U Function)
{
    INT8U *p, i, j;

    i=Port-1;
    if (ComLink[i]->TxdStatus==TXDSEND)
        ComLink[i]->TxdTail=0;
    ComLink[i]->FrameHead=ComLink[i]->TxdTail;
    p=ComLink[i]->TxdBuf+ComLink[i]->FrameHead;
    p[0]=STARTCODE10;
    p[1]=Function;
    ComLink[i]->LastControl=Function;
    if ((Function==DLRESETRDL)||(Function==DLREQACD)||(Function==DLREQSTATUS))
        p[1]&=(~P101_FCV);
    else
        p[1]|=P101_FCV;

    if (p[1]&P101_FCV)//FCV有效,翻转FCB
    {
        if (ComLink[i]->TlaConCode&0x20)
        {
            p[1]&=(~P101_FCB);
            ComLink[i]->TlaConCode&=0xDF;
        }
        else
        {
            p[1]|=P101_FCB;
            ComLink[i]->TlaConCode|=0x20;
        }
    }
    else//FCV无效,清FCB
        p[1]&=(~P101_FCB);
    p[1]|=P101_PRM;
    p[1]&=(~P101_DIR);//清方向位,防止干扰。
    p[1]|=ComLink[i]->IEC_DIR;//子站向主站传输,平衡模式为1,非平衡模式为0。
    for(j=0;j<ComLink[i]->LinkAddrSize;j++)
        p[2+j]=((ComLink[i]->SourceNo>>(8*j))&0xff);
    p[2+ComLink[i]->LinkAddrSize]=CheckSum(Port,p);
    p[3+ComLink[i]->LinkAddrSize]=ENDCODE;
    ComLink[i]->TxdTail+=ComLink[i]->FixFrmLength;//移动发送尾指针

    memcpy(ComLink[i]->TxdBuf_Pri,p,ComLink[i]->FixFrmLength);//将发送数据保存到启动站重发数据区
    ComLink[i]->TxdTail_Pri=ComLink[i]->FixFrmLength;
}


BOOL	DLStatusCheck(INT8U Port)
{
	INT8U i;
	i = Port - 1;
	return (ComLink[i]->DLPriStatus==PRIENABLE);
}

//超时处理函数
void TimeOut(INT8U Port)
{
    INT8U i;
    i=Port-1;
    if(ComLink[i]->TimeOutTick_Pri)//单位是秒
    {
        ComLink[i]->TimeOutTick_Pri--;
        if(!ComLink[i]->TimeOutTick_Pri)
        {
            ComLink[i]->ComStatus.TimeOutCount++;
            TimeOutFun(Port,1,1);
        }
    }
    if(ComLink[i]->TimeOutTick_Sec)//单位是秒
    {
        ComLink[i]->TimeOutTick_Sec--;
        if(!ComLink[i]->TimeOutTick_Sec)
        {
            ComLink[i]->ComStatus.TimeOutCount++;
            TimeOutFun(Port,1,0);
        }
    }

    if(ComLink[i]->BalanMode)//平衡模式下,为了在链路空闲期内及时处理应用层的一级数据任务,在超过设定的空闲时间后每秒检测应用层一次。
    {
        ComLink[i]->IdleTimeCount++;
        if((ComLink[i]->IdleTimeCount>=ComLink[i]->DLIdleTime)&&(ComLink[i]->DLPriStatus==PRIENABLE))//DLIdleTime最小不能小于2
        {
            ComApp[i]->DLCommand=DL_SCAN1S;
            ComApp[i]->LengthIn=0;

            //应用层调用
            Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
                                ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
            S101_2002DLSendProc(Port);
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -