COH2.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include "COH2.h"
  2. #include "usart.h"
  3. #include <stdint.h>
  4. #include <stdio.h> // printf
  5. #include <string.h>
  6. //#include "tim.h" // 用于传感器超时100ms处理
  7. #define RS485_TX_MODE HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET) // 使能RS485发送模式
  8. #define RS485_RX_MODE HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET) // 使能RS485接收模式
  9. extern uint8_t dataReceive2[];
  10. //#define NUM_CO_SENSORS 4 // CO传感器数量
  11. //#define NUM_H2_SENSORS 4 // H2传感器数量
  12. //// CO传感器地址
  13. //uint8_t CO_addresses[NUM_CO_SENSORS] = {0x0E, 0x0F, 0x10, 0x11};
  14. //// H2传感器地址
  15. //uint8_t H2_addresses[NUM_H2_SENSORS] = {0x0B, 0x0A, 0x0C, 0x0D};
  16. #define NUM_CO_SENSORS 1 // CO传感器数量
  17. #define NUM_H2_SENSORS 1 // H2传感器数量
  18. // CO传感器地址
  19. uint8_t CO_addresses[NUM_CO_SENSORS] = {0x0E};
  20. // H2传感器地址
  21. uint8_t H2_addresses[NUM_H2_SENSORS] = {0x0B};
  22. uint16_t calculate_crc16(uint8_t *data, uint16_t length)
  23. {
  24. uint16_t crc = 0xFFFF;
  25. for (uint16_t i = 0; i < length; i++) {
  26. crc ^= (uint16_t)data[i];
  27. for (uint8_t j = 0; j < 8; j++) {
  28. if (crc & 0x0001) {
  29. crc >>= 1;
  30. crc ^= 0xA001;
  31. } else {
  32. crc >>= 1;
  33. }
  34. }
  35. }
  36. return crc;
  37. }
  38. // 查找传感器地址在数组中的索引
  39. int find_sensor_index(uint8_t address, uint8_t *address_array, int num_sensors)
  40. {
  41. for (int i = 0; i < num_sensors; i++) {
  42. if (address == address_array[i]) {
  43. return i;
  44. }
  45. }
  46. return -1; // 地址未找到
  47. }
  48. // 发送MODBUS指令读取传感器数据
  49. void send_modbus_command(uint8_t sensor_address)
  50. {
  51. uint8_t command[8];
  52. command[0] = sensor_address; // 传感器地址
  53. command[1] = 0x03; // 功能码:读取保持寄存器
  54. command[2] = 0x00; // 起始地址高字节
  55. command[3] = 0x00; // 起始地址低字节
  56. command[4] = 0x00; // 读取寄存器数量高字节
  57. command[5] = 0x02; // 读取寄存器数量低字节
  58. uint16_t crc = calculate_crc16(command, 6);
  59. command[6] = crc & 0xFF; // CRC低字节
  60. command[7] = (crc >> 8) & 0xFF; // CRC高字节
  61. RS485_TX_MODE; // 切换到发送模式
  62. HAL_UART_Transmit(&huart2, command, 8,1000);//不用阻塞函数,防止系统卡死
  63. // 注意:在这里不要立即切换到接收模式,需要在发送完成回调中处理
  64. }
  65. void send_H2_0x0B_command(void)
  66. {
  67. uint8_t command[8];
  68. command[0] = 0x0B; // 传感器地址
  69. command[1] = 0x03; // 功能码:读取保持寄存器
  70. command[2] = 0x00; // 起始地址高字节
  71. command[3] = 0x00; // 起始地址低字节
  72. command[4] = 0x00; // 读取寄存器数量高字节
  73. command[5] = 0x02; // 读取寄存器数量低字节
  74. uint16_t crc = calculate_crc16(command, 6);
  75. command[6] = crc & 0xFF; // CRC低字节
  76. command[7] = (crc >> 8) & 0xFF; // CRC高字节
  77. RS485_TX_MODE; // 切换到发送模式
  78. HAL_UART_Transmit(&huart2, command, 8,1000);
  79. // 注意:在这里不要立即切换到接收模式,需要在发送完成回调中处理
  80. }
  81. void send_CO_0x0E_command(void)
  82. {
  83. uint8_t command[8];
  84. command[0] = 0x0E; // 传感器地址
  85. command[1] = 0x03; // 功能码:读取保持寄存器
  86. command[2] = 0x00; // 起始地址高字节
  87. command[3] = 0x00; // 起始地址低字节
  88. command[4] = 0x00; // 读取寄存器数量高字节
  89. command[5] = 0x02; // 读取寄存器数量低字节
  90. uint16_t crc = calculate_crc16(command, 6);
  91. command[6] = crc & 0xFF; // CRC低字节
  92. command[7] = (crc >> 8) & 0xFF; // CRC高字节
  93. RS485_TX_MODE; // 切换到发送模式
  94. HAL_UART_Transmit(&huart2, command, 8,1000);
  95. // 注意:在这里不要立即切换到接收模式,需要在发送完成回调中处理
  96. }
  97. // 处理接收的数据并转换为浮点数
  98. void receive_and_store_data(uint8_t sensor_address)
  99. {
  100. // uint8_t received_data[9]; // 接收缓冲区,接收9字节
  101. // HAL_UART_Receive_DMA(&huart2, received_data, 9);
  102. HAL_Delay(50);
  103. uint16_t crc_received = (dataReceive2[8] << 8) | dataReceive2[7];
  104. uint16_t crc_calculated = calculate_crc16(dataReceive2, 7);
  105. if (crc_received == crc_calculated)
  106. {
  107. // 提取有效数据部分并转换为浮点数
  108. uint8_t data_part[4] = {dataReceive2[3], dataReceive2[4], dataReceive2[5], dataReceive2[6]};
  109. float result = modbus_to_float(data_part);
  110. // 检查地址是否属于CO传感器
  111. int index = find_sensor_index(sensor_address, CO_addresses, NUM_CO_SENSORS);
  112. if (index != -1) {
  113. CO_data[index] = result; // 存储到CO数据数组
  114. }
  115. // 检查地址是否属于H2传感器
  116. else if ((index = find_sensor_index(sensor_address, H2_addresses, NUM_H2_SENSORS)) != -1) {
  117. H2_data[index] = result; // 存储到H2数据数组
  118. }
  119. // printf("sensor %02X: %.2f\n", sensor_address, result);
  120. }
  121. else {
  122. // printf("CRC fail:%02X\n", sensor_address);
  123. }
  124. }
  125. // 处理接收的数据并转换为浮点数
  126. void receive_and_store_data_CO_0E(void)
  127. {
  128. uint16_t crc_received = (dataReceive2[8] << 8) | dataReceive2[7];
  129. uint16_t crc_calculated = calculate_crc16(dataReceive2, 7);
  130. if (crc_received == crc_calculated)
  131. {
  132. // 提取有效数据部分并转换为浮点数
  133. uint8_t data_part[4] = {dataReceive2[3], dataReceive2[4], dataReceive2[5], dataReceive2[6]};
  134. float result = modbus_to_float(data_part);
  135. CO_data[0] = result; // 存储到CO数据数组
  136. // printf("CO 0x0E: %.2f\n", result);
  137. }
  138. }
  139. // 处理接收的数据并转换为浮点数
  140. void receive_and_store_data_H2_0B(void)
  141. {
  142. uint16_t crc_received = (dataReceive2[8] << 8) | dataReceive2[7];
  143. uint16_t crc_calculated = calculate_crc16(dataReceive2, 7);
  144. if (crc_received == crc_calculated)
  145. {
  146. // 提取有效数据部分并转换为浮点数
  147. uint8_t data_part[4] = {dataReceive2[3], dataReceive2[4], dataReceive2[5], dataReceive2[6]};
  148. float result = modbus_to_float(data_part);
  149. H2_data[0] = result; // 存储到CO数据数组
  150. // printf("H2 0x0B: %.2f\n", result);
  151. }
  152. }
  153. // 将MODBUS数据转换为IEEE-754浮点数
  154. float modbus_to_float(uint8_t *data)
  155. {
  156. uint8_t reordered_data[4];
  157. reordered_data[0] = data[2]; // 高字节1
  158. reordered_data[1] = data[3]; // 高字节2
  159. reordered_data[2] = data[0]; // 低字节1
  160. reordered_data[3] = data[1]; // 低字节2
  161. float result;
  162. memcpy(&result, reordered_data, sizeof(float));
  163. return result;
  164. }
  165. void read_gas_sensors_485data(void)
  166. {
  167. // for (int i = 0; i < NUM_CO_SENSORS; i++) {
  168. // send_modbus_command(CO_addresses[i]);
  169. // receive_and_store_data(CO_addresses[i]);
  170. // }
  171. // for (int i = 0; i < NUM_H2_SENSORS; i++) {
  172. // send_modbus_command(H2_addresses[i]);
  173. // receive_and_store_data(H2_addresses[i]);
  174. // }
  175. send_H2_0x0B_command();
  176. receive_and_store_data(CO_addresses[0]);
  177. send_CO_0x0E_command();
  178. receive_and_store_data(H2_addresses[0]);
  179. }