• Linux串口断帧处理


    报文格式
    1 Byte
    4 Byte
    N Byte
    4 Byte
    1 Byte
    0x02
    报文长度
    报文
    CRC16
    0x03

    1. 每条报文以 STX(0x02)起始符开始,以 ETX(0x03)终止符结束。
    2. 报文正文长度采用 4 字节的 10 进制字符串标识,如报文正文长度为十
    进制 298,则相应的字段为"0298"。
    3. 报文正文采用 json 字符串形式进行描述。
    4. 报文正文后跟报文正文的 CRC16 校验码,CRC16 校验码采用 4 字节的
    16 进制字符串标识,如 CRC16 校验码为 0x89 0xA9,则相应的字段为为"89A9"。
    5. 串口数据采用 CRC16(XMODEM)算法校验,举例:校验报文原文"abcdefg",
    CRC16 结果为 0x7658。
    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #define START_BYTE 0x02
    10. #define END_BYTE 0x03
    11. static int times = 0;
    12. int my_read(uint8_t *data, uint32_t max_len)
    13. {
    14. char *a="\x02\x30\x30\x37\x37\x7B\x22\x64\x61\x74\x61\x22\x3A\x7B\x22\x61";
    15. char *b="\x63\x74\x69\x6F\x6E\x22\x3A\x31\x7D\x2C\x22\x63\x6D\x64\x22\x3A\x22\x43\x32\x22\x2C\x22\x74\x69\x6D\x65\x22\x3A\x22\x31\x36\x39\x37\x31\x31\x30\x36\x39\x39\x30\x38\x33\x22\x2C\x22\x6D\x73\x67\x5F\x69\x64\x22\x3A\x22\x31\x36\x39\x37\x31\x31\x30\x36\x39\x39\x22";
    16. char *c="\x7D\x44\x42\x46\x32\x03";
    17. size_t bytesRead = 0;
    18. if(times==0)
    19. {
    20. bytesRead = 16;
    21. memcpy(data, a, 16);
    22. times++;
    23. }
    24. else if(times==1)
    25. {
    26. bytesRead = 65;
    27. memcpy(data, b, bytesRead);
    28. times++;
    29. }
    30. else
    31. {
    32. times = 0;
    33. bytesRead = 6;
    34. memcpy(data, c, bytesRead);
    35. }
    36. return bytesRead;
    37. }
    38. int my_recv(uint8_t *recv_data, uint32_t *recv_len)
    39. {
    40. // 从串口接收数据
    41. uint8_t buffer[1024] = {0};
    42. *recv_len = 0;
    43. size_t bytesRead = 0;
    44. while (true) {
    45. bytesRead = my_read(buffer, sizeof(buffer));
    46. // 处理接收到的数据
    47. if (bytesRead <= 0)
    48. {
    49. break;
    50. }
    51. printf("bytesRead=%ld\n",bytesRead);
    52. if(buffer[0] == START_BYTE)
    53. {
    54. *recv_len = bytesRead;
    55. memcpy(recv_data, buffer, bytesRead);
    56. }
    57. else
    58. {
    59. if((*recv_len+bytesRead)> sizeof(buffer))
    60. {
    61. *recv_len = 0;
    62. break;
    63. }
    64. memcpy(recv_data+*recv_len, buffer, bytesRead);
    65. *recv_len += bytesRead;
    66. }
    67. if(recv_data[0] != START_BYTE)
    68. {
    69. *recv_len = 0;
    70. break;
    71. }
    72. if(recv_data[*recv_len-1] == END_BYTE)
    73. {
    74. return *recv_len;
    75. }
    76. }
    77. return -1;
    78. }
    79. int main() {
    80. uint8_t frame[1024];
    81. int frame_len;
    82. memset(frame, 0, sizeof(frame));
    83. printf("len=%d\n", my_recv(frame, &frame_len));
    84. if(frame_len > 6)
    85. {
    86. // 打印报文数据
    87. printf("Received frame: ");
    88. for (size_t i = 0; i < frame_len-10; i++) {
    89. printf("%02x ", frame[i+5]);
    90. }
    91. printf("\n");
    92. }
    93. return 0;
    94. }

  • 相关阅读:
    springboot相关-JDBC
    (附源码)springboot养老院系统 毕业设计 645488
    [机缘参悟-65]:《兵者,诡道也》-7-三十六计解读-败战计
    开发者分享|MindSpore Lite 体验,一键实现图像分割
    MyBatis--逆向工程
    静态划分信道(信道划分介质访问控制)
    【Python爬虫】爬取名人名言页面并进行简单的数据清洗(入门级)
    小程序生成分享海报图片并保存相册
    C语言中的 指针 和 引用的区别
    【2010NOIP普及组】T4. 三国游戏 试题解析
  • 原文地址:https://blog.csdn.net/lu_linux/article/details/133806049