// // Created by DELL on 2024/10/16. // #include #include "mini_gateway_master.h" #include "usart.h" #include "modbus.h" #include "cmsis_os2.h" #include "modbus_slave.h" uint8_t error_count = 0; static nmbs_t nmbs; extern uint8_t slaves[SLAVE_ADDRESS_END]; // 保存已经存在的从站号 //static osMutexId_t mini_mutex; extern uint8_t is_slave_exist; static uint8_t coil[INNER_SLAVE_ADDRESS_END] = {0}; static int32_t uart_read(uint8_t *buf, uint16_t count, int32_t byte_timeout_ms, void *arg) { HAL_StatusTypeDef status = HAL_UART_Receive(&huart4, buf, count, byte_timeout_ms); if (status == HAL_OK) { return count; } else { return 0; } } static int32_t uart_write(const uint8_t *buf, uint16_t count, int32_t byte_timeout_ms, void *arg) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET); HAL_UART_Transmit(&huart4, buf, count, byte_timeout_ms); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET); return count; } void sync_ac_status(ffx_status_t *status) { uint16_t power; uint16_t mode; uint16_t fan_speed; uint16_t set_temp; if (status->power == 0x01) { power = 0xAA; fan_speed = status->fan_speed + 1; set_temp = status->set_temp; } else power = 0x55; mode = status->mode + 1; switch (status->mode) { case 0://制冷模式 mode = status->mode + 1; break; case 1://制热模式 mode = status->mode + 3; break; case 2://除湿模式 mode = status->mode; break; case 3://送风模式 mode = status->mode; break; case 4://加湿模式、送风 mode = 3; break; default: break; } uint16_t regs[5] = {power, mode, set_temp * 10, fan_speed, 0}; nmbs_error err2 = nmbs_write_multiple_registers(&nmbs, 102 + 25 * (status->inner_num - 1), 5, regs); if (err2 == NMBS_ERROR_NONE) { set_reg_value(INNER_ERROR1_REG_ADDRESS, 0); error_count = 0; } else { set_reg_value(INNER_ERROR1_REG_ADDRESS, 1); error_count++; } } _Noreturn void mini_mater_task(void *pv) { uint8_t is_error_ffx[8] = {0}; for (;;) { // if (osMutexAcquire(mini_mutex, osWaitForever) == osOK) { bool is_power_on = false; ffx_status_t status; for (int i = 0; i < sizeof(coil); i++) { if (coil[i] != 0) { uint16_t data[10]; uint8_t inner_num = i + 1; nmbs_error err = nmbs_read_holding_registers(&nmbs, (MINI_GATEWAY_INNER_POWER_ADDRESS + 25 * i), 4, &data[0]); if (err == NMBS_ERROR_NONE) { status.power = data[0]; status.mode = data[1]; status.fan_speed = data[3] - 2; status.set_temp = data[2] / 10; status.inner_num = inner_num; if ((status.power == INNER_POWER_ON) && (is_power_on == false)) { osDelay(100); is_power_on = true; set_reg_value(POWER_REG_ADDRESS, status.power); set_reg_value(WORK_MODE_REG_ADDRESS, status.mode); set_reg_value(FAN_SPEED_REG_ADDRESS, status.fan_speed); set_reg_value(SET_TEMP_REG_ADDRESS, status.set_temp); set_reg_value(INNER_ERROR1_REG_ADDRESS, 0); error_count = 0; } } else { error_count++; is_error_ffx[i]++; is_power_on = true; if ((status.power == INNER_POWER_OFF) && is_error_ffx[i] > 3) { set_reg_value(INNER_ERROR1_REG_ADDRESS, 1); set_reg_value(POWER_REG_ADDRESS, status.power); error_count = 0; is_error_ffx[i] = 0; } } } osDelay(1000); } if ((status.power == INNER_POWER_OFF) && (is_power_on == false)) { set_reg_value(INNER_ERROR1_REG_ADDRESS, 0); set_reg_value(POWER_REG_ADDRESS, status.power); error_count = 0; } osDelay(1000); // osMutexRelease(mini_mutex); // } } } // 检测从机是否存在 bool check_inner_slave_exist(uint8_t slave_addr) { nmbs_set_destination_rtu_address(&nmbs, slave_addr); // 设置从机地址 bool result; osDelay(100); nmbs_read_coils(&nmbs, MINI_GATEWAY_INNER_COIL_ADDRESS + slave_addr - 1, 1, &result); if (result) { return true; } else { return false; } } _Noreturn void gateway_poll_task(void *pv) { uint8_t count = 0; for (;;) { nmbs_bitfield regs = {0}; // if (osMutexAcquire(mini_mutex, osWaitForever) == osOK) { for (int i = 0; i <= INNER_SLAVE_ADDRESS_END; i++) { coil[i] = 0; } nmbs_error err1 = nmbs_read_coils(&nmbs, MINI_GATEWAY_INNER_COIL_ADDRESS, 8, ®s[0]); nmbs_read_coils(&nmbs, MINI_GATEWAY_INNER_COIL2_ADDRESS, 8, ®s[1]); nmbs_read_coils(&nmbs, MINI_GATEWAY_INNER_COIL_ERROR3_ADDRESS, 1, ®s[3]); nmbs_read_coils(&nmbs, MINI_GATEWAY_INNER_COIL_ERROR4_ADDRESS, 1, ®s[4]); osDelay(500); if (err1 == NMBS_ERROR_NONE) { set_reg_value(INNER_GROUP1_REG_ADDRESS, regs[0]); set_reg_value(INNER_GROUP2_REG_ADDRESS, regs[1]); set_reg_value(INNER_ERROR1_REG_ADDRESS, 0); set_reg_value(INNER_ERROR3_REG_ADDRESS, regs[3] << 2); set_reg_value(INNER_ERROR4_REG_ADDRESS, regs[4] << 3); error_count = 0; uint8_t buf; for (int i = 0; i <= INNER_SLAVE_ADDRESS_END; i++) { buf = (regs[0] - is_slave_exist) << (7 - i); coil[i] = buf >> (7); } } else { nmbs_error err2 = nmbs_read_coils(&nmbs, MINI_GATEWAY_INNER_COIL_ADDRESS, 8, ®s[0]); osDelay(300); if (err2 == NMBS_ERROR_NONE) { uint8_t buf; for (int i = 0; i <= INNER_SLAVE_ADDRESS_END; i++) { buf = (regs[0] - is_slave_exist) << (7 - i); coil[i] = buf >> (7); } error_count = 0; set_reg_value(INNER_GROUP1_REG_ADDRESS, regs[0]); } } count--; osDelay(500); // osMutexRelease(mini_mutex); osDelay(1000 * 60 * 10); // } } } void mini_gateway_master_init(void) { // mini_mutex = osMutexNew(NULL); nmbs_platform_conf platformConf;// 配置uart nmbs_platform_conf_create(&platformConf); platformConf.transport = NMBS_TRANSPORT_RTU;// RTU platformConf.read = &uart_read; // 读写函数1 platformConf.write = &uart_write; // 读写函数 nmbs_client_create(&nmbs, &platformConf);// 创建客户端 nmbs_set_read_timeout(&nmbs, 300); nmbs_set_byte_timeout(&nmbs, 300); nmbs_set_destination_rtu_address(&nmbs, MINI_GATEWAY_SLAVE_ADDRESS); osThreadNew(gateway_poll_task, NULL, NULL); osThreadNew(mini_mater_task, NULL, NULL); }