TMS320F28335: MODBUS RTU

Part Number: TMS320F28335

28335有MODBUS RTU例程吗

  • #include <stdlib.h>
    #include <string.h>
    #include "GlobalHeadFile.h"
    
    #ifndef Modbus_C
    #define Modbus_C
    
    Modbus_Callback	pWriteCoil_Callback = NULL;	//写Coil回调函数
    Modbus_Callback	pWriteHolding_Callback = NULL;	//写Holding回调函数
    
    /**
     * @brief 绑定写Coil的回调函数
     * 
     * @param pCallback : 回调函数地址
     */
    void Set_WriteCoil_Callback(Modbus_Callback pCallback)
    {
        if(pCallback != NULL)
        {
            pWriteCoil_Callback = pCallback;
        }
    }
    /**
     * @brief 绑定写Holding的回调函数
     * 
     * @param pCallback : 回调函数地址
     */
    void Set_WriteHolding_Callback(Modbus_Callback pCallback)
    {
        if(pCallback != NULL)
        {
            pWriteHolding_Callback = pCallback;
        }
    }
    /**
     * @brief                   整理Modbus错误应答帧
     * 
     * @param id                站号
     * @param funcCode          功能码
     * @param errCode           错误码
     * @param txData            发送缓冲
     * @param txDataLen         发送数据长度
     */
    void PackErrorResponse(Uint16 id,Uint16 funcCode,Uint16 errCode, Uint16* txData, Uint16* txDataLen)
    {
        *(txData)           = id;
        *(txData + 1)       = 0x80 | funcCode;
        *(txData + 2)       = errCode;
    
        CRC16_Append(txData,3);
    
        *txDataLen = 5;
    }
    
    /**
     * @brief 读取Coil
     * 
     * @param id        站号
     * @param startAddr 寄存器起始地址
     * @param number    寄存器个数
     * @param txData    发送缓冲区
     * @param txDataLen 发送数据长度
     */
    void PackResponse_ReadCoil(Uint16 id,Uint16 startAddr,Uint16 number, Uint16* txData, Uint16* txDataLen)
    {
        Uint16 idx;
        Uint16 coilValue;
        Uint16 byteNumber;
        *(txData)       = id;
        *(txData + 1)   = MFC_ReadCoil;
        byteNumber      = (number - 1) / 8 + 1;   //字节数
        *(txData + 2)   = byteNumber;
    
        for(idx = 0; idx < byteNumber; idx++)
        {
            coilValue = SysCoil_Get_Byte(startAddr + idx * 8);
            *(txData + 3 + idx) = coilValue;
        }
        
        CRC16_Append(txData,byteNumber + 3);
    
        *txDataLen = byteNumber + 5;
    }
    
    /**
     * @brief 写单个Coil
     * 应答帧与请求帧一模一样
     * @param id        : 站号
     * @param rxData    : 接收的数据帧
     * @param rxDataLen : 接收的数据长度
     * @param txData    : 发送的数据缓冲
     * @param txDataLen : 发送的数据长度
     */
    void PackResponse_WriteSingleCoil(Uint16 id,Uint16* rxData, Uint16 rxDataLen, Uint16* txData, Uint16* txDataLen)
    {
        //写单个寄存器时,regNumber既是写入的值: 0xFF00/0x0000
        Uint16 coilValue = ((Uint16)*(rxData + 4) << 8 ) | *(rxData + 5);
        Uint16 coilValue_Bool = (coilValue == 0xFF00) ? 1 : 0;
    
        //写入的值必须是0xFF00或0x0000,否则是非法值
        if((coilValue != 0xFF00) && (coilValue != 0))
        {
            PackErrorResponse(id,MFC_WriteSingleCoil,MEC_InvalidValue,txData,txDataLen);
            return;
        }
        //没有处理函数,则返回不支持功能错误
        if(pWriteCoil_Callback == NULL)
        {
            PackErrorResponse(id,MFC_WriteSingleCoil,MEC_InvalidFunction,txData,txDataLen);
            return;
        }
        
        Uint16 coilAddr = ((Uint16)*(rxData + 2) << 8 ) | *(rxData + 3);
        (*pWriteCoil_Callback)(coilAddr,1,&coilValue_Bool);
    
        Uint16 i = 0;
        while (i < rxDataLen)
        {
            *(txData + i)   = *(rxData + i);
            i++;
        }
        
        *txDataLen = rxDataLen;
    }
    
    /**
     * @brief 写多个Coil
     * @param id        : 站号
     * @param rxData    : 接收的数据帧
     * @param rxDataLen : 接收的数据长度
     * @param txData    : 发送的数据缓冲
     * @param txDataLen : 发送的数据长度
     */
    void PackResponse_WriteMultiCoil(Uint16 id,Uint16* rxData, Uint16 rxDataLen, Uint16* txData, Uint16* txDataLen)
    {
        //注意,写入的值CoilValue,是按字节排布的,每个bit代表一个Coil的值
        Uint16 coilAddr = ((Uint16)*(rxData + 2) << 8 ) | *(rxData + 3);
        Uint16 coilNumber = ((Uint16)*(rxData + 4) << 8 ) | *(rxData + 5);
        Uint16 byteNumber = (Uint16)*(rxData + 6);
    
        //判断帧数据长度是否正确,返回错误值错误
        if(((coilNumber-1)/8 + 1 != byteNumber) || (rxDataLen != byteNumber + 9))
        {
            PackErrorResponse(id,MFC_WriteMultipleCoils,MEC_InvalidValue,txData,txDataLen);
            return;
        }
        //没有处理函数,则返回不支持功能错误
        if(pWriteCoil_Callback == NULL)
        {
            PackErrorResponse(id,MFC_WriteSingleCoil,MEC_InvalidFunction,txData,txDataLen);
            return;
        }
        
        //调用命令执行函数
        (*pWriteCoil_Callback)(coilAddr,coilNumber,(rxData+7));
    
        Uint16 i = 0;
        while (i < 6)
        {
            *(txData + i)   = *(rxData + i);
            i++;
        }
        CRC16_Append(txData,6);
        
        *txDataLen = 8;
    }
    
    /**
     * @brief 处理读取Holding应答消息
     * 
     * @param id        站号
     * @param startAddr 寄存器起始地址
     * @param number    寄存器个数
     * @param txData    发送缓冲区
     * @param txDataLen 发送数据长度
     */
    void PackResponse_ReadHolding(Uint16 id,Uint16 startAddr,Uint16 number, Uint16* txData, Uint16* txDataLen)
    {
        Uint16 idx;    
        Uint16 holdValue;
        *(txData)       = id;
        *(txData + 1)   = MFC_ReadHolding;
        *(txData + 2)   = number * 2;
        for(idx = 0; idx < number; idx ++)
        {
            holdValue = SysHolding_Get(startAddr+idx);
            *(txData + idx * 2 + 3)   = holdValue >> 8;
            *(txData + idx * 2 + 4)   = holdValue & 0xFF;
        }
    
        CRC16_Append(txData,number*2 + 3);
    
        *txDataLen = number*2 + 5;
    }
    
    /**
     * @brief 写单个Holding
     * @param id        : 站号
     * @param rxData    : 接收的数据帧
     * @param rxDataLen : 接收的数据长度
     * @param txData    : 发送的数据缓冲
     * @param txDataLen : 发送的数据长度
     */
    void PackResponse_WriteSingleHolding(Uint16 id,Uint16* rxData, Uint16 rxDataLen, Uint16* txData, Uint16* txDataLen)
    {
        Uint16 regAddr = ((Uint16)*(rxData + 2) << 8 ) | *(rxData + 3);
    //    Uint16 regValue = ((Uint16)*(rxData + 4) << 8 ) | *(rxData + 5);
    
        //没有处理函数,则返回不支持功能错误
        if(pWriteHolding_Callback == NULL)
        {
            PackErrorResponse(id,MFC_WriteSingleHolding,MEC_InvalidFunction,txData,txDataLen);
            return;
        }
        
        //(*pWriteHolding_Callback)(regAddr,1,&regValue);
        (*pWriteHolding_Callback)(regAddr,1,(rxData + 4));
    
        Uint16 i = 0;
        while (i < rxDataLen)
        {
            *(txData + i)   = *(rxData + i);
            i++;
        }
        
        *txDataLen = rxDataLen;
    }
    
    /**
     * @brief 写多个Holding
     * @param id        : 站号
     * @param rxData    : 接收的数据帧
     * @param rxDataLen : 接收的数据长度
     * @param txData    : 发送的数据缓冲
     * @param txDataLen : 发送的数据长度
     */
    void PackResponse_WriteMultiHolding(Uint16 id,Uint16* rxData, Uint16 rxDataLen, Uint16* txData, Uint16* txDataLen)
    {
        Uint16 regAddr = ((Uint16)*(rxData + 2) << 8 ) | *(rxData + 3);
        Uint16 regNumber = ((Uint16)*(rxData + 4) << 8 ) | *(rxData + 5);
        Uint16 byteNumber = (Uint16)*(rxData + 6);
    
        //没有处理函数,则返回不支持功能错误
        if(pWriteHolding_Callback == NULL)
        {
            PackErrorResponse(id,MFC_WriteMultipleHoldings,MEC_InvalidFunction,txData,txDataLen);
            return;
        }
    
        //判断帧数据长度是否正确,返回错误值错误
        if((regNumber * 2 != byteNumber) || (rxDataLen != byteNumber + 9))
        {
            PackErrorResponse(id,MFC_WriteMultipleHoldings,MEC_InvalidValue,txData,txDataLen);
            return;
        }
        
        (*pWriteHolding_Callback)(regAddr,regNumber,(rxData + 7));
    
        Uint16 i = 0;
        while (i < 6)
        {
            *(txData + i)   = *(rxData + i);
            i++;
        }
    
        CRC16_Append(txData,6);
        *txDataLen = 8;
    }
    
    
    /**
     * @brief 解析收到的帧
     * 
     * @param rxData    接收到的数据
     * @param rxDataLen 接收到的数据长度
     * @param slaveId   站号
     * @param txData    发送数据缓冲
     * @param txDataLen 发送数据长度
     */
    void Modbus_ProcessFrame(Uint16* rxData, Uint16 rxDataLen, Uint16 slaveId, Uint16* txData, Uint16* txDataLen)
    {
        Uint16 crcGet;          /** 收到的数据中CRC码 */
        Uint16 crcCalc;         /** 计算出来 CRC码 */
        Uint16 startAddr;       /** 起始地址*/
        Uint16 regNumber;       /** 寄存器个数*/
    
        /** 接收数据长度或Id不匹配,这里匹配广播地址*/
        if((rxData == NULL)  || (rxDataLen < 7) || ((*(rxData) != slaveId) && (*(rxData) != ID_BROADCAST)) )
        {
            *txDataLen = 0;
            return;
        }
    
        /** CRC校验 */
        crcGet = (Uint16)(*(rxData + rxDataLen - 2) << 8) | *(rxData + rxDataLen - 1);
        crcCalc = CRC16_Calc(rxData,rxDataLen-2);
        /** CRC校验失败,非广播消息时应答*/
        if(crcGet != crcCalc)
        {
            if(*(rxData) != ID_BROADCAST)
            {
                PackErrorResponse(slaveId,*(rxData + 1),MEC_CRCError, txData, txDataLen);
            }
            else
            {
                *txDataLen = 0;
            }
            return;
        }
    
        startAddr = ((Uint16)*(rxData + 2) << 8 ) | *(rxData + 3);
        regNumber = ((Uint16)*(rxData + 4) << 8 ) | *(rxData + 5);
    
        /** 根据功能码进行相应处理 */
        switch (*(rxData + 1))
        {
        case MFC_ReadCoil:  //读取Coil
            PackResponse_ReadCoil(slaveId,startAddr,regNumber,txData,txDataLen);
            break ;
    
        case MFC_ReadHolding:   //读取Holding
            PackResponse_ReadHolding(slaveId,startAddr,regNumber,txData,txDataLen);
            break;
    
        case MFC_WriteSingleCoil: //写单个Coil寄存器,FuncCode(1Byte) + Addr(2Bytes) + Value(2Bytes)
            PackResponse_WriteSingleCoil(slaveId,rxData,rxDataLen,txData,txDataLen);
            break;
    
        case MFC_WriteMultipleCoils: //写多个Coil,FuncCode(1Byte) + Addr(2Bytes) + CoilNum(2Bytes) + ByteNum(1Byte)+CoilValue((CoilNum-1)/8+1)
            PackResponse_WriteMultiCoil(slaveId,rxData,rxDataLen,txData,txDataLen);
            break;
    
        case MFC_WriteSingleHolding:   //写单个Holding
            PackResponse_WriteSingleHolding(slaveId,rxData,rxDataLen,txData,txDataLen);
            break;
    
        case MFC_WriteMultipleHoldings: //写多个Holding
            PackResponse_WriteMultiHolding(slaveId,rxData,rxDataLen,txData,txDataLen);
            break;
    
        case MFC_Upgrade:               //更新程序
            //调用UPProtocol处理函数,去掉帧头(id)和帧尾(CRC)
    		UPProtocol_ProcessFrame(&rxData[1],rxDataLen - 3,&txData[1],txDataLen);
            if(txData > 0)
            {
                txData[0] = slaveId;
                CRC16_Append(txData,*txDataLen + 1);
                *txDataLen   += 3;
            }
            break;
        default:
            PackErrorResponse(slaveId, *(rxData + 1),MEC_InvalidAddress, txData, txDataLen);
            break ;
        }
    
        /** 广播消息,不应答,将发送长度设置为0 */
        if(*(rxData) == ID_BROADCAST)
        {
            *txDataLen = 0;
        }
    }
    
    #endif  //#ifndef Modbus_C
    
    

  • 请问整个工程文件在哪下载