/*************************************************************************
 *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码。
}