YHPID.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include "main.h"
  2. #include "YHPID.h"
  3. /**
  4. @* 野火PID串口工具
  5. @* 所有多字节的低字节在前
  6. @* 包头固定为四字节的0x59485A53;
  7. @* 通道地址1到5对应软件上的CH1到CH5,CH1为0x01,CH2为0x02;
  8. @* 包长度为从包头到校验的所有数据长度。
  9. @* 指令为相应的功能码。
  10. @* 参数为指令需要参数时加入。
  11. @* 校验为校验和方式——8位。
  12. ***/
  13. // 包头常量
  14. #define PACK_HEADER 0x59485A53
  15. #define CMD_DATA_UPLOAD 0x02
  16. #define CMD_PID_UPLOAD 0x03
  17. uint32_t g_dwinbuffer[23] ; // 当用DMA发送的时候 帧头要四字节对齐
  18. // 发送 PID 参数到上位机
  19. void Send_PID_To_PC(uint8_t channel, float P, float I, float D)
  20. {
  21. uint8_t index = 0, *tx_buf;
  22. tx_buf = (uint8_t *)g_dwinbuffer;
  23. // 包头(4字节,高字节在前)
  24. tx_buf[index++] = (uint8_t)((PACK_HEADER >> 24) & 0xFF);
  25. tx_buf[index++] = (uint8_t)((PACK_HEADER >> 16) & 0xFF);
  26. tx_buf[index++] = (uint8_t)((PACK_HEADER >> 8) & 0xFF);
  27. tx_buf[index++] = (uint8_t)(PACK_HEADER & 0xFF);
  28. // 通道地址(1字节)
  29. tx_buf[index++] = channel;
  30. // 包长度(4字节,从包头到校验,含校验共 0x17 = 23)
  31. uint32_t length = 0x17;
  32. tx_buf[index++] = (uint8_t)(length & 0xFF);
  33. tx_buf[index++] = (uint8_t)((length >> 8) & 0xFF);
  34. tx_buf[index++] = (uint8_t)((length >> 16) & 0xFF);
  35. tx_buf[index++] = (uint8_t)((length >> 24) & 0xFF);
  36. // 指令(1字节)
  37. tx_buf[index++] = CMD_PID_UPLOAD;
  38. // P 参数(4字节 float)
  39. memcpy(&tx_buf[index], &P, 4);
  40. index += 4;
  41. // I 参数(4字节 float)
  42. memcpy(&tx_buf[index], &I, 4);
  43. index += 4;
  44. // D 参数(4字节 float)
  45. memcpy(&tx_buf[index], &D, 4);
  46. index += 4;
  47. // 校验和(1字节,前面所有字节的累加和的低8位)
  48. uint8_t checksum = 0;
  49. for (uint8_t i = 0; i < index; i++) {
  50. checksum += tx_buf[i];
  51. }
  52. tx_buf[index++] = checksum;
  53. HAL_GPIO_WritePin(GPIOB, RS485_RE_Pin, GPIO_PIN_SET);
  54. HAL_UART_Transmit_DMA(&huart1, tx_buf, index);
  55. }
  56. // 发送 实际值 参数到上位机
  57. void Send_DATA_To_PC(uint8_t channel, float data)
  58. {
  59. uint8_t tx_buf[15]; // 总长度 0x0F = 15字节
  60. uint32_t index = 0;
  61. // 包头(4字节,高字节在前)
  62. tx_buf[index++] = (uint8_t)((PACK_HEADER >> 24) & 0xFF);
  63. tx_buf[index++] = (uint8_t)((PACK_HEADER >> 16) & 0xFF);
  64. tx_buf[index++] = (uint8_t)((PACK_HEADER >> 8) & 0xFF);
  65. tx_buf[index++] = (uint8_t)(PACK_HEADER & 0xFF);
  66. // 通道地址(1字节)
  67. tx_buf[index++] = channel;
  68. // 包长度(4字节,从包头到校验,含校验共 0x0F = 15)
  69. uint32_t length = 0x0F;
  70. tx_buf[index++] = (uint8_t)(length & 0xFF);
  71. tx_buf[index++] = (uint8_t)((length >> 8) & 0xFF);
  72. tx_buf[index++] = (uint8_t)((length >> 16) & 0xFF);
  73. tx_buf[index++] = (uint8_t)((length >> 24) & 0xFF);
  74. // 指令(1字节)
  75. tx_buf[index++] = CMD_DATA_UPLOAD;
  76. // SPEED 参数(4字节 float)
  77. memcpy(&tx_buf[index], &data, 4);
  78. index += 4;
  79. // 校验和(1字节,前面所有字节的累加和的低8位)
  80. uint8_t checksum = 0;
  81. for (uint8_t i = 0; i < index; i++) {
  82. checksum += tx_buf[i];
  83. }
  84. tx_buf[index++] = checksum;
  85. HAL_GPIO_WritePin(GPIOB, RS485_RE_Pin, GPIO_PIN_SET);
  86. HAL_UART_Transmit_DMA(&huart1, tx_buf, index);
  87. }