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

📄 modbus.c.svn-base

📁 给MOTO 360 单片机 开发的MODBUS协议 直流奥特寻协议。。要用SDS编译
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
        {
            (*pCoil) |= (1 << (LocCoilRef%8));
        }
        else
        {
            (*pCoil) &= (~(1 << (LocCoilRef%8)));
        }
        READY_DATA = 1;
        Ret = 1;
    }
    return Ret;
}

static int ModbusGetCoils(int LocCoilRef, int CoilN, void * pData)
{
    int Ret = 0;
    unsigned char * pCoil;
    if(LocCoilRef + CoilN < MODBUS_MAX_COIL)
    {
        pCoil = (unsigned char *)(HRDATA_BASE + MODBUS_COILDATA_OFFSET);
        pCoil += (LocCoilRef/8);
        READY_DATA = 0;
        while(READY_DATA);
        bitcpy((unsigned char *)pData, pCoil, 0, (LocCoilRef%8), CoilN);
        READY_DATA = 1;
        Ret = CoilN;
    }
    return Ret;
}

//Val=0xFF:置1 =0x00:置0
static int ModbusGetCoil(int LocCoilRef, unsigned char * Val)
{
    int Ret = 0;
    unsigned char * pCoil;
    if(LocCoilRef < MODBUS_MAX_COIL)
    {
        pCoil = (unsigned char *)(HRDATA_BASE + MODBUS_COILDATA_OFFSET);
        pCoil += (LocCoilRef/8);
        READY_DATA = 0;
        while(READY_DATA);

        if(((*pCoil) &= (1 << (LocCoilRef%8))) > 0)
        {
            (*Val) = 0xFF;
        }
        else
        {
            (*Val) = 0x00;
        }
        READY_DATA = 1;
        Ret = 1;
    }
    return Ret;
}

