CRCSupport.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace HslCommunication.Serial
  6. {
  7. /// <summary>
  8. /// 用于CRC16验证的类,提供了标准的验证方法
  9. /// </summary>
  10. public class SoftCRC16
  11. {
  12. /// <summary>
  13. /// 来校验对应的接收数据的CRC校验码,默认多项式码为0xA001
  14. /// </summary>
  15. /// <param name="data">需要校验的数据,带CRC校验码</param>
  16. /// <returns>返回校验成功与否</returns>
  17. public static bool CheckCRC16(byte[] data)
  18. {
  19. return CheckCRC16(data, 0xA0, 0x01);
  20. }
  21. /// <summary>
  22. /// 指定多项式码来校验对应的接收数据的CRC校验码
  23. /// </summary>
  24. /// <param name="data">需要校验的数据,带CRC校验码</param>
  25. /// <param name="CH">多项式码高位</param>
  26. /// <param name="CL">多项式码低位</param>
  27. /// <returns>返回校验成功与否</returns>
  28. public static bool CheckCRC16(byte[] data, byte CH, byte CL)
  29. {
  30. int length = data.Length;
  31. byte[] buf = new byte[length - 2];
  32. Array.Copy(data, 0, buf, 0, buf.Length);
  33. byte[] CRCbuf = CRC16(buf, CH, CL);
  34. if (CRCbuf[length - 2] == data[length - 2] &&
  35. CRCbuf[length - 1] == data[length - 1])
  36. {
  37. return true;
  38. }
  39. return false;
  40. }
  41. /// <summary>
  42. /// 获取对应的数据的CRC校验码,默认多项式码为0xA001
  43. /// </summary>
  44. /// <param name="data">需要校验的数据,不包含CRC字节</param>
  45. /// <returns>返回带CRC校验码的字节数组,可用于串口发送</returns>
  46. public static byte[] CRC16(byte[] data)
  47. {
  48. return CRC16(data, 0xA0, 0x01);
  49. }
  50. /// <summary>
  51. /// 通过指定多项式码来获取对应的数据的CRC校验码
  52. /// </summary>
  53. /// <param name="data">需要校验的数据,不包含CRC字节</param>
  54. /// <param name="CL">多项式码地位</param>
  55. /// <param name="CH">多项式码高位</param>
  56. /// <returns>返回带CRC校验码的字节数组,可用于串口发送</returns>
  57. public static byte[] CRC16(byte[] data, byte CH, byte CL)
  58. {
  59. byte[] buf = new byte[data.Length + 2];
  60. data.CopyTo(buf, 0);
  61. byte CRC16Lo;
  62. byte CRC16Hi; // CRC寄存器
  63. byte SaveHi;
  64. byte SaveLo;
  65. byte[] tmpData;
  66. int Flag;
  67. // 预置寄存器
  68. CRC16Lo = 0xFF;
  69. CRC16Hi = 0xFF;
  70. tmpData = data;
  71. for (int i = 0; i < tmpData.Length; i++)
  72. {
  73. CRC16Lo = (byte)(CRC16Lo ^ tmpData[i]); // 每一个数据与CRC寄存器低位进行异或,结果返回CRC寄存器
  74. for (Flag = 0; Flag <= 7; Flag++)
  75. {
  76. SaveHi = CRC16Hi;
  77. SaveLo = CRC16Lo;
  78. CRC16Hi = (byte)(CRC16Hi >> 1); // 高位右移一位
  79. CRC16Lo = (byte)(CRC16Lo >> 1); // 低位右移一位
  80. if ((SaveHi & 0x01) == 0x01) // 如果高位字节最后一位为1
  81. {
  82. // 则低位字节右移后前面补1
  83. CRC16Lo = (byte)(CRC16Lo | 0x80);
  84. }
  85. // 否则自动补0
  86. // 如果最低位为1,则将CRC寄存器与预设的固定值进行异或运算
  87. if ((SaveLo & 0x01) == 0x01)
  88. {
  89. CRC16Hi = (byte)(CRC16Hi ^ CH);
  90. CRC16Lo = (byte)(CRC16Lo ^ CL);
  91. }
  92. }
  93. }
  94. buf[buf.Length - 2] = CRC16Lo;
  95. buf[buf.Length - 1] = CRC16Hi;
  96. // 返回最终带有CRC校验码结尾的信息
  97. return buf;
  98. }
  99. }
  100. }