#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;
}
}
}
}