/***********************************************SLAVE***********************************************/
void SCC_comproc_modebus_s(int port_number)
{
    unsigned short i, RefNum, N, nBytes, SendLen = 0;

    /*SendLen 包括CRC在内的发送长度*/

    //接收判断
    if (SCC_RBUF[port_number][0]!=SCC_STNO[port_number])
    {
        goto intbk;	
    }

    if (((*SCC_RX_BD0_LN[port_number])<=2)||((*SCC_RX_BD0_LN[port_number])>256)) 
    {
        goto intbk;
    }

    i=CRC16(SCC_RBUF[port_number],(*SCC_RX_BD0_LN[port_number])-2);
    if (i!=*(SCC_RBUF[port_number]+(*SCC_RX_BD0_LN[port_number])-2)+(*(SCC_RBUF[port_number]+(*SCC_RX_BD0_LN[port_number])-1)*0x100)) 
    {
        goto intbk;//Lowbyte first.
    }

    RefNum = SCC_RBUF[port_number][2]*0x100+SCC_RBUF[port_number][3];
    N = SCC_RBUF[port_number][4]*0x100+SCC_RBUF[port_number][5];


    DBDataPrint(*SCC_RX_BD0_LN[port_number], port_number, SCC_RBUF[port_number], DIAG_RECV_MSG);

    switch(SCC_RBUF[port_number][1])
    {
    case 1:
    case 2:
        {
            if(ModbusGetCoils(RefNum, N, SCC_TBUF[port_number] + 3) == N)
            {
                nBytes=(N+7)/8;
                SCC_TBUF[port_number][0] = SCC_STNO[port_number];
                SCC_TBUF[port_number][1] = SCC_RBUF[port_number][1];
                SCC_TBUF[port_number][2] = nBytes;		//NBytes
                SendLen = 5+nBytes;
            }
            else
            {

                SCC_TBUF[port_number][0] = SCC_STNO[port_number];
                SCC_TBUF[port_number][1] = SCC_RBUF[port_number][1] + 0x80;
                SCC_TBUF[port_number][2] = 0x01;
                SendLen = 5;
            }
            break;
        }
    case 5:
        {

            if(ModbusSetCoil(RefNum, SCC_RBUF[port_number][4]) == 1)
            {
                SCC_TBUF[port_number][0]=SCC_STNO[port_number];
                SCC_TBUF[port_number][1]=SCC_RBUF[port_number][1];
                SCC_TBUF[port_number][2]=SCC_RBUF[port_number][2];
                SCC_TBUF[port_number][3]=SCC_RBUF[port_number][3];
                SCC_TBUF[port_number][4]=SCC_RBUF[port_number][4];
                SCC_TBUF[port_number][5]=SCC_RBUF[port_number][5];
                SendLen = 8;
            }
            else
            {
                SCC_TBUF[port_number][0]=SCC_STNO[port_number];
                SCC_TBUF[port_number][1]=SCC_RBUF[port_number][1] + 0x80;
                SCC_TBUF[port_number][2]=0x01;
                SendLen = 5;
            }
            break;
        }
    case 15:
        {
            if(ModbusSetCoils(RefNum, N, SCC_RBUF[port_number]+7) == N)
            {
                SCC_TBUF[port_number][0]=SCC_STNO[port_number];
                SCC_TBUF[port_number][1]=SCC_RBUF[port_number][1];
                SCC_TBUF[port_number][2]=SCC_RBUF[port_number][2];
                SCC_TBUF[port_number][3]=SCC_RBUF[port_number][3];
                SCC_TBUF[port_number][4]=SCC_RBUF[port_number][4];
                SCC_TBUF[port_number][5]=SCC_RBUF[port_number][5];
                SendLen = 8;
            }
            else
            {
                SCC_TBUF[port_number][0]=SCC_STNO[port_number];
                SCC_TBUF[port_number][1]=SCC_RBUF[port_number][1] + 0x80;
                SCC_TBUF[port_number][2]=0x01;
                SendLen = 5;
            }
            break;
        }
    case 3:
    case 4:
        {
            if(ModbusGetRegs(RefNum, N, SCC_TBUF[port_number]+3) == N)
            {
                SCC_TBUF[port_number][0]=SCC_STNO[port_number];
                SCC_TBUF[port_number][1]=SCC_RBUF[port_number][1];
                SCC_TBUF[port_number][2]=N*2;	//NBytes
                SendLen = 5+N*2;
            }
            else
            {
                SCC_TBUF[port_number][0]=SCC_STNO[port_number];
                SCC_TBUF[port_number][1]=SCC_RBUF[port_number][1] + 0x80;
                SCC_TBUF[port_number][2]=0x01;
                SendLen = 5;
            }
            break;
        }
    case 6:
        {
            if(ModbusSetRegs(RefNum, 1, SCC_RBUF[port_number] + 4) == 1)
            {
                SCC_TBUF[port_number][0]=SCC_STNO[port_number];
                SCC_TBUF[port_number][1]=SCC_RBUF[port_number][1];
                SCC_TBUF[port_number][2]=SCC_RBUF[port_number][2];
                SCC_TBUF[port_number][3]=SCC_RBUF[port_number][3];
                SCC_TBUF[port_number][4]=SCC_RBUF[port_number][4];
                SCC_TBUF[port_number][5]=SCC_RBUF[port_number][5];
                SendLen = 8;
            }
            else
            {
                SCC_TBUF[port_number][0]=SCC_STNO[port_number];
                SCC_TBUF[port_number][1]=SCC_RBUF[port_number][1] + 0x80;
                SCC_TBUF[port_number][2]=0x01;
                SendLen = 5;
            }
            break;
        }
    case 16:
        {
            if(ModbusSetRegs(RefNum, N, SCC_RBUF[port_number] + 7) == N)
            {
                SCC_TBUF[port_number][0]=SCC_STNO[port_number];
                SCC_TBUF[port_number][1]=SCC_RBUF[port_number][1];
                SCC_TBUF[port_number][2]=SCC_RBUF[port_number][2];
                SCC_TBUF[port_number][3]=SCC_RBUF[port_number][3];
                SCC_TBUF[port_number][4]=SCC_RBUF[port_number][4];
                SCC_TBUF[port_number][5]=SCC_RBUF[port_number][5];
                SendLen = 8;
            }
            else
            {
                SCC_TBUF[port_number][0]=SCC_STNO[port_number];
                SCC_TBUF[port_number][1]=SCC_RBUF[port_number][1] + 0x80;
                SCC_TBUF[port_number][2]=0x01;
                SendLen = 5;
            }
            break;
        }
    default:
        {
            goto intbk;	
            break;
        }

    }

    /*CRC*/
    i=CRC16(SCC_TBUF[port_number],SendLen - 2);
    SCC_TBUF[port_number][SendLen - 2]=i&0xff;				//lo first
    SCC_TBUF[port_number][SendLen - 1]=i>>8;

    /*Send*/
    ((struct GSMR_L*)GSMR_L[port_number])->ENT=0;
    (*SCC_TX_BD0_LN[port_number])=SendLen;
    (*SCC_TX_BD0_ST[port_number])=0xB000;
    ((struct GSMR_L*)GSMR_L[port_number])->ENT=1;


intbk:	

    (*SCC_RX_BD0_ST[port_number])=0xb000;	
    (*SCC_RX_BD0_LN[port_number])=0x0;

    DBDataPrint(*SCC_TX_BD0_LN[port_number], port_number, SCC_TBUF[port_number], DIAG_SEND_MSG);

    return;
}

