/*************************************************************************
*modbus 数据部分
*************************************************************************/
/*----------------------------------------------------------------------
* BCD编码与解码
*--------------------------------------------------------------------*/
#if 0
int pow(int base, int index)
{
int i, ret = 1;
for (i = 0; i < index; i++)
ret = ret * base;
return ret;
}
float pow1(float base, float index)
{
int i, ret = 1;
for (i = 0; i < index; i++)
ret = ret * base;
return ret;
}
#endif
void QLSWJPackBCD(BYTE* buff, const double value, int width, int decimal)/*把一个double型的数据编码成一个成BCD格式的数据*/
{
int i; if ((double)value >= pow(10.0, width-decimal))
{
memset(buff, 0, width);
return;
} for (i=0; i<(width-decimal)/2; i++)
{
buff[i] = (int)(value/pow(10.0, width-decimal-i*2-1)) % 10*16
+ (int)(value/pow(10.0, width-decimal-i*2-2)) % 10;
} for (i=(width-decimal)/2; i<width/2; i++)
{
buff[i] = (int)(value*pow(10, i*2+decimal-width+1)) % 10 *16
+ (int)(value*pow(10, i*2+decimal-width+2)) % 10;
}
}double QLSWJUnPackBCD(const BYTE* buff, int width, int decimal)
{
double value = 0;
int i; for (i=0; i<(width-decimal)/2; i++)
{
value+=(buff[i]/16 * pow(10, width-decimal-i*2-1)
+ buff[i]%16 * pow(10, width-decimal-i*2-2));
} for (i=(width-decimal)/2; i<width/2; i++)
{
value+=(((double)(buff[i]/16) / pow(10, i*2+decimal-width+1))
+((double)(buff[i]%16) / pow(10, i*2+decimal-width+2)));
} return value;
}void QLSWJPackWord(WORD *pWord, const double value, int width, int decimal)
{
BYTE bcdbuff[2];
memset(bcdbuff, 0, sizeof(bcdbuff)); QLSWJPackBCD(bcdbuff, value, width, decimal); *pWord = MAKEWORD(bcdbuff[1], bcdbuff[0]);
}double QLSWJUnPackWord(const WORD wd, int width, int decimal)
{
BYTE bcdbuff[2];
memset(bcdbuff, 0, sizeof(bcdbuff)); bcdbuff[0] = HIBYTE(wd);
bcdbuff[1] = LOBYTE(wd); return QLSWJUnPackBCD(bcdbuff, width, decimal);
}
void QLSWJPackBCDW(WORD* buff, const double value, int width, int decimal)
{
int i;
BYTE *bb = (BYTE*)OslMalloc(width/2); QLSWJPackBCD(bb, value, width, decimal); for (i=0; i<(width/4); i++)
{
buff[i] = MAKEWORD(bb[i*2+1], bb[i*2]);
} OslMfree(bb);
}double QLSWJUnPackBCDW(const WORD* buff, int width, int decimal)
{
int i;
double value;
BYTE *bb = (BYTE*)OslMalloc(width/2); for (i=0; i<(width/4); i++)
{
bb[i*2] = HIBYTE(buff[i]);
bb[i*2+1] = LOBYTE(buff[i]);
}
value = QLSWJUnPackBCD(bb, width, decimal);
OslMfree(bb);
return value;
}/*----------------------------------------------------------------------
* CRC16算法
*--------------------------------------------------------------------*/
WORD QLSWJCRC16(const BYTE *buff, const int len, WORD *pCRC)
{
WORD CRC;
WORD ww=0 ;
int j=0;
int i=0;
if (pCRC == NULL)
pCRC = &CRC;
*pCRC = 0xFFFF; // 1.预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器; for (j=0; j<len; j++)
{
// 2.把第一个8位二进制数据与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器;
*pCRC = MAKEWORD((buff[j]^LOBYTE(*pCRC)), HIBYTE(*pCRC));
for (i=0; i<8; i++)
{
ww = *pCRC;
*pCRC = *pCRC >> 1; // 3.把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;
if ((ww & 0x0001) != 0) // 4.如果移出位为0:重复第3步(再次右移一位);
*pCRC = *pCRC ^ 0xA001; // 如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;
} // 5.重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
} // 6.重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
// 7.将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;
return (*pCRC); // 8.最后得到的CRC寄存器内容即为:CRC码。
}
*modbus 数据部分
*************************************************************************/
/*----------------------------------------------------------------------
* BCD编码与解码
*--------------------------------------------------------------------*/
#if 0
int pow(int base, int index)
{
int i, ret = 1;
for (i = 0; i < index; i++)
ret = ret * base;
return ret;
}
float pow1(float base, float index)
{
int i, ret = 1;
for (i = 0; i < index; i++)
ret = ret * base;
return ret;
}
#endif
void QLSWJPackBCD(BYTE* buff, const double value, int width, int decimal)/*把一个double型的数据编码成一个成BCD格式的数据*/
{
int i; if ((double)value >= pow(10.0, width-decimal))
{
memset(buff, 0, width);
return;
} for (i=0; i<(width-decimal)/2; i++)
{
buff[i] = (int)(value/pow(10.0, width-decimal-i*2-1)) % 10*16
+ (int)(value/pow(10.0, width-decimal-i*2-2)) % 10;
} for (i=(width-decimal)/2; i<width/2; i++)
{
buff[i] = (int)(value*pow(10, i*2+decimal-width+1)) % 10 *16
+ (int)(value*pow(10, i*2+decimal-width+2)) % 10;
}
}double QLSWJUnPackBCD(const BYTE* buff, int width, int decimal)
{
double value = 0;
int i; for (i=0; i<(width-decimal)/2; i++)
{
value+=(buff[i]/16 * pow(10, width-decimal-i*2-1)
+ buff[i]%16 * pow(10, width-decimal-i*2-2));
} for (i=(width-decimal)/2; i<width/2; i++)
{
value+=(((double)(buff[i]/16) / pow(10, i*2+decimal-width+1))
+((double)(buff[i]%16) / pow(10, i*2+decimal-width+2)));
} return value;
}void QLSWJPackWord(WORD *pWord, const double value, int width, int decimal)
{
BYTE bcdbuff[2];
memset(bcdbuff, 0, sizeof(bcdbuff)); QLSWJPackBCD(bcdbuff, value, width, decimal); *pWord = MAKEWORD(bcdbuff[1], bcdbuff[0]);
}double QLSWJUnPackWord(const WORD wd, int width, int decimal)
{
BYTE bcdbuff[2];
memset(bcdbuff, 0, sizeof(bcdbuff)); bcdbuff[0] = HIBYTE(wd);
bcdbuff[1] = LOBYTE(wd); return QLSWJUnPackBCD(bcdbuff, width, decimal);
}
void QLSWJPackBCDW(WORD* buff, const double value, int width, int decimal)
{
int i;
BYTE *bb = (BYTE*)OslMalloc(width/2); QLSWJPackBCD(bb, value, width, decimal); for (i=0; i<(width/4); i++)
{
buff[i] = MAKEWORD(bb[i*2+1], bb[i*2]);
} OslMfree(bb);
}double QLSWJUnPackBCDW(const WORD* buff, int width, int decimal)
{
int i;
double value;
BYTE *bb = (BYTE*)OslMalloc(width/2); for (i=0; i<(width/4); i++)
{
bb[i*2] = HIBYTE(buff[i]);
bb[i*2+1] = LOBYTE(buff[i]);
}
value = QLSWJUnPackBCD(bb, width, decimal);
OslMfree(bb);
return value;
}/*----------------------------------------------------------------------
* CRC16算法
*--------------------------------------------------------------------*/
WORD QLSWJCRC16(const BYTE *buff, const int len, WORD *pCRC)
{
WORD CRC;
WORD ww=0 ;
int j=0;
int i=0;
if (pCRC == NULL)
pCRC = &CRC;
*pCRC = 0xFFFF; // 1.预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器; for (j=0; j<len; j++)
{
// 2.把第一个8位二进制数据与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器;
*pCRC = MAKEWORD((buff[j]^LOBYTE(*pCRC)), HIBYTE(*pCRC));
for (i=0; i<8; i++)
{
ww = *pCRC;
*pCRC = *pCRC >> 1; // 3.把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;
if ((ww & 0x0001) != 0) // 4.如果移出位为0:重复第3步(再次右移一位);
*pCRC = *pCRC ^ 0xA001; // 如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;
} // 5.重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
} // 6.重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
// 7.将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;
return (*pCRC); // 8.最后得到的CRC寄存器内容即为:CRC码。
}
#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF))/*一个word的高位*/
解释下这个
在C#里调用算了。
费那个劲