mini_gateway_master.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. //
  2. // Created by DELL on 2024/10/16.
  3. //
  4. #include <stdint.h>
  5. #include "mini_gateway_master.h"
  6. #include "usart.h"
  7. #include "modbus.h"
  8. #include "cmsis_os2.h"
  9. #include "modbus_slave.h"
  10. uint8_t error_count = 0;
  11. static nmbs_t nmbs;
  12. extern uint8_t slaves[SLAVE_ADDRESS_END]; // 保存已经存在的从站号
  13. static osMutexId_t mini_mutex;
  14. extern uint8_t is_slave_exist;
  15. static uint8_t coil[INNER_SLAVE_ADDRESS_END] = {0};
  16. static int32_t uart_read(uint8_t *buf, uint16_t count, int32_t byte_timeout_ms,
  17. void *arg) {
  18. HAL_StatusTypeDef status = HAL_UART_Receive(&huart4, buf, count, byte_timeout_ms);
  19. if (status == HAL_OK) {
  20. return count;
  21. } else {
  22. return 0;
  23. }
  24. }
  25. static int32_t uart_write(const uint8_t *buf, uint16_t count, int32_t byte_timeout_ms,
  26. void *arg) {
  27. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
  28. HAL_UART_Transmit(&huart4, buf, count, byte_timeout_ms);
  29. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET);
  30. return count;
  31. }
  32. void sync_ac_status(ffx_status_t *status) {
  33. uint16_t power;
  34. uint16_t mode;
  35. uint16_t fan_speed;
  36. uint16_t set_temp;
  37. if (status->power == 0x01) {
  38. power = 0xAA;
  39. fan_speed = status->fan_speed + 1;
  40. set_temp = status->set_temp;
  41. } else
  42. power = 0x55;
  43. mode = status->mode + 1;
  44. switch (status->mode) {
  45. case 0://制冷模式
  46. mode = status->mode + 1;
  47. break;
  48. case 1://制热模式
  49. mode = status->mode + 3;
  50. break;
  51. case 2://除湿模式
  52. mode = status->mode;
  53. break;
  54. case 3://送风模式
  55. mode = status->mode;
  56. break;
  57. case 4://加湿模式、送风
  58. mode = 3;
  59. break;
  60. default:
  61. break;
  62. }
  63. uint16_t regs[5] = {power, mode, set_temp * 10, fan_speed, 0};
  64. nmbs_error err2 = nmbs_write_multiple_registers(&nmbs, 102 + 25 * (status->inner_num - 1), 5, regs);
  65. if (err2 == NMBS_ERROR_NONE) {
  66. set_reg_value(INNER_ERROR1_REG_ADDRESS, 0);
  67. error_count = 0;
  68. } else {
  69. set_reg_value(INNER_ERROR1_REG_ADDRESS, 1);
  70. error_count++;
  71. }
  72. }
  73. static bool check_comm() {
  74. uint16_t data;
  75. nmbs_error err = nmbs_read_holding_registers(&nmbs, 102, 1, &data);
  76. return err == NMBS_ERROR_NONE;
  77. }
  78. _Noreturn void mini_mater_task(void *pv) {
  79. uint8_t is_error_ffx[8] = {0};
  80. for (;;) {
  81. // if (osMutexAcquire(mini_mutex, osWaitForever) == osOK) {
  82. bool is_power_on = false;
  83. ffx_status_t status = {0};
  84. for (int i = 0; i < sizeof(coil); i++) {
  85. HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_13);
  86. if (coil[i] != 0) {
  87. uint16_t data[10];
  88. uint8_t inner_num = i + 1;
  89. nmbs_error err = nmbs_read_holding_registers(&nmbs,
  90. (MINI_GATEWAY_INNER_POWER_ADDRESS + 25 * i),
  91. 4, &data[0]);
  92. if (err == NMBS_ERROR_NONE) {
  93. if (data[0] == 0xAA) {
  94. status.power = 1;
  95. status.fan_speed = data[3] - 2;
  96. status.set_temp = data[2] / 10;
  97. } else
  98. status.power = 0;
  99. switch (data[1]) {
  100. case 1://制冷模式
  101. status.mode = 0;
  102. break;
  103. case 4://制热模式
  104. status.mode = 1;
  105. break;
  106. case 2://除湿模式
  107. status.mode = 2;
  108. break;
  109. case 3://送风模式
  110. status.mode = 3;
  111. break;
  112. default:
  113. break;
  114. }
  115. status.inner_num = inner_num;
  116. if ((status.power == INNER_POWER_ON) && (is_power_on == false)) {
  117. osDelay(100);
  118. is_power_on = true;
  119. set_reg_value(POWER_REG_ADDRESS, status.power);
  120. set_reg_value(WORK_MODE_REG_ADDRESS, status.mode);
  121. set_reg_value(FAN_SPEED_REG_ADDRESS, status.fan_speed);
  122. set_reg_value(SET_TEMP_REG_ADDRESS, status.set_temp);
  123. set_reg_value(INNER_ERROR1_REG_ADDRESS, 0);
  124. error_count = 0;
  125. DEBUG_PRINTF("Read that the slave is turned on.\n");
  126. }
  127. } else {
  128. error_count++;
  129. is_error_ffx[i]++;
  130. is_power_on = true;
  131. if ((status.power == INNER_POWER_OFF) && is_error_ffx[i] > 3) {
  132. set_reg_value(INNER_ERROR1_REG_ADDRESS, 1);
  133. set_reg_value(POWER_REG_ADDRESS, status.power);
  134. error_count = 0;
  135. is_error_ffx[i] = 0;
  136. }
  137. }
  138. }
  139. osDelay(1000);
  140. }
  141. if ((status.power == INNER_POWER_OFF) && (is_power_on == false)) {
  142. set_reg_value(INNER_ERROR1_REG_ADDRESS, 0);
  143. set_reg_value(POWER_REG_ADDRESS, status.power);
  144. error_count = 0;
  145. }
  146. osDelay(1000);
  147. // osMutexRelease(mini_mutex);
  148. // }
  149. }
  150. }
  151. // 检测从机是否存在
  152. bool check_inner_slave_exist(uint8_t slave_addr) {
  153. nmbs_set_destination_rtu_address(&nmbs, slave_addr); // 设置从机地址
  154. bool result;
  155. osDelay(100);
  156. nmbs_read_coils(&nmbs, MINI_GATEWAY_INNER_COIL_ADDRESS + slave_addr - 1, 1, &result);
  157. if (result) {
  158. return true;
  159. } else {
  160. return false;
  161. }
  162. }
  163. _Noreturn void gateway_poll_task(void *pv) {
  164. uint8_t count = 0;
  165. for (;;) {
  166. while(1) {
  167. if(check_comm())
  168. break;
  169. osDelay(1500);
  170. DEBUG_PRINTF("Waiting for gateway to start.\n");
  171. }
  172. nmbs_bitfield regs = {0};
  173. // if (osMutexAcquire(mini_mutex, osWaitForever) == osOK) {
  174. for (int i = 0; i <= INNER_SLAVE_ADDRESS_END; i++) {
  175. coil[i] = 0;
  176. }
  177. nmbs_error err1 = nmbs_read_coils(&nmbs, MINI_GATEWAY_INNER_COIL_ADDRESS, 8, &regs[0]);
  178. nmbs_read_coils(&nmbs, MINI_GATEWAY_INNER_COIL2_ADDRESS, 8, &regs[1]);
  179. nmbs_read_coils(&nmbs, MINI_GATEWAY_INNER_COIL_ERROR3_ADDRESS, 1, &regs[3]);
  180. nmbs_read_coils(&nmbs, MINI_GATEWAY_INNER_COIL_ERROR4_ADDRESS, 1, &regs[4]);
  181. // osDelay(500);
  182. if (err1 == NMBS_ERROR_NONE) {
  183. set_reg_value(INNER_GROUP1_REG_ADDRESS, regs[0]);
  184. set_reg_value(INNER_GROUP2_REG_ADDRESS, regs[1]);
  185. set_reg_value(INNER_ERROR1_REG_ADDRESS, 0);
  186. set_reg_value(INNER_ERROR3_REG_ADDRESS, regs[3] << 2);
  187. set_reg_value(INNER_ERROR4_REG_ADDRESS, regs[4] << 3);
  188. error_count = 0;
  189. uint8_t buf;
  190. for (int i = 0; i <= INNER_SLAVE_ADDRESS_END; i++) {
  191. buf = regs[0] << (7 - i);
  192. coil[i] = buf >> 7;
  193. }
  194. } else {
  195. nmbs_error err2 = nmbs_read_coils(&nmbs, MINI_GATEWAY_INNER_COIL_ADDRESS, 8, &regs[0]);
  196. osDelay(300);
  197. if (err2 == NMBS_ERROR_NONE) {
  198. uint8_t buf;
  199. for (int i = 0; i <= INNER_SLAVE_ADDRESS_END; i++) {
  200. buf = regs[0] << (7 - i);
  201. coil[i] = buf >> 7;
  202. }
  203. error_count = 0;
  204. set_reg_value(INNER_GROUP1_REG_ADDRESS, regs[0]);
  205. }
  206. }
  207. count--;
  208. // osMutexRelease(mini_mutex);
  209. // }
  210. osDelay(1000 * 60 * 1);
  211. }
  212. }
  213. void mini_gateway_master_init(void) {
  214. // mini_mutex = osMutexNew(NULL);
  215. nmbs_platform_conf platformConf;// 配置uart
  216. nmbs_platform_conf_create(&platformConf);
  217. platformConf.transport = NMBS_TRANSPORT_RTU;// RTU
  218. platformConf.read = &uart_read; // 读写函数1
  219. platformConf.write = &uart_write; // 读写函数
  220. nmbs_client_create(&nmbs, &platformConf);// 创建客户端
  221. nmbs_set_read_timeout(&nmbs, 300);
  222. nmbs_set_byte_timeout(&nmbs, 300);
  223. nmbs_set_destination_rtu_address(&nmbs, MINI_GATEWAY_SLAVE_ADDRESS);
  224. osThreadNew(gateway_poll_task, NULL, NULL);
  225. osThreadNew(mini_mater_task, NULL, NULL);
  226. }