generic_io/EAOTCP/modbus/Src/modbus_tcp.c

630 lines
20 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "modbus.h"
#include "tcpserver.h"
#define MODBUS_TCP g_ch395q_sta.socket[CH395Q_SOCKET_0].config
#define MODBUS_SOCKET CH395Q_SOCKET_0
uint8_t tx_start[4];
void modbus_errfunction_tcp(uint8_t uCmdCode, uint8_t uErrorCode);
/*******************************************************************************
函数名称 ReadCoilStateFUNC
功 能 功能码:0x01,读取线圈
参 数
返 回 值
*发送:[硬件地址][01][线圈起始地址高][线圈起始地址低][线圈数量高][线圈数量低][CRC低][CRC高]
*返回:[硬件地址][01][字节长度][线圈值][线圈值][线圈值][CRC低][CRC高]
*******************************************************************************/
void readcoilstate_tcp(uint8_t * upRxdbuf, uint16_t wRxdLen)
{
uint16_t wCoilStartAddr,wCoilNum,wTotalCoilNum;
uint8_t i,k,uCommIndexNum = 0,uByteCount,uCoilVal,uErrorCode,uExit = 0;
uint8_t upTxdbuf[MAX_SIZE] = {0};
wCoilStartAddr = MAKEWORD(upRxdbuf[1], upRxdbuf[0]); //获取线圈起始地址
wCoilNum = MAKEWORD(upRxdbuf[3], upRxdbuf[2]); //获取线圈个数
if((wCoilNum >= 0x0001) || (wCoilNum <= MAX_COIL_NUM))
{
if(((wCoilStartAddr <= COIL_ADD_MAX)) &&
(wCoilNum + wCoilStartAddr <= COIL_ADD_MAX + 1))//(wCoilStartAddr >= COIL_ADD_MIN) &&
{
uByteCount = (wCoilNum + 7) / 8; //返回数据字节个数
upTxdbuf[uCommIndexNum ++] = tx_start[0];
upTxdbuf[uCommIndexNum ++] = tx_start[1];
upTxdbuf[uCommIndexNum ++] = tx_start[2];
upTxdbuf[uCommIndexNum ++] = tx_start[3];
upTxdbuf[uCommIndexNum ++] = (uint8_t)((uByteCount + 2 + 1) >> 8);
upTxdbuf[uCommIndexNum ++] = (uint8_t)((uByteCount + 2 + 1) & 0xFF);
upTxdbuf[uCommIndexNum ++] = LOCAL_ADDRESS;
upTxdbuf[uCommIndexNum ++] = ReadCoilState;
upTxdbuf[uCommIndexNum ++] = uByteCount;
wTotalCoilNum = 0;
for(k = 0; k < uByteCount; k++)
{
upTxdbuf[uCommIndexNum] = 0;
for(i = 0; i < 8; i++)
{
GetOneCoilVal(wCoilStartAddr + wTotalCoilNum,&uCoilVal);
upTxdbuf[uCommIndexNum] |= uCoilVal << i;
wTotalCoilNum ++;
if(wTotalCoilNum >= wCoilNum)
{
uExit = 1;
break;
}
}
uCommIndexNum ++;
if(uExit == 1)
{
break;
}
}
modbus_tx_len = (uCommIndexNum <= 255 ? uCommIndexNum : 255);
memcpy(modbus_tx_data, upTxdbuf, modbus_tx_len);
tcp_write(server_pcb_modbus,modbus_tx_data,modbus_tx_len,1);
return;
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_ADDRESS;
}
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_VALUE;
}
modbus_errfunction_tcp(ReadCoilState, uErrorCode);
return;
}
/*******************************************************************************
函数名称 ReadDisInputStateFUNC
功 能 功能码:0x02,读取离散量
参 数
返 回 值
*发送:[硬件地址][02][离散量起始地址高][离散量起始地址低][离散量数量高][离散量数量低][CRC低][CRC高]
*返回:[硬件地址][02][字节长度][离散量值][离散量值][离散量值][CRC低][CRC高]
*******************************************************************************/
void readdisinputstate_tcp(uint8_t * upRxdbuf, uint16_t wRxdLen)
{
uint16_t wDisStartAddr,wDisNum,wTotalDisNum;
uint8_t i,k,uCommIndexNum = 0,uByteCount,uDisVal,uErrorCode,uExit = 0;
uint8_t upTxdbuf[MAX_SIZE];
wDisStartAddr = MAKEWORD(upRxdbuf[1], upRxdbuf[0]); //获取离散量起始地址
wDisNum = MAKEWORD(upRxdbuf[3], upRxdbuf[2]); //获取离散量个数
if((wDisNum >= 0x0001) || (wDisNum <= MAX_DIS_NUM))
{
if(((wDisStartAddr <= DIS_ADD_MAX)) &&
(wDisNum + wDisStartAddr <= DIS_ADD_MAX + 1))//(wDisStartAddr >= DIS_ADD_MIN) &&
{
uByteCount = (wDisNum + 7) / 8; //返回数据字节个数
upTxdbuf[uCommIndexNum ++] = tx_start[0];
upTxdbuf[uCommIndexNum ++] = tx_start[1];
upTxdbuf[uCommIndexNum ++] = tx_start[2];
upTxdbuf[uCommIndexNum ++] = tx_start[3];
upTxdbuf[uCommIndexNum ++] = (uint8_t)((uByteCount + 2 + 1) >> 8);
upTxdbuf[uCommIndexNum ++] = (uint8_t)((uByteCount + 2 + 1) & 0xFF);
upTxdbuf[uCommIndexNum ++] = LOCAL_ADDRESS;
upTxdbuf[uCommIndexNum ++] = ReadDisInputState;
upTxdbuf[uCommIndexNum ++] = uByteCount;
wTotalDisNum = 0;
for(k = 0; k < uByteCount; k++)
{
upTxdbuf[uCommIndexNum] = 0;
for(i = 0; i < 8; i++)
{
GetOneDisInputVal(wDisStartAddr + wTotalDisNum,&uDisVal);
upTxdbuf[uCommIndexNum] |= uDisVal << i;
wTotalDisNum ++;
if(wTotalDisNum >= wDisNum)
{
uExit = 1;
break;
}
}
uCommIndexNum ++;
if(uExit == 1)
{
break;
}
}
modbus_tx_len = (uCommIndexNum <= 255 ? uCommIndexNum : 255);
memcpy(modbus_tx_data, upTxdbuf, modbus_tx_len);
tcp_write(server_pcb_modbus,modbus_tx_data,modbus_tx_len,1);
return;
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_ADDRESS;
}
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_VALUE;
}
modbus_errfunction_tcp(ReadDisInputState, uErrorCode);
return;
}
/*******************************************************************************
函数名称 ReadHoldRegFUNC
功 能 功能码:0x03,读取保持寄存器
参 数
返 回 值
*发送:[硬件地址][03][起始地址高][起始地址低][总寄存器数高][总寄存器数低][CRC低][CRC高]
*返回:[硬件地址][03][字节数][寄存器0高][寄存器0低][寄存器1高][寄存器1低][寄存器n高][寄存器n低][CRC低][CRC高]
*******************************************************************************/
void readholdreg_tcp(uint8_t * upRxdbuf, uint16_t wRxdLen)
{
uint16_t wRegStartAdd, wRegLen, i, wRegValue;
uint8_t uErrorCode, uCommIndexNum = 0;
uint8_t upTxdbuf[MAX_SIZE];
if(upRxdbuf == NULL) return;
wRegStartAdd = MAKEWORD(upRxdbuf[1], upRxdbuf[0]); //获取寄存器起始地址
wRegLen = MAKEWORD(upRxdbuf[3], upRxdbuf[2]); //获取读取寄存器长度
if((wRegLen >= 0x01) && (wRegLen <= MAX_HOLD_REG_NUM))
{
if(((wRegStartAdd <= HOLD_REG_ADD_MAX)) &&
(((wRegStartAdd + wRegLen) >= HOLD_REG_ADD_MIN) && ((wRegStartAdd + wRegLen) <= HOLD_REG_ADD_MAX + 1)))//(wRegStartAdd >= HOLD_REG_ADD_MIN) &&
{
upTxdbuf[uCommIndexNum ++] = tx_start[0];
upTxdbuf[uCommIndexNum ++] = tx_start[1];
upTxdbuf[uCommIndexNum ++] = tx_start[2];
upTxdbuf[uCommIndexNum ++] = tx_start[3];
upTxdbuf[uCommIndexNum ++] = (uint8_t)((wRegLen * 2 + 2 + 1) >> 8);
upTxdbuf[uCommIndexNum ++] = (uint8_t)((wRegLen * 2 + 2 + 1) & 0xFF);
upTxdbuf[uCommIndexNum ++] = LOCAL_ADDRESS;
upTxdbuf[uCommIndexNum ++] = ReadHoldReg;
upTxdbuf[uCommIndexNum ++] = wRegLen * 2;
for(i = 0; i < wRegLen; i++)
{
//获取16位数据并返回
wRegValue = GetHoldRegData(wRegStartAdd + i);
upTxdbuf[uCommIndexNum ++] = (uint8_t)(wRegValue >> 8);
upTxdbuf[uCommIndexNum ++] = (uint8_t)(wRegValue & 0xFF);
}
modbus_tx_len = (uCommIndexNum <= 255 ? uCommIndexNum : 255);
memcpy(modbus_tx_data, upTxdbuf, modbus_tx_len);
tcp_write(server_pcb_modbus,modbus_tx_data,modbus_tx_len,1);
return;
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_ADDRESS;
}
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_VALUE;
}
modbus_errfunction_tcp(ReadHoldReg, uErrorCode);
return;
}
/*******************************************************************************
函数名称 ReadInputRegFUNC
功 能 功能码:0x04,读取输入寄存器
参 数
返 回 值
*发送:[硬件地址][04][起始地址高][起始地址低][总寄存器数高][总寄存器数低][ CRC低 ][ CRC高 ]
*返回:[硬件地址][04][ 字节数 ][寄存器0高 ][ 寄存器0低 ][ 寄存器1高 ][ 寄存器1低 ][ 寄存器n高 ][ 寄存器n低 ][ CRC低 ][ CRC高 ]
*******************************************************************************/
void readinputreg_tcp(uint8_t * upRxdbuf, uint16_t wRxdLen)
{
uint16_t wRegStartAdd, wRegLen, i, wRegValue;
uint8_t uErrorCode, uCommIndexNum = 0;
uint8_t upTxdbuf[MAX_SIZE];
if(upRxdbuf == NULL) return;
wRegStartAdd = MAKEWORD(upRxdbuf[1], upRxdbuf[0]); //获取寄存器起始地址
wRegLen = MAKEWORD(upRxdbuf[3], upRxdbuf[2]); //获取读取寄存器长度
if((wRegLen >= 0x01) && (wRegLen <= MAX_INPUT_REG_NUM))
{
if(((wRegStartAdd <= INPUT_REG_ADD_MAX)) &&
((wRegStartAdd + wRegLen) <= INPUT_REG_ADD_MAX + 1))//(wRegStartAdd >= INPUT_REG_ADD_MIN) &&
{
upTxdbuf[uCommIndexNum ++] = tx_start[0];
upTxdbuf[uCommIndexNum ++] = tx_start[1];
upTxdbuf[uCommIndexNum ++] = tx_start[2];
upTxdbuf[uCommIndexNum ++] = tx_start[3];
upTxdbuf[uCommIndexNum ++] = (uint8_t)((wRegLen * 2 + 2 + 1) >> 8);
upTxdbuf[uCommIndexNum ++] = (uint8_t)((wRegLen * 2 + 2 + 1) & 0xFF);
upTxdbuf[uCommIndexNum ++] = LOCAL_ADDRESS;
upTxdbuf[uCommIndexNum ++] = ReadInputReg;
upTxdbuf[uCommIndexNum ++] = wRegLen * 2;
for(i = 0; i < wRegLen; i++)
{
//获取16位数据并返回
wRegValue = GetInputRegData(wRegStartAdd + i);
upTxdbuf[uCommIndexNum ++] = (uint8_t)(wRegValue >> 8);
upTxdbuf[uCommIndexNum ++] = (uint8_t)(wRegValue & 0xFF);
}
modbus_tx_len = (uCommIndexNum <= 255 ? uCommIndexNum : 255);
memcpy(modbus_tx_data, upTxdbuf, modbus_tx_len);
tcp_write(server_pcb_modbus,modbus_tx_data,modbus_tx_len,1);
return;
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_ADDRESS;
}
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_VALUE;
}
modbus_errfunction_tcp(ReadInputReg, uErrorCode);
return;
}
/*******************************************************************************
函数名称 WriteSingleRegFUNC
功 能 功能码:0x06 预设(写)单寄存器
参 数
返 回 值
*发送:[硬件地址][06][寄存器地址高][寄存器地址低][寄存器值高][寄存器值低][CRC低][CRC高]
*返回:[硬件地址][06][寄存器地址高][寄存器地址低][寄存器值高][寄存器值低][CRC低][CRC高]
*******************************************************************************/
void writesinglereg_tcp(uint8_t * upRxdbuf, uint16_t wRxdLen)
{
uint16_t wRegAddr, wRegValue;
uint8_t uCommIndexNum = 0, uErrorCode;
uint8_t upTxdbuf[MAX_SIZE];
if(upRxdbuf == NULL) return;
wRegAddr = MAKEWORD(upRxdbuf[1], upRxdbuf[0]); //获取寄存器地址
wRegValue = MAKEWORD(upRxdbuf[3], upRxdbuf[2]); //获取数据
if((wRegAddr <= HOLD_REG_ADD_MAX))//(wRegAddr >= HOLD_REG_ADD_MIN) &&
{
WriteHoldRegData(wRegAddr, wRegValue);
upTxdbuf[uCommIndexNum ++] = tx_start[0];
upTxdbuf[uCommIndexNum ++] = tx_start[1];
upTxdbuf[uCommIndexNum ++] = tx_start[2];
upTxdbuf[uCommIndexNum ++] = tx_start[3];
upTxdbuf[uCommIndexNum ++] = (uint8_t)((wRxdLen + 2) >> 8);
upTxdbuf[uCommIndexNum ++] = (uint8_t)((wRxdLen + 2) & 0xFF);
upTxdbuf[uCommIndexNum ++] = LOCAL_ADDRESS;
upTxdbuf[uCommIndexNum ++] = WriteSingleReg;
memcpy(upTxdbuf + uCommIndexNum, upRxdbuf, 4);
uCommIndexNum += 4;
modbus_tx_len = (uCommIndexNum <= 255 ? uCommIndexNum : 255);
memcpy(modbus_tx_data, upTxdbuf, modbus_tx_len);
tcp_write(server_pcb_modbus,modbus_tx_data,modbus_tx_len,1);
return;
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_ADDRESS;
}
modbus_errfunction_tcp(WriteSingleReg, uErrorCode);
return;
}
/*******************************************************************************
函数名称 WriteMultiRegFUNC
功 能 功能码:0x10 写多个保持寄存器
参 数
返 回 值
*******************************************************************************/
void writemultireg_tcp(uint8_t * upRxdbuf, uint16_t wRxdLen)
{
uint16_t i, wRegStartAdd, wRegNum, uErrorCode, wRegValue;
uint8_t uCommIndexNum = 0, uByteNum;
uint8_t upTxdbuf[MAX_SIZE];
if(upRxdbuf == NULL) return;
wRegStartAdd = MAKEWORD(upRxdbuf[1], upRxdbuf[0]); //获取寄存器地址
wRegNum = MAKEWORD(upRxdbuf[3], upRxdbuf[2]); //获取寄存器数量
uByteNum = upRxdbuf[4]; //获取字节数
if((wRegNum >= 0x01) && (wRegNum <= MAX_HOLD_REG_NUM) && (uByteNum == wRegNum * 2))
{
if(((wRegStartAdd <= HOLD_REG_ADD_MAX) &&
(wRegStartAdd + wRegNum <= HOLD_REG_ADD_MAX + 1)))//(wRegStartAdd >= HOLD_REG_ADD_MIN) &&
{
for(i = 0; i < wRegNum; i++)
{
wRegValue = MAKEWORD(upRxdbuf[6 + i * 2], upRxdbuf[5 + i * 2]);
WriteHoldRegData(wRegStartAdd + i, wRegValue);
}
upTxdbuf[uCommIndexNum ++] = tx_start[0];
upTxdbuf[uCommIndexNum ++] = tx_start[1];
upTxdbuf[uCommIndexNum ++] = tx_start[2];
upTxdbuf[uCommIndexNum ++] = tx_start[3];
upTxdbuf[uCommIndexNum ++] = (uint8_t)((wRxdLen + 2) >> 8);
upTxdbuf[uCommIndexNum ++] = (uint8_t)((wRxdLen + 2) & 0xFF);
upTxdbuf[uCommIndexNum ++] = LOCAL_ADDRESS;
upTxdbuf[uCommIndexNum ++] = WriteMultiReg;
memcpy(upTxdbuf + uCommIndexNum, upRxdbuf, 4);
uCommIndexNum += 4;
modbus_tx_len = (uCommIndexNum <= 255 ? uCommIndexNum : 255);
memcpy(modbus_tx_data, upTxdbuf, modbus_tx_len);
tcp_write(server_pcb_modbus,modbus_tx_data,modbus_tx_len,1);
return;
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_ADDRESS;
}
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_VALUE;
}
modbus_errfunction_tcp(WriteMultiReg, uErrorCode);
return;
}
/*******************************************************************************
函数名称 WriteSingleCoilFUNC
功 能 功能码:0x05 写单个线圈寄存器
参 数
返 回 值
*******************************************************************************/
void writesinglecoil_tcp(uint8_t * upRxdbuf, uint16_t wRxdLen)
{
uint16_t wCoilAddr, wCoilValue;
uint8_t uCommIndexNum = 0, uErrorCode;
uint8_t upTxdbuf[MAX_SIZE];
wCoilAddr = MAKEWORD(upRxdbuf[1], upRxdbuf[0]); //获取线圈地址
wCoilValue = MAKEWORD(upRxdbuf[3], upRxdbuf[2]); //获取线圈数据
if((wCoilValue == 0x0000) || (wCoilValue == 0xFF00))
{
if((wCoilAddr <= COIL_ADD_MAX))//(wCoilAddr >= DIS_ADD_MIN ) &&
{
WriteOneCoilData(wCoilAddr, wCoilValue);
upTxdbuf[uCommIndexNum ++] = tx_start[0];
upTxdbuf[uCommIndexNum ++] = tx_start[1];
upTxdbuf[uCommIndexNum ++] = tx_start[2];
upTxdbuf[uCommIndexNum ++] = tx_start[3];
upTxdbuf[uCommIndexNum ++] = (uint8_t)((wRxdLen + 2) >> 8);
upTxdbuf[uCommIndexNum ++] = (uint8_t)((wRxdLen + 2) & 0xFF);
upTxdbuf[uCommIndexNum ++] = LOCAL_ADDRESS;
upTxdbuf[uCommIndexNum ++] = WriteSingleCoil;
memcpy(upTxdbuf + uCommIndexNum, upRxdbuf, 4);
uCommIndexNum += 4;
modbus_tx_len = (uCommIndexNum <= 255 ? uCommIndexNum : 255);
memcpy(modbus_tx_data, upTxdbuf, modbus_tx_len);
tcp_write(server_pcb_modbus,modbus_tx_data,modbus_tx_len,1);
return;
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_ADDRESS;
}
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_VALUE;
}
modbus_errfunction_tcp(WriteSingleCoil, uErrorCode);
return;
}
/*******************************************************************************
函数名称 WriteMultiCoilFUNC
功 能 功能码:0x0F,写多个线圈
参 数
返 回 值
*发送:[硬件地址][0F][起始地址高][起始地址低][线圈数量高][线圈数量低][字节数][线圈值][CRC低][CRC高]
*返回:[硬件地址][0F][起始地址高][起始地址低][线圈数量高][线圈数量低][CRC低][CRC高]
*******************************************************************************/
void writemulticoil_tcp(uint8_t * upRxdbuf, uint16_t wRxdLen)
{
uint16_t wCoilStartAddr,wCoilNum,wCoilVal,wTotalCoilNum;
uint8_t i,k,uCommIndexNum = 0,uByteNum,uByteVal,uExit = 0,uErrorCode;
uint8_t upTxdbuf[MAX_SIZE];
wCoilStartAddr = MAKEWORD(upRxdbuf[1], upRxdbuf[0]); //获取线圈地址
wCoilNum = MAKEWORD(upRxdbuf[3], upRxdbuf[2]); //获取线圈个数
uByteNum = upRxdbuf[4]; //获取字节数
if((wCoilNum >= 0x01) && (wCoilNum <= MAX_COIL_NUM) && (wCoilNum <= 8 * uByteNum))
{
if((wCoilStartAddr <= COIL_ADD_MAX) &&
(wCoilStartAddr + wCoilNum <= COIL_ADD_MAX + 1))//(wCoilStartAddr >= COIL_ADD_MIN) &&
{
wTotalCoilNum = 0;
for(k = 0; k < uByteNum; k++)
{
uByteVal = upRxdbuf[5 + k];
for(i = 0; i < 8; i++)
{
if(uByteVal & (1 << i)) wCoilVal = 0xFF00;
else wCoilVal = 0x0000;
WriteOneCoilData(wCoilStartAddr + wTotalCoilNum, wCoilVal);
wTotalCoilNum ++;
if(wTotalCoilNum >= wCoilNum)
{
uExit = 1;
break;
}
}
if(uExit == 1)
{
break;
}
}
upTxdbuf[uCommIndexNum ++] = tx_start[0];
upTxdbuf[uCommIndexNum ++] = tx_start[1];
upTxdbuf[uCommIndexNum ++] = tx_start[2];
upTxdbuf[uCommIndexNum ++] = tx_start[3];
upTxdbuf[uCommIndexNum ++] = (uint8_t)((wRxdLen + 2) >> 8);
upTxdbuf[uCommIndexNum ++] = (uint8_t)((wRxdLen + 2) & 0xFF);
upTxdbuf[uCommIndexNum ++] = LOCAL_ADDRESS;
upTxdbuf[uCommIndexNum ++] = WriteMultiCoil;
memcpy(upTxdbuf + uCommIndexNum, upRxdbuf, 4);
uCommIndexNum += 4;
modbus_tx_len = (uCommIndexNum <= 255 ? uCommIndexNum : 255);
memcpy(modbus_tx_data, upTxdbuf, modbus_tx_len);
tcp_write(server_pcb_modbus,modbus_tx_data,modbus_tx_len,1);
return;
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_ADDRESS;
}
}
else
{
uErrorCode = MB_EX_ILLEGAL_DATA_VALUE;
}
modbus_errfunction_tcp(WriteMultiCoil, uErrorCode);
return;
}
/*******************************************************************************
函数名称 : MODBUS_ERRFunction
功 能: 错误回应指令
参 数: 无
返 回 值: 无
异常功能码 = 功能码+0x80
*******************************************************************************/
void modbus_errfunction_tcp(uint8_t uCmdCode, uint8_t uErrorCode)
{
uint8_t uCommIndexNum = 0;
uint8_t upTxdbuf[MAX_SIZE];
upTxdbuf[uCommIndexNum ++] = tx_start[0];
upTxdbuf[uCommIndexNum ++] = tx_start[1];
upTxdbuf[uCommIndexNum ++] = tx_start[2];
upTxdbuf[uCommIndexNum ++] = tx_start[3];
upTxdbuf[uCommIndexNum ++] = 0x00;
upTxdbuf[uCommIndexNum ++] = 0x03;
upTxdbuf[uCommIndexNum ++] = LOCAL_ADDRESS;
upTxdbuf[uCommIndexNum ++] = uCmdCode | 0x80;
upTxdbuf[uCommIndexNum ++] = uErrorCode;
modbus_tx_len = (uCommIndexNum <= 255 ? uCommIndexNum : 255);
memcpy(modbus_tx_data, upTxdbuf, modbus_tx_len);
tcp_write(server_pcb_modbus,modbus_tx_data,modbus_tx_len,1);
}
/*******************************************************************************
函数名称 Modbus_Analysis
功 能 CRC校验
参 数 ptr--校验数组指针 len--校验数据长度
返 回 值 CRC校验码双字节
*******************************************************************************/
void modbus_analysis_tcp(uint8_t * upRxdbuf, uint16_t wRxdLen)
{
uint8_t uSlaveAdd, uCmdCode;
if((upRxdbuf == NULL) || (wRxdLen < 2)) return;
for(int i = 0;i < 4;i++)
{
tx_start[i] = upRxdbuf[i];
}
uSlaveAdd = upRxdbuf[6];
uCmdCode = upRxdbuf[7];
// 从机地址为本机地址或者是广播帧
if((uSlaveAdd == LOCAL_ADDRESS) || (uSlaveAdd == BROADCAST_ADDRESS))
{
switch(uCmdCode)
{
case ReadCoilState:
readcoilstate_tcp(upRxdbuf + 8, wRxdLen - 8); // 读线圈状态
break;
case ReadDisInputState:
readdisinputstate_tcp(upRxdbuf + 8, wRxdLen - 8); // 读离散输入状态
break;
case ReadHoldReg:
readholdreg_tcp(upRxdbuf + 8, wRxdLen - 8); // 读取保持寄存器
break;
case ReadInputReg:
readinputreg_tcp(upRxdbuf + 8, wRxdLen - 8); // 读取输入寄存器
break;
case WriteSingleReg:
writesinglereg_tcp(upRxdbuf + 8, wRxdLen - 8); // 写单个寄存器
break;
case WriteMultiCoil:
writemulticoil_tcp(upRxdbuf + 8, wRxdLen - 8); // 写多个线圈
break;
case WriteMultiReg:
writemultireg_tcp(upRxdbuf + 8, wRxdLen - 8); // 写多个寄存器
break;
case WriteSingleCoil:
writesinglecoil_tcp(upRxdbuf + 8, wRxdLen - 8); // 写单个线圈
break;
default:
modbus_errfunction_tcp(upRxdbuf[7], 0x01); // 错误码处理
break;
}
}
}
void modbus_process_tcp(void)
{
uint8_t *pFrame;
uint16_t wFrameLen = 0;
pFrame = modbus_rx_data; // 接收数据
wFrameLen = modbus_rx_len; // 接收数据长度
if(wFrameLen < 2) return; // 数据长度不是有效值
modbus_analysis_tcp(pFrame, wFrameLen); // 协议处理
}