//检查主站收到的Modbus数据是否正确,返回0:正确,返回>0错误
int CheckMModbusMsg(unsigned char * pMsg, int nRecvLen, int nStationNo, int FunctionCode)
{
    int Ret = 0;
    unsigned short usCRC;       //数据中的CRC
    unsigned short usDataLen;   //数据长度,不包括CRC
    if(nRecvLen > 5 && nRecvLen < 260)      //LenOK
    {
        if(pMsg[0] == nStationNo)
        {
            if(pMsg[1] == FunctionCode)
            {
                switch(FunctionCode)
                {
                case 1:
                case 2:
                case 3:
                case 4:
                    usDataLen = pMsg[2] + 3;
                    break;
                case 5:
                case 6:
                case 15:
                case 16:
                    usDataLen = 6;
                    break;
                }
                usCRC = pMsg[usDataLen] + pMsg[usDataLen + 1] * 0x100;
                if(usDataLen + 2 <= nRecvLen && usCRC == CRC16(pMsg, usDataLen))
                {
                    Ret = 0;    //CRC OK
                }
                else    //CRC ERROR
                {
                    Ret = 4;
                }
            }
            else//FunctionCode
            {
                Ret = 6;
            }
        }
        else//nStationNo
        {
            Ret = 3;
        }
    }
    else//nRecvLen
    {
        Ret = 5;
    }




    return Ret;
}


//////////////////////////////////////////////
//Modbus 主站接收处理函数
//////////////////////////////////////////////
void SCC_comproc_modebus_m(int port_number)
{
    unsigned short i, NBytes, N, LocRefNum, error = DIAG_RECV_MSG;
    unsigned char * pMsg;
    int nRecvLen;
    int nStationNo;
    int FunctionCode;

    pMsg = SCC_RBUF[port_number];
    nRecvLen = *SCC_RX_BD0_LN[port_number];
    nStationNo = SCC_TASK_STNO[port_number][SCC_TASKID[port_number]];
    FunctionCode = SCC_TASK_RW[port_number][SCC_TASKID[port_number]];


    if((error = CheckMModbusMsg(pMsg, nRecvLen, nStationNo, FunctionCode)) != 0)
    {
        goto intbk;
    }



    //if (((*SCC_RX_BD0_LN[port_number])<=5)||((*SCC_RX_BD0_LN[port_number])>260)) 
    //{
    //    error = 5;//长度有错误。滤掉
    //    goto intbk;
    //}

    //i=CRC16(SCC_RBUF[port_number],(*SCC_RX_BD0_LN[port_number])-2);
    //if (i!=*(SCC_RBUF[port_number]+(*SCC_RX_BD0_LN[port_number])-2)+(*(SCC_RBUF[port_number]+(*SCC_RX_BD0_LN[port_number])-1)*0x100)) 
    //{
    //    error = 4;
    //    goto intbk;//Lowbyte first.
    //}


    //if (SCC_RBUF[port_number][0]!=SCC_TASK_STNO[port_number][SCC_TASKID[port_number]]) 
    //{
    //    error = 3;
    //    goto intbk;
    //}

    if (SCC_BUSY[port_number]!=1)
    {
        error = 2;
        goto intbk;
    }

⌨️ 快捷键说明

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