mini_gateway_master.c 8.9 KB

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