Data_deal.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. #include "Data_deal.h"
  2. //note: 2021-2-23 新加入BCDtoHEX相互转的几个函数 ---- Daiyf。
  3. union Tmp
  4. {
  5. float value; //浮点运算联合体
  6. unsigned char array[4];
  7. };
  8. union Tmp1
  9. {
  10. signed short value; //S16运算联合体 -32768-32767
  11. unsigned char array[2];
  12. };
  13. union Tmp2
  14. {
  15. signed long value; //S32运算联合体 -2147483648--2147483647 存放18位AD值 -131072-131071
  16. unsigned char array[4];
  17. };
  18. union Tmp3
  19. {
  20. unsigned long value; //U32运算联合体 存放18位AD值0x00000-0x3FFFF
  21. unsigned char array[4];
  22. };
  23. /*
  24. // C prototype : void StrToHex(BYTE *pbDest, BYTE *pbSrc, int nLen)
  25. // parameter(s): [OUT] pbDest - 输出缓冲区
  26. // [IN] pbSrc - 字符串
  27. // [IN] nLen - 16进制数的字节数(字符串的长度/2)
  28. // return value:
  29. // remarks : 字符串转成16进制数
  30. */
  31. void StrToHex(uint8_t *pbDest, uint8_t *pbSrc, int nLen)
  32. {
  33. char h1,h2;
  34. uint8_t s1,s2;
  35. int i;
  36. for (i=0; i<nLen; i++)
  37. {
  38. h1 = pbSrc[2*i];
  39. h2 = pbSrc[2*i+1];
  40. s1 = toupper(h1) - 0x30;
  41. if (s1 > 9)
  42. s1 -= 7;
  43. s2 = toupper(h2) - 0x30;
  44. if (s2 > 9)
  45. s2 -= 7;
  46. pbDest[i] = s1*16 + s2;
  47. }
  48. }
  49. /*
  50. // C prototype : void HexToStr(BYTE *pbDest, BYTE *pbSrc, int nLen)
  51. // parameter(s): [OUT] pbDest - 存放在目标字符串中
  52. // [IN] pbSrc - 输入16进制的起始地址
  53. // [IN] nLen - 16进制的字节数
  54. // return value:
  55. // remarks : 16进制转换成字符串
  56. */
  57. void HexToStr(uint8_t *pbDest, uint8_t *pbSrc, int nLen)
  58. {
  59. char ddl,ddh;
  60. int i;
  61. for (i=0; i<nLen; i++)
  62. {
  63. ddh = 48 + pbSrc[i] / 16;
  64. ddl = 48 + pbSrc[i] % 16;
  65. if (ddh > 57) ddh = ddh + 7;
  66. if (ddl > 57) ddl = ddl + 7;
  67. pbDest[i*2] = ddh;
  68. pbDest[i*2+1] = ddl;
  69. }
  70. pbDest[nLen*2] = '\0';
  71. }
  72. /*******************************************************************************
  73. * Function Name : Switch_U32_To_AD7691BYTE4
  74. * Description : 将32位无符号整数转成4字节数组存储
  75. * Input : temp_U32_data--要转换的U32变量 data--转换后的4字节存储
  76. * Output : None
  77. * Return : None
  78. *******************************************************************************/
  79. void Switch_U32_To_BYTE4(unsigned long temp_U32_data, unsigned char*data)
  80. {
  81. union Tmp3 U32Tmp;
  82. unsigned char i = 0;
  83. U32Tmp.value = temp_U32_data;
  84. for(i = 0; i < 4; i++)
  85. {
  86. data[i] = U32Tmp.array[i]; //将U32转换成四字节
  87. }
  88. }
  89. /*******************************************************************************
  90. * Function Name : Switch_BYTE4_To_U32
  91. * Description : 将U32的4字节数组转成32位无符号整数
  92. * Input : data--转换前四字节数组 temp_U32_data--要转换的U32变量
  93. * Output : None
  94. * Return : None
  95. *******************************************************************************/
  96. unsigned long Switch_BYTE4_To_U32(unsigned char*data)
  97. {
  98. union Tmp3 U32Tmp;
  99. unsigned char i = 0;
  100. unsigned long temp_U32_data = 0;
  101. for(i = 0; i < 4; i++)
  102. {
  103. U32Tmp.array[i] = *(data + i); //4字节数据暂存
  104. }
  105. temp_U32_data = U32Tmp.value; //4字节转换的U32有符号整数
  106. return(temp_U32_data);
  107. }
  108. /*******************************************************************************
  109. * Function Name : Switch_S32_to_ASCII
  110. * Description : 将32位有符号整数转成ASCII字符串显示
  111. * Input : S32
  112. * Output : ASCII字符串
  113. * Return : None
  114. *******************************************************************************/
  115. void Switch_S32_to_ASCII(signed long data, unsigned char*str)
  116. {
  117. unsigned short i; //u16
  118. signed long temp, tempoten; //s32
  119. unsigned char temp_length, temp_str[12] = {0};
  120. if(data < 0)
  121. {
  122. str[0] = '-'; //1.确定符号位
  123. data = -data;
  124. }
  125. else str[0] = '+';
  126. temp = data;
  127. i = 0;
  128. tempoten = temp / 10;
  129. while(tempoten != 0) //由低到高存储ASCII码
  130. {
  131. temp_str[i] = temp - 10 * tempoten + 48; //to ascii code
  132. temp = tempoten;
  133. tempoten = temp / 10;
  134. i++;
  135. }
  136. temp_str[i] = temp + 48;
  137. temp_length = i + 1;
  138. for(i = 0; i < temp_length; i++)
  139. {
  140. str[i + 1] = temp_str[temp_length - 1 - i]; //由高到低存储ASCII码
  141. }
  142. }
  143. /*******************************************************************************
  144. * Function Name : S32_to_u8
  145. * Description : 将32位数转换成8位数组
  146. * Input : data--要转变量 str--转换后的字节数组
  147. * Output : None
  148. * Return : None
  149. *******************************************************************************/
  150. void S32_to_u8(signed long data,unsigned char*str)
  151. {
  152. str[0] = data>>24;
  153. str[1] = data>>16;
  154. str[2] = data>>8;
  155. str[3] = data;
  156. }
  157. /*******************************************************************************
  158. * Function Name : Switch_Float_To_ASCII 注:小数点有效数字3位
  159. * Description : 将浮点数转成ASCII字符串
  160. * Input : temp_float_data--要转换的float变量 str--转换后的字节数组
  161. * Output : None
  162. * Return : None
  163. *******************************************************************************/
  164. void Switch_Float_To_ASCII(float temp_float_data, unsigned char*str)
  165. {
  166. unsigned short i, j, k;
  167. signed long temp, tempoten;
  168. unsigned char intpart[20], data[20];
  169. if(temp_float_data < 0)
  170. {
  171. str[0] = '-';
  172. temp_float_data = -temp_float_data;
  173. }
  174. else str[0] = '+';
  175. temp = (signed long)temp_float_data;
  176. i = 0;
  177. tempoten = temp / 10;
  178. while(tempoten != 0)
  179. {
  180. intpart[i] = temp - 10 * tempoten + 48; //to ASCII code
  181. temp = tempoten;
  182. tempoten = temp / 10;
  183. i++;
  184. }
  185. intpart[i] = temp + 48;
  186. for(k = 1; k <= i + 1; k++) str[k] = intpart[i + 1 - k];
  187. for(j = 0; j < 20; j++)
  188. {
  189. data[j] = 0;
  190. }
  191. temp = (temp_float_data * 1000) - ((signed long)(temp_float_data)) * 1000; //取小数
  192. if(temp)
  193. {
  194. Switch_S32_to_ASCII(temp, data);
  195. str[i + 2] = '.';
  196. str[i + 3] = data[1]; //第1位肯定不为0
  197. if(data[2] != '0')
  198. {
  199. str[i + 4] = data[2]; //取2位
  200. }
  201. else
  202. {
  203. str[i + 4] = 0;
  204. }
  205. if(data[3] != '0')
  206. {
  207. str[i + 5] = data[3]; //取3位
  208. }
  209. else
  210. {
  211. str[i + 5] = 0;
  212. }
  213. str[i + 6] = 0;
  214. }
  215. else
  216. {
  217. str[i + 3] = 0;
  218. }
  219. }
  220. /*******************************************************************************
  221. * Function Name : Switch_S16_To_Byte2
  222. * Description : 将有符号整数转成2字节数组存储
  223. * Input : temp_S16_data--要转换的S16变量 data--转换后的2字节数组
  224. * Output : None
  225. * Return : None
  226. *******************************************************************************/
  227. void Switch_S16_To_Byte2(signed short temp_S16_data, unsigned char*data)
  228. {
  229. union Tmp1 S16Tmp;
  230. unsigned char i = 0;
  231. S16Tmp.value = temp_S16_data; //将S16转存
  232. for(i = 0; i < 2; i++)
  233. {
  234. data[i] = S16Tmp.array[i]; //将S16转换成2字节
  235. }
  236. }
  237. /*******************************************************************************
  238. * Function Name : Switch_Byte2_To_S16
  239. * Description : 2字节数组转成有符号整数
  240. * Input : data--转换前的2字节数组
  241. * Output : None
  242. * Return : 转换后的有符号整数
  243. *******************************************************************************/
  244. signed short Switch_Byte2_To_S16(unsigned char*data)
  245. {
  246. union Tmp1 S16Tmp;
  247. unsigned char i = 0;
  248. signed short temp_S16_data = 0;
  249. for(i = 0; i < 2; i++)
  250. {
  251. S16Tmp.array[i] = data[i]; //2字节数据暂存
  252. }
  253. temp_S16_data = S16Tmp.value; //2字节转换的S16有符号整数
  254. return(temp_S16_data);
  255. }
  256. /*******************************************************************************
  257. * Function Name : Switch_Byte4_To_Float
  258. * Description : 四字节数组转成浮点数
  259. * Input : data--转换前的四字节数组
  260. * Output : None
  261. * Return : 转换后的浮点数
  262. *******************************************************************************/
  263. float Switch_Byte4_To_Float(unsigned char*data)
  264. {
  265. union Tmp floatTmp;
  266. unsigned char i = 0;
  267. float temp_float_data = 0;
  268. for(i = 0; i < 4; i++)
  269. {
  270. floatTmp.array[i] = data[i]; //四字节数据暂存
  271. }
  272. temp_float_data = floatTmp.value; //四字节转换的浮点数
  273. return(temp_float_data);
  274. }
  275. /*******************************************************************************
  276. * Function Name : Switch_Float_To_Byte4
  277. * Description : 将浮点数转成四字节数组存储
  278. * Input : temp_float_data--要转换的float变量 data--转换后的四字节数组
  279. * Output : None
  280. * Return : None
  281. *******************************************************************************/
  282. void Switch_Float_To_Byte4(float temp_float_data, unsigned char*data)
  283. {
  284. union Tmp floatTmp;
  285. unsigned char i = 0;
  286. floatTmp.value = temp_float_data; //将浮点数转存
  287. for(i = 0; i < 4; i++)
  288. {
  289. data[i] = floatTmp.array[i]; //将浮点数转换成四字节
  290. }
  291. }
  292. /******************************************************************************
  293. //4字节数存放到数组中 数组起始地址存放高字节
  294. //输入:uint16_t *buf数组起始地址, uint32_t data32存放数
  295. //返回:无
  296. ******************************************************************************/
  297. void Data32ToBuf(uint16_t *buf, uint32_t data32)
  298. {
  299. *buf++ = data32>>16;
  300. *buf = data32;
  301. }
  302. /******************************************************************************
  303. //2字节数组组成一个32位数 数组起始地址存放高字节
  304. //输入:uint16_t *buf数组起始地址, int32_t data32存放数
  305. //返回:32位数
  306. ******************************************************************************/
  307. int32_t BufToData32(uint16_t *buf)
  308. {
  309. uint8_t i;
  310. int32_t temp=0;
  311. int32_t data32=0 ;
  312. for(i=0;i<2;i++)
  313. {
  314. temp = *buf++;
  315. data32 = (data32<<16) + (temp&0xffff);
  316. }
  317. return data32;
  318. }
  319. /*******************************************************************************
  320. * Function Name : Calc_LRC
  321. * Description : LRC校验
  322. * Input : data--要校验的数组 data_len--校验的长度
  323. * Output : None
  324. * Return : lrc 校验后的值
  325. *******************************************************************************/
  326. uint16_t Calc_LRC(uint8_t* data, int data_len)
  327. {
  328. int i;
  329. uint16_t lrc = 0;
  330. for ( i = 0; i < data_len; i++)
  331. {
  332. lrc ^= data[i];
  333. }
  334. return lrc;
  335. }
  336. /*******************************************************************************
  337. * Function Name : LRC_Check
  338. * Description : LRC校验
  339. * Input : data--要校验的数组
  340. * Output : None
  341. * Return : result 校验后的值
  342. *******************************************************************************/
  343. uint16_t LRC_Check(uint8_t *data)
  344. {
  345. uint8_t i;
  346. int k;
  347. uint16_t result;
  348. uint16_t lrcdata[12];
  349. for (i = 1;i < 12 + 1;i++)
  350. {
  351. if (data[i]>0x40)
  352. lrcdata[i - 1] = data[i] - 0x41 + 10;
  353. else
  354. lrcdata[i - 1] = data[i] - 0x30;
  355. }
  356. k = 0;
  357. for (i = 0;i<12 / 2;i++)
  358. {
  359. k += (lrcdata[2 * i] * 16 + lrcdata[2 * i + 1]);
  360. }
  361. k = k % 256;
  362. k = 256 - k;
  363. result = k % 256;
  364. return result;
  365. }
  366. //单字节BCD转为HEX子程序
  367. unsigned char BCDtoHEX(unsigned char bcd_data)
  368. {
  369. unsigned char temp;
  370. temp=(bcd_data/16*10 + bcd_data%16);
  371. return temp;
  372. }
  373. //单字节HEX转为BCD子程序
  374. unsigned char HEXtoBCD(unsigned char hex_data)
  375. {
  376. unsigned char temp;
  377. temp=(hex_data/10*16 + hex_data%10);
  378. return temp;
  379. }
  380. /********** BCD to HEX **********/
  381. //双字节数值范围:0~9999
  382. uint16_t BCD2HEX(uint16_t bcd)
  383. {
  384. uint16_t temp;
  385. temp = (((bcd>>12) & 0x000f) * 1000)
  386. + (((bcd>>8) & 0x000f) * 100)
  387. + (((bcd>>4) & 0x000f) * 10)
  388. + (bcd& 0x000f);
  389. return temp;
  390. }
  391. /********** BCD to HEX **********/
  392. //双字节数值范围:0~9999
  393. uint16_t HEX2BCD(uint16_t hex)
  394. {
  395. uint16_t bcd;
  396. bcd = ((HEXtoBCD((hex/100))) << 8);
  397. bcd += HEXtoBCD(hex%100);
  398. return bcd;
  399. }
  400. /*******************************************************************************
  401. * Function Name : MODBUS_ASCII_AsciiToFloat
  402. * Description : 将目标中的8个字节转化为一个浮点数
  403. * Input : pbDest--要转化的数组
  404. * Output : None
  405. * Return : float 转化后的值
  406. *******************************************************************************/
  407. float MODBUS_ASCII_AsciiToFlaot(uint8_t *pbDest)
  408. {
  409. union Tmp floatTmp;
  410. unsigned char data[8];
  411. unsigned char i = 0;
  412. float temp_float_data = 0;
  413. for(i = 0; i < 4; i++)
  414. {
  415. data[i] = MODBUS_ASCII_AsciiToHex(pbDest+i*2); //一个字节一个转
  416. floatTmp.array[3-i] = data[i]; //四字节数据暂存
  417. }
  418. temp_float_data = floatTmp.value; //四字节转换的浮点数
  419. return(temp_float_data);
  420. }
  421. /*******************************************************************************
  422. * Function Name : MODBUS_Float_to_ASCII
  423. * Description : float数据转换为8个字节的ASCII数据
  424. * Input : data32--要转换的数据
  425. * Output : pAsciiBuf 转换后的数组
  426. * Return :
  427. *******************************************************************************/
  428. void MODBUS_Float_to_ASCII(float data32 ,uint8_t *pAsciiBuf )
  429. {
  430. uint8_t i;
  431. union Tmp2 a32Tmp;
  432. union Tmp floatTmp;
  433. floatTmp.value = data32;
  434. for(i=0;i<4;i++)a32Tmp.array[i]=floatTmp.array[i];
  435. for(i=0;i<8;i++)
  436. {
  437. pAsciiBuf[i] = (a32Tmp.value>>(28-i*4))&0x0F;
  438. if(pAsciiBuf[i]<=0x09)
  439. pAsciiBuf[i] = pAsciiBuf[i]+0x30;
  440. else
  441. {
  442. pAsciiBuf[i]=toupper(pAsciiBuf[i])+55;
  443. }
  444. }
  445. }
  446. /*******************************************************************************
  447. * Function Name : MODBUS_ASCII_AsciiToHex
  448. * Description : 转化为16进制
  449. * Input : pbDest--要转化的数组
  450. * Output : None
  451. * Return : s1*16 + s2 转化后的值
  452. *******************************************************************************/
  453. uint8_t MODBUS_ASCII_AsciiToHex(uint8_t *pbDest)
  454. {
  455. char h1,h2;
  456. uint8_t s1,s2;
  457. h1 = pbDest[0];
  458. h2 = pbDest[1];
  459. s1 = toupper(h1) - 0x30;
  460. if (s1 > 9)
  461. s1 -= 7;
  462. s2 = toupper(h2) - 0x30;
  463. if (s2 > 9)
  464. s2 -= 7;
  465. return (s1*16 + s2);
  466. }
  467. /*******************************************************************************
  468. * Function Name : MODBUS_ASCII_GetLrc
  469. * Description : LRC校验
  470. * Input : pCyAsciiBuf--要校验的数组 cyLen--长度
  471. * Output : None
  472. * Return : cyLrcVal 校验后的值
  473. *******************************************************************************/
  474. uint8_t MODBUS_ASCII_GetLrc(uint8_t *pCyAsciiBuf, uint8_t cyLen)
  475. {
  476. uint8_t i;
  477. uint8_t cyLrcVal;
  478. if (1 == (cyLen % 2) )
  479. {
  480. return 0;
  481. }
  482. cyLen /= 2;
  483. cyLrcVal = 0;
  484. for (i = 0; i < cyLen; i++)
  485. {
  486. cyLrcVal += MODBUS_ASCII_AsciiToHex(pCyAsciiBuf + i * 2);
  487. }
  488. cyLrcVal = ~cyLrcVal;
  489. cyLrcVal += 1;
  490. return (cyLrcVal);
  491. }
  492. /*******************************************************************************
  493. * Function Name : MODBUS_S32_to_ASCII
  494. * Description : 32位数据转换为单个8位数据
  495. * Input : data32--要转换的数据
  496. * Output : pAsciiBuf 转换后的数组
  497. * Return :
  498. *******************************************************************************/
  499. void MODBUS_S32_to_ASCII(int32_t data32 ,uint8_t *pAsciiBuf )
  500. {
  501. uint8_t i;
  502. for(i=0;i<8;i++)
  503. {
  504. pAsciiBuf[i] = (data32>>(28-i*4))&0x0F;
  505. if(pAsciiBuf[i]<=0x09)
  506. pAsciiBuf[i] = pAsciiBuf[i]+0x30;
  507. else
  508. {
  509. pAsciiBuf[i]=toupper(pAsciiBuf[i])+55;
  510. }
  511. }
  512. }
  513. /*******************************************************************************
  514. * Function Name : MODBUS_S16_to_ASCII
  515. * Description : 16为数据转换为ASCII数据
  516. * Input : data16--要转换的数据
  517. * Output : pAsciiBuf 转换后的数组
  518. * Return :
  519. *******************************************************************************/
  520. void MODBUS_S16_to_ASCII(int16_t data16 ,uint8_t *pAsciiBuf )
  521. {
  522. uint8_t i;
  523. for(i=0;i<4;i++)
  524. {
  525. pAsciiBuf[i] = (data16>>(12-i*4))&0x0F;
  526. if(pAsciiBuf[i]<=0x09)//if((pAsciiBuf[i]>=0x00)&&(pAsciiBuf[i]<=0x09))
  527. pAsciiBuf[i] = pAsciiBuf[i]+0x30;
  528. else
  529. {
  530. pAsciiBuf[i]=toupper(pAsciiBuf[i])+55;
  531. }
  532. }
  533. }
  534. /*******************************************************************************
  535. * Function Name : MODBUS_S8_to_ASCII
  536. * Description : 8为数据转换为ASCII数据
  537. * Input : data8--要转换的数据
  538. * Output : pAsciiBuf 转换后的数组
  539. * Return :
  540. *******************************************************************************/
  541. void MODBUS_S8_to_ASCII(int8_t data8 ,uint8_t *pAsciiBuf )
  542. {
  543. uint8_t i;
  544. for(i=0;i<2;i++)
  545. {
  546. pAsciiBuf[i] = (data8>>(4-i*4))&0x0F;
  547. if(pAsciiBuf[i]<=0x09)//if((pAsciiBuf[i]>=0x00)&&(pAsciiBuf[i]<=0x09))
  548. pAsciiBuf[i] = pAsciiBuf[i]+0x30;
  549. else
  550. {
  551. pAsciiBuf[i]=toupper(pAsciiBuf[i])+55;
  552. }
  553. }
  554. }
  555. /*******************************************************************************
  556. * Function Name : CRC16
  557. * Description : CRC16校验
  558. * Input : pBuf--要校验的数据 nLength--校验的长度
  559. * Output : ((wReturn & 0xff) << 8) | (wReturn >> 8) 校验后的数组
  560. * Return :
  561. *******************************************************************************/
  562. uint16_t CRC16(unsigned char *pBuf,int nLength)
  563. {
  564. uint16_t wReturn = 0xFFFF;
  565. int nDataLen=0;
  566. int nIndex=0;
  567. for(nDataLen=0;nDataLen<nLength;nDataLen++)
  568. {
  569. wReturn^=(unsigned short)(pBuf[nDataLen]);//(BYTE(pBuf[nDataLen]));
  570. for(nIndex=0;nIndex<8;nIndex++)
  571. {
  572. if(wReturn&0x0001)
  573. {
  574. wReturn>>=1;
  575. wReturn^=0xA001;
  576. }
  577. else
  578. {
  579. wReturn>>=1;
  580. }
  581. }
  582. }
  583. return ((wReturn & 0xff) << 8) | (wReturn >> 8);//高低互换
  584. }
  585. static uint16_t const wCRC16Table[256] = {
  586. 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
  587. 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
  588. 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
  589. 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
  590. 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
  591. 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
  592. 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
  593. 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
  594. 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
  595. 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
  596. 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
  597. 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
  598. 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
  599. 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
  600. 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
  601. 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
  602. 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
  603. 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
  604. 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
  605. 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
  606. 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
  607. 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
  608. 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
  609. 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
  610. 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
  611. 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
  612. 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
  613. 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
  614. 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
  615. 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
  616. 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
  617. 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040};
  618. uint16_t Key_CRC16(const unsigned char* pDataIn, const unsigned char iLenIn)
  619. {
  620. uint16_t wResult = 0xFFFF;
  621. uint16_t wTableNo = 0;
  622. int i = 0;
  623. for( i = 0; i < iLenIn; i++)
  624. {
  625. wTableNo = ((wResult & 0xff) ^ (pDataIn[i] & 0xff));
  626. wResult = ((wResult >> 8) & 0xff) ^ wCRC16Table[wTableNo];
  627. }
  628. return wResult;
  629. }
  630. void InvertUint8(unsigned char *dBuf, unsigned char *srcBuf)
  631. {
  632. int i;
  633. unsigned char tmp[4];
  634. tmp[0] = 0;
  635. for(i = 0; i < 8; i++)
  636. {
  637. if(srcBuf[0] & (1 << i))
  638. tmp[0] |= 1 << (7 - i);
  639. }
  640. dBuf[0] = tmp[0];
  641. }
  642. void InvertUint16(unsigned short *dBuf, unsigned short *srcBuf)
  643. {
  644. int i;
  645. unsigned short tmp[4];
  646. tmp[0] = 0;
  647. for (i = 0; i < 16; i++)
  648. {
  649. if(srcBuf[0] & (1 << i))
  650. tmp[0] |= 1 << (15 - i);
  651. }
  652. dBuf[0] = tmp[0];
  653. }
  654. unsigned short CRC16_MODBUS(unsigned char *puchMsg, unsigned int usDataLen)
  655. {
  656. int i;
  657. unsigned short temp;
  658. unsigned short temp1;
  659. unsigned short wCRCin = 0xFFFF;
  660. unsigned short wCPoly = 0x8005;
  661. unsigned char wChar = 0;
  662. while(usDataLen--)
  663. {
  664. wChar = *(puchMsg++);
  665. InvertUint8(&wChar, &wChar);
  666. wCRCin ^= (wChar << 8);
  667. for(i = 0; i < 8; i++)
  668. {
  669. if(wCRCin & 0x8000)
  670. wCRCin = (wCRCin << 1)^wCPoly;
  671. else
  672. wCRCin = wCRCin << 1;
  673. }
  674. }
  675. InvertUint16(&wCRCin, &wCRCin);
  676. temp1=wCRCin>>8&0x00ff;
  677. temp=(temp1)+(wCRCin<<8);
  678. return(temp);
  679. }