• 通信缓冲数据ModBusRTU


    #include "ModBusRTU.h"


    //通信缓冲数据
    ModBusRTU_CommInfoType    g_datModBusRTUSendInfo,g_datModBusRTUReciveInfo;


    uint8_t        g_arrayModBusRTUBuffer[MODBUSRTU_BUFLEN*2];                               /* 数据缓冲区 ,此数据缓冲区长度可根据单片机资源适当调大,以提高通讯速度*/
    uint8_t        *g_pModBusRTUBuffer = g_arrayModBusRTUBuffer;
    uint8_t        *g_pModBusRTUBufferHead = g_arrayModBusRTUBuffer;
    uint8_t        *g_pModBusRTUBufferTail = &g_arrayModBusRTUBuffer[MODBUSRTU_BUFLEN];        //指向数组的末尾
    uint8_t        g_ModBusRTURecv_Flag = 0;
    uint16_t    g_ModBusRTURecv_Length = 0;


    //网络接受缓冲器
    uint8_t        g_arrayModBusRTURecBuf[MODBUSRTU_BUFLEN] = {0};

    //应答数据缓存
    uint8_t g_arrayModBusRTUTxBuf[MODBUSRTU_BUFLEN];
    uint16_t g_ModBusRTUTxLen;
    void (*g_pFunModBusRTUSendDat)(uint8_t *pDat,uint16_t len);

    static void IOA_ModBusRTUDataBackup(uint8_t *pDat,uint16_t len);

    uint16_t crc16(uint8_t *ptr, uint8_t len)
    {
        uint16_t crc=0xFFFF;
        uint8_t i;
        while(len--)
        {
            crc ^=*ptr++;
            for(i=0;i<8;i++)
            {
                if(crc & 0x01)
                {
                    crc>>=1; crc^=0xA001;
                }
                else
                {
                    crc>>=1;
                }
            }
        }
        return crc;
    }


    static void IOA_ModBusRTUDataBackup(uint8_t *pDat,uint16_t len)
    {
        uint16_t surLen;
        if(len > 0 && len <= MODBUSRTU_BUFLEN)
        {
            if((g_ModBusRTURecv_Length + len) <= MODBUSRTU_BUFLEN)  // 如果如果接收完该数据还未到缓冲区的末尾,即缓冲区剩余空间能够存储下该帧数据
            {
                surLen = (uint16_t)(g_pModBusRTUBufferTail - g_pModBusRTUBufferHead);   // 计算缓冲区中剩余的数据空间,地址数相减
                if(len > surLen)  // 如果剩余的数据空间不够存储长度为LEN的数据
                {
                    if(surLen > 0)
                    {
                        memcpy(g_pModBusRTUBufferHead,pDat,surLen);
                        g_ModBusRTURecv_Length += surLen;
                    }
                    g_pModBusRTUBufferHead = g_arrayModBusRTUBuffer;                 // 帧头移到缓冲区开头
                    len = len - surLen;                                        // 计算剩余未读数据的长度
                    memcpy(g_pModBusRTUBufferHead,&(pDat[surLen]),len);
                    g_ModBusRTURecv_Length += len;  // 接收缓冲区的数据长度 = 刚接收的数据长度
                }
                else  // 如果剩余的数据空间够存储长度为LEN的数据,则将数据存储head处
                {
                    memcpy(g_pModBusRTUBufferHead,pDat,len);
                    g_ModBusRTURecv_Length += len;
                }    
            }
            else        //如果接收数据的长度大于缓冲区的长度,则丢弃缓冲区
            {
                g_pModBusRTUBufferHead = g_arrayModBusRTUBuffer;   // g_pSocketBufferHead指针指向缓冲区的开头
                g_pModBusRTUBuffer = g_pModBusRTUBufferHead;       // g_pSocketBuffer指针也指向缓冲区的开头
                
                memcpy(g_pModBusRTUBufferHead,pDat,len);
                g_ModBusRTURecv_Length = len;
            }
            g_pModBusRTUBufferHead += len;    
            if(g_pModBusRTUBufferHead > g_pModBusRTUBufferTail)                    //仅仅用于调试使用这个代码在工程中无效
            {
                int i = 1;
                i++;
            }
            g_ModBusRTURecv_Flag = 1;  // 接收完成后标志位置1
        }
    }

    void ModBusRTU_ask( void )
    {
        uint8_t    serial_i = 0;
        uint8_t    remainderNumTemp = 0, remainderAddrTemp = 0;
        uint16_t divisorAddrTemp = 0;
        uint16_t ctcCheckTemp;
        g_arrayModBusRTUTxBuf[0] = g_ucModBus_ID;
        g_arrayModBusRTUTxBuf[1] = g_datModBusRTUReciveInfo.mode;
        switch(g_datModBusRTUReciveInfo.mode)
        {
            case MODBUSRTU_FUNC01:
            {
                g_arrayModBusRTUTxBuf[2] = g_datModBusRTUReciveInfo.regNum/8;
                remainderNumTemp = g_datModBusRTUReciveInfo.regNum%8;
                if(remainderNumTemp)
                {
                    g_arrayModBusRTUTxBuf[2] += 1;
                }
                //先把数据清零
                for(serial_i = 0; serial_i < g_arrayModBusRTUTxBuf[2]; serial_i++)
                {
                        g_arrayModBusRTUTxBuf[3 + serial_i] = 0;
                }
                //进行赋值操作
                for(serial_i = 0; serial_i < g_datModBusRTUReciveInfo.regNum; serial_i++)
                {
                    divisorAddrTemp = (g_datModBusRTUReciveInfo.regAddr + serial_i)/8;
                    remainderAddrTemp = (g_datModBusRTUReciveInfo.regAddr + serial_i)%8;
                    if(g_bit0xDat[divisorAddrTemp] & (0x01<                 {
                        g_arrayModBusRTUTxBuf[2 + g_arrayModBusRTUTxBuf[2] - serial_i/8] |= (0x01<<(serial_i%8));
                    }
                }
                ctcCheckTemp = crc16(g_arrayModBusRTUTxBuf,3 + g_arrayModBusRTUTxBuf[2]);
                //注意,ModBusRTU CRC校验位低位在前。
                g_arrayModBusRTUTxBuf[3 + g_arrayModBusRTUTxBuf[2]] = (uint8_t)ctcCheckTemp;
                g_arrayModBusRTUTxBuf[4 + g_arrayModBusRTUTxBuf[2]] = (uint8_t)(ctcCheckTemp >> 8);
                g_ModBusRTUTxLen = 5 + g_arrayModBusRTUTxBuf[2];
                break;
            }
            case MODBUSRTU_FUNC02:
            {
                g_arrayModBusRTUTxBuf[2] = g_datModBusRTUReciveInfo.regNum/8;
                remainderNumTemp = g_datModBusRTUReciveInfo.regNum%8;
                if(remainderNumTemp)
                {
                    g_arrayModBusRTUTxBuf[2] += 1;
                }
                //先把数据清零
                for(serial_i = 0; serial_i < g_arrayModBusRTUTxBuf[2]; serial_i++)
                {
                        g_arrayModBusRTUTxBuf[3 + serial_i] = 0;
                }
                //进行赋值操作
                for(serial_i = 0; serial_i < g_datModBusRTUReciveInfo.regNum; serial_i++)
                {
                    divisorAddrTemp = (g_datModBusRTUReciveInfo.regAddr + serial_i)/8;
                    remainderAddrTemp = (g_datModBusRTUReciveInfo.regAddr + serial_i)%8;
                    if(g_bit1xDat[divisorAddrTemp] & (0x01<                 {
                        g_arrayModBusRTUTxBuf[2 + g_arrayModBusRTUTxBuf[2] - serial_i/8] |= (0x01<<(serial_i%8));
                    }
                }
                
                ctcCheckTemp = crc16(g_arrayModBusRTUTxBuf,3 + g_arrayModBusRTUTxBuf[2]);
                //注意,ModBusRTU CRC校验位低位在前。
                g_arrayModBusRTUTxBuf[3 + g_arrayModBusRTUTxBuf[2]] = (uint8_t)ctcCheckTemp;
                g_arrayModBusRTUTxBuf[4 + g_arrayModBusRTUTxBuf[2]] = (uint8_t)(ctcCheckTemp >> 8);
                g_ModBusRTUTxLen = 5 + g_arrayModBusRTUTxBuf[2];
                break;
            }
            case MODBUSRTU_FUNC03:
            {
                g_arrayModBusRTUTxBuf[2] = g_datModBusRTUReciveInfo.regNum * 2;
                for(serial_i = 0; serial_i < g_arrayModBusRTUTxBuf[2]; serial_i++)
                {
                    if(serial_i%2)
                    {
                        g_arrayModBusRTUTxBuf[3 + serial_i] = (uint8_t)g_word4xDat[g_datModBusRTUReciveInfo.regAddr + serial_i/2];
                    }
                    else
                    {
                        g_arrayModBusRTUTxBuf[3 + serial_i] = (uint8_t)(g_word4xDat[g_datModBusRTUReciveInfo.regAddr + serial_i/2] >> 8);
                    }
                }
                ctcCheckTemp = crc16(g_arrayModBusRTUTxBuf,3 + g_arrayModBusRTUTxBuf[2]);
                g_arrayModBusRTUTxBuf[3 + g_arrayModBusRTUTxBuf[2]] = (uint8_t)ctcCheckTemp;
                g_arrayModBusRTUTxBuf[4 + g_arrayModBusRTUTxBuf[2]] = (uint8_t)(ctcCheckTemp >> 8);
                g_ModBusRTUTxLen = 5 + g_arrayModBusRTUTxBuf[2];
                break;
            }
            case MODBUSRTU_FUNC04:
            {
                g_arrayModBusRTUTxBuf[2] = g_datModBusRTUReciveInfo.regNum * 2;
                for(serial_i = 0; serial_i < g_arrayModBusRTUTxBuf[2]; serial_i++)
                {
                    if(serial_i%2)
                    {
                        g_arrayModBusRTUTxBuf[3 + serial_i] = (uint8_t)g_word3xDat[g_datModBusRTUReciveInfo.regAddr + serial_i/2];
                    }
                    else
                    {
                        g_arrayModBusRTUTxBuf[3 + serial_i] = (uint8_t)(g_word3xDat[g_datModBusRTUReciveInfo.regAddr + serial_i/2] >> 8);
                    }
                }
                ctcCheckTemp = crc16(g_arrayModBusRTUTxBuf,3 + g_arrayModBusRTUTxBuf[2]);
                g_arrayModBusRTUTxBuf[3 + g_arrayModBusRTUTxBuf[2]] = (uint8_t)ctcCheckTemp;
                g_arrayModBusRTUTxBuf[4 + g_arrayModBusRTUTxBuf[2]] = (uint8_t)(ctcCheckTemp >> 8);
                g_ModBusRTUTxLen = 5 + g_arrayModBusRTUTxBuf[2];
                break;
            }
            case MODBUSRTU_FUNC05:
            case MODBUSRTU_FUNC15:
            case MODBUSRTU_FUNC06:
            case MODBUSRTU_FUNC16:
            {
                g_arrayModBusRTUTxBuf[2] = (uint8_t)(g_datModBusRTUReciveInfo.regAddr >> 8);
                g_arrayModBusRTUTxBuf[3] = (uint8_t)(g_datModBusRTUReciveInfo.regAddr);
                g_arrayModBusRTUTxBuf[4] = (uint8_t)(g_datModBusRTUReciveInfo.regNum >> 8);
                g_arrayModBusRTUTxBuf[5] = (uint8_t)(g_datModBusRTUReciveInfo.regNum);
                ctcCheckTemp = crc16(g_arrayModBusRTUTxBuf,6);
                g_arrayModBusRTUTxBuf[6] = (uint8_t)ctcCheckTemp;
                g_arrayModBusRTUTxBuf[7] = (uint8_t)(ctcCheckTemp >> 8);
                g_ModBusRTUTxLen = 8;
                
                break;
            }
            default:
            {
                break;
            }
        }
        
        MODBUSRTU_SENDDATA(g_arrayModBusRTUTxBuf,g_ModBusRTUTxLen);
    }


    void ModBusRTU_UartHandle(uint8_t *pDat,uint16_t len)
    {
        uint8_t    serial_i = 0;
        uint8_t    remainderNumTemp = 0;
        uint8_t    remainderAddrTemp = 0;
        uint16_t divisorAddrTemp = 0;
        uint16_t ctcCheckTemp = 0;
        uint16_t surLen = 0;
        uint8_t        datlessFlag = 0;
        uint8_t *pPosTemp = g_arrayModBusRTURecBuf;
        IOA_ModBusRTUDataBackup(pDat, len);
        if(g_ModBusRTURecv_Flag == 1)        //有网络数据没有处理
        {
            while(g_ModBusRTURecv_Length >= MODBUSRTU_LESSLEN)        //至少有12个数据包
            {
                surLen = g_pModBusRTUBufferTail - g_pModBusRTUBuffer;
                if(surLen >= MODBUSRTU_LEN_HEAD)
                {
                    memcpy(g_arrayModBusRTURecBuf, g_pModBusRTUBuffer, MODBUSRTU_LEN_HEAD);
                }
                else
                {
                    memcpy(g_arrayModBusRTURecBuf, g_pModBusRTUBuffer, surLen);
                    memcpy(&g_arrayModBusRTURecBuf[surLen], g_arrayModBusRTUBuffer, MODBUSRTU_LEN_HEAD - surLen);
                }
                pPosTemp = g_arrayModBusRTURecBuf;
                g_datModBusRTUReciveInfo.id = *((uint16_t *)pPosTemp);
                g_datModBusRTUReciveInfo.mode = *(pPosTemp + 1);
                g_datModBusRTUReciveInfo.regAddr = (((uint16_t)pPosTemp[2])<<8) + pPosTemp[3];
                g_datModBusRTUReciveInfo.regNum = (((uint16_t)pPosTemp[4])<<8) + pPosTemp[5];
                if(g_datModBusRTUReciveInfo.id == g_ucModBus_ID)
                {
                    switch(g_datModBusRTUReciveInfo.mode)
                    {
                        case MODBUSRTU_FUNC01:
                        {
                            //复制尾部数据
                            if(g_ModBusRTURecv_Length < MODBUSRTU_LESSLEN)
                            {
                                datlessFlag = 1;
                                break;
                            }
                            surLen = g_pModBusRTUBufferTail - g_pModBusRTUBuffer;
                            if(surLen >= MODBUSRTU_LESSLEN)
                            {
                                memcpy(&g_arrayModBusRTURecBuf[MODBUSRTU_LEN_HEAD], &g_pModBusRTUBuffer[MODBUSRTU_LEN_HEAD], MODBUSRTU_LESSLEN - MODBUSRTU_LEN_HEAD);        
                            }
                            else
                            {
                                memcpy(g_arrayModBusRTURecBuf, g_pModBusRTUBuffer, surLen);
                                memcpy(&g_arrayModBusRTURecBuf[surLen], g_arrayModBusRTUBuffer, MODBUSRTU_LESSLEN - surLen);
                            }
                            //处理数据
                            ctcCheckTemp = crc16(g_arrayModBusRTURecBuf,6);
                            g_datModBusRTUReciveInfo.crcCheck = pPosTemp[6] + (((uint16_t)pPosTemp[7])<<8);
                            //判断调节:crc16校验正确,地址没有越界,最长只能读取125个寄存器数据,数据内容没有越界
                            if((ctcCheckTemp == g_datModBusRTUReciveInfo.crcCheck) &&        
                                (g_datModBusRTUReciveInfo.regAddr < MODBUS_0XLEN) &&
                                (g_datModBusRTUReciveInfo.regNum <= 125) &&
                                ((g_datModBusRTUReciveInfo.regAddr + g_datModBusRTUReciveInfo.regNum) <= MODBUS_0XLEN))
                            {
                                pPosTemp += MODBUSRTU_LESSLEN;
                                ModBusRTU_ask();
                                
                                //长度减小
                                if(surLen >= MODBUSRTU_LESSLEN)
                                {
                                    g_pModBusRTUBuffer += MODBUSRTU_LESSLEN;
                                }
                                else
                                {
                                    g_pModBusRTUBuffer = &g_arrayModBusRTUBuffer[MODBUSRTU_LESSLEN - surLen];
                                }
                                g_ModBusRTURecv_Length -= MODBUSRTU_LESSLEN;
                                datlessFlag = 2;    
                            }
                            break;
                        }
                        case MODBUSRTU_FUNC02:
                        {
                            //复制尾部数据
                            if(g_ModBusRTURecv_Length < MODBUSRTU_LESSLEN)
                            {
                                datlessFlag = 1;
                                break;
                            }
                            surLen = g_pModBusRTUBufferTail - g_pModBusRTUBuffer;
                            if(surLen >= MODBUSRTU_LESSLEN)
                            {
                                memcpy(&g_arrayModBusRTURecBuf[MODBUSRTU_LEN_HEAD], &g_pModBusRTUBuffer[MODBUSRTU_LEN_HEAD], MODBUSRTU_LESSLEN - MODBUSRTU_LEN_HEAD);        
                            }
                            else
                            {
                                memcpy(g_arrayModBusRTURecBuf, g_pModBusRTUBuffer, surLen);
                                memcpy(&g_arrayModBusRTURecBuf[surLen], g_arrayModBusRTUBuffer, MODBUSRTU_LESSLEN - surLen);
                            }
                            //处理数据
                            ctcCheckTemp = crc16(g_arrayModBusRTURecBuf,6);
                            g_datModBusRTUReciveInfo.crcCheck = pPosTemp[6] + (((uint16_t)pPosTemp[7])<<8);
                            //判断调节:crc16校验正确,地址没有越界,最长只能读取125个寄存器数据,数据内容没有越界
                            if((ctcCheckTemp == g_datModBusRTUReciveInfo.crcCheck) &&        
                                (g_datModBusRTUReciveInfo.regAddr < MODBUS_1XLEN) &&
                                (g_datModBusRTUReciveInfo.regNum <= 125) &&
                                ((g_datModBusRTUReciveInfo.regAddr + g_datModBusRTUReciveInfo.regNum) <= MODBUS_1XLEN))
                            {
                                pPosTemp += MODBUSRTU_LESSLEN;
                                ModBusRTU_ask();
                                //长度减小
                                if(surLen >= MODBUSRTU_LESSLEN)
                                {
                                    g_pModBusRTUBuffer += MODBUSRTU_LESSLEN;
                                }
                                else
                                {
                                    g_pModBusRTUBuffer = &g_arrayModBusRTUBuffer[MODBUSRTU_LESSLEN - surLen];
                                }
                                g_ModBusRTURecv_Length -= MODBUSRTU_LESSLEN;
                                datlessFlag = 2;    
                            }
                            break;
                        }
                        case MODBUSRTU_FUNC03:
                        {
                            //复制尾部数据
                            if(g_ModBusRTURecv_Length < MODBUSRTU_LESSLEN)
                            {
                                datlessFlag = 1;
                                break;
                            }
                            surLen = g_pModBusRTUBufferTail - g_pModBusRTUBuffer;
                            if(surLen >= MODBUSRTU_LESSLEN)
                            {
                                memcpy(&g_arrayModBusRTURecBuf[MODBUSRTU_LEN_HEAD], &g_pModBusRTUBuffer[MODBUSRTU_LEN_HEAD], MODBUSRTU_LESSLEN - MODBUSRTU_LEN_HEAD);        
                            }
                            else
                            {
                                memcpy(g_arrayModBusRTURecBuf, g_pModBusRTUBuffer, surLen);
                                memcpy(&g_arrayModBusRTURecBuf[surLen], g_arrayModBusRTUBuffer, MODBUSRTU_LESSLEN - surLen);
                            }
                            //处理数据
                            ctcCheckTemp = crc16(g_arrayModBusRTURecBuf,6);
                            g_datModBusRTUReciveInfo.crcCheck = pPosTemp[6] + (((uint16_t)pPosTemp[7])<<8);
                            //判断调节:crc16校验正确,地址没有越界,最长只能读取125个寄存器数据,数据内容没有越界
                            if((ctcCheckTemp == g_datModBusRTUReciveInfo.crcCheck) &&        
                                (g_datModBusRTUReciveInfo.regAddr < MODBUS_3XLEN) &&
                                (g_datModBusRTUReciveInfo.regNum >= 1) && (g_datModBusRTUReciveInfo.regNum <= 125) &&
                                ((g_datModBusRTUReciveInfo.regAddr + g_datModBusRTUReciveInfo.regNum) <= MODBUS_3XLEN))
                            {
                                pPosTemp += MODBUSRTU_LESSLEN;
                                ModBusRTU_ask();
                                //长度减小
                                if(surLen >= MODBUSRTU_LESSLEN)
                                {
                                    g_pModBusRTUBuffer += MODBUSRTU_LESSLEN;
                                }
                                else
                                {
                                    g_pModBusRTUBuffer = &g_arrayModBusRTUBuffer[MODBUSRTU_LESSLEN - surLen];
                                }
                                g_ModBusRTURecv_Length -= MODBUSRTU_LESSLEN;
                                datlessFlag = 2;    
                            }
                            break;
                        }
                        case MODBUSRTU_FUNC04:
                        {
                            //复制尾部数据
                            if(g_ModBusRTURecv_Length < MODBUSRTU_LESSLEN)
                            {
                                datlessFlag = 1;
                                break;
                            }
                            surLen = g_pModBusRTUBufferTail - g_pModBusRTUBuffer;
                            if(surLen >= MODBUSRTU_LESSLEN)
                            {
                                memcpy(&g_arrayModBusRTURecBuf[MODBUSRTU_LEN_HEAD], &g_pModBusRTUBuffer[MODBUSRTU_LEN_HEAD], MODBUSRTU_LESSLEN - MODBUSRTU_LEN_HEAD);        
                            }
                            else
                            {
                                memcpy(g_arrayModBusRTURecBuf, g_pModBusRTUBuffer, surLen);
                                memcpy(&g_arrayModBusRTURecBuf[surLen], g_arrayModBusRTUBuffer, MODBUSRTU_LESSLEN - surLen);
                            }
                            //处理数据
                            ctcCheckTemp = crc16(g_arrayModBusRTURecBuf,6);
                            g_datModBusRTUReciveInfo.crcCheck = pPosTemp[6] + (((uint16_t)pPosTemp[7])<<8);
                            //判断调节:crc16校验正确,地址没有越界,最长只能读取125个寄存器数据,数据内容没有越界
                            if((ctcCheckTemp == g_datModBusRTUReciveInfo.crcCheck) &&        
                                (g_datModBusRTUReciveInfo.regAddr < MODBUS_4XLEN) &&
                                (g_datModBusRTUReciveInfo.regNum <= 125) &&
                                (g_datModBusRTUReciveInfo.regAddr + g_datModBusRTUReciveInfo.regNum) <= MODBUS_4XLEN)
                            {
                                pPosTemp += MODBUSRTU_LESSLEN;
                                ModBusRTU_ask();
                                //长度减小
                                if(surLen >= MODBUSRTU_LESSLEN)
                                {
                                    g_pModBusRTUBuffer += MODBUSRTU_LESSLEN;
                                }
                                else
                                {
                                    g_pModBusRTUBuffer = &g_arrayModBusRTUBuffer[MODBUSRTU_LESSLEN - surLen];
                                }
                                g_ModBusRTURecv_Length -= MODBUSRTU_LESSLEN;
                                datlessFlag = 2;    
                            }
                            break;
                        }
                        case MODBUSRTU_FUNC05:
                        {
                            //复制尾部数据
                            if(g_ModBusRTURecv_Length < MODBUSRTU_LESSLEN)
                            {
                                datlessFlag = 1;
                                break;
                            }
                            surLen = g_pModBusRTUBufferTail - g_pModBusRTUBuffer;
                            if(surLen >= MODBUSRTU_LESSLEN)
                            {
                                memcpy(&g_arrayModBusRTURecBuf[MODBUSRTU_LEN_HEAD], &g_pModBusRTUBuffer[MODBUSRTU_LEN_HEAD], MODBUSRTU_LESSLEN - MODBUSRTU_LEN_HEAD);        
                            }
                            else
                            {
                                memcpy(g_arrayModBusRTURecBuf, g_pModBusRTUBuffer, surLen);
                                memcpy(&g_arrayModBusRTURecBuf[surLen], g_arrayModBusRTUBuffer, MODBUSRTU_LESSLEN - surLen);
                            }
                            //处理数据
                            ctcCheckTemp = crc16(g_arrayModBusRTURecBuf,6);
                            g_datModBusRTUReciveInfo.crcCheck = pPosTemp[6] + (((uint16_t)pPosTemp[7])<<8);
                            //判断调节:crc16校验正确,地址没有越界,最长只能读取125个寄存器数据,数据内容没有越界
                            if((ctcCheckTemp == g_datModBusRTUReciveInfo.crcCheck) &&        
                                (g_datModBusRTUReciveInfo.regAddr < MODBUS_0XLEN))
                            {
                                divisorAddrTemp = (g_datModBusRTUReciveInfo.regAddr + serial_i)/8;
                                remainderAddrTemp = (g_datModBusRTUReciveInfo.regAddr + serial_i)%8;
                                if(g_datModBusRTUReciveInfo.regNum == 0x0000)
                                {
                                    g_bit0xDat[divisorAddrTemp] &= (~(0x01<                             }
                                else if(g_datModBusRTUReciveInfo.regNum == 0xFF00)
                                {
                                    g_bit0xDat[divisorAddrTemp] |= (0x01<                             }
                                pPosTemp += MODBUSRTU_LESSLEN;
                                ModBusRTU_ask();
                                //长度减小
                                if(surLen >= MODBUSRTU_LESSLEN)
                                {
                                    g_pModBusRTUBuffer += MODBUSRTU_LESSLEN;
                                }
                                else
                                {
                                    g_pModBusRTUBuffer = &g_arrayModBusRTUBuffer[MODBUSRTU_LESSLEN - surLen];
                                }
                                g_ModBusRTURecv_Length -= MODBUSRTU_LESSLEN;
                                datlessFlag = 2;    
                            }
                            break;
                        }
                        case MODBUSRTU_FUNC15:
                        {
                            g_datModBusRTUReciveInfo.datLen = pPosTemp[6];
                            //复制尾部数据
                            if(g_ModBusRTURecv_Length < (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1))
                            {
                                datlessFlag = 1;
                                break;
                            }
                            surLen = g_pModBusRTUBufferTail - g_pModBusRTUBuffer;
                            if(surLen >= (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1))
                            {
                                memcpy(&g_arrayModBusRTURecBuf[MODBUSRTU_LEN_HEAD], &g_pModBusRTUBuffer[MODBUSRTU_LEN_HEAD], (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1) - MODBUSRTU_LEN_HEAD);        
                            }
                            else
                            {
                                memcpy(g_arrayModBusRTURecBuf, g_pModBusRTUBuffer, surLen);
                                memcpy(&g_arrayModBusRTURecBuf[surLen], g_arrayModBusRTUBuffer, (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1) - surLen);
                            }
                            //处理数据
                            remainderNumTemp = g_datModBusRTUReciveInfo.regNum%8;
                            if((g_ModBusRTURecv_Length >=  (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1)) &&
                                (((remainderNumTemp == 0) && (g_datModBusRTUReciveInfo.datLen == g_datModBusRTUReciveInfo.regNum/8)) ||
                                ((remainderNumTemp > 0) && (g_datModBusRTUReciveInfo.datLen == (g_datModBusRTUReciveInfo.regNum/8 + 1)))))
                            {
                                ctcCheckTemp = crc16(g_arrayModBusRTURecBuf,(7 + g_datModBusRTUReciveInfo.datLen));
                                g_datModBusRTUReciveInfo.crcCheck = pPosTemp[7 + g_datModBusRTUReciveInfo.datLen] + (((uint16_t)pPosTemp[8 + g_datModBusRTUReciveInfo.datLen])<<8);
                                //判断调节:crc16校验正确,地址没有越界,最长只能读取125个寄存器数据,数据内容没有越界
                                if((ctcCheckTemp == g_datModBusRTUReciveInfo.crcCheck) &&        
                                (g_datModBusRTUReciveInfo.regAddr < MODBUS_0XLEN) &&
                                (g_datModBusRTUReciveInfo.regNum <= 125) &&
                                ((g_datModBusRTUReciveInfo.regAddr + g_datModBusRTUReciveInfo.regNum) <= MODBUS_0XLEN))
                                {
                                    g_datModBusRTUReciveInfo.pDat = &(pPosTemp[7]);
                                    //进行赋值操作
                                    for(serial_i = 0; serial_i < g_datModBusRTUReciveInfo.regNum; serial_i++)
                                    {
                                        divisorAddrTemp = (g_datModBusRTUReciveInfo.regAddr + serial_i)/8;
                                        remainderAddrTemp = (g_datModBusRTUReciveInfo.regAddr + serial_i)%8;
                                        if(g_datModBusRTUReciveInfo.pDat[g_datModBusRTUReciveInfo.datLen - serial_i/8] & (0x01<<(serial_i%8)))
                                        {
                                            g_bit0xDat[divisorAddrTemp] |= (0x01<                                     }
                                        else
                                        {
                                            g_bit0xDat[divisorAddrTemp] &= (~(0x01<                                     }
                                    }
                                    pPosTemp += (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1);
                                    ModBusRTU_ask();
                                    
                                    //长度减小
                                    if(surLen >= (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1))
                                    {
                                        g_pModBusRTUBuffer += (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1);
                                    }
                                    else
                                    {
                                        g_pModBusRTUBuffer = &g_arrayModBusRTUBuffer[(MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1) - surLen];
                                    }
                                    g_ModBusRTURecv_Length -= (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1);
                                    datlessFlag = 2;    
                                }
                            }
                            break;
                        }
                        case MODBUSRTU_FUNC06:
                        {
                            //复制尾部数据
                            if(g_ModBusRTURecv_Length < MODBUSRTU_LESSLEN)
                            {
                                datlessFlag = 1;
                                break;
                            }
                            surLen = g_pModBusRTUBufferTail - g_pModBusRTUBuffer;
                            if(surLen >= MODBUSRTU_LESSLEN)
                            {
                                memcpy(&g_arrayModBusRTURecBuf[MODBUSRTU_LEN_HEAD], &g_pModBusRTUBuffer[MODBUSRTU_LEN_HEAD], MODBUSRTU_LESSLEN - MODBUSRTU_LEN_HEAD);        
                            }
                            else
                            {
                                memcpy(g_arrayModBusRTURecBuf, g_pModBusRTUBuffer, surLen);
                                memcpy(&g_arrayModBusRTURecBuf[surLen], g_arrayModBusRTUBuffer, MODBUSRTU_LESSLEN - surLen);
                            }
                            //处理数据
                            ctcCheckTemp = crc16(g_arrayModBusRTURecBuf,6);
                            g_datModBusRTUReciveInfo.crcCheck = pPosTemp[6] + (((uint16_t)pPosTemp[7])<<8);
                            //判断调节:crc16校验正确,地址没有越界,最长只能读取125个寄存器数据,数据内容没有越界
                            if((ctcCheckTemp == g_datModBusRTUReciveInfo.crcCheck) &&        
                                (g_datModBusRTUReciveInfo.regAddr < MODBUS_4XLEN))
                            {
                                g_word4xDat[g_datModBusRTUReciveInfo.regAddr] = g_datModBusRTUReciveInfo.regNum;
                                pPosTemp += MODBUSRTU_LESSLEN;
                                ModBusRTU_ask();
                                //长度减小
                                if(surLen >= MODBUSRTU_LESSLEN)
                                {
                                    g_pModBusRTUBuffer += MODBUSRTU_LESSLEN;
                                }
                                else
                                {
                                    g_pModBusRTUBuffer = &g_arrayModBusRTUBuffer[MODBUSRTU_LESSLEN - surLen];
                                }
                                g_ModBusRTURecv_Length -= MODBUSRTU_LESSLEN;
                                datlessFlag = 2;
                            }
                            break;
                        }
                        case MODBUSRTU_FUNC16:
                        {
                            g_datModBusRTUReciveInfo.datLen = pPosTemp[6];
                            //复制尾部数据
                            if(g_ModBusRTURecv_Length < (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1))
                            {
                                datlessFlag = 1;
                                break;
                            }
                            surLen = g_pModBusRTUBufferTail - g_pModBusRTUBuffer;
                            if(surLen >= (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1))
                            {
                                memcpy(&g_arrayModBusRTURecBuf[MODBUSRTU_LEN_HEAD], &g_pModBusRTUBuffer[MODBUSRTU_LEN_HEAD], (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1) - MODBUSRTU_LEN_HEAD);        
                            }
                            else
                            {
                                memcpy(g_arrayModBusRTURecBuf, g_pModBusRTUBuffer, surLen);
                                memcpy(&g_arrayModBusRTURecBuf[surLen], g_arrayModBusRTUBuffer, (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1) - surLen);
                            }
                            //处理数据
                            if((g_ModBusRTURecv_Length >=  (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1)) &&
                                (g_datModBusRTUReciveInfo.datLen == (g_datModBusRTUReciveInfo.regNum * 2)) &&
                                (g_datModBusRTUReciveInfo.regAddr < MODBUS_4XLEN) &&
                                (g_datModBusRTUReciveInfo.regNum >= 1) && (g_datModBusRTUReciveInfo.regNum <= 125) &&
                                ((g_datModBusRTUReciveInfo.regAddr + g_datModBusRTUReciveInfo.regNum) <= MODBUS_4XLEN))
                            {
                                ctcCheckTemp = crc16(g_arrayModBusRTURecBuf,7 + g_datModBusRTUReciveInfo.datLen);
                                g_datModBusRTUReciveInfo.crcCheck = pPosTemp[7 + g_datModBusRTUReciveInfo.datLen] + (((uint16_t)pPosTemp[8 + g_datModBusRTUReciveInfo.datLen])<<8);
                                if(ctcCheckTemp == g_datModBusRTUReciveInfo.crcCheck)
                                {
                                    for(serial_i = 0; serial_i < g_datModBusRTUReciveInfo.regNum; serial_i++)
                                    {
                                        g_word4xDat[g_datModBusRTUReciveInfo.regAddr] = (((uint16_t)pPosTemp[7 + serial_i])<<8) + pPosTemp[8 + serial_i];
                                    }
                                    pPosTemp += (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1);
                                    ModBusRTU_ask();
                                    //长度减小
                                    if(surLen >= (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1))
                                    {
                                        g_pModBusRTUBuffer += (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1);
                                    }
                                    else
                                    {
                                        g_pModBusRTUBuffer = &g_arrayModBusRTUBuffer[(MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1) - surLen];
                                    }
                                    g_ModBusRTURecv_Length -= (MODBUSRTU_LESSLEN + g_datModBusRTUReciveInfo.datLen + 1);
                                    datlessFlag = 2;
                                }
                            }
                            break;
                        }
                        default:
                        {
                            break;
                        }
                    }
                    //1:数据长度不够;2:处理完数据
                    if(datlessFlag)
                    {
                        datlessFlag = 0;
                        continue;
                    }
                }
                //坐标后移
                g_pModBusRTUBuffer++;
                if(g_pModBusRTUBuffer > g_pModBusRTUBufferTail)
                {
                    g_pModBusRTUBuffer = g_arrayModBusRTUBuffer;
                }
                g_ModBusRTURecv_Length--;
                if(g_ModBusRTURecv_Length < MODBUSRTU_LESSLEN)
                {
                    g_ModBusRTURecv_Flag = 0;
                    break;
                }
            }
        }
    }

  • 相关阅读:
    工程机械——起重机导电滑环
    设计模式之美——依赖反转原则
    认识O(NlogN)的排序
    CycloneDDS配置详细说明中文版(三)
    【web-攻击访问控制】(5.3)保障访问控制的安全:多层权限模型
    6款支持中文开源OCR软件的简单使用
    bp神经网络是什么网络,bp神经网络和神经网络
    【Unity3D】UI Toolkit元素
    JavaScript系列从入门到精通系列第七篇:JavaScrip当中的运算符,主要涉及JavaScript当中的六大数据类型的四则运算
    R语言数据结构-----列表
  • 原文地址:https://blog.csdn.net/xdpcxq/article/details/128166907