```
/**
封裝ADU數(shù)據(jù)
@param const MbFrameType? ? frameType? 幀類型
@param const unsigned char? devAddr? 設(shè)備地址
@param const unsigned char? funCode? 功能碼
@param const unsigned char* pData? ? 數(shù)據(jù)
@param const nsigned? char? dataLen? 數(shù)據(jù)長度
@param unsigned char*? ? ? pOutAduData 封裝ADU數(shù)據(jù)
@return pOutAduData據(jù)的長度
**/
unsigned char packMbAduData(const MbFrameType frameType, const unsigned char devAddr, const unsigned char* pData,const unsigned char dataLen, unsigned char* pOutAduData)
{
if (frameType == FrameRtu){
return packMbRtuAduData(devAddr, pData, dataLen, pOutAduData);
}else if (frameType == FrameAscii) {
return packMbAsciiAduData(devAddr, pData, dataLen, pOutAduData);
}else
return 0;
}
/**
封裝基于RTU的PDU數(shù)據(jù)
@param const unsigned char? devAddr? 設(shè)備地址
@param const unsigned char? funCode? 功能碼
@param const unsigned char* pData? ? 數(shù)據(jù)
@param const nsigned? char? dataLen? 數(shù)據(jù)長度
@param unsigned char*? ? ? pOutRtuData 封裝的RTU PDU數(shù)據(jù)
@return pOutRtuData據(jù)的長度
**/
unsigned char packMbRtuAduData(const unsigned char devAddr, const unsigned char* pData,const unsigned char dataLen, unsigned char* pOutRtuData)
{
unsigned short crc? ? = 0;
unsigned char? req_pdu_len = packMbRtuPduData(devAddr, pData, dataLen, pOutRtuData);
if (req_pdu_len > 0){
crc = calcMbRtuPduCrc(pOutRtuData, req_pdu_len);
pOutRtuData[req_pdu_len++] = (crc & 0x00FF);
pOutRtuData[req_pdu_len++] = (crc & 0xFF00) >> 8;
}
return req_pdu_len;
}
/**
封裝基于ASCII的PDU數(shù)據(jù)
@param const unsigned char? devAddr? 設(shè)備地址
@param const unsigned char* pData? ? 數(shù)據(jù)
@param const nsigned? char? dataLen? 數(shù)據(jù)長度
@param unsigned char*? ? ? pOutAsciiCmd 封裝報的ASCII PDU數(shù)據(jù)
@return pOutAsciiCmd據(jù)的長度
**/
unsigned char packMbAsciiAduData(const unsigned char devAddr, const unsigned char* pData, const unsigned char dataLen, unsigned char* pOutAsciiCmd)
{
unsigned short i = 0, j = 0, lrc = 0;
unsigned char fl;
char sz[3];
unsigned char req_pdu_len = 0;
unsigned char req_pdu_bin[PDU_MAX_LEN];
req_pdu_len = packMbRtuPduData(devAddr, pData, dataLen, req_pdu_bin);
if (req_pdu_len > 0){
pOutAsciiCmd[j++] = ':';
for (i = 0; i < req_pdu_len; i++){
fl = req_pdu_bin[i];
sprintf(sz, "%02X", fl);
pOutAsciiCmd[j++] = sz[0];
pOutAsciiCmd[j++] = sz[1];
}
lrc = calcMbAsciiPduLrc(req_pdu_bin, req_pdu_len);
sprintf(sz, "%02X", lrc);
pOutAsciiCmd[j++] = sz[0];
pOutAsciiCmd[j++] = sz[1];
pOutAsciiCmd[j++] = '\r';
pOutAsciiCmd[j++] = '\n';
}
return j;
}
/**
基于ASCII的PDU數(shù)據(jù)轉(zhuǎn)為RTU Pdu數(shù)據(jù)
@param const unsigned char*? pAsciiPdu ASCII的PDU數(shù)據(jù)
@param const unsigned char? asciiPduLen ASCII的PDU數(shù)據(jù)的長度
@param unsigned char*? ? ? pRtuPduData? 轉(zhuǎn)換后的RTU Pdu數(shù)據(jù)
@return RTU Pdu數(shù)據(jù)長度
**/
unsigned char MbAsciiPdu2RtuPdu(const unsigned char* pAsciiPdu, unsigned char asciiPduLen, unsigned char* pRtuPduData)
{
unsigned char j = 0;
unsigned char i = 0;
char? sz[2];
int dv;
unsigned fc = 0;
// 取出地址和功能碼
if (asciiPduLen >= 4){
sscanf((char*)pAsciiPdu + 0, "%2s", sz);
sscanf(sz, "%x", &dv);
pRtuPduData[j++] = dv;
sscanf((char*)pAsciiPdu + 2, "%2s", sz);
sscanf(sz, "%x", &dv);
fc = dv;
pRtuPduData[j++] = dv;
}
// asciiPduLen - 5: 去掉‘:’和LRC及\r\n的長度;i += 2:ASCII協(xié)議中每兩字節(jié)對應RTU中的一個字節(jié)
for (i = 4; i < asciiPduLen - 5; i += 2){
sscanf((char*)pAsciiPdu + i, "%2s", sz);
sscanf(sz, "%x", &dv);
if (fc == ReadHoldingRegister){
dv /= 2;
}
pRtuPduData[j++] = dv;
}
return j;
}
/**
以下三個方法用來校驗響應數(shù)據(jù)
@param const MbFrameType frameType? 幀類型
@param const unsigned char* pRspData? ASCII的PDU數(shù)據(jù)
@param const unsigned char? rspDataLen ASCII的PDU數(shù)據(jù)的長度
@return 成功返回0怎囚,否則返回>1
**/
unsigned char checkMbResponseData(const MbFrameType frameType, const unsigned char* pRspData, const unsigned char rspDataLen)
{
if (frameType == FrameAscii){
return checkMbResponseAsciiData(pRspData, rspDataLen);
}else if (frameType == FrameRtu){
return checkMbResponseRtuData(pRspData, rspDataLen);
}else{
return UnknowFrameType;
}
}
unsigned char checkMbResponseAsciiData(const unsigned char* pRspData, const unsigned char rspDataLen)
{
char sz[2];
char i, fc, len;
int dv;
unsigned char lrc = 0, rsp_lcr = 0;
if (!pRspData || rspDataLen < 3) return ParamError;
sscanf((char*)pRspData + 3, "%2s", sz);
sscanf(sz, "%x", &dv);
fc? = dv;
sscanf((char*)pRspData + 5, "%2s", sz);
sscanf(sz, "%x", &dv);
len? = dv;
// 響應數(shù)據(jù)中的LRC
if (fc >= ReadCoilStatus && fc <= ReadInputRegister){? // 功能碼0x01 ---- 0x04
sscanf((char*)pRspData + 7 + len, "%2s", sz);
sscanf(sz, "%x", &dv);
rsp_lcr = dv;
}else if (fc >= WriteSingleCoil && fc <= WriteSingleRegister){? // 功能碼0x05---0x06
sscanf((char*)pRspData + 14, "%2s", sz);
sscanf(sz, "%x", &dv);
rsp_lcr = dv;
}else if (fc >= MaskWriteRegister){ // 功能碼0x16
sscanf((char*)pRspData + 18, "%2s", sz);
sscanf(sz, "%x", &dv);
rsp_lcr = dv;
}else{
return InvalidFunctionCode;
}
// 重新計算LRC
for (i = 1; i < rspDataLen - 5; i += 2){
sscanf((char*)pRspData + i, "%2s", sz);
sscanf(sz, "%x", &dv);
lrc += dv;
}
lrc = (~lrc) + 1;
//printf("---fc:%d,len:%dlrc:%02X %0X----", fc, len, lrc, rsp_lcr);
if (lrc == rsp_lcr) return MB_OK;
return MemoryParityError;
}
unsigned char checkMbResponseRtuData(const unsigned char* pRspData, const unsigned char rspDataLen)
{
char fc, len;
unsigned short int crc, rsp_rcr;
if (!pRspData || rspDataLen < 3) return ParamError;
fc? = pRspData[1];
len? = pRspData[2];
// 響應數(shù)據(jù)中的CRC
if (fc >= ReadCoilStatus && fc <= ReadInputRegister){? // 功能碼0x01 ---- 0x04
rsp_rcr = (pRspData[3 + len] << 8) + pRspData[4 + len];
}else if (fc >= WriteSingleCoil && fc <= WriteSingleRegister){? // 功能碼0x05---0x06
rsp_rcr = (pRspData[6] << 8) + pRspData[7];
}else if (fc >= MaskWriteRegister){ // 功能碼0x16
rsp_rcr = (pRspData[8] << 8) + pRspData[9];
}else{
return InvalidFunctionCode;
}
// 重新計算的CRC
crc = calcMbRtuPduCrc(pRspData, rspDataLen - 2);
crc = u16ToBigEndian(crc);
if (rsp_rcr == crc) return MB_OK;
return MemoryParityError;
}
/**
? 指低地址存放最高有效字節(jié)
**/
unsigned short u16ToBigEndian(unsigned short v)
{
return ((v & 0xFF00) >> 8) + ((v & 0x00FF) << 8);
}
/**
? 指高地址存放最低有效字節(jié)
**/
unsigned short u16ToLittleEndian(unsigned short v)
{
return ((v & 0xFF00) >> 8) + ((v & 0x00FF) << 8);
}
/**
以5個方法RS485通信數(shù)據(jù)轉(zhuǎn)STM32數(shù)據(jù)
**/
short int toHostInt16(unsigned char *pv)
{
unsigned short int v = (pv[1] << 8) + pv[0];
return (short int)*((short int*)&v);
}
int? toHostInt32(unsigned char *pv)
{
unsigned int v = ((pv[2] << 24) + (pv[3] << 16) + (pv[0] << 8) + pv[1]);
return (int)*((int*)&v);
}
__int64? toHostInt64(unsigned char *pv)
{
unsigned __int64 v = (((__int64)pv[4] << 56) + ((__int64)pv[5] << 48) + ((__int64)pv[6] << 40) + ((__int64)pv[7] << 32)? +? //hight bits
? ? ? (pv[0] << 24)? ? ? ? + (pv[1] << 16)? ? ? ? ? + (pv[2] << 8)? ? ? ? ? + pv[3]); //low bits
return (__int64)*((__int64*)&v);
}
float toHostFloat32(unsigned char *pv)
{
unsigned int v = ((pv[2] << 24) + (pv[3] << 16) + (pv[0] << 8) + pv[1]);
return (float)*((float*)&v);
}
double toHostFloat64(unsigned char *pv)
{
unsigned __int64 v = (((__int64)pv[4] << 56) + ((__int64)pv[5] << 48) + ((__int64)pv[6] << 40) + ((__int64)pv[7] << 32)? +? //hight bits
? ? ? (pv[0] << 24)? ? ? ? + (pv[1] << 16)? ? ? ? ? + (pv[2] << 8)? ? ? ? ? + pv[3]); //low bits
return (double)*((double*)&v);
}
```