OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2846|回复: 0

一个串口协议,末尾4位是校验和,但是根据代码一直算不出校验和,请各位忙帮看看

[复制链接]

21

主题

131

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
425
金钱
425
注册时间
2019-5-12
在线时间
168 小时
发表于 2020-7-31 17:11:16 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 hejun96 于 2020-8-2 12:09 编辑

串口协议的校验和是先从ASCII码转换成十六进制显示出来,但是一直算不到末尾4位的校验和

//      /S00/1/ 0044 000000000000 0000 40 003C 3D 5C 21 1B 0100001F FFFF15 00000000 002D 0000 00 2C 2048
//     /S00/1/ 0044 000000000000 0000 40 003C 3D 5C 21 1B 0100001F FFFF14 00000000 002D 0000 00 2C 1F48

//     /S00/1/ 0044 000000000000 0000 40 003C 3C 5C 21 1B 0100011F FFFF13 000002F8 0001 0000 00 2C 155C
//                 以上面这行数据为例,算一下末尾的 2048 1F48  155C 为校验位,均为十六进制表示
//在u8 USART1_Tranfer(void)中的checksum表示的是校验

//     /S00/1/ 0044 1403190A0C24 1962 00 008C 07 CC 20 00 00010013 FFFF15 00000F0A 0002 0000 00 2C 455C
//     /S00/1/ 0044 1403190A0C24 1962 00 008C 07 CC 20 00 0000001F FFFF15 00000F0A 0002 0000 00 2C 575C
//      /S00/1/ 0044 1403190A0C24 1962 00 008C 07 CC 20 00 0000001F FFFF15 00000F0A 0002 0000 00 2C 575C


//      /S00/1/ 0044 1203140A1114 03E8 00 044C 50 0A 64 32 11011111 646464 000007D0 0000 0064 01 2C 058F

//前34个字节变化,校验和的前2个字节累加
//       /S00/1/ 0044000000000000000040003C3D5C211B 0100011FFFFF130000000000010000002C 0C 46
//       /S00/1/ 0044000000000000000040003E3D5C211B 0100011FFFFF130000000000010000002C 0E 46
//-------------------------------------------------------------------------------------------
//       /S00/1/ 0044000000000000000040003E3D5C211B 0100011FFFFF130000000000010000002C 0E 46
//      /S00/1/ 0044000000000000000040003C3D5C211B 0100011FFFFF130000000000010000002C 0C 46
//-------------------------------------------------------------------------------------------
//     /S00/1/ 0044000000000000000040003C3C5C211B 010F011FFFFF130000000000010000002C 21 46
//     /S00/1/ 0044000000000000000040003E3E5C211B 010F011FFFFF130000000000010000002C 25 46


//     /S00/1/ 00440000000000000000400000005C211B010F011FFFFF130000000000010000002CFB40




//后34个字节变化,校验和的后2个字节累加               
//     /S00/1/ 00440000000000000000400000005C211B 010F000FFFFF110000000000010000002C F8 3F
//     /S00/1/ 00440000000000000000400000005C211B 010F001FFFFF110000000000010000002C F8 40               



//推测:末尾的4位校验位,前2位和前34个字节有关,后2位和后34个字节有关



//     /S22/1/ 004414010B090000777740003C3C5C1B1B 0100010FFFFF130000000000010000002C                 4A        53
//  /S21/1/ 004614010B090000777740003C3C5C1B1B 01000101FFFF130000000000010000002C        01         68        53

//   /S00/1/ 004414010B090000777740003C3C5C1B1B 01000101FFFF130000000000010000002C 3553
//    /S00/1/ 004414010B090000777740003C3C5C1B1B 0100011FFFFF1300000000002D0000002C 5D56


//     /S00/1/ 004414010B090000777740003C3C5C1B1B 0100011FFFFF1300000000002D0000002C 5D 56
//     /S00/1/ 004414010B090000777740003C3C5C1B1B 01000101FFFF1300000000002D0000002C 48 55



//                /S22/1/ 004414010B090000777740003C3C5C1B1B 0100011FFFFF1300000000002D0000002C 5D 56
//                /S00/1/ 004414010B090000777740003C3C5C1B1B 01010113FFFF1300000000002D0000002C 4B 56

               
//                /S00/1/ 004414010B090000777740003C3C5C1B1B 0100010FFFFF1300000000002D0000002C 5D55
//                /S00/1/ 004414010B090000777740003C3C5C1B1B 01010103FFFF130000000000060000002C 3D53


//                /S00/1/ 004414010B090000777740003E3C5C1B1B 0101011FFFFF1300000000002D0000002C 60 56
//                /S00/1/ 004414010B090000777740003C3C5C1B1B 0101011FFFFF1300000000002D0000002C 5E 56


//                /S22/1/ 004414010B090000777740003C3C5C1B1B 01010101FFFF1300000000002D0000002C 49 55
//                /S00/1/ 004414010B090000777740003C3C5C1B1B 01010103FFFF130000000000030000002C 3A 53
//校验和前2字节对前34字节可加可减,校验和后2字节对后34字节只能是数字作加减,字母和数字间不能加减

//                /S00/1/ 004414010B090000777740003C3C5C1B1B 0100011FFFFF1300000000002D0000002C 5D56
//                /S00/1/ 004414010B090000777740003C3C5C1B1B 01010113FFFF1300000000002D0000002C 4B56

//                /S00/1/ 004414010B090000777740003C3C5C1B1B 01010113FFFF1300000000002D0000002C 4B 56
//                /S00/1/ 004414010B090000777740003C3C5C1B1B 0101011FFFFF1300000000000A0000002C 5B 54


//                /S00/1/ 004414010B090000777740003C3D5C1B1B 0100011FFFFF130000000000010000002C 4B 54
//                /S00/1/ 004414010B090000777700003C3D5C1B1B 0100011FFFFF130000000000010000002C 4B 50
//------------------------------------------------------------------------------------------
//                /S00/1/ 004414010B090000777700003C3D5C1B1B 0100011FFFFF130000000000010000002C 4B 50
//                /S00/1/ 004414010B090000777700003C3C5C1B1B 0100011FFFFF130000000000010000002C 4A 50
               
//                /S00/1/ 004414010B090000777700003C3C5C1B1B 0100001FFFFF140000000000010000002C 4A 50
//                /S00/1/ 004414010B090000777700003C3C5C1B1B 0100001FFFFF120000000000010000002C 48 50
//                /S00/1/ 004414010B090000777700003C3C5C1B1B 0100001FFFFF150000000000010000002C 4B 50
//               
               
//      /S22/1/ 004414010B090000777700003C3C5C1B1B 0100001FFFFF150000000000010000002C                 4B 50
//    /S21/1/ 004614010B090000777700003C3C5C1B1B 01000013FFFF150000000000010000002C         01         6B 50
//    /S00/1/ 004414010B090000777700003C3C5C1B1B 01010013FFFF150000000000010000002C                 39 50               
               


/S00/1/  固定头

0044xxx...... 都是十六进制表示


  1. /*十六进制转成ASCII码*/
  2. u8 HexToAscill(u16 *hex, u8 *ascillbuf, u8 buflenth)
  3. {
  4.         u16 phex=*hex;
  5.         u8 i=1;
  6.         for(i=0;i<buflenth;i++)
  7.         {
  8.                  ascillbuf[i] = 0;
  9.         }
  10.         i = 1;
  11.         if(&ascillbuf[buflenth-1]==NULL||phex==NULL)
  12.         {
  13.                 for(i=0;i<buflenth;i++)
  14.                 {
  15.                         if(ascillbuf[i]==0)
  16.                         {
  17.                                 ascillbuf[i] = 0 + '0';
  18.                         }
  19.                 }
  20.                 return 0;
  21.         }

  22.         while(phex!=0)
  23.         {
  24.                 if((phex)%16<=9)
  25.                 {
  26.                         ascillbuf[buflenth-i] = (phex)%16 + '0';
  27.                 }
  28.                 else
  29.                 {
  30.                         ascillbuf[buflenth-i] = (phex)%16 + '7';//将10进制的phex转换成16进制取其个位+'7'ASSCII
  31.                 }
  32.                
  33.                 phex = (phex)/16;
  34.                
  35.                 i++;
  36.                
  37.                 if(buflenth<i)
  38.                 {
  39.                         break;
  40.                 }
  41.         }
  42.         for(i=0;i<buflenth;i++)
  43.         {
  44.                 if(ascillbuf[i]==0)
  45.                 {
  46.                         ascillbuf[i] = 0 + '0';
  47.                 }
  48.         }
  49.         return 1;
  50. }



  51. typedef union{
  52.         u8 usart1_data[75];
  53.         struct{
  54.                 u8  head[7];// /S00/1/
  55.                 u8  data_lentgh[4];/*from time data to checksum data*/
  56.                 u8  datetime[12];
  57.                 u8  random_number[4];
  58.                 u8  fault_code[2];
  59.                 u8  tds1_value[4];/*原水*/
  60.                 u8  tds2_value[2];/*净水*/
  61.                 u8  ntc0_temperature[2];/*不加热*/
  62.                 u8  ntc1_temperature[2];/*热水*/
  63.                 u8  ntc2_temperature[2];/*保温*/
  64.                 u8  fixed_state[8];//固定状态
  65.                 u8  percentage_of_filter_core[6];/*1 2 3*/
  66.                 u8  total_running_time_of_water_pump[8];/*单位:秒*/               
  67. ///                u8  PressurePumpCurrent[4];//增压泵电流,单位:mA               
  68.                 u8  real_time_water_output[4];/*单位:毫升*/
  69.                 u8  the_rest_of_the_day_bucket[4];
  70.                 u8  fixtype[2];        
  71.                 u8  end0[2];
  72.         }s;
  73. }__attribute__ ((aligned (1)))USART1_TRANSFER0_DATA_UNION;
  74. extern volatile  USART1_TRANSFER0_DATA_UNION     Usart1_transf_data;

  75. typedef union{
  76.         u8 all[4];
  77.         struct{
  78.                 u8 checksum[4];
  79.                 u8 end[2];/*\r\n*/
  80.         }s;
  81. }__attribute__ ((aligned (1)))USART1_DATA_END;
  82. extern volatile  USART1_DATA_END                 Usart1_data_end;

  83. u8 USART1_Tranfer(void)
  84. {
  85.         char i=0,j=0,z=0;
  86.     u8 datanum = 0;
  87.     u8 head3 = 0;
  88.     u8 head4 = 0;
  89.     u16 checksum = 0;
  90.         u16 *p=NULL;
  91.         u8 req_dat_num=0,req_dat[30];
  92.         u8 transdata[164]={0};
  93.         static u16 ticker=0;

  94.         
  95.         
  96.         if(Transf_fifo[BEGIN]!=0)
  97.         {
  98.                

  99.                 System_Data.usart1_tran_data_len = sizeof(USART1_TRANSFER0_DATA_UNION)+req_dat_num-7;
  100.                 //System_Data.usart1_tran_data_len = 77;//对应协议下发数据的指令字符串长度,除去Check Sum
  101.                 Usart1_transf_data.s.head[0] = '/';
  102.                 Usart1_transf_data.s.head[1] = 'S';
  103.                 Usart1_transf_data.s.head[2] = head3;
  104.                 Usart1_transf_data.s.head[3] = head4;
  105.                 Usart1_transf_data.s.head[4] = '/';
  106.                 Usart1_transf_data.s.head[5] = '1';
  107.                 Usart1_transf_data.s.head[6] = '/';
  108.                 Usart1_transf_data.s.end0[0] = '2';
  109.                 Usart1_transf_data.s.end0[1] = 'C';

  110.                 Usart1_transf_data.s.ntc0_temperature[0] = '2';
  111.                 Usart1_transf_data.s.ntc0_temperature[1] = '2';

  112.                

  113.                 for(i=0;i<sizeof(Usart1_transf_data.s.datetime);i++)
  114.                 {
  115.                         if(Usart1_transf_data.s.datetime[i]==0)
  116.                         {
  117.                                 Usart1_transf_data.s.datetime[i] += '0';//时间码
  118.                         }
  119.                 }
  120.                 for(i=0;i<sizeof(Usart1_transf_data.s.random_number);i++)//回应随机数
  121.                 {
  122.                         if(Usart1_transf_data.s.random_number[i]==0)
  123.                         {
  124.                                 Usart1_transf_data.s.random_number[i] += '0';
  125.                         }
  126.                 }               
  127.                 for(i=0;i<sizeof(Usart1_transf_data.s.fixed_state);i++)//固定状态
  128.                 {
  129.                         Usart1_transf_data.s.fixed_state[i] = System_Data.fixed_state[i];//固定状态的首字符为0
  130.                 }
  131.                 for(i=0;i<sizeof(Usart1_transf_data.s.fixed_state);i++)//fixed_state[0] 为预留
  132.                 {
  133.                         if(Usart1_transf_data.s.fixed_state[i]==0)
  134.                         {
  135.                                 Usart1_transf_data.s.fixed_state[i] += '0';
  136.                         }
  137.                 }
  138.                 for(i=0;i<sizeof(Usart1_transf_data.s.percentage_of_filter_core);i++)
  139.                 {
  140.                         Usart1_transf_data.s.percentage_of_filter_core[i] = 'F';//表示滤芯的首位值
  141.                 }
  142.                 if(Save_Data.s.machine_type==0||Save_Data.s.machine_type>9)
  143.                 {
  144.                          Usart1_transf_data.s.percentage_of_filter_core[4] = '0';//表示的是滤芯的第5位,为什么不是'1'呢?
  145.                 }
  146.                 else
  147.                 {
  148.                         Usart1_transf_data.s.percentage_of_filter_core[4] = Save_Data.s.machine_type + '0'; //不太明白
  149.                 }
  150.                
  151.                 if(MachineWorkStatus==10)
  152.                 {
  153.                           Usart1_transf_data.s.percentage_of_filter_core[5] = 'A';//代表第六个元素的ASCII值
  154.                 }
  155.                 else
  156.                 {
  157.                          Usart1_transf_data.s.percentage_of_filter_core[5] = MachineWorkStatus + '0';//
  158.                 }
  159.                
  160.                 HexToAscill((u16*)&(System_Data.pressure_pump_all_run_time), (u8*)Usart1_transf_data.s.total_running_time_of_water_pump, \
  161.                                  sizeof(Usart1_transf_data.s.total_running_time_of_water_pump));
  162.                
  163.                 //增加串口协议,用4位十六进制数表示增压泵电流,单位:mA
  164. ///                HexToAscill((u16*)&(System_Data.press_pump_current), (u8*)Usart1_transf_data.s.PressurePumpCurrent, \
  165. ///                                 sizeof(Usart1_transf_data.s.PressurePumpCurrent));
  166.                
  167.         
  168.                 HexToAscill((u16*)&(System_Data.real_time_water_output), (u8*)Usart1_transf_data.s.real_time_water_output, \
  169.                                  sizeof(Usart1_transf_data.s.real_time_water_output));

  170.                 HexToAscill((u16*)&(System_Data.the_rest_of_the_day_bucket), (u8*)Usart1_transf_data.s.the_rest_of_the_day_bucket, \
  171.                                  sizeof(Usart1_transf_data.s.the_rest_of_the_day_bucket));

  172.                 HexToAscill((u16*)&(System_Data.fixtype), (u8*)Usart1_transf_data.s.fixtype, \
  173.                                  sizeof(Usart1_transf_data.s.fixtype));
  174.                
  175.                 /*头部*/
  176.                 for(i=0;i<sizeof(USART1_TRANSFER0_DATA_UNION);i++)
  177.                 {
  178.                         transdata[i] = Usart1_transf_data.usart1_data[i];
  179.                 }
  180.                 /*中部 添加请求上位机的信息数据*/
  181.                 for(i=sizeof(USART1_TRANSFER0_DATA_UNION);i<sizeof(USART1_TRANSFER0_DATA_UNION)+req_dat_num;i++)
  182.                 {
  183.                         transdata[i] = req_dat[i-sizeof(USART1_TRANSFER0_DATA_UNION)];
  184.                 }
  185.                 p = (u16*)&transdata[7];
  186.                 for(i=0;i<(req_dat_num+sizeof(USART1_TRANSFER0_DATA_UNION)-7)/2;i++)
  187.                 {
  188.                         checksum += p[i];
  189.             // if(p[i]>64) checksum -= 55;
  190.             // else
  191.             checksum -= 48;
  192.             //if(i == 10) temp = checksum;
  193.                 }
  194.         temp = p[12]-48;//
  195.                 HexToAscill((u16*)&(checksum), (u8*)Usart1_data_end.s.checksum, \
  196.                                  sizeof(Usart1_data_end.s.checksum));
  197.                
  198.                 Usart1_data_end.s.end[0] = '\r';
  199.                 Usart1_data_end.s.end[1] = '\n';
  200.                  /*尾部*/
  201.                 for(i=sizeof(USART1_TRANSFER0_DATA_UNION)+req_dat_num;i<req_dat_num+sizeof(USART1_TRANSFER0_DATA_UNION)+sizeof(USART1_DATA_END);i++)
  202.                 {
  203.                         transdata[i] = Usart1_data_end.all[i-sizeof(USART1_TRANSFER0_DATA_UNION)-req_dat_num];
  204.                 }
  205.                
  206.                 datanum = sizeof(USART1_TRANSFER0_DATA_UNION)+sizeof(USART1_DATA_END)+req_dat_num;
  207.                 for(i=0;i<datanum;i++)
  208.                 {
  209.                         USART_SendData(USART1,transdata[i]);
  210.                         
  211.                         while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}
  212.                 }
  213.                 for(i=0;i<FIFO_LENGTH-1;i++)
  214.                 {
  215.                         Transf_fifo[i] = Transf_fifo[i+1];
  216.                 }
  217.                 Transf_fifo[FIFO_LENGTH-1] = 0;
  218.         }


  219.         return 0;
  220. }
复制代码


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 02:26

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表