通信缓冲数据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<<remainderAddrTemp))
                {
                    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<<remainderAddrTemp))
                {
                    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<<remainderAddrTemp));
                            }
                            else if(g_datModBusRTUReciveInfo.regNum == 0xFF00)
                            {
                                g_bit0xDat[divisorAddrTemp] |= (0x01<<remainderAddrTemp);
                            }
                            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<<remainderAddrTemp);
                                    }
                                    else
                                    {
                                        g_bit0xDat[divisorAddrTemp] &= (~(0x01<<remainderAddrTemp));
                                    }
                                }
                                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;
            }
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

!chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值