/* USER CODE BEGIN Header */ /** ****************************************************************************** * File Name : freertos.c * Description : Code for freertos applications ****************************************************************************** * @attention * * Copyright (c) 2024 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "FreeRTOS.h" #include "task.h" #include "main.h" #include "cmsis_os.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "timers.h" #include "usart.h" #include "can.h" #include "rtc.h" #include "uType.h" #include "remote.h" #include "queue.h" #include "iwdg.h" #include "adc.h" #include "WIFI.h" #include "w25qxx.h" #include "spi.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ typedef StaticQueue_t osStaticMessageQDef_t; /* USER CODE BEGIN PTD */ extern RTC_HandleTypeDef hrtc; /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /** * @breaf 485串口uart2接收数组定义 */ extern uint8_t uart2RXDATAbuffer[BUFFER_SIZE2]; extern uint8_t dataReceive2[BUFFER_SIZE2];// 485 //extern volatile uint8_t uart2DataReady ; #define MAX_FRAME_SIZE 40 // 一帧最大 40 字节 /** * @breaf 4G串口uart3接收数组定义 */ extern uint8_t receiveBuff4G[BUFFER_SIZE4G]; //extern uint8_t receiveBuff4G_DMAbuffer[BUFFER_SIZE4G]; volatile uint16_t uart4GHead = 0; // 缓冲区写指针 volatile uint16_t uart4GTail = 0; // 缓冲区读指针 /** * @breaf ML307A参数定义 */ typedef enum { AT, CPIN, CEREG, CFUN, TIME, MUECONFIG, MDIALUPCFG, MQTTDISC, MQTTCFG_CLEAN, MQTTCFG_CACHED, MQTTCONNE, MQTTSUB, MQTTSUB1, MIP_CONNECT, MIPCFG, MIPCLOSE, MDIALUP, MIP_REGISTER, Heartbeat, Systemwarninglevel, Remote, CHECK_AT, CHECK_CPIN, CHECK_MQTT, CHECK_MIPSTATE, IDLE0, IDLE, IDLE1, SEND_MLX } ML307A_StateTypeDef; static ML307A_StateTypeDef ml307aState = AT; time_t epoch_time = 0; static uint8_t mipclose_count = 0; typedef enum { Debug_MODE, // 试验模式 WARNING_MODE, // 预警模式 SET_MODE, // 设置模式 } SYSTEM_OPERATINGMODE; volatile SYSTEM_OPERATINGMODE system_operatingmode = WARNING_MODE; // 屏幕显示模式 typedef enum { DWIN_STATE_DEBUG, DWIN_STATE_WARNING, DWIN_STATE_SET, DWIN_STATE_AVIATION, DWIN_STATE_AVIATION_READ, DWIN_STATE_4G, DWIN_STATE_DEBUG_SWITCH, DWIN_STATE_WARNING_SWITCH, DWIN_STATE_SET_SWITCH, DWIN_STATE_IDLE } DWIN_State_t; volatile DWIN_State_t dwin_state = DWIN_STATE_WARNING; SYSTEM_Cloud_MODE system_cloud_mode = Cloud_WIFI_MODE; // 系统为WIFI模式还是4G模式 // Cloud_WIFI_MODE // Cloud_4G_MODE typedef enum { WIFI_AT, WIFI_RESTORE, WIFI_CWMODE, WIFI_RST, WIFI_TCPDATAMODE, WIFI_CIPSNTP, WIFI_TZONE, WIFI_DPM, WIFI_CWSTAT, WIFI_CWJAP, WIFI_CWQAP, WIFI_CIPSTART, WIFI_CIPSEND_Register, WIFI_unixtime, WIFI_Remote, WIFI_TIME, WIFI_IDLE } WIFI_StateTypeDef; static WIFI_StateTypeDef wifistate = WIFI_CWMODE; // 温度预警等级 typedef enum { TEMP_LEVEL_0, // 正常状态 TEMP_LEVEL_1, // 一级预警 TEMP_LEVEL_2 // 二级报警 } TempSystemLevel_t; volatile TempSystemLevel_t temp_system_level = TEMP_LEVEL_0; uint8_t temp_level_buffer[MAX_TEMP_NODE_NUM] = {0}; // 状态变量记录每个温度小板的 temp_system_level // 压力预警等级 typedef enum { PRE_LEVEL_0, // 正常状态 PRE_LEVEL_1, // 一级预警 PRE_LEVEL_2 // 二级报警 } PreSystemLevel_t; volatile PreSystemLevel_t pre_system_level = PRE_LEVEL_0; uint8_t pre_level_buffer[MAX_PRESSURE_NODE_NUM] = {0}; // 状态变量记录每个压力小板的 pre_system_level // CO预警等级 typedef enum { CO_LEVEL_0, // 正常状态 CO_LEVEL_1, // 一级预警 CO_LEVEL_2 // 二级报警 } COSystemLevel_t; volatile COSystemLevel_t co_system_level = CO_LEVEL_0; float co_level_buffer[MAX_CO_NODE_NUM] = {0.0f}; // 状态变量记录每个CO小板的 co_system_level // H2预警等级 typedef enum { H2_LEVEL_0, // 正常状态 H2_LEVEL_1, // 一级预警 H2_LEVEL_2 // 二级报警 } H2SystemLevel_t; volatile H2SystemLevel_t h2_system_level = H2_LEVEL_0; float h2_level_buffer[MAX_H2_NODE_NUM] = {0.0f}; // 状态变量记录每个CO小板的 h2_system_level /** * @breaf 温度数据组包用 */ typedef struct _CANTemp_raw { uint8_t NodeId; uint8_t PacktSeq; uint8_t SliceNum; uint16_t SliceMask; uint8_t data[SLICE_DATA_SIZE*MAX_SLICE_NUM]; uint8_t Finished; }CanTemp_raw; CanTemp_raw g_canTempRaw[MAX_TEMP_NODE_NUM]; /** * @breaf 485串口2接收处理参数定义 */ typedef struct _UartTemp_raw { uint8_t NodeId; uint8_t Finished; uint8_t data[4]; }UartTemp_raw; UartTemp_raw g_485TempRaw[MAX_H2_NODE_NUM]; /** * @breaf 供电标志位 */ bool screen_powered = false; bool actuator_powered = false; bool gas_powered = false; /** * @breaf 迪文屏状态显示等级 */ int previous_actuator_state = actuator_closed; static int previous_dwin_warning_state_level = SYSTEM_LEVEL_3; static int previous_dwin_power_state = dwin_power_closed; /** * @breaf 处理迪文待发送的数据的缓冲区 * @breaf 用于比较数据是否与上次一样避免重复发送 */ typedef struct _DwinTemp_data { uint32_t count_ms; uint8_t recv_flag; uint8_t offline_flag; uint8_t data[3]; }DwinTemp_Data; DwinTemp_Data g_prevdata_temp[MAX_TEMP_NODE_NUM]__attribute__((section(".ccmram"))); typedef struct _DwinPress_data { uint32_t count_ms; uint8_t recv_flag; uint8_t offline_flag; uint8_t data[2]; }DwinPress_Data; DwinPress_Data g_prevdata_press[MAX_PRESSURE_NODE_NUM]__attribute__((section(".ccmram"))); typedef struct _DwinH2_data { uint32_t count_ms; uint8_t recv_flag; uint8_t offline_flag; uint8_t data[4]; }DwinH2_Data; DwinH2_Data g_prevdata_h2[MAX_H2_NODE_NUM]__attribute__((section(".ccmram"))); typedef struct _DwinCO_data { uint32_t count_ms; uint8_t recv_flag; uint8_t offline_flag; uint8_t data[4]; }DwinCO_Data; DwinCO_Data g_prevdata_co[MAX_CO_NODE_NUM]__attribute__((section(".ccmram"))); /** * @breaf 标志位 */ bool DWIN_stopsend_flag = true; // DWIN能否发送指令标志位。用于发送停止掉发送状态指令 bool flash_save_parameter_flag = false; // 修改参数时用于存入flash标志位 bool flash_save_terminal_flag = false; // 修改终端ID和手机号时用于存入flash标志位 bool gas_start_read_flag = false; // 气体读取标志位 bool DWIN_terminal_SHOW_flag = false; // 迪文接收修改终端ID存入flash的标志位 /** * @breaf 检查传感器在线状态的状态机 */ typedef enum { SENSOR_STATE_TEMP, SENSOR_STATE_PRE, SENSOR_STATE_H2, SENSOR_STATE_CO, SENSOR_STATE_MAX } SensorCheckState; static SensorCheckState current_state = SENSOR_STATE_TEMP; //#define TEMP_NODE_GROUP_SIZE 5 // 每次检测的温度传感器数量 //static uint8_t current_temp_group = 0; // 当前检测温度的组编号 FlashData flash_data = { .controltransmit_flag = 0, // 默认打开传输传感器数据 .temp_first_threshold = 60, // 温度一级阈值 60 ℃ .temp_second_threshold = 100, // 温度二级阈值 100 ℃ .pressure_threshold = 100, // 压力阈值 100 pa .co_threshold = 10, // CO二级阈值 10 ppm .h2_threshold = 10, // H2二级阈值 10 ppm .heart_upload_frequency = 30, // 心跳上传云平台频率 30 s .mainboard_upload_frequency = 3, // 主板上传云平台频率 3 s .smallboard_upload_frequency = 1, // 小板CAN上传至主板频率 1 s .object_emissivity = 95, // 初始发射率 0.95(后续除100) .version = 1, // 系统版本号 }; /** * @brief AT指令应答内容 */ char *MQTTSTATE_Responses[] = { "+MQTTSTATE: 1", "+MQTTSTATE: 2", "+MQTTSTATE: 3", NULL }; char *MQTTSTATEreceivedResponse = NULL; // 用来存储MQTT连接状态接收到的响应 SensorDataBuffer sensor_data_buffer = {0}; SensorDWINDataBuffer sensor_dwin_data_buffer = {0}; uint8_t DWIN_STARTSHOW_flag = 0; uint8_t DWIN_STARTSHOW_count = 0; static char mqtt_sub_topic[100]__attribute__((section(".ccmram"))); // 订阅主题缓冲区 static char mqtt_sub_cmd[150]__attribute__((section(".ccmram"))); // AT 指令缓冲区 //QueueSetHandle_t xQueueSet; bool check_can = true; // 轮流检查can和cloud的队列的标志位 bool check_dwin_gas = true; // 轮流检查can和cloud的队列的标志位 bool ReadHEXNDWIN_flag = true; extern uint8_t terminalId[7]; extern uint8_t g_board_id[6]; #define STABLE_TIME_MS 1500 // 1.5秒稳定时间 #define TEMP_DEBOUNCE_TIME_MS 200 // 防止短时间内频繁变化 //static uint32_t last_change_time = 0; // 用于保存上次检测时的时间戳 //static uint32_t last_temp_level_change_time = 0; // 上次temp_level变更的时间 //static uint8_t last_tempmax_level = 0; // 上一次的最大温度等级 static DWIN_power_t last_dwin_power_state = dwin_power_closed; // 初始为关闭 volatile DWIN_power_t dwin_power_state = dwin_power_closed;// 迪文供电情况标志位 volatile DWIN_Init_t dwin_init_state = dwin_Init_closed; // 迪文屏初始化标志位 volatile DWIN_Show_t dwin_show_state = dwin_show_closed; // 迪文屏发送数据标志位 volatile actuator_t actuator_powered_state = actuator_closed; volatile SystemLevel_t system_level = SYSTEM_LEVEL_0; uint8_t temp_buffer[MAX_FRAME_SIZE]__attribute__((section(".ccmram"))) = {0}; // 临时存放一帧数据 uint8_t Ambient_temperature = 0; static int last_system_level = -1; bool REGISTER_OK_start_flag = false; bool REGISTER_OK_start_flag_DWIN = false; static uint8_t gas_command_index = 0; static uint8_t dwin_command_index = 0; static uint32_t prev_extid = 0; uint8_t sensor_status[6] = {0x3F, 0xFF, 0xFF, 0xFF, 0x77, 0x70}; // 传感器在线情况初始化全 0,0为掉线,1为在线 uint8_t prev_sensor_status[6] = {0}; // 记录上一次的状态 bool S_offline_flag = false; uint16_t trigger_info[3] = {0}; // 存储触发信息 uint16_t send_remote_uploadfrequency = 0; uint32_t adc_val = 0 ; // ADC读取电压 uint8_t voltage_int = 0; uint8_t percent = 0; char display_str[10]; extern uint8_t receiveBuff4G_MIPURC[256];//4G处理mipurc的接收缓冲区 int g_cip_id = -1; // 初始无效 //uint8_t wifi_ssid[20] = "jiaLong"; // WiFi 名称 //uint8_t wifi_password[20] = "JL88888888"; // WiFi 密码 extern uint32_t W25_Tempaddress ; extern volatile uint8_t flash_print_busy; uint8_t flash_temp_prc0h2[512] = {0}; // 存入flash的温度和压力数据 WIFI_Config_t wifi_config = { .ssid = "jiaLong", .password = "JL88888888" }; extern uint8_t rx_len; #define WIFI_MAX_RETRY 3 // WIFI发送数据重试次数 uint32_t wifior4G_flag = 0; volatile bool heartbeat_reply_received = false; // 心跳的通用应答标志位 volatile bool unixtime_reply_received = false; // unixtime的80FF应答标志位 /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ void uart3_disable(void); void MCU_REBOOT(void); void sendWifiJoinCommand(uint8_t *ssid, uint8_t *password) ; void Send_Remote(void); void InitializeBoardDataProcess(void); void ClearSensorDataBuffer(void) ; void Uart2_ProcessNextMessage(void); bool is_electric_actuator_response(uint8_t *data); void process_electric_actuator(uint8_t *data); void process_mode(uint8_t *data); bool is_mode_response(uint8_t *data); bool is_threshold_response(uint8_t *data); void process_threshold(uint8_t *data) ; bool is_wifi_response(uint8_t *data);// 判断是否为WIFI账号密码修改 void process_wifi(uint8_t *data); // 处理阈值数据 bool is_terminal_response(uint8_t *data); void process_terminal_data(uint8_t *data); bool is_gas_sensor_response(uint8_t *data); void process_gas_sensor(uint8_t *data) ; static inline float parse_modbus_float(uint8_t *data); static void process_single_gas_sensor(uint8_t sensor_type, uint8_t id, uint8_t *data, float *level_buffer, uint8_t max_nodes, float threshold, volatile uint8_t *system_level, uint8_t (*sensor_data_buffer)[4], uint8_t *sensor_valid); bool is_restart_response(uint8_t *data) ; uint8_t CalculateChecksum(uint8_t* data, uint16_t length); //void CAN_Send_Parameter(uint32_t node_id , FlashData *flash_data , uint8_t len); void ProcessQueues(void); void ProcessDWINSHOW_gasread(void) ; void MidProcessData(CanRx_msg *can_msg) ; void MIDprocess_cloudmessage(Remote_msg *rt_msg) ; void update_temp_cloud_send_buffer(uint8_t id); void WriteToCircularBuffer(uint8_t *data, uint16_t length); void print_SensorDataBuffer(SensorDataBuffer *buffer); void DWIN_STARTSHOW(void); void DWIN_WARNING_MODE(void); void DWIN_SHOW(void); DWIN_State_t get_current_dwin_state(void); void DWIN_PARAM_SHOW(void); void check_trigger_source(void); void check_sensor_line(void); void check_temp_line(void); void check_pre_line(void); void check_h2_line(void); void check_co_line(void); void read_gas(void); void read_dwin(void) ; void DWIN_CHECK(void); void DWIN_START_CHECK(void); void printCurrentRTCTime(void); uint16_t calculate_crc16(uint8_t *data, uint16_t length) ; void send_modbus_command(uint8_t sensor_address) ; void Check_DWIN_Button(void); float modbus_to_float(uint8_t *data) ; double standard_to_float(const char* f_num) ; void control_actuator(bool enable); void control_gas_sensors(bool enable) ; void control_wifi_wakeup(bool enable) ; void Read_parameter_From_Flash(void) ; void Read_terminal_From_Flash(void) ; void Save_parameter_To_Flash( uint8_t controltransmit_flag , uint8_t temp_first_threshold , uint8_t temp_second_threshold , uint8_t pressure_threshold , uint8_t co_threshold , uint8_t h2_threshold , uint8_t smallboard_upload_frequency , uint8_t heart_upload_frequency , uint8_t mainboard_upload_frequency, uint8_t sensoronline_upload_frequency) ; // 向 Flash 写入 parameter void Save_terminal_To_Flash(uint8_t* terminalId , uint8_t* g_board_id ,uint8_t version); // 向 Flash 写入 terminal void Save_W25_Tempaddress_To_Flash(void); void Save_version_To_Flash(void); void Save_wifior4G_flag_To_Flash(void); void Save_WIFI_To_Flash(void); void Load_WIFI_From_Flash(void); void Read_Remaining_stack_space(void); uint8_t CalculateBatteryLevel(uint32_t adcValue,uint8_t *voltage); uint32_t ReadADCValue(void); void Enter_SleepMode(void); /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN Variables */ /* USER CODE END Variables */ /* Definitions for HighestLevel */ osThreadId_t HighestLevelHandle; const osThreadAttr_t HighestLevel_attributes = { .name = "HighestLevel", .stack_size = 512 * 4, .priority = (osPriority_t) osPriorityRealtime, }; /* Definitions for Common */ osThreadId_t CommonHandle; const osThreadAttr_t Common_attributes = { .name = "Common", .stack_size = 512 * 4, .priority = (osPriority_t) osPriorityNormal4, }; /* Definitions for temp_pressure */ osThreadId_t temp_pressureHandle; const osThreadAttr_t temp_pressure_attributes = { .name = "temp_pressure", .stack_size = 1024 * 4, .priority = (osPriority_t) osPriorityNormal, }; /* Definitions for check_sensor */ osThreadId_t check_sensorHandle; const osThreadAttr_t check_sensor_attributes = { .name = "check_sensor", .stack_size = 512 * 4, .priority = (osPriority_t) osPriorityBelowNormal, }; /* Definitions for display */ osThreadId_t displayHandle; const osThreadAttr_t display_attributes = { .name = "display", .stack_size = 512 * 4, .priority = (osPriority_t) osPriorityHigh, }; /* Definitions for cloud */ osThreadId_t cloudHandle; const osThreadAttr_t cloud_attributes = { .name = "cloud", .stack_size = 1024 * 4, .priority = (osPriority_t) osPriorityNormal, }; /* Definitions for SystemStatus */ osThreadId_t SystemStatusHandle; const osThreadAttr_t SystemStatus_attributes = { .name = "SystemStatus", .stack_size = 512 * 4, .priority = (osPriority_t) osPriorityAboveNormal, }; /* Definitions for can_message_queue */ osMessageQueueId_t can_message_queueHandle; uint8_t can_message_queueBuffer[ 512 * sizeof( CanRx_msg ) ]; osStaticMessageQDef_t can_message_queueControlBlock; const osMessageQueueAttr_t can_message_queue_attributes = { .name = "can_message_queue", .cb_mem = &can_message_queueControlBlock, .cb_size = sizeof(can_message_queueControlBlock), .mq_mem = &can_message_queueBuffer, .mq_size = sizeof(can_message_queueBuffer) }; /* Definitions for cloud_message_queue */ osMessageQueueId_t cloud_message_queueHandle; uint8_t cloud_message_queueBuffer[ 512 * sizeof( Remote_msg ) ]; osStaticMessageQDef_t cloud_message_queueControlBlock; const osMessageQueueAttr_t cloud_message_queue_attributes = { .name = "cloud_message_queue", .cb_mem = &cloud_message_queueControlBlock, .cb_size = sizeof(cloud_message_queueControlBlock), .mq_mem = &cloud_message_queueBuffer, .mq_size = sizeof(cloud_message_queueBuffer) }; /* Definitions for uart2rxqueue */ osMessageQueueId_t uart2rxqueueHandle; uint8_t uart2queueBuffer[ 64 * sizeof( Uart2Rx_msg ) ]; osStaticMessageQDef_t uart2queueControlBlock; const osMessageQueueAttr_t uart2rxqueue_attributes = { .name = "uart2rxqueue", .cb_mem = &uart2queueControlBlock, .cb_size = sizeof(uart2queueControlBlock), .mq_mem = &uart2queueBuffer, .mq_size = sizeof(uart2queueBuffer) }; /* Definitions for uart3rxqueue */ osMessageQueueId_t uart3rxqueueHandle; uint8_t uart3rxqueueBuffer[ 30 * sizeof( Uart3Rx_msg ) ]; osStaticMessageQDef_t uart3rxqueueControlBlock; const osMessageQueueAttr_t uart3rxqueue_attributes = { .name = "uart3rxqueue", .cb_mem = &uart3rxqueueControlBlock, .cb_size = sizeof(uart3rxqueueControlBlock), .mq_mem = &uart3rxqueueBuffer, .mq_size = sizeof(uart3rxqueueBuffer) }; /* Definitions for dataMutex */ osMutexId_t dataMutexHandle; const osMutexAttr_t dataMutex_attributes = { .name = "dataMutex" }; /* Definitions for dataReadySem */ osSemaphoreId_t dataReadySemHandle; const osSemaphoreAttr_t dataReadySem_attributes = { .name = "dataReadySem" }; /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN FunctionPrototypes */ /* USER CODE END FunctionPrototypes */ void HighestLevel_Task(void *argument); void Common_Task(void *argument); void temp_pressure_Task(void *argument); void check_sensor_Task(void *argument); void display_Task(void *argument); void cloud_Task(void *argument); void SystemStatus_Task(void *argument); void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ /** * @brief FreeRTOS initialization * @param None * @retval None */ void MX_FREERTOS_Init(void) { /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Create the mutex(es) */ /* creation of dataMutex */ dataMutexHandle = osMutexNew(&dataMutex_attributes); /* USER CODE BEGIN RTOS_MUTEX */ /* add mutexes, ... */ /* USER CODE END RTOS_MUTEX */ /* Create the semaphores(s) */ /* creation of dataReadySem */ dataReadySemHandle = osSemaphoreNew(1, 1, &dataReadySem_attributes); /* USER CODE BEGIN RTOS_SEMAPHORES */ /* add semaphores, ... */ /* USER CODE END RTOS_SEMAPHORES */ /* USER CODE BEGIN RTOS_TIMERS */ /* start timers, add new ones, ... */ /* USER CODE END RTOS_TIMERS */ /* Create the queue(s) */ /* creation of can_message_queue */ can_message_queueHandle = osMessageQueueNew (512, sizeof(CanRx_msg), &can_message_queue_attributes); /* creation of cloud_message_queue */ cloud_message_queueHandle = osMessageQueueNew (512, sizeof(Remote_msg), &cloud_message_queue_attributes); /* creation of uart2rxqueue */ uart2rxqueueHandle = osMessageQueueNew (64, sizeof(Uart2Rx_msg), &uart2rxqueue_attributes); /* creation of uart3rxqueue */ uart3rxqueueHandle = osMessageQueueNew (30, sizeof(Uart3Rx_msg), &uart3rxqueue_attributes); /* USER CODE BEGIN RTOS_QUEUES */ /* add queues, ... */ if(system_cloud_mode == Cloud_4G_MODE) { wifior4G_flag = 0 ; // 4G模式 标志位为0 } if(system_cloud_mode == Cloud_WIFI_MODE) { wifior4G_flag = 1 ; // WIFI模式 标志位为1 } InitializeBoardDataProcess(); ClearSensorDataBuffer(); Save_version_To_Flash(); Read_parameter_From_Flash(); Read_terminal_From_Flash(); Load_W25_Tempaddress_From_Flash(); Read_wifior4G_flag_From_Flash(); Load_version_From_Flash(); /* USER CODE END RTOS_QUEUES */ /* Create the thread(s) */ /* creation of HighestLevel */ HighestLevelHandle = osThreadNew(HighestLevel_Task, NULL, &HighestLevel_attributes); /* creation of Common */ CommonHandle = osThreadNew(Common_Task, NULL, &Common_attributes); /* creation of temp_pressure */ temp_pressureHandle = osThreadNew(temp_pressure_Task, NULL, &temp_pressure_attributes); /* creation of check_sensor */ check_sensorHandle = osThreadNew(check_sensor_Task, NULL, &check_sensor_attributes); /* creation of display */ displayHandle = osThreadNew(display_Task, NULL, &display_attributes); /* creation of cloud */ cloudHandle = osThreadNew(cloud_Task, NULL, &cloud_attributes); /* creation of SystemStatus */ SystemStatusHandle = osThreadNew(SystemStatus_Task, NULL, &SystemStatus_attributes); /* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */ /* USER CODE END RTOS_THREADS */ /* USER CODE BEGIN RTOS_EVENTS */ /* add events, ... */ /* USER CODE END RTOS_EVENTS */ } /* USER CODE BEGIN Header_HighestLevel_Task */ /** * @brief Function implementing the HighestLevel thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_HighestLevel_Task */ void HighestLevel_Task(void *argument) { /* USER CODE BEGIN HighestLevel_Task */ /* Infinite loop */ uint16_t counter = 0; // 闪灯计数器 uint16_t gas_counter = 0; // 气体计数器 for(;;) { osDelay(5); counter++; Check_DWIN_Button(); if (counter >= 100) { HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5); // 切换 LED 状态 counter = 0; // 重置计数器 HAL_IWDG_Refresh(&hiwdg); } if(dwin_power_state != previous_dwin_power_state) // previous_dwin_warning_state_level { // previous_dwin_warning_state_level = SYSTEM_LEVEL_3; previous_dwin_power_state = dwin_power_state; } if (dwin_power_state == dwin_power_opened) { if (last_dwin_power_state != dwin_power_opened) // 状态刚从关闭变为开启 { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); // 外设DWIN 24V 高电平开启 DWIN_STARTSHOW_flag = 1; dwin_state = DWIN_STATE_WARNING_SWITCH; REGISTER_OK_start_flag_DWIN = false; } // 更新上一次状态 last_dwin_power_state = dwin_power_opened; } else if(dwin_power_state == dwin_power_closed) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); // 外设DWIN 24V 低电平关闭 dwin_state = DWIN_STATE_IDLE; dwin_show_state = dwin_show_closed ; previous_dwin_warning_state_level = SYSTEM_LEVEL_3; previous_actuator_state = actuator_closed; REGISTER_OK_start_flag_DWIN = false; last_dwin_power_state = dwin_power_closed;// 更新上一次状态 } if (temp_system_level == TEMP_LEVEL_1 || temp_system_level == TEMP_LEVEL_2) { if (temp_system_level == TEMP_LEVEL_2 || pre_system_level == PRE_LEVEL_2 || co_system_level == CO_LEVEL_2 || h2_system_level == H2_LEVEL_2) { system_level = SYSTEM_LEVEL_2; // 温度至少1级,且其他有2级时,触发2级 } else { system_level = SYSTEM_LEVEL_1; // 仅温度达到1级 } } else { system_level = SYSTEM_LEVEL_0; // 温度为0级,则系统也为0级 } if (system_level == SYSTEM_LEVEL_2) { gas_counter++; // dwin_warning_state_level = DWIN_WARNING_LEVEL_2_STATE; actuator_powered = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_11) == GPIO_PIN_RESET; if ( actuator_powered ) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET); // 使能 电推杆12V芯片 低电平开启 control_actuator(true); // 开启电推杆供电 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_RESET); printf("SYSTEM_LEVEL_2 actuator_power_opened\n"); actuator_powered_state = actuator_opened; } gas_powered = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4) == GPIO_PIN_RESET; if ( gas_powered ) { control_gas_sensors(true); // 打开气体供电 printf("gas_power_opened\n"); if (gas_counter >= 8000) // 气体上电后等待40秒再开始读数 { gas_start_read_flag = true; // printf("gas_start_read\n"); gas_counter = 0; } }else{ gas_start_read_flag = true; } } else if (system_level == SYSTEM_LEVEL_0) { // printf("system_level == SYSTEM_LEVEL_0\r\n"); // dwin_warning_state_level = DWIN_WARNING_LEVEL_0_STATE; // actuator_powered = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_11) == GPIO_PIN_SET; // if ( actuator_powered ) // { // control_actuator(false); // 关闭电推杆供电 //// HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); //// HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_SET); // // printf("actuator_power_closed\n"); // } gas_powered = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4) == GPIO_PIN_RESET; if ( gas_powered ) { // control_gas_sensors(true); // 打开气体供电 // printf("gas_power_closed\n"); // printf("gas_power_opened_SYSTEM_LEVEL_0\n"); gas_start_read_flag = false; }else{ control_gas_sensors(false); // 关闭气体供电 gas_start_read_flag = false; } // gas_start_read_flag = false; } if(system_cloud_mode == Cloud_WIFI_MODE) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET); // PC7高电平唤醒WIFI HAL_GPIO_WritePin(GPIOC, V3_8V_4G_enable_Pin, GPIO_PIN_SET); // 4G电源3.8V高电平断电 wifior4G_flag = 1; // WIFI模式 }else{ HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET); // PC7低电平休眠WIFI HAL_GPIO_WritePin(GPIOC, V3_8V_4G_enable_Pin, GPIO_PIN_RESET); // 4G电源3.8V低电平开启 wifior4G_flag = 0; // 4G模式 } } /* USER CODE END HighestLevel_Task */ } /* USER CODE BEGIN Header_Common_Task */ /** * @brief Function implementing the Common thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_Common_Task */ void Common_Task(void *argument) { /* USER CODE BEGIN Common_Task */ /* Infinite loop */ // uint16_t adc = 0; for(;;) { osDelay(100); // adc++; // if(adc > 20) // { // adc_val = ReadADCValue(); // percent = CalculateBatteryLevel(adc_val, &voltage_int); // printf("adc %d %d %d\n",adc_val,voltage_int,percent); // } Uart2_ProcessNextMessage(); if(flash_save_parameter_flag) { Save_parameter_To_Flash( flash_data.controltransmit_flag , flash_data.temp_first_threshold , flash_data.temp_second_threshold , flash_data.pressure_threshold , flash_data.co_threshold , flash_data.h2_threshold , flash_data.smallboard_upload_frequency , flash_data.heart_upload_frequency , flash_data.mainboard_upload_frequency, flash_data.sensoronline_upload_frequency); flash_save_parameter_flag = false; } // if(flash_save_terminal_flag) // { //// vTaskSuspend(displayHandle); //// vTaskSuspend(temp_pressureHandle); // Save_terminal_To_Flash(terminalId , g_board_id ,flash_data.version); // vTaskResume(displayHandle); // vTaskResume(temp_pressureHandle); // flash_save_terminal_flag = false; // } } /* USER CODE END Common_Task */ } /* USER CODE BEGIN Header_temp_pressure_Task */ /** * @brief Function implementing the temp_pressure thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_temp_pressure_Task */ void temp_pressure_Task(void *argument) { /* USER CODE BEGIN temp_pressure_Task */ /* Infinite loop */ // InitializeBoardDataProcess(); for(;;) { ProcessQueues(); osDelay(20); // HAL_IWDG_Refresh(&hiwdg); // DWIN_STARTSHOW(); } /* USER CODE END temp_pressure_Task */ } /* USER CODE BEGIN Header_check_sensor_Task */ /** * @brief Function implementing the check_sensor thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_check_sensor_Task */ void check_sensor_Task(void *argument) { /* USER CODE BEGIN check_sensor_Task */ /* Infinite loop */ uint32_t delay_time = 0; uint32_t adc_delay_time = 0; for(;;) { // process_uart3_buffer(); // 处理4G模组收到的数据 osDelay(100); if( delay_time > 7000 ) { check_sensor_line(); delay_time = 0; } delay_time += 100; if( adc_delay_time > 7000 ) { adc_val = ReadADCValue(); percent = CalculateBatteryLevel(adc_val, &voltage_int); adc_delay_time = 0; } adc_delay_time += 100; Enter_SleepMode(); // 最低等级任务 空闲时刻让 CPU 进入低功耗 // Read_Remaining_stack_space(); } /* USER CODE END check_sensor_Task */ } /* USER CODE BEGIN Header_display_Task */ /** * @brief Function implementing the display thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_display_Task */ void display_Task(void *argument) { /* USER CODE BEGIN display_Task */ /* Infinite loop */ for(;;) { ProcessDWINSHOW_gasread(); vTaskDelay(pdMS_TO_TICKS(90)); } /* USER CODE END display_Task */ } /* USER CODE BEGIN Header_cloud_Task */ /** * @brief Function implementing the cloud thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_cloud_Task */ void cloud_Task(void *argument) { /* USER CODE BEGIN cloud_Task */ /* Infinite loop */ /** * @brief 4G串口3使能 */ __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE); HAL_UART_Receive_DMA(&huart3, receiveBuff4G, BUFFER_SIZE4G); // 启动USART3的DMA接收 for(;;) { if(system_cloud_mode == Cloud_4G_MODE) { switch (ml307aState) { case AT: // osDelay(200); if (sendCmd_4G_3("AT\r\n", "OK","OK",1, 1)) { printf("AT_OK\r\n"); ml307aState = CPIN; // CFUN CPIN } else { printf("AT_fail\r\n"); ml307aState = AT; // AT } break; case CPIN: osDelay(3000); if (sendCmd_4G("AT+CPIN?\r\n","+CPIN: READY", 2, 1)) { // +CPIN: READY printf("CPIN_OK\r\n"); ml307aState = CEREG; } else { printf("CPIN_fail\r\n"); ml307aState = AT; } // osDelay(100); break; case CEREG: osDelay(2000); if (sendCmd_4G("AT+CEREG?\r\n","+CEREG: 0,1", 2, 1)) { printf("CEREG_OK\r\n"); ml307aState = CFUN; } else { printf("CEREG_fail\r\n"); ml307aState = CPIN; } // osDelay(100); break; case CFUN: if (sendCmd_4G_3("AT+CFUN=1\r\n", "OK", "OK", 1, 1)) { printf("CFUN_OK\r\n"); ml307aState = TIME; } else { printf("CFUN_fail\r\n"); ml307aState = CEREG; // CFUN CEREG } // osDelay(100); break; case TIME: sendCmd_4G_3("AT+CCLK?\r\n", "OK", "OK", 1, 1); epoch_time = parse_cclk_time((char *)receiveBuff4G); if (epoch_time != 2) { // printf("unix: %ld\n", epoch_time); Set_RTC_Time(epoch_time); // 设置 RTC printCurrentRTCTime(); ml307aState = MIP_CONNECT; // ml307aState = MIP_CONNECT MUECONFIG }else{ ml307aState = CFUN; } // osDelay(100); break; // mqtt case MUECONFIG: if (sendCmd_4G_3("AT+MUECONFIG=\"autoconn\",1\r\n", "OK", "OK", 1, 3)) { printf("MUECONFIG_OK\r\n"); ml307aState = MDIALUPCFG; } else { printf("MUECONFIG_fail\r\n"); ml307aState = CFUN; } osDelay(100); break; case MDIALUPCFG: if (sendCmd_4G_3("AT+MDIALUPCFG=\"auto\",1\r\n", "OK", "OK", 1, 3)) { printf("MDIALUPCFG_OK\r\n"); ml307aState = MQTTCFG_CACHED;// MQTTDISC MQTTCFG_CLEAN MQTTCFG_CACHED } else { ml307aState = MQTTDISC; } osDelay(200); break; case MQTTCFG_CACHED: if (sendCmd_4G_3("AT+MQTTCFG=\"cached\",0,1\r\n", "OK", "OK", 1, 3)) { printf("MQTTCFG_CACHED_OK\r\n"); ml307aState = MQTTCONNE; } else { printf("MQTTCFG_CACHED_fail\r\n"); ml307aState = MQTTDISC; } osDelay(200); break; case MQTTCONNE: // 博客测试 106.14.207.159 1883 // 公司测试 121.199.29.128 7883 // 阿里平台 47.100.6.214 1883 if (sendCmd_4G_3("AT+MQTTCONN=0,\"47.100.6.214\",1883,\"BATT|securemode=2,signmethod=hmacsha1,timestamp=1729351701003|\",\"BATT&k1vccLJvsUy\",\"E664F110C5752BDB294C14ADC5594A673C6552B8\"\r\n", "OK", "OK",1, 1)) {// +MQTTURC: \"conn\",0,0 printf("MQTTCONNE_OK\r\n"); ml307aState = MQTTSUB; }else{ printf("MQTTCONNE_fail\r\n"); ml307aState = MQTTDISC; } osDelay(200); break; // sendCmd_4G("AT+MQTTSUB=0,\"/sys/k1vccLJvsUy/BATT/thing/service/property/set\",1\r\n", "OK", 1, 1) case MQTTSUB: if (sendCmd_4G_3("AT+MQTTSUB=0,\"/sys/k1vccLJvsUy/BATT/thing/service/property/set\",1\r\n", "OK", "OK", 1, 1)) { // +MQTTSUB: 0,33243 printf("MQTTSUB_OK\r\n"); ml307aState = MQTTSUB1; }else{ printf("MQTTSUB_fail\r\n"); ml307aState = MQTTDISC; } osDelay(100); break; case MQTTSUB1: sprintf(mqtt_sub_topic, "/k1vccLJvsUy/%02X%02X%02X%02X%02X%02X%02X/user/get", terminalId[0], terminalId[1], terminalId[2], terminalId[3], terminalId[4], terminalId[5], terminalId[6]); sprintf(mqtt_sub_cmd, "AT+MQTTSUB=0,\"%s\",1\r\n", mqtt_sub_topic); if (sendCmd_4G_3(mqtt_sub_cmd, "OK", "OK", 1, 1)) { printf("MQTTSUB_OK: %s\r\n", mqtt_sub_topic); HAL_GPIO_WritePin(V5V_CAN_EN_GPIO_Port, V5V_CAN_EN_Pin, GPIO_PIN_SET); ml307aState = MIP_CONNECT; }else{ printf("MQTTSUB_fail\r\n"); ml307aState = MQTTDISC; } osDelay(100); break; case MQTTDISC: if (sendCmd_4G_3("AT+MQTTDISC=0\r\n", "OK", "OK", 1, 3)) { printf("AT+MQTTDISC_OK\r\n"); ml307aState = MUECONFIG; } else { printf("AT+MQTTDISC_fail\r\n"); ml307aState = MUECONFIG; } osDelay(200); break; // tcp case MIP_CONNECT: // 私有测试 183.230.40.96 1883 // 公司测试 121.199.29.128 7342 // 重庆正式平台 47.109.73.167 10001 // 重庆测试平台 47.109.73.167 10002 // TCP模拟 183.230.40.96 1883 if (sendCmd_4G_3("AT+MIPOPEN=0,\"TCP\",\"47.109.73.167\",10002\r\n", "OK", "+MIPOPEN: 0,0", 5, 2)) {// +MIPOPEN: 0,0 // if (sendCmd_4G_2("AT+MIPOPEN=0,\"TCP\",\"47.109.73.167\",10001,10,2\r\n", "+MIPOPEN: 0,0", "OK",5, 2)) {// +MIPOPEN: 0,0 printf("MIPOPEN_TCP_IP_OK\r\n"); ml307aState = MIPCFG; // MIPSEND } else { printf("MIPOPEN_TCP_IP_fail\r\n"); if(sendCmd_4G_3("AT+MIPCLOSE=0\r\n", "OK", "OK", 5, 1)){ printf("MIPOPEN_fail\r\n"); } ml307aState = MIPCLOSE; // MIP_CONNECT } // osDelay(100); break; case MIPCFG: // 设置命令发送和接收数据格式 if (sendCmd_4G_3("AT+MIPCFG=\"encoding\",0,1,1\r\n", "OK", "OK", 1, 1)) { ml307aState = MIP_REGISTER; // MIPSEND printf("MIPCFG_OK\r\n"); } else { ml307aState = MIP_CONNECT; printf("MIPCFG_fail\r\n"); } // osDelay(100); break; case MIPCLOSE: mipclose_count++; if (mipclose_count >= 10) { ml307aState = AT; // 强制跳转 AT 状态 printf("MIPCLOSE_max_retries,to AT,%d\r\n",mipclose_count); } if (mipclose_count >= 100) { mipclose_count = 0; // 重置次数 NVIC_SystemReset(); break; // 直接跳出,不再继续执行下面逻辑 } if (sendCmd_4G_3("AT+MIPCLOSE=0,0\r\n", "+MIPCLOSE: 0", "+MIPCLOSE: 0", 2, 1)) { ml307aState = MIP_CONNECT; printf("MIPCLOSE_OK\r\n"); } else { ml307aState = TIME; printf("MIPCLOSE_fail\r\n"); } // osDelay(300); break; case MDIALUP: // sendCmd_4G("AT+MDIALUP?\r\n", "OK", 1, 1); sendCmd_4G_3("AT+CSQ\r\n", "OK", "OK", 1, 1); ml307aState = MIPCLOSE; // osDelay(100); break; // 注册 7E0100002d202412040001000100000000000000000000000000000000000000000000000000000000002024000000010000d5e3413939393939757E case MIP_REGISTER: // printf("MIP_REGISTER\r\n"); osDelay(3000); if(0 == Send_Register()){ REGISTER_OK_start_flag = true; last_system_level = -1; ml307aState = Systemwarninglevel; // MIP_senddata }else{ ml307aState = MDIALUP; // MIPCLOSE REGISTER_OK_start_flag = false; // printf("MIPCLOSE\r\n"); } // osDelay(100); break; // 心跳 7E000200002024120400010001107E case Heartbeat: { gas_start_read_flag = false; if( Send_Heartbeat() ) { REGISTER_OK_start_flag = false; ml307aState = MIPCLOSE; } gas_start_read_flag = true; uint32_t delay_time = 0; while (delay_time < flash_data.heart_upload_frequency * 1000) { // 检查系统状态,如果不再是 LEVEL_0 立即退出 if (system_level != SYSTEM_LEVEL_0) { break;} osDelay(100); delay_time += 100; } break; } case Systemwarninglevel: if(Send_systemlevel()) { REGISTER_OK_start_flag = false; ml307aState = MIPCLOSE; } ml307aState = Remote; break; case Remote: { uint32_t start_tick = osKernelGetTickCount(); uint32_t last_remote_tick = start_tick; // 记录 Send_Remote 发送时间 uint32_t last_heartbeat_tick = start_tick; // 记录 Send_Heartbeat 发送时间 uint32_t last_sensorline_tick = start_tick; // 记录 sensorline 发送时间 while (1) { uint32_t current_tick = osKernelGetTickCount(); bool task_executed = false; // 标志是否执行了任务 if(system_level == SYSTEM_LEVEL_0) { send_remote_uploadfrequency = flash_data.mainboard_upload_frequency * 30 ; } if(system_level == SYSTEM_LEVEL_1 || system_level == SYSTEM_LEVEL_2) { send_remote_uploadfrequency = flash_data.mainboard_upload_frequency; } // 发送 Send_Remote(),仅当 controltransmit_flag == 0 且达到发送间隔 if (flash_data.controltransmit_flag == 0 && (current_tick - last_remote_tick) >= send_remote_uploadfrequency * 1000) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // 4G UART0_DTR低电平唤醒 Send_Remote(); last_remote_tick = current_tick; // 记录 Remote 发送时间 task_executed = true; // 记录任务已执行 } if ((current_tick - last_heartbeat_tick) >= flash_data.heart_upload_frequency * 1000) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // 4G UART0_DTR低电平唤醒 // 发送心跳 if (Send_Heartbeat()) { REGISTER_OK_start_flag = false; ml307aState = MIPCLOSE; break; // 退出 while(1),结束 Remote 状态 } last_heartbeat_tick = current_tick; task_executed = true; // 记录任务已执行 } // 发送传感器在线情况,仅当达到 sensoronline_upload_frequency if ((current_tick - last_sensorline_tick) >= flash_data.sensoronline_upload_frequency * 1000) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // 4G UART0_DTR低电平唤醒 if (Send_sensorline()) { REGISTER_OK_start_flag = false; ml307aState = MIPCLOSE; break; // 退出 while(1) } last_sensorline_tick = current_tick; // 记录 sensorline 发送时间 task_executed = true; // 记录任务已执行 } if(system_level != last_system_level) { printf("System_Level_Changed: %d\n", system_level); check_trigger_source(); last_system_level = system_level; ml307aState = Systemwarninglevel; break; } // **发送完后立即进入 SLEEP** if (task_executed) { sendCmd_4G_3("AT+MLPMCFG=\"sleepmode\",2,0\r\n", "OK", "OK", 1, 1); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // 4G UART0_DTR高电平休眠 Enter_SleepMode(); // 让 CPU 进入低功耗 } osDelay(10); } break; } case IDLE0: // if (sendCmd_4G("AT+MGNSSLOC=1\r\n", "OK", 1, 1)) { // AT+MNTP // AT+CCLK? //// sendCmd_4G("AT+CCLK?\r\n", "OK", 1, 1); // ml307aState = IDLE0; // } else { // printf("AT+MNTP_fail\r\n"); // } // if (sendCmd_4G("AT+MGNSS=1\r\n", "OK", 1, 1)) { // ml307aState = IDLE1; // } else { // printf("AT+MGNSSLOC=0_fail\r\n"); // ml307aState = IDLE1; // } osDelay(100); break; case IDLE: // Send_Remote(); if (sendCmd_4G("AT+MGNSSLOC?\r\n", "OK", 1, 1)) { ml307aState = IDLE0; } else { printf("AT+MGNSSLOC=0_fail\r\n"); ml307aState = IDLE0; } osDelay(300); break; case IDLE1: // Send_Remote(); if (sendCmd_4G("AT+MGNSSLOC\r\n", "OK", 1, 1)) { ml307aState = IDLE0; } else { printf("AT+MGNSSLOC_fail\r\n"); ml307aState = IDLE0; } osDelay(300); break; default: // HAL_IWDG_Refresh(&hiwdg); ml307aState = AT; break; } } else if(system_cloud_mode == Cloud_WIFI_MODE) { // static uint8_t rst_fail_count = 0; // 记录AT失败次数 switch(wifistate) { case WIFI_AT: { const char* cp_keywords[1]; int result; sendATOnly("AT\r\n"); cp_keywords[0] = "OK"; result = wait_uart3_multi_response(cp_keywords, 1, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); if(result == 0) printf("WIFI_AT_OK\r\n"); wifistate = WIFI_CWMODE; break; } case WIFI_RESTORE: { const char* cp_keywords[1]; int result; sendATOnly("AT+RESTORE\r\n"); cp_keywords[0] = "+INIT:DONE,0"; osDelay(500); result = wait_uart3_multi_response(cp_keywords, 1, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 2000); switch (result) { case 0: printf("WIFI_RESTORE_OK\r\n"); wifistate = WIFI_CWMODE; break; default: osDelay(1000); printf("WIFI_RESTORE_UNKNOWN\r\n"); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET); // 低电平睡眠 osDelay(1000); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET); // 高电平唤醒 wifistate = WIFI_RESTORE; break; } break; } case WIFI_CWMODE: { const char* cp_keywords[1]; int result; sendATOnly("AT+CWMODE=0\r\n"); cp_keywords[0] = "OK"; result = wait_uart3_multi_response(cp_keywords, 1, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); switch (result) { case 0: printf("WIFI_CWMODE_OK\r\n"); wifistate = WIFI_RST; // WIFI_RST WIFI_DPM break; default: printf("WIFI_CWMODE_UNKNOWN\r\n"); wifistate = WIFI_RESTORE; break; } break; } case WIFI_RST: { const char* cp_keywords[1]; int result; sendATOnly("AT+RST\r\n"); cp_keywords[0] = "+INIT:DONE,0"; result = wait_uart3_multi_response(cp_keywords, 1, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 2000); switch (result) { case 0: printf("WIFI_RST_OK\r\n"); wifistate = WIFI_TCPDATAMODE; break; default: printf("WIFI_RST_UNKNOWN\r\n"); wifistate = WIFI_RESTORE; break; } break; } case WIFI_TCPDATAMODE: { const char* cp_keywords[1]; int result; sendATOnly("AT+TCPDATAMODE=0\r\n"); // 0以文本形式发送。1以字符串形式发送 cp_keywords[0] = "OK"; result = wait_uart3_multi_response(cp_keywords, 1, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); switch (result) { case 0: printf("WIFI_TCPDATAMODE_OK\r\n"); wifistate = WIFI_CWSTAT; break; default: printf("WIFI_TCPDATAMODE_UNKNOWN\r\n"); wifistate = WIFI_RESTORE; break; } break; } case WIFI_CWSTAT: { const char* cp_keywords[5]; int result; sendATOnly("AT+CWSTAT\r\n"); cp_keywords[0] = "wpa_state=COMPLETED"; cp_keywords[1] = "wpa_state=DISCONNECTED"; cp_keywords[2] = "wpa_state=SCANNING"; cp_keywords[3] = "wpa_state=ASSOCIATED"; cp_keywords[4] = "wpa_state=4WAY_HANDSHAKE"; result = wait_uart3_multi_response(cp_keywords, 5, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 3000); switch (result) { case 0: printf("WIFI_CWSTAT_COMPLETED\r\n"); wifistate = WIFI_DPM; // WIFI_CIPSTART break; case 1: printf("WIFI_CWSTAT_DISCONNECTED\r\n"); wifistate = WIFI_CWJAP; break; case 2: printf("WIFI_CWSTAT_SCANNING\r\n"); wifistate = WIFI_CWJAP; break; case 3: printf("WIFI_CWSTAT_ASSOCIATED\r\n"); wifistate = WIFI_CIPSTART; break; case 4: printf("WIFI_CWSTAT_4WAY_HANDSHAKE\r\n"); wifistate = WIFI_CWQAP; break; default: printf("WIFI_CWSTAT_UNKNOWN\r\n"); wifistate = WIFI_RESTORE; break; } break; } case WIFI_DPM: { const char* cp_keywords[1]; int result = -1; int retry = 0; for (retry = 0; retry < 3; retry++) { sendATOnly("AT+DPM=1,0\r\n"); // 睡眠SLEEP3模式 cp_keywords[0] = "OK"; result = wait_uart3_multi_response(cp_keywords, 1, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); if (result == 0) { break; } } switch (result) { case 0: printf("WIFI_DPM_OK\r\n"); wifistate = WIFI_IDLE; break; default: printf("WIFI_DPM_UNKNOWN\r\n"); wifistate = WIFI_RESTORE; break; } break; } case WIFI_IDLE: { const char* cp_keywords[1]; int result; cp_keywords[0] = "+INIT:DONE,0"; result = wait_uart3_multi_response(cp_keywords, 1, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); switch (result) { case 0: printf("WIFI_RST_OK\r\n"); wifistate = WIFI_CIPSTART; break; default: printf("WIFI_RST_UNKNOWN\r\n"); wifistate = WIFI_IDLE; break; } break; } case WIFI_CWQAP: // 断开AP连接 { const char* cp_keywords[1]; int result; sendATOnly("AT+CWQAP\r\n"); cp_keywords[0] = "OK"; result = wait_uart3_multi_response(cp_keywords, 1, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); switch (result) { case 0: printf("WIFI_CWQAP_OK\r\n"); wifistate = WIFI_CWJAP; break; default: printf("WIFI_CWQAP_UNKNOWN\r\n"); wifistate = WIFI_RESTORE; break; } break; } case WIFI_CWJAP: { //printf("WiFi SSID (ASCII): %s\n", wifi_ssid); //printf("WiFi SSID (HEX): "); //for (int i = 0; i < strlen((char *)wifi_ssid); i++) { // printf("%02X ", wifi_ssid[i]); //} //printf("\n"); //printf("WiFi Password (ASCII): %s\n", wifi_password); //printf("WiFi Password (HEX): "); //for (int i = 0; i < strlen((char *)wifi_password); i++) { // printf("%02X ", wifi_password[i]); //} //printf("\n"); if(dwin_state != DWIN_STATE_AVIATION) { Load_WIFI_From_Flash(); } printf("WIFI.SSID: %s\n", wifi_config.ssid); printf("WIFI.Password: %s\n", wifi_config.password); const char* cp_keywords[5]; int result; sendWifiJoinCommand(wifi_config.ssid, wifi_config.password); cp_keywords[0] = "+CWJAP:1"; cp_keywords[1] = "ERROR:-14"; cp_keywords[2] = "+CWDAP:0,DEAUTH"; // 与已连接的AP断开连接 cp_keywords[3] = "+CWJAP:0,WRONGPWD"; // WPA 4次握手失败,预共享密钥(密码)可能不正确 cp_keywords[4] = "+CWJAP:0,TIMEOUT"; // 连续尝试连接后,连接尝试失败。 result = wait_uart3_multi_response(cp_keywords, 5, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 3000); switch (result) { case 0: printf("WIFI_CWJAP_OK\r\n"); wifistate = WIFI_DPM; // WIFI_CIPSTART WIFI_DPM break; case 1: printf("WIFI_CWJAP_ERROR:-14\r\n"); wifistate = WIFI_CWJAP; break; case 2: printf("WIFI_CWJAP_+CWDAP:0,DEAUTH\r\n"); wifistate = WIFI_CWJAP; break; case 3: printf("WIFI_CWJAP_+CWJAP:0,WRONGPWD\r\n"); wifistate = WIFI_RESTORE; break; case 4: printf("WIFI_CWJAP_+CWJAP:0,TIMEOUT\r\n"); wifistate = WIFI_RESTORE; break;; default: printf("WIFI_CWJAP_UNKNOWN\r\n"); wifistate = WIFI_CWJAP; break; } break; } case WIFI_CIPSTART: { // 47.109.73.167,10001 水陆平台 // 36.110.15.166,10002 航空平台公网 // 10.90.0.14,10002 航空平台内网 // 192.168.0.14,8080 测试平台1 // 192.168.0.41,8080 测试平台2 // 192.168.0.63,8080 公司测试平台3 control_wifi_wakeup(true); sendATOnly("AT+CLRDPMSLPEXT\r\n"); osDelay(100); const char* cp_keywords[3]; cp_keywords[0] = "+CIPSTART:"; cp_keywords[1] = "ERROR:-14"; cp_keywords[2] = "ERROR:-736"; int result = -1; int retry = 0; for (retry = 0; retry < 3; retry++) { sendATOnly("AT+CIPSTART=10.90.0.14,10002,0\r\n"); result = wait_uart3_multi_response(cp_keywords, 3, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 3000); if (result == 0) { break; } } if (result == 0) { int port_id = extract_cip_port((const char *)receiveBuff4G_MIPURC); printf("WIFI_CIPSTART_OK, ID = %d\r\n", port_id); g_cip_id = port_id; wifistate = WIFI_CIPSEND_Register; // WIFI_CIPSEND_Register WIFI_CIPSNTP break; } else { switch (result) { case 1: printf("WIFI_CIPSTART_ERROR:-14\r\n"); wifistate = WIFI_RESTORE; break; case 2: printf("WIFI_CIPSTART_ERROR:-736\r\n"); wifistate = WIFI_RESTORE; break; default: printf("WIFI_CIPSTART_UNKNOWN\r\n"); wifistate = WIFI_RESTORE; break; } break; } } case WIFI_CIPSNTP: // 航空局域网连不上公网 连不上SNTP { // ntp.aliyun.com // cn.pool.ntp.org // ntp.ntsc.ac.cn(中国国家授时中心) const char* cp_keywords[2]; int result; sendATOnly("AT+CIPSNTP=1,\"ntp.ntsc.ac.cn\",123\r\n"); cp_keywords[0] = "OK"; cp_keywords[1] = "+CWDAP:0,DEAUTH"; result = wait_uart3_multi_response(cp_keywords, 2, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 2000); switch (result) { case 0: printf("WIFI_CIPSNTP_OK\r\n"); wifistate = WIFI_TZONE; break; case 2: printf("WIFI_CIPSNTP_again\r\n"); wifistate = WIFI_CIPSNTP; break; default: printf("WIFI_CIPSNTP_UNKNOWN\r\n"); wifistate = WIFI_TCPDATAMODE; break; } break; } case WIFI_TZONE: { const char* cp_keywords[1]; int result; sendATOnly("AT+TZONE=0\r\n"); // 28800为+8时区 cp_keywords[0] = "OK"; result = wait_uart3_multi_response(cp_keywords, 1, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); switch (result) { case 0: printf("WIFI_TZONE_OK\r\n"); wifistate = WIFI_TIME; break; default: printf("WIFI_TZONE_UNKNOWN\r\n"); wifistate = WIFI_TCPDATAMODE; break; } break; } case WIFI_TIME: { const char* cp_keywords[1]; int result; int retry_count = 0; const int max_retry = 6; while (retry_count < max_retry) { sendATOnly("AT+TIME=?\r\n"); cp_keywords[0] = "+TIME:"; result = wait_uart3_multi_response(cp_keywords, 1, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); if (result == 0) { epoch_time = Parse_WIFI_Time_To_Epoch((char*)receiveBuff4G_MIPURC); if (epoch_time > 1735689600) { // 判定为有效时间(大于2025年) printf("WIFI_TIME_OK\r\n"); Set_RTC_Time(epoch_time); // 设置 RTC printCurrentRTCTime(); break; } else { printf("TIME invalid (epoch: %ld), retrying\r\n", epoch_time); } } else { printf("WIFI_TIME_UNKNOWN, retrying\r\n"); } retry_count++; vTaskDelay(pdMS_TO_TICKS(1000)); // 等待 1 秒再发 } if (retry_count >= max_retry) { // printf("TIME fetch failed, using RTC fallback.\r\n"); epoch_time = Get_RTC_Time(); printCurrentRTCTime(); } wifistate = WIFI_CIPSEND_Register; break; } case WIFI_CIPSEND_Register: { const char* cp_keywords[2]; cp_keywords[0] = "+TRDTC:"; cp_keywords[1] = "ERROR:-4"; // tcp 客户端 socket 与服务器断开了 int result; int retry_count = 0; bool success = false; while (retry_count < 5) { WIFI_Send_Register(1); osDelay (500); result = wait_uart3_multi_response(cp_keywords, 2, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); if (result == 0) // 收到 OK { printf("WIFI_Register_OK\r\n"); REGISTER_OK_start_flag = true; wifistate = WIFI_unixtime; success = true; break; } else { retry_count++; printf("WIFI_Register_Retry %d failed\r\n", retry_count); osDelay (300); } } if (!success) // 重试 5 次都失败 { if (result == 1) // ERROR:-4 { printf("WIFI_Register_ERROR:-4\r\n"); } else { printf("WIFI_Register_UNKNOWN\r\n"); } REGISTER_OK_start_flag = false; wifistate = WIFI_RESTORE; } break; } case WIFI_unixtime: { const char* cp_keywords[2]; cp_keywords[0] = "+TRDTC:"; cp_keywords[1] = "ERROR:-4"; int result; int retry_count = 0; bool success = false; while (retry_count < 5) { WIFI_Send_unix(1); osDelay (500); result = wait_uart3_multi_response(cp_keywords, 2, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); if (unixtime_reply_received) { printf("WIFI_unixtime_OK\r\n"); printCurrentRTCTime(); REGISTER_OK_start_flag = true; unixtime_reply_received = false; wifistate = WIFI_Remote; success = true; break; } else { retry_count++; printf("WIFI_unixtime_Retry %d failed\r\n", retry_count); osDelay (300); } } if (!success) // 重试 5 次都失败 { if (result == 1) // ERROR:-4 { printf("WIFI_unixtime_ERROR:-4\r\n"); } else { printf("WIFI_unixtime_UNKNOWN\r\n"); } REGISTER_OK_start_flag = false; wifistate = WIFI_RESTORE; } break; } case WIFI_Remote: { uint64_t wifi_start_tick = osKernelGetTickCount(); uint32_t wifi_last_temp_tick = wifi_start_tick; // 记录 WIFI_Send_Temperature_Data 发送时间 uint32_t wifi_last_pre_tick = wifi_start_tick; // 记录 WIFI_Send_Pressure_CO_H2_Data 发送时间 uint32_t wifi_last_heartbeat_tick = wifi_start_tick; // 记录 Send_Heartbeat 发送时间 uint64_t wifi_last_sensorline_tick = wifi_start_tick; // 记录 sensorline 发送时间 static int wifi_sensorline_success_count = 0; int result; const char* cp_keywords[4]; cp_keywords[0] = "OK"; cp_keywords[1] = "ERROR:-4"; cp_keywords[2] = "ERROR:-1"; cp_keywords[3] = "+TRXTC:"; const char* heartcp_keywords[1]; heartcp_keywords[0] = "+TRXTC:"; while (1) { uint32_t current_tick = osKernelGetTickCount(); bool task_executed = false; // 标志是否执行了任务 if(system_level == SYSTEM_LEVEL_0) { send_remote_uploadfrequency = flash_data.mainboard_upload_frequency * 30 ; } if(system_level == SYSTEM_LEVEL_1 || system_level == SYSTEM_LEVEL_2) { send_remote_uploadfrequency = flash_data.mainboard_upload_frequency; } // 发送 温度 压力气体数据,仅当 controltransmit_flag == 0 且达到发送间隔 if (flash_data.controltransmit_flag == 0 && (current_tick - wifi_last_temp_tick) >= send_remote_uploadfrequency * 1000) { control_wifi_wakeup(true); // 发送 AT+CLRDPMSLPEXT,并等待 OK 响应 bool clr_ok = false; for (int i = 0; i < 3; i++) // 最多重试 3 次 { sendATOnly("AT+CLRDPMSLPEXT\r\n"); if (wait_uart3_multi_response(cp_keywords,4, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000)==0) { clr_ok = true; control_wifi_wakeup(false); break; } osDelay(100); } if (!clr_ok) { printf("AT+CLRDPMSLPEXT failed after retries, skip sending\r\n"); return; } int retry_count = 0; while (retry_count < WIFI_MAX_RETRY) { epoch_time = Get_RTC_Time(); // 获取 RTC 时间 WIFI_Send_Temperature_Data(1,&sensor_data_buffer); result = wait_uart3_multi_response(cp_keywords, 4, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); if (result == 0) { printf("WIFI_Send_Temperature_Data_OK\r\n"); REGISTER_OK_start_flag = true; wifi_last_temp_tick = current_tick; // 记录 Remote 发送时间 task_executed = true; // 记录任务已执行 break; }else{ retry_count++; switch (result) { case 1: printf("WIFI_Send_Temperature_Data_ERROR:-4\r\n"); REGISTER_OK_start_flag = false; break; case 2: printf("WIFI_Send_Temperature_Data_ERROR:-1\r\n"); REGISTER_OK_start_flag = false; break; default: printf("WIFI_Send_Temperature_Data_UNKNOWN\r\n"); REGISTER_OK_start_flag = false; break; } } osDelay(100); } if (retry_count >= WIFI_MAX_RETRY) { printf("WIFI_Send_Temperature_Data FAILED after 3 retries. Goto WIFI_RESTORE\r\n"); wifistate = WIFI_RESTORE; break; } } if (flash_data.controltransmit_flag == 0 && (current_tick - wifi_last_pre_tick) >= send_remote_uploadfrequency * 1000) { control_wifi_wakeup(true); // 发送 AT+CLRDPMSLPEXT,并等待 OK 响应 bool clr_ok = false; for (int i = 0; i < 3; i++) // 最多重试 3 次 { sendATOnly("AT+CLRDPMSLPEXT\r\n"); if (wait_uart3_multi_response(cp_keywords,4, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000)==0) { clr_ok = true; control_wifi_wakeup(false); break; } osDelay(100); } if (!clr_ok) { printf("AT+CLRDPMSLPEXT failed after retries, skip sending\r\n"); return; } int retry_count = 0; while (retry_count < WIFI_MAX_RETRY) { epoch_time = Get_RTC_Time(); // 获取 RTC 时间 WIFI_Send_Pressure_CO_H2_Data(1,&sensor_data_buffer); result = wait_uart3_multi_response(cp_keywords, 4, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); if (result == 0) { printf("WIFI_Send_Pressure_CO_H2_Data_OK\r\n"); REGISTER_OK_start_flag = true; osDelay (20); // flash_write_tempprecoh2_data(flash_temp_prc0h2, 512); // Save_W25_Tempaddress_To_Flash(); wifi_last_pre_tick = current_tick; // 记录 Remote 发送时间 task_executed = true; // 记录任务已执行 break; }else{ retry_count++; switch (result) { case 1: printf("WIFI_Send_Pressure_CO_H2_Data_ERROR:-4\r\n"); REGISTER_OK_start_flag = false; break; case 2: printf("WIFI_Send_Pressure_CO_H2_Data_ERROR:-1\r\n"); REGISTER_OK_start_flag = false; break; default: printf("WIFI_Send_Pressure_CO_H2_Data_UNKNOWN\r\n"); REGISTER_OK_start_flag = false; break; } } osDelay(100); } if (retry_count >= WIFI_MAX_RETRY) { printf("WIFI_Send_Pressure_CO_H2_Data FAILED after 3 retries. Goto WIFI_RESTORE\r\n"); wifistate = WIFI_RESTORE; break; } } // 心跳 if ((current_tick - wifi_last_heartbeat_tick) >= flash_data.heart_upload_frequency * 1000) { control_wifi_wakeup(true); // 发送 AT+CLRDPMSLPEXT,并等待 OK 响应 bool clr_ok = false; for (int i = 0; i < 3; i++) // 最多重试 3 次 { sendATOnly("AT+CLRDPMSLPEXT\r\n"); osDelay(300); if (wait_uart3_multi_response(cp_keywords,4, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000)==0) { clr_ok = true; control_wifi_wakeup(false); break; } osDelay(300); } if (!clr_ok) { printf("AT+CLRDPMSLPEXT failed after retries, skip sending\r\n"); return; } int retry_count = 0; while (retry_count < WIFI_MAX_RETRY) { WIFI_Send_Heartbeat(1); osDelay (300); result = wait_uart3_multi_response(heartcp_keywords, 1, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); osDelay (500); if (heartbeat_reply_received) { printf("WIFI_Send_Heartbeat_OK\r\n"); REGISTER_OK_start_flag = true; wifi_last_heartbeat_tick = current_tick; heartbeat_reply_received = false; // 清除通用应答已接收标志位 task_executed = true; // 记录任务已执行 break; }else{ retry_count++; printf("WIFI_Send_Heartbeat_Not received\r\n"); } osDelay(300); } if (retry_count >= WIFI_MAX_RETRY) { printf("WIFI_Send_Heartbeat FAILED after 3 retries. Goto WIFI_RESTORE\r\n"); wifistate = WIFI_RESTORE; break; } } // 发送传感器在线情况,仅当达到 sensoronline_upload_frequency if ((current_tick - wifi_last_sensorline_tick) >= flash_data.sensoronline_upload_frequency * 1000) { control_wifi_wakeup(true); // 发送 AT+CLRDPMSLPEXT,并等待 OK 响应 bool clr_ok = false; for (int i = 0; i < 3; i++) // 最多重试 3 次 { sendATOnly("AT+CLRDPMSLPEXT\r\n"); if (wait_uart3_multi_response(cp_keywords,4, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000)==0) { clr_ok = true; control_wifi_wakeup(false); break; } osDelay(100); } if (!clr_ok) { printf("AT+CLRDPMSLPEXT failed after retries, skip sending\r\n"); return; } int retry_count = 0; while (retry_count < WIFI_MAX_RETRY) { epoch_time = Get_RTC_Time(); // 获取 RTC 时间 WIFI_Send_sensorline(1); result = wait_uart3_multi_response(cp_keywords, 4, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); if (result == 0) { printf("WIFI_Send_sensorline_OK\r\n"); REGISTER_OK_start_flag = true; wifi_last_sensorline_tick = current_tick; // 记录 sensorline 发送时间 task_executed = true; // 记录任务已执行 wifi_sensorline_success_count++; break; }else{ retry_count++; switch (result) { case 1: printf("WIFI_Send_sensorline_ERROR:-4\r\n"); REGISTER_OK_start_flag = false; break; case 2: printf("WIFI_Send_sensorline_ERROR:-1\r\n"); REGISTER_OK_start_flag = false; break; default: printf("WIFI_Send_sensorline_UNKNOWN\r\n"); REGISTER_OK_start_flag = false; break; } } osDelay(100); } if (retry_count >= WIFI_MAX_RETRY) { printf("WIFI_Send_sensorline FAILED after 3 retries. Goto WIFI_RESTORE\r\n"); wifistate = WIFI_RESTORE; break; } } if(system_level != last_system_level) { control_wifi_wakeup(true); // 发送 AT+CLRDPMSLPEXT,并等待 OK 响应 bool clr_ok = false; for (int i = 0; i < 3; i++) // 最多重试 3 次 { sendATOnly("AT+CLRDPMSLPEXT\r\n"); if (wait_uart3_multi_response(cp_keywords,4, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000)==0) { clr_ok = true; control_wifi_wakeup(false); break; } osDelay(100); } if (!clr_ok) { printf("AT+CLRDPMSLPEXT failed after retries, skip sending\r\n"); return; } int retry_count = 0; while (retry_count < WIFI_MAX_RETRY) { printf("System_Level_Changed: %d\n", system_level); check_trigger_source(); // 检查触发二级的传感器信息 epoch_time = Get_RTC_Time(); // 获取 RTC 时间 WIFI_Send_systemlevel(1); result = wait_uart3_multi_response(cp_keywords, 4, (char*)receiveBuff4G_MIPURC, sizeof(receiveBuff4G_MIPURC), 1000); if(result == 0) { printf("WIFI_Send_systemlevel_OK\r\n"); REGISTER_OK_start_flag = true; task_executed = true; // 记录任务已执行 last_system_level = system_level; break; }else{ retry_count++; switch (result) { case 1: printf("WIFI_Send_systemlevel_ERROR:-4\r\n"); REGISTER_OK_start_flag = false; break; case 2: printf("WIFI_Send_systemlevel_ERROR:-1\r\n"); REGISTER_OK_start_flag = false; break; default: printf("WIFI_Send_systemlevel_UNKNOWN\r\n"); REGISTER_OK_start_flag = false; break; } } osDelay(100); } if (retry_count >= WIFI_MAX_RETRY) { printf("WIFI_Send_systemlevel FAILED after 3 retries. Goto WIFI_RESTORE\r\n"); wifistate = WIFI_RESTORE; break; } } if (wifi_sensorline_success_count >= 100) { wifistate = WIFI_unixtime; wifi_sensorline_success_count = 0; // 重置计数 printf("Reached 100 minutes, switching to WIFI_unixtime\r\n"); } // **发送完后立即进入 SLEEP** if (task_executed) { if(system_level == SYSTEM_LEVEL_0) { sendATOnly("AT+SETDPMSLPEXT\r\n"); } Enter_SleepMode(); // 让 CPU 进入低功耗 } osDelay(10); } break; } default: wifistate = WIFI_AT; break; } } } /* USER CODE END cloud_Task */ } /* USER CODE BEGIN Header_SystemStatus_Task */ /** * @brief Function implementing the SystemStatus thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_SystemStatus_Task */ void SystemStatus_Task(void *argument) { /* USER CODE BEGIN SystemStatus_Task */ /* Infinite loop */ uint16_t gass_counter = 0; // 气体开启计数器 for(;;) { // if(system_level != last_system_level) // { // printf("System_Level_Changed: %d\n", system_level); // check_trigger_source(); // last_system_level = system_level; // if(REGISTER_OK_start_flag) // ml307aState = Systemwarninglevel; // } if (system_level == SYSTEM_LEVEL_1) { gass_counter++; // dwin_warning_state_level = DWIN_WARNING_LEVEL_1_STATE; actuator_powered = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_11) == GPIO_PIN_SET; if ( actuator_powered ) { control_actuator(false); // 关闭电推杆供电 // HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); // HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_SET); actuator_powered_state = actuator_closed; printf("actuator_power_closed\n"); } gas_powered = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4) == GPIO_PIN_RESET; if ( gas_powered ) { control_gas_sensors(true); // 打开气体供电 printf("gas_power_opened\n"); if(gass_counter >= 400) // 气体上电后等待40秒再开始读数 { gas_start_read_flag = true; printf("gas_start_read\n"); gass_counter = 0; } } else{ if(gass_counter >= 400) // 气体上电后等待40秒再开始读数 { gas_start_read_flag = true; // printf("gas_start_read\n"); gass_counter = 0; } } } osDelay(100); } /* USER CODE END SystemStatus_Task */ } /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ void sendWifiJoinCommand(uint8_t *ssid, uint8_t *password) { char at_command[128]; sprintf(at_command, "AT+CWJAP=%s,4,2,%s\r\n", ssid, password); sendATOnly(at_command); } void Send_Remote(void) { sendCmd_4G_3("AT+CCLK?\r\n", "OK", "OK", 1, 1); epoch_time = parse_cclk_time((char *)receiveBuff4G); if (epoch_time != 2) { // printf("unix: %ld\n", epoch_time); Set_RTC_Time(epoch_time); // 设置 RTC } else { epoch_time = Get_RTC_Time(); // 获取 RTC 时间 // printf("RTC unix: %ld\n", epoch_time); } gas_start_read_flag = false; if(Send_Temperature_Data(&sensor_data_buffer)) { REGISTER_OK_start_flag = false; ml307aState = MIPCLOSE; } //printf("remote\r\n"); if(Send_Pressure_CO_H2_Data(&sensor_data_buffer)) { REGISTER_OK_start_flag = false; ml307aState = MIPCLOSE; } // gas_start_read_flag = true; flash_write_tempprecoh2_data(flash_temp_prc0h2, 512); Save_W25_Tempaddress_To_Flash(); // Load_W25_Tempaddress_From_Flash(); // printf("\r\n"); // for (uint32_t i = 0; i < 512; i++) // { // printf("%02X ", flash_temp_prc0h2[i]); // if ((i + 1) % 16 == 0) // printf("\r\n"); // } } void InitializeBoardDataProcess(void) { uint8_t i=0; for (i = 0; i < MAX_TEMP_NODE_NUM; i++) { g_canTempRaw[i].NodeId = 0; g_canTempRaw[i].PacktSeq = 0; g_canTempRaw[i].SliceNum = 0; g_canTempRaw[i].SliceMask = 0; g_prevdata_temp[i].count_ms = 0; g_prevdata_temp[i].recv_flag = 0; g_prevdata_temp[i].data[0] = 0; g_prevdata_temp[i].data[1] = 0; g_prevdata_temp[i].data[2] = 0; } for(i=0; iInstance == USART2) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; memcpy(uart2_msg.data, dataReceive2, MAX_FRAME_SIZE); if (xQueueSendToBackFromISR(uart2rxqueueHandle, &uart2_msg, &xHigherPriorityTaskWoken) != pdPASS) { uint8_t discard_buffer[MAX_FRAME_SIZE]; xQueueReceiveFromISR(uart2rxqueueHandle, &discard_buffer, &xHigherPriorityTaskWoken); xQueueSendToBackFromISR(uart2rxqueueHandle, &uart2_msg, &xHigherPriorityTaskWoken); } } } void Uart2_ProcessNextMessage(void) { uint8_t rxBuffer[40]; memset(rxBuffer, 0, 40); if (xQueueReceive(uart2rxqueueHandle, rxBuffer, (TickType_t)0) == pdPASS) // portMAX_DELAY (TickType_t)0 { printf("rxBuffer: "); for (int i = 0; i < rx_len; i++) { printf("%02X ", rxBuffer[i]); } printf("\n"); if (is_gas_sensor_response(rxBuffer)) { process_gas_sensor(rxBuffer); return; } if (is_mode_response(rxBuffer)) { process_mode(rxBuffer); return; } if (is_electric_actuator_response(rxBuffer)) { process_electric_actuator(rxBuffer); return; } if (is_threshold_response(rxBuffer)) { process_threshold(rxBuffer); return; } if (is_terminal_response(rxBuffer)) { process_terminal_data(rxBuffer); return; } if (is_wifi_response(rxBuffer)) { process_wifi(rxBuffer); return; } if (is_restart_response(rxBuffer)) { NVIC_SystemReset(); return; } } } bool is_electric_actuator_response(uint8_t *data) // 判断是否是电推杆的回应 { uint8_t header[] = {0x5A, 0xA5, 0x06, 0x83, 0x10, 0x03, 0x01}; return memcmp(data, header, sizeof(header)) == 0; } void process_electric_actuator(uint8_t *data) // 处理电推杆正反转 { uint16_t actuator_cmd = (data[7] << 8) | data[8]; if (actuator_cmd == 2) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_SET); } else if (actuator_cmd == 1) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_RESET); } } bool is_mode_response(uint8_t *data) // 判断是否是运行模式的更改 { uint8_t header[] = {0x5A, 0xA5, 0x06, 0x83, 0x15, 0x00, 0x01}; return memcmp(data, header, sizeof(header)) == 0; } void process_mode(uint8_t *data) // 是否是模式的更改 { uint16_t mode_cmd = (data[7] << 8) | data[8]; if (mode_cmd == 1) { // 实验模式 system_operatingmode = Debug_MODE; dwin_state = DWIN_STATE_DEBUG_SWITCH; } else if (mode_cmd == 2) { // 发布模式 system_operatingmode = WARNING_MODE; dwin_state = DWIN_STATE_WARNING_SWITCH; }else if (mode_cmd == 3) { // 设置模式 system_operatingmode = SET_MODE; dwin_state = DWIN_STATE_SET_SWITCH; }else if (mode_cmd == 4) { // 航空 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET); // PC7高电平唤醒WIFI HAL_GPIO_WritePin(GPIOC, V3_8V_4G_enable_Pin, GPIO_PIN_SET); // 4G电源3.8V高电平断电 system_cloud_mode = Cloud_WIFI_MODE; dwin_state = DWIN_STATE_AVIATION; // printf("UART2_Rxcallback_Cloud_WIFI_MODE\n"); }else if (mode_cmd == 5) { // 水陆 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET); // PC7低电平睡眠WIFI HAL_GPIO_WritePin(GPIOC, V3_8V_4G_enable_Pin, GPIO_PIN_RESET); // 4G电源3.8V低电平开启 dwin_state = DWIN_STATE_4G; system_cloud_mode = Cloud_4G_MODE; flash_clear_all_data(); // printf("UART2_Rxcallback_Cloud_4G_MODE\n"); wifior4G_flag = 0; Save_wifior4G_flag_To_Flash(); }else if (mode_cmd == 6) { // 开发者 }else if (mode_cmd == 7) { // 航空wifi名称密码确定 flash_clear_all_data(); Save_WIFI_To_Flash(); // 点击确定后再将wifi账密写入flash wifior4G_flag = 1; Save_wifior4G_flag_To_Flash(); dwin_state = DWIN_STATE_AVIATION_READ; wifistate = WIFI_RESTORE; // 重新启动 cloud_Task if (cloudHandle != NULL) { vTaskDelete(cloudHandle); // 删除原任务 vTaskDelay(pdMS_TO_TICKS(10)); // 等待任务真正被清理 } cloudHandle = osThreadNew(cloud_Task, NULL, &cloud_attributes); } } bool is_threshold_response(uint8_t *data) // 判断是否为阈值数据响应 { uint8_t header[] = {0x5A, 0xA5, 0x06, 0x83, 0x55}; return memcmp(data, header, sizeof(header)) == 0; } void process_threshold(uint8_t *data) // 处理阈值数据 { // Dwinthreshold_msg param_msg; uint16_t address = (data[4] << 8) | data[5]; uint16_t dwindata = (data[7] << 8) | data[8]; // printf("ADDR: 0x%04X, DATA: 0x%04X\n", address, dwindata); switch (address) { case 0x5500: // SENSOR_TEMP_FIRST_THRESHOLD 0x6000 flash_data.temp_first_threshold = dwindata; printf("temp_first_threshold %d \n",dwindata); CAN_Send_Parameter(0x00110000, &flash_data, 8); break; case 0x5501: // SENSOR_TEMP_SECOND_THRESHOLD 0x6010 flash_data.temp_second_threshold = dwindata; printf("temp_second_threshold %d \n",dwindata); CAN_Send_Parameter(0x00110000, &flash_data, 8); break; case 0x5502: // MAINBOARD_UPLOAD_FREQUENCY 0x6020 flash_data.mainboard_upload_frequency = dwindata; printf("mainboard_upload_frequency %d \n",dwindata); CAN_Send_Parameter(0x00110000, &flash_data, 8); break; case 0x5503: // SMALLBOARD_UPLOAD_FREQUENCY 0x6030 flash_data.smallboard_upload_frequency = dwindata; printf("smallboard_upload_frequency %d \n",dwindata); CAN_Send_Parameter(0x00110000, &flash_data, 8); break; case 0x5504: // OBJECT_EMISSIVITY 0x6040 flash_data.object_emissivity = dwindata; printf("object_emissivity %d \n",dwindata); CAN_Send_Parameter(0x00110000, &flash_data, 8); break; case 0x5505: // SENSOR_PRESSURE 0x6050 flash_data.pressure_threshold = dwindata; printf("pressure_threshold %d \n",dwindata); CAN_Send_Parameter(0x00110000, &flash_data, 8); break; case 0x5506: // SENSOR_CO 0x6060 flash_data.co_threshold = dwindata; printf("co_threshold %d \n",dwindata); CAN_Send_Parameter(0x00110000, &flash_data, 8); break; case 0x5507: // SENSOR_H2 0x6070 flash_data.h2_threshold = dwindata; printf("h2_threshold %d \n",dwindata); CAN_Send_Parameter(0x00110000, &flash_data, 8); break; case 0x5510: // WIFI账号 0x60A0 printf("h2_threshold %d \n",dwindata); break; case 0x5530: // WIFI密码 0x60C0 printf("h2_threshold %d \n",dwindata); break; default: printf("Unknown address: 0x%04X\n", address); return; } } bool is_wifi_response(uint8_t *data) // 判断是否为WIFI账号密码修改 { // 忽略data[2]字节数,帧结构中 5A A5 ?? 83 56 return (data[0] == 0x5A && data[1] == 0xA5 && data[3] == 0x83 && data[4] == 0x56); } void process_wifi(uint8_t *data) // 处理WIFI账号密码修改 { uint16_t address = (data[4] << 8) | data[5]; uint8_t *payload = &data[7]; uint8_t len = 0; // 计算 payload 实际有效长度,遇到 0xFF 0xFF 立即停止 for (int i = 0; i < 40 ; i++) { if (payload[i] == 0xFF) { len = i; printf("uart2_len1: %d\n", len); break; } } // 如果没有遇到 0xFFFF,使用报文中提供的长度,但最多不超过20 if (len == 0) { len = data[2] - 6; if (len > 40) len = 40; printf("uart2_len2: %d\n", len); } // printf("uart2_SSID: %s\n", wifi_config.ssid); // printf("uart2_SSID: %s\n", wifi_config.ssid); switch (address) { case 0x5610: // WIFI账号 0x60A0 memset(wifi_config.ssid, 0, 20); memcpy(wifi_config.ssid, payload, len); printf("uart2_SSID: %s\n", wifi_config.ssid); break; case 0x5630: // WIFI密码 0x60C0 memset(wifi_config.password, 0, 20); memcpy(wifi_config.password, payload, len); printf("uart2_Password: %s\n", wifi_config.password); break; default: printf("Unknown address: 0x%04X\n", address); return; } } bool is_terminal_response(uint8_t *data) // 判断是否为终端数据响应 { uint8_t header[] = {0x5A, 0xA5, 0x0C, 0x83, 0x55}; return memcmp(data, header, sizeof(header)) == 0; } void process_terminal_data(uint8_t *data) // 处理终端数据 { Dwinterminal_msg terminal_msg; terminal_msg.Sensoraddress = data[5]; memcpy(terminal_msg.data, &data[7], sizeof(terminal_msg.data)); if(terminal_msg.Sensoraddress == 0x08) { unsigned long long decimal_value = 0; // 用于存储转换后的十进制数 // 1. 提取6个字节并转换为十进制 for (int i = 0; i < 6; i++) { decimal_value = (decimal_value << 8) | terminal_msg.data[2 + i]; } // 2. 将 decimal_value 转换成字符串 "20240000000300" char decimal_str[15]; // 14 位数字 + 1 个结束符 sprintf(decimal_str, "%llu", decimal_value); // 3. 按两两一组提取并存储到 terminalId 中(高字节在前) for (int i = 0; i < 7; i++) { terminalId[i] = (decimal_str[i * 2] - '0') * 16 + (decimal_str[i * 2 + 1] - '0'); } DWIN_terminal_SHOW_flag = true; } if (terminal_msg.Sensoraddress == 0x09) { unsigned long long decimal_value = 0; // 用于存储转换后的十进制数 // 1. 提取5个字节并转换为十进制 for (int i = 0; i < 5; i++) { decimal_value = (decimal_value << 8) | terminal_msg.data[3 + i]; } // 2. 将 decimal_value 转换成字符串 "202412040002" char decimal_str[13]; // 12 位数字 + 1 个结束符 sprintf(decimal_str, "%llu", decimal_value); // 3. 按两两一组提取并存储到 g_board_id 中(高字节在前) for (int i = 0; i < 6; i++) { g_board_id[i] = (decimal_str[i * 2] - '0') * 16 + (decimal_str[i * 2 + 1] - '0'); } DWIN_terminal_SHOW_flag = true; } } bool is_gas_sensor_response(uint8_t *data) // 判断是否为气体传感器响应 { // 检查前三个字节是否符合要求 if (!((data[0] == 0x10 || data[0] == 0x11 || data[0] == 0x12 || data[0] == 0x01 || data[0] == 0x02 || data[0] == 0x03) && data[1] == 0x03 && data[2] == 0x04)) { return false; // 帧头不匹配,直接返回 false } uint16_t crc_received = (data[8] << 8) | data[7]; uint16_t crc_calculated = calculate_crc16(data, 7); return memcmp(&crc_received, &crc_calculated, sizeof(crc_calculated)) == 0; } void process_gas_sensor(uint8_t *data) // 处理气体传感器数据 { uint8_t id = data[0]; if (id < 0x0F) { // 处理 CO 传感器 process_single_gas_sensor(SENSOR_CO, id - 1, data, co_level_buffer, MAX_CO_NODE_NUM, flash_data.co_threshold, &co_system_level, sensor_data_buffer.co_data, sensor_data_buffer.co_valid); } else { // 处理 H2 传感器 process_single_gas_sensor(SENSOR_H2, id - 16, data, h2_level_buffer, MAX_H2_NODE_NUM, flash_data.h2_threshold, &h2_system_level, sensor_data_buffer.h2_data, sensor_data_buffer.h2_valid); } // printf("CO System Level: %d\n", co_system_level); // printf("H2 System Level: %d\n", h2_system_level); } static void process_single_gas_sensor(uint8_t sensor_type, uint8_t id, uint8_t *data, float *level_buffer, uint8_t max_nodes, float threshold, volatile uint8_t *system_level, uint8_t (*sensor_data_buffer)[4], uint8_t *sensor_valid) { if (id >= max_nodes) return; // 解析浮点数数据 float value = parse_modbus_float(&data[3]); level_buffer[id] = value; // 标记该传感器为有效,并重置其超时计数 sensor_valid[id] = 1; // printf("Sensor %d value: %.1f\n", id + 1, value); // 存储数据 memcpy(sensor_data_buffer[id], &data[3], 4); // 更新接收到的时间 uint32_t current_ms = HAL_GetTick(); if (sensor_type == SENSOR_CO) { g_prevdata_co[id].count_ms = current_ms; // 更新 CO 传感器的接收时间 g_prevdata_co[id].recv_flag = 1; g_prevdata_co[id].offline_flag = 0; // printf("usrt2 co %d current_ms %d\n", id, current_ms); } else if (sensor_type == SENSOR_H2) { g_prevdata_h2[id].count_ms = current_ms; // 更新 H2 传感器的接收时间 g_prevdata_h2[id].recv_flag = 1; g_prevdata_h2[id].offline_flag = 0; // printf("usrt2 h2 %d current_ms %d\n", id, current_ms); } // 计算最大值,默认掉线传感器值为 0 float max_value = 0.0f; uint8_t valid_count = 0; for (int i = 0; i < max_nodes; i++) { if (sensor_valid[i]) { // 传感器有数据 if (level_buffer[i] > max_value) { max_value = level_buffer[i]; } valid_count++; } } // 计算预警等级 if (valid_count > 0) { // 只要有至少一个传感器在线 *system_level = (max_value > threshold) ? 2 : 0; } else { // **所有传感器掉线,默认给 `system_level` 一个特殊值** *system_level = 0; printf("Warning: All %s sensors are offline!\n", sensor_type == SENSOR_CO ? "CO" : "H2"); } // **记录第一个触发二级报警的传感器** if (*system_level == 2 && trigger_info[0] == 0) { trigger_info[0] = (sensor_type == SENSOR_CO) ? 0xF008 : 0xF006; // 传感器类型 trigger_info[1] = id + 1; // 传感器编号 trigger_info[2] = (uint8_t)value; // 触发时的值(转换为整数存储) } } bool is_restart_response(uint8_t *data) { uint8_t header[] = {0x5A, 0xA5, 0x06, 0x83, 0x16, 0x00, 0x01}; return memcmp(data, header, sizeof(header)) == 0; } void CAN_Send_Parameter(uint32_t node_id , FlashData *flash_data , uint8_t len) { CAN_TxHeaderTypeDef Tx_Header; uint32_t TxMailBox; uint32_t ret_status = 0; uint8_t msg[8] = {0}; msg[0] = flash_data->temp_first_threshold & 0xFF; msg[1] = flash_data->temp_second_threshold & 0xFF; msg[2] = flash_data->smallboard_upload_frequency & 0xFF; // 温度上传频率 msg[3] = 0x5F; // 发射率 msg[4] = 0x00; // 压力阈值高字节 msg[5] = flash_data->pressure_threshold & 0xFF; // 压力阈值低字节 msg[6] = 0x01; // 压力上传频率 msg[7] = 0x00; Tx_Header.ExtId = node_id; Tx_Header.IDE = CAN_ID_EXT; Tx_Header.RTR = CAN_RTR_DATA; Tx_Header.DLC = len; ret_status = HAL_CAN_AddTxMessage(&hcan1,&Tx_Header,msg,&TxMailBox); if(0 != ret_status){ printf("HAL_CAN_AddTxMessage failed , ret_status:0x%x \r\n", ret_status); printf("hcan->ErrorCode: 0x%x \r\n", hcan1.ErrorCode); } } void ProcessQueues(void) { CanRx_msg can_msg; while (1) { if (can_message_queueHandle != NULL && xQueueReceive(can_message_queueHandle, &can_msg, (TickType_t)0 ) == pdPASS) // (TickType_t)0 { // printf("MidProcess_can\n"); // 处理 CAN队列 数据 MidProcessData(&can_msg); } osDelay(1); } } void MidProcessData(CanRx_msg *can_msg) // 处理接收到的CAN 数据 { if (can_msg == NULL) return; Dwin_msg dw_msg; Remote_msg rt_msg; uint8_t data_type = (can_msg->ExtId >> 28) & 0xFF; uint8_t nodeId = (can_msg->ExtId >> 20) & 0xFF; uint8_t packtSeq = (can_msg->ExtId >> 12) & 0xFF; uint8_t sliceNum = (can_msg->ExtId >> 8) & 0x0F; uint8_t sliceId = (can_msg->ExtId >> 4) & 0x0F; //printf("Raw ExtId: 0x%x, data_type: 0x%x, nodeId: 0x%x, packtSeq: 0x%x, sliceNum: 0x%x, sliceId: 0x%x\r\n", // can_msg->ExtId, data_type, nodeId, packtSeq, sliceNum, sliceId); //for (int i = 0; i < SLICE_DATA_SIZE; i++) //{ // printf("can_msg.data[%d]: 0x%x\r\n", i, can_msg->data[i]); //} if(data_type == 0) return; if(nodeId >= 16)//温度数据 { uint8_t sensor_id = nodeId-16; dw_msg.SensorType = SENSOR_TEMPERATURE; dw_msg.SensorId = sensor_id; if (sensor_id >= MAX_TEMP_NODE_NUM) return; if (sliceId == 0x1) // 处理 sliceId 为 0x1 的数据 { // 判断 temp_system_level uint8_t templevel = can_msg->data[0]; // 获取当前板的等级 if( templevel > 3 ) {templevel = 0;} temp_level_buffer[sensor_id] = (templevel <= 2) ? templevel : 0; uint8_t tempmax_level = 0; // 先设为 0 for (uint8_t i = 0; i < MAX_TEMP_NODE_NUM; i++) { if (temp_level_buffer[i] > tempmax_level) { tempmax_level = temp_level_buffer[i]; } } // 判断 tempmax_level 是否稳定 // if (tempmax_level == last_tempmax_level) // { // 如果 tempmax_level 不变且时间超过 1.5秒 // if ((HAL_GetTick() - last_change_time) >= STABLE_TIME_MS) // { // // 如果 tempmax_level 不变且时间超过去抖时间100ms // if ((HAL_GetTick() - last_temp_level_change_time) >= TEMP_DEBOUNCE_TIME_MS) // { // 根据最大等级来设置 temp_system_level temp_system_level = (tempmax_level == 0) ? TEMP_LEVEL_0 : (tempmax_level == 1) ? TEMP_LEVEL_1 : TEMP_LEVEL_2; // printf("Updated temp_system_level to [%d]\n", temp_system_level); // } // } // } // else // { // // 如果 tempmax_level 发生变化,重置计时 // last_change_time = HAL_GetTick(); // 更新最后变化的时间戳 // } // 更新 last_tempmax_level 为当前的 tempmax_level // last_tempmax_level = tempmax_level; // last_temp_level_change_time = HAL_GetTick(); // 更新 temp_level 变更的时间 // printf("temp_system_level[%d]\r\n",temp_system_level); //printf("Sensor ID: %d, Templevel: %d, Tempmax Level: %d, System Level: %d\n", //sensor_id, templevel, tempmax_level, temp_system_level); //taskENTER_CRITICAL(); //memset(sensor_dwin_data_buffer.temp_data[sensor_id], 0, 3); //memcpy(sensor_dwin_data_buffer.temp_data[sensor_id], &can_msg->data[1], 3); //taskEXIT_CRITICAL(); memset(sensor_dwin_data_buffer.temp_data[sensor_id], 0, 3); memcpy(sensor_dwin_data_buffer.temp_data[sensor_id], &can_msg->data[1], 3); sensor_dwin_data_buffer.temp_valid[sensor_id] = 1; //printf("sensor_dwin_data_buffer.Temp Data[%d]: %02X %02X %02X\n", // sensor_id, // sensor_dwin_data_buffer.temp_data[sensor_id][0], // sensor_dwin_data_buffer.temp_data[sensor_id][1], // sensor_dwin_data_buffer.temp_data[sensor_id][2]); g_prevdata_temp[sensor_id].count_ms = HAL_GetTick(); g_prevdata_temp[sensor_id].recv_flag =1; g_prevdata_temp[sensor_id].offline_flag =0; memcpy(dw_msg.data, &can_msg->data[1], 3); memset(&dw_msg.data[3], 0, sizeof(dw_msg.data) - 3); //for (int i = 0; i < 8; i++) //{ // printf("_sensor_id[%d]___dw_msg.data[%d]: 0x%x\r\n",sensor_id, i, dw_msg.data[i]); //} //for (int sensor_id = 0; sensor_id < 30; sensor_id++) //{ // printf("sensor_dwin_data_buffer.Temp Data[%d]: %02X %02X %02X\n", // sensor_id, // sensor_dwin_data_buffer.temp_data[sensor_id][0], // sensor_dwin_data_buffer.temp_data[sensor_id][1], // sensor_dwin_data_buffer.temp_data[sensor_id][2]); //} g_canTempRaw[sensor_id].data[0] = can_msg->data[5]; // 第6个字节 横坐标 g_canTempRaw[sensor_id].data[1] = can_msg->data[6]; // 第7个字节 纵坐标 g_canTempRaw[sensor_id].data[2] = can_msg->data[7]; // 第8个字节 九宫格第一个值 Ambient_temperature = can_msg->data[4]; // 第4个字节 环境温度 Ambient_temperature // if (dwin_power_state != dwin_power_closed && display_message_queueHandle) // { // xQueueSendToBack(display_message_queueHandle, &dw_msg, (TickType_t)0); // } } else if (sliceId == 0x2) // 处理 sliceId 为 0x2 的数据 { if (g_canTempRaw[sensor_id].SliceMask == 0) { g_canTempRaw[sensor_id].PacktSeq = packtSeq; g_canTempRaw[sensor_id].SliceNum = sliceNum; } else if (g_canTempRaw[sensor_id].PacktSeq != packtSeq) { // 拼包可能出错,丢掉不完整的数据 g_canTempRaw[sensor_id].SliceMask = 0; g_canTempRaw[sensor_id].PacktSeq = packtSeq; g_canTempRaw[sensor_id].SliceNum = sliceNum; } if (sliceId <= MAX_SLICE_NUM) { memcpy(g_canTempRaw[sensor_id].data + 3, can_msg->data, SLICE_DATA_SIZE); g_canTempRaw[sensor_id].data[11] = Ambient_temperature; g_canTempRaw[sensor_id].SliceMask |= (1 << sliceId); } //printf("g_canTempRaw[%d].data: ", sensor_id); //for (int i = 0; i < 11; i++) //{ // printf("0x%02X ", g_canTempRaw[sensor_id].data[i]); //} //printf("\n"); // 判断数据是否收齐 uint16_t tmp_mask = 0; for (uint8_t i = 0; i < g_canTempRaw[sensor_id].SliceNum; i++) { tmp_mask |= (1 << i); } if (tmp_mask + 1 == g_canTempRaw[sensor_id].SliceMask) { g_canTempRaw[sensor_id].Finished = 1; } if (g_canTempRaw[sensor_id].Finished == 1) { memcpy(rt_msg.data, g_canTempRaw[sensor_id].data, SLICE_DATA_SIZE * MAX_SLICE_NUM); rt_msg.SensorId = sensor_id; rt_msg.SensorType = SENSOR_TEMPERATURE; //printf("yun g_canTempRaw[%d].data: ", sensor_id); //for (int i = 0; i < 12; i++) //{ // printf("0x%02X ", g_canTempRaw[sensor_id].data[i]); //} //printf("\n"); //printf("rt_msg.data: "); //for (int i = 0; i < SLICE_DATA_SIZE * MAX_SLICE_NUM; i++) //{ // printf("0x%02X ", rt_msg.data[i]); //} //printf("\n"); if (cloud_message_queueHandle) { xQueueSendToBack(cloud_message_queueHandle, &rt_msg, (TickType_t)0); uint8_t temp_data_id = rt_msg.SensorId; memcpy(sensor_data_buffer.temp_data[temp_data_id], rt_msg.data, 12); sensor_data_buffer.temp_valid[temp_data_id] = 1; // check_can = false; } // 清空 g_canTempRaw,准备下一次接收数据 memset(&g_canTempRaw[sensor_id], 0, sizeof(g_canTempRaw[sensor_id])); } } // osDelay(1); } else if( nodeId >= 2) //压力数据 { //发送给 迪文屏一份 dw_msg.SensorType = SENSOR_PRESSURE; uint8_t pre_SensorId = nodeId - 2; //id 从0 开始 dw_msg.SensorId = pre_SensorId; // 判断 pre_system_level uint8_t prelevel = can_msg->data[0]; pre_level_buffer[pre_SensorId] = (prelevel == 2) ? 2 : 0; uint8_t premax_level = 0; for(uint8_t i = 0; i < MAX_PRESSURE_NODE_NUM; i++) { if(pre_level_buffer[i] > premax_level) { premax_level = temp_level_buffer[i]; } } // 根据最大等级设置 pre_system_level pre_system_level = (premax_level == 0) ? PRE_LEVEL_0 : PRE_LEVEL_2; memcpy(dw_msg.data, &can_msg->data[1], 2); g_prevdata_press[pre_SensorId].count_ms = HAL_GetTick(); g_prevdata_press[pre_SensorId].recv_flag =1; g_prevdata_press[pre_SensorId].offline_flag =0; uint8_t pressure_data_id = pre_SensorId; memcpy(sensor_dwin_data_buffer.pressure_data[pressure_data_id], dw_msg.data, 2); sensor_dwin_data_buffer.pressure_valid[pressure_data_id] = 1; // if (dwin_power_state != dwin_power_closed && display_message_queueHandle) // { // xQueueSendToBack(display_message_queueHandle, &dw_msg, (TickType_t)0); // } //发送给 4G 一份 rt_msg.SensorType = SENSOR_PRESSURE; rt_msg.SensorId = dw_msg.SensorId; memcpy(rt_msg.data, &can_msg->data[1], 2); if (cloud_message_queueHandle) { xQueueSendToBack(cloud_message_queueHandle, &rt_msg, (TickType_t)0); uint8_t id = rt_msg.SensorId; memcpy(sensor_data_buffer.pressure_data[id], rt_msg.data, 2); sensor_data_buffer.pressure_valid[id] = 1; } // osDelay(10); } } void print_SensorDataBuffer(SensorDataBuffer *buffer) { printf("------ Sensor Data Buffer ------\n"); // 打印温度数据 printf("\n[Temperature Data]\n"); for (uint8_t i = 0; i < MAX_TEMP_NODE_NUM; i++) { // if (buffer->temp_valid[i]) // { printf("Temp[%d]: ", i); for (uint8_t j = 0; j < 11; j++) { printf("%02X ", buffer->temp_data[i][j]); } printf("\n"); // } } // 打印压力数据 printf("\n[Pressure Data]\n"); for (uint8_t i = 0; i < MAX_PRESSURE_NODE_NUM; i++) { if (buffer->pressure_valid[i]) { printf("Pressure[%d]: %02X %02X\n", i, buffer->pressure_data[i][0], buffer->pressure_data[i][1]); } } // 打印 CO 数据 printf("\n[CO Data]\n"); for (uint8_t i = 0; i < MAX_CO_NODE_NUM; i++) { if (buffer->co_valid[i]) { printf("CO[%d]: %02X %02X %02X %02X\n", i, buffer->co_data[i][0], buffer->co_data[i][1], buffer->co_data[i][2], buffer->co_data[i][3]); } } // 打印 H2 数据 printf("\n[H2 Data]\n"); for (uint8_t i = 0; i < MAX_H2_NODE_NUM; i++) { if (buffer->h2_valid[i]) { printf("H2[%d]: %02X %02X %02X %02X\n", i, buffer->h2_data[i][0], buffer->h2_data[i][1], buffer->h2_data[i][2], buffer->h2_data[i][3]); } } printf("------ End of Sensor Data ------\n"); } void DWIN_STARTSHOW(void) { if(DWIN_STARTSHOW_flag ==1) { DWIN_STARTSHOW_count = 1; DWIN_stopsend_flag = false; printf("DWIN_STARTSHOW_flag =1\n"); DWIN_START_CHECK(); vTaskDelay(pdMS_TO_TICKS(500)); SendWENBENDWIN(0x2990,"DC2025_T2"); // 屏保界面版本号 // vTaskDelay(pdMS_TO_TICKS(100)); // SendASCIIHEXNDWIN(0x4000, versionmessage, versionmessage_length);// 版本: DC2025_T2 // vTaskDelay(pdMS_TO_TICKS(100)); // SendASCIIHEXNDWIN(0x4100, upgrademessage, upgrademessage_length);// 最后升级:2025/01/14 vTaskDelay(pdMS_TO_TICKS(100)); SendDWINThreshold(0x6030,flash_data.smallboard_upload_frequency); vTaskDelay(pdMS_TO_TICKS(100)); SendDWINThreshold(0x6040,flash_data.object_emissivity); vTaskDelay(pdMS_TO_TICKS(100)); SendDWINThreshold(0x6050,flash_data.pressure_threshold); vTaskDelay(pdMS_TO_TICKS(100)); SendDWINThreshold(0x6000,flash_data.temp_first_threshold); vTaskDelay(pdMS_TO_TICKS(100)); SendDWINThreshold(0x6010,flash_data.temp_second_threshold); vTaskDelay(pdMS_TO_TICKS(100)); SendDWINThreshold(0x6020,flash_data.mainboard_upload_frequency); vTaskDelay(pdMS_TO_TICKS(100)); SendDWINThreshold(0x6060,flash_data.co_threshold); vTaskDelay(pdMS_TO_TICKS(100)); SendDWINThreshold(0x6070,flash_data.h2_threshold); vTaskDelay(pdMS_TO_TICKS(100)); // SendDWINThreshold(0x60A0,flash_data.pressure_upload_frequency); // vTaskDelay(pdMS_TO_TICKS(100)); SendDWINterminal(0x6080, terminalId); vTaskDelay(pdMS_TO_TICKS(200)); SendDWINterminal(0x6090, g_board_id); vTaskDelay(pdMS_TO_TICKS(200)); DWIN_SWITCH_PAGES(0x0084, 0x0001) ; vTaskDelay(pdMS_TO_TICKS(100)); previous_dwin_warning_state_level = SYSTEM_LEVEL_0; printf("DWIN_STARTSHOW_flag end\n"); DWIN_STARTSHOW_flag = 2; dwin_show_state = dwin_show_opened; // check_dwin_gas = false; DWIN_stopsend_flag = true; } else{ check_dwin_gas = false; } } void DWIN_WARNING_MODE(void) // 预警模式下使用 { if(dwin_power_state == dwin_power_closed) { previous_dwin_warning_state_level = SYSTEM_LEVEL_3 ; } if((dwin_power_state == dwin_power_opened) && (system_level != previous_dwin_warning_state_level)) // previous_dwin_warning_state_level { vTaskDelay(pdMS_TO_TICKS(300)); gas_start_read_flag = false; if (system_level == SYSTEM_LEVEL_2) { vTaskDelay(pdMS_TO_TICKS(50)); SendHEXNDWIN(0x1001, 0x0002); // 2二级状态 vTaskDelay(pdMS_TO_TICKS(50)); DWIN_PLAY_MUSIC(0X00A0, 0X0301); }else{ vTaskDelay(pdMS_TO_TICKS(20)); SendHEXNDWIN(0x1001, 0x0000); // 0正常状态 vTaskDelay(pdMS_TO_TICKS(30)); DWIN_PLAY_MUSIC(0X00A0, 0X0401); } gas_start_read_flag = true; previous_dwin_warning_state_level = system_level; } if(temp_system_level != TEMP_LEVEL_0) { if(gas_start_read_flag) { read_gas(); check_dwin_gas = false; return; } } check_dwin_gas = false; return; } void ProcessDWINSHOW_gasread(void) { // while (1){ // if (check_dwin_gas) // { if( DWIN_STARTSHOW_flag ==1 ) { DWIN_SHOW(); osDelay(1); } // } else { if(gas_start_read_flag) { read_gas(); osDelay(1); } // else // { // check_dwin_gas = true; // } // } // osDelay(1); // } } void DWIN_SHOW(void) { while (1) { switch (dwin_state) { case DWIN_STATE_DEBUG: { DWIN_CHECK(); // read_dwin(); osDelay(300); sprintf(display_str, "%d%%", percent); // 构造字符串,如 "75%" SendWENBENDWIN(0x1200, display_str); osDelay(300); if(system_cloud_mode == Cloud_4G_MODE) { SendHEXNDWIN(0x1016, 0x0000); // 显示水陆图标 } else { SendHEXNDWIN(0x1016, 0x0001); // 显示航空图标 } osDelay(300); if (REGISTER_OK_start_flag) { SendHEXNDWIN(0x1013, 0x0001); // 显示联网图标 } else { SendHEXNDWIN(0x1013, 0x0000); // 取消联网图标 } osDelay(300); for(uint8_t i = 0; i < MAX_TEMP_NODE_NUM; i++) { // if (dwin_show_closed == dwin_show_state || DWIN_stopsend_flag == false) // break; if (sensor_dwin_data_buffer.temp_valid[i]) { SendMLXDWIN(0x3000 + (i * 0x10), i + 1, sensor_dwin_data_buffer.temp_data[i][0], sensor_dwin_data_buffer.temp_data[i][1], sensor_dwin_data_buffer.temp_data[i][2]); sensor_dwin_data_buffer.temp_valid[i] = 0; vTaskDelay(pdMS_TO_TICKS(100)); } } if(temp_system_level == TEMP_LEVEL_0) { SendHEXNDWIN(0x31E0, 0xFFFF); // 文本框清空 osDelay(100); SendHEXNDWIN(0x31F0, 0xFFFF); // 文本框清空 osDelay(100); SendHEXNDWIN(0x3200, 0xFFFF); // 文本框清空 osDelay(100); SendHEXNDWIN(0x3210, 0xFFFF); // 文本框清空 osDelay(100); SendHEXNDWIN(0x3220, 0xFFFF); // 文本框清空 osDelay(100); SendHEXNDWIN(0x3230, 0xFFFF); // 文本框清空 osDelay(100); SendHEXNDWIN(0x3240, 0xFFFF); // 文本框清空 osDelay(100); SendHEXNDWIN(0x3250, 0xFFFF); // 文本框清空 osDelay(100); SendHEXNDWIN(0x3260, 0xFFFF); // 文本框清空 osDelay(100); } osDelay(100); if(temp_system_level != TEMP_LEVEL_0) { for(uint8_t i = 0; i < MAX_PRESSURE_NODE_NUM; i++) { if (sensor_dwin_data_buffer.pressure_valid[i]) { SendPressureDWIN(0x31E0 + (i * 0x10), i + 1, (sensor_dwin_data_buffer.pressure_data[i][0] << 8) | sensor_dwin_data_buffer.pressure_data[i][1]); sensor_dwin_data_buffer.pressure_valid[i] = 0; vTaskDelay(pdMS_TO_TICKS(60)); } } for(uint8_t i = 0; i < MAX_H2_NODE_NUM; i++) { SendH2DWIN(0x3210 + (i * 0x10), i + 1, modbus_to_float(sensor_data_buffer.h2_data[i])); sensor_data_buffer.h2_valid[i] = 0; vTaskDelay(pdMS_TO_TICKS(60)); } for(uint8_t i = 0; i < MAX_CO_NODE_NUM; i++) { SendCODWIN(0x3240 + (i * 0x10), i + 1, modbus_to_float(sensor_data_buffer.co_data[i])); sensor_data_buffer.co_valid[i] = 0; vTaskDelay(pdMS_TO_TICKS(60)); } if(gas_start_read_flag) { osDelay(500); send_modbus_command(0x11); osDelay(500); send_modbus_command(0x10); osDelay(500); send_modbus_command(0x12); osDelay(500); send_modbus_command(0x02); osDelay(500); send_modbus_command(0x01); osDelay(500); send_modbus_command(0x03); osDelay(500); } } get_current_dwin_state(); osDelay(1000); check_dwin_gas = false; break; } case DWIN_STATE_WARNING: { static TickType_t last_display_tick = 0; TickType_t now = xTaskGetTickCount(); // 每 2 秒更新一次显示 if ((now - last_display_tick) >= pdMS_TO_TICKS(2000)) { last_display_tick = now; // printf("percent %d \n",percent); sprintf(display_str, "%d%%", percent); // 构造字符串,如 "75%" SendWENBENDWIN(0x1200, display_str); osDelay(200); SendDWINterminal(0x6080, terminalId); osDelay(200); if (REGISTER_OK_start_flag) { SendHEXNDWIN(0x1013, 0x0001); // 显示联网图标 } else { SendHEXNDWIN(0x1013, 0x0000); // 取消联网图标 } osDelay(200); if(system_cloud_mode == Cloud_4G_MODE) { SendHEXNDWIN(0x1016, 0x0000); // 显示水陆图标 } else { SendHEXNDWIN(0x1016, 0x0001); // 显示航空图标 } } get_current_dwin_state(); DWIN_WARNING_MODE(); break; } case DWIN_STATE_SET: { static TickType_t SETlast_display_tick = 0; TickType_t SETnow = xTaskGetTickCount(); if ((SETnow - SETlast_display_tick) >= pdMS_TO_TICKS(5000)) { SETlast_display_tick = SETnow; osDelay(100); SendDWINThreshold(0x6000, flash_data.temp_first_threshold); osDelay(100); SendDWINThreshold(0x6010, flash_data.temp_second_threshold); osDelay(100); SendDWINThreshold(0x6020, flash_data.mainboard_upload_frequency); osDelay(100); SendDWINThreshold(0x6030, flash_data.smallboard_upload_frequency); osDelay(100); SendDWINThreshold(0x6050, flash_data.pressure_threshold); osDelay(100); SendDWINThreshold(0x6060, flash_data.co_threshold); osDelay(100); SendDWINThreshold(0x6070, flash_data.h2_threshold); osDelay(100); SendDWINThreshold(0x6040, flash_data.object_emissivity); osDelay(100); SendDWINterminal(0x6080, terminalId); osDelay(100); SendDWINterminal(0x6090, g_board_id); osDelay(100); get_current_dwin_state(); } break; } case DWIN_STATE_AVIATION: { static TickType_t AVIATION_last_display_tick = 0; TickType_t AVIATION_now = xTaskGetTickCount(); if ((AVIATION_now - AVIATION_last_display_tick) >= pdMS_TO_TICKS(3000)) { AVIATION_last_display_tick = AVIATION_now; osDelay(100); Send_uint8HEX_DWIN(0x60A0, wifi_config.ssid, sizeof(wifi_config.ssid) ); printf("DWIN.ssid :%s \n",wifi_config.ssid); osDelay(100); Send_uint8HEX_DWIN(0x60C0, wifi_config.password, sizeof(wifi_config.password) ); printf("DWIN.password :%s \n",wifi_config.password); osDelay(100); // ReadHEXNDWIN(0x5610,0x0A); // osDelay(400); // ReadHEXNDWIN(0x5630,0x0A); // osDelay(400); } break; } case DWIN_STATE_AVIATION_READ: osDelay(100); SendHEXNDWIN(0x1016, 0x0001); //航空模式图标 osDelay(100); dwin_state = DWIN_STATE_WARNING_SWITCH; break; case DWIN_STATE_4G: osDelay(100); SendHEXNDWIN(0x1016, 0x0000); //水陆模式图标 osDelay(100); dwin_state = DWIN_STATE_WARNING_SWITCH; break; case DWIN_STATE_DEBUG_SWITCH: osDelay(100); DWIN_SWITCH_PAGES(0x0084, 0x0001) ; osDelay(100); SendDWINterminal(0x6080, terminalId); osDelay(100); dwin_state = DWIN_STATE_DEBUG; get_current_dwin_state(); break; case DWIN_STATE_WARNING_SWITCH: osDelay(100); DWIN_SWITCH_PAGES(0x0084, 0x000E) ; osDelay(100); sprintf(display_str, "%d%%", percent); SendWENBENDWIN(0x1200, display_str); osDelay(100); SendDWINterminal(0x6080, terminalId); osDelay(100); dwin_state = DWIN_STATE_WARNING; get_current_dwin_state(); break; case DWIN_STATE_SET_SWITCH: osDelay(100); DWIN_SWITCH_PAGES(0x0084, 0x0006) ; osDelay(100); dwin_state = DWIN_STATE_SET; get_current_dwin_state(); break; case DWIN_STATE_IDLE: default: break; } osDelay(1); } } DWIN_State_t get_current_dwin_state(void) { switch(dwin_state) { case DWIN_STATE_DEBUG_SWITCH: printf("DWIN_STATE_DEBUG_SWITCH\n"); return DWIN_STATE_DEBUG_SWITCH; case DWIN_STATE_WARNING_SWITCH: printf("DWIN_STATE_WARNING_SWITCH\n"); return DWIN_STATE_WARNING_SWITCH; case DWIN_STATE_SET_SWITCH: printf("DWIN_STATE_SET_SWITCH\n"); return DWIN_STATE_SET_SWITCH; case DWIN_STATE_DEBUG: // printf("DWIN_STATE_DEBUG\n"); return DWIN_STATE_DEBUG; case DWIN_STATE_WARNING: // printf("DWIN_STATE_WARNING\n"); return DWIN_STATE_WARNING; case DWIN_STATE_SET: // printf("DWIN_STATE_SET\n"); return DWIN_STATE_SET; default: return DWIN_STATE_IDLE; } } void read_gas(void) // 发送读取 H2 CO 数据 // H2 1 - 15 // CO 16 - 31 { switch (gas_command_index) { case 0: send_modbus_command(0x11); break; case 1: send_modbus_command(0x10); break; case 2: send_modbus_command(0x12); break; case 3: send_modbus_command(0x02); break; case 4: send_modbus_command(0x01); break; case 5: send_modbus_command(0x03); break; default: gas_command_index = 0; break; } gas_command_index = (gas_command_index + 1) % 6; vTaskDelay(pdMS_TO_TICKS(490)); } void read_dwin(void) { switch (dwin_command_index) { case 0: ReadHEXNDWIN(0x1003, 0x01); break; case 1: ReadHEXNDWIN(0x5500, 0x01); break; case 2: ReadHEXNDWIN(0x5501, 0x01); break; case 3: ReadHEXNDWIN(0x5502, 0x01); break; case 4: ReadHEXNDWIN(0x5503, 0x01); break; case 5: ReadHEXNDWIN(0x5504, 0x01); break; case 6: ReadHEXNDWIN(0x5505, 0x01); break; case 7: ReadHEXNDWIN(0x5506, 0x01); break; case 8: ReadHEXNDWIN(0x5507, 0x01); break; case 9: ReadHEXNDWIN(0x5510, 0x01); break; case 10: ReadHEXNDWIN(0x5508, 0x04); break; case 11: ReadHEXNDWIN(0x5509, 0x04); break; case 12: ReadHEXNDWIN(0x1500, 0x01); break; default: dwin_command_index = 0; break; } dwin_command_index = (dwin_command_index + 1) % 13; vTaskDelay(pdMS_TO_TICKS(800)); } void check_trigger_source(void) { if (trigger_info[0] == 0) { // 只记录最早触发的 if (temp_system_level == TEMP_LEVEL_2) { // 温度触发 for (uint8_t i = 0; i < MAX_TEMP_NODE_NUM; i++) { if (temp_level_buffer[i] == 2) { trigger_info[0] = 0xF00A; // 温度类型 trigger_info[1] = i + 1; // 传感器编号 trigger_info[2] = sensor_dwin_data_buffer.temp_data[i][0]; // 记录值 break; } } } if (pre_system_level == PRE_LEVEL_2) { // 压力触发 for (uint8_t i = 0; i < MAX_PRESSURE_NODE_NUM; i++) { if (pre_level_buffer[i] == 2) { trigger_info[0] = 0xF00C; // 压力类型 trigger_info[1] = i + 1; if( sensor_dwin_data_buffer.pressure_data[i][0] > 0 ) { sensor_dwin_data_buffer.pressure_data[i][1] = 0xFF; } printf("sensor_dwin_data_buffer.pressure_data[%d][0][1] %d %d\r\n",i,sensor_dwin_data_buffer.pressure_data[i][0],sensor_dwin_data_buffer.pressure_data[i][1]); trigger_info[2] = sensor_dwin_data_buffer.pressure_data[i][1]; break; } } } } } #define CHECK_INTERVAL_MS 600000 //#define vTaskDelay_MS 50 void check_sensor_line(void) { if (system_level == SYSTEM_LEVEL_0) { check_temp_line(); S_offline_flag = true; } else { switch (current_state) { case SENSOR_STATE_TEMP: check_temp_line(); S_offline_flag = true; // printf("check_temp_line \r\n"); break; case SENSOR_STATE_PRE: check_pre_line(); // printf("check_pre_line \r\n"); break; case SENSOR_STATE_H2: check_h2_line(); // printf("check_h2_line \r\n"); break; case SENSOR_STATE_CO: check_co_line(); S_offline_flag = true; // printf("check_co_line \r\n"); break; default: break; } // printf("offline_flag %d\n",S_offline_flag); // 切换到下一个状态 current_state = (SensorCheckState)((current_state + 1) % SENSOR_STATE_MAX); } } void check_temp_line(void) { uint32_t current_ms = HAL_GetTick(); // uint8_t start_index = current_temp_group * TEMP_NODE_GROUP_SIZE; // uint8_t end_index = start_index + TEMP_NODE_GROUP_SIZE; // // if (end_index > MAX_TEMP_NODE_NUM) { // end_index = MAX_TEMP_NODE_NUM; // 防止越界 // } // 连续 多少秒没有收到温度传感器数值,写0到屏幕和平台 // for (uint8_t i = start_index; i < end_index; i++) // 检测当前组的传感器 for (uint8_t i = 0; i < MAX_TEMP_NODE_NUM; i++) { // 更新 sensor_status uint8_t byte_index = 3 - (i / 8); // **反向计算所属字节** uint8_t bit_index = i % 8; // **从 bit0 开始顺序排列** if (current_ms - g_prevdata_temp[i].count_ms >= CHECK_INTERVAL_MS) { g_prevdata_temp[i].recv_flag = 0; g_prevdata_temp[i].offline_flag = 1; // memset(sensor_dwin_data_buffer.temp_data[i], 0, sizeof(sensor_dwin_data_buffer.temp_data[i])); // memset(sensor_data_buffer.temp_data[i], 0, sizeof(sensor_data_buffer.temp_data[i])); sensor_status[byte_index] &= ~(1 << bit_index); // **清零(掉线)** g_prevdata_temp[i].count_ms = current_ms; // printf("offline_Temp[%d]\r\n", i + 1); } if (g_prevdata_temp[i].offline_flag == 0) { sensor_status[byte_index] |= (1 << bit_index); // **置位(在线)** } else { sensor_status[byte_index] &= ~(1 << bit_index); // **清零(掉线)** } } // 切换到下一组 // current_temp_group = (current_temp_group + 1) % ((MAX_TEMP_NODE_NUM + TEMP_NODE_GROUP_SIZE - 1) / TEMP_NODE_GROUP_SIZE); } void check_pre_line(void) { uint32_t current_ms = HAL_GetTick(); if (system_level != SYSTEM_LEVEL_0) { // 连续多少秒没有收到压力传感器数值,写0到屏幕和平台 uint8_t bit_positions[] = {4, 5, 6}; // 1号传感器对应 bit4,2号对应 bit5,3号对应 bit6 for (uint8_t i = 0; i < MAX_PRESSURE_NODE_NUM; i++) { if (current_ms - g_prevdata_press[i].count_ms >= CHECK_INTERVAL_MS) { g_prevdata_press[i].recv_flag = 0; g_prevdata_press[i].offline_flag = 1; memset(sensor_dwin_data_buffer.pressure_data[i], 0, sizeof(sensor_dwin_data_buffer.pressure_data[i])); // memset(sensor_data_buffer.pressure_data[i], 0, sizeof(sensor_data_buffer.pressure_data[i])); sensor_status[4] &= ~(1 << bit_positions[i]); // 清零(掉线)** g_prevdata_press[i].count_ms = current_ms; // printf("offline_pre[%d]\r\n", i+1); } if (g_prevdata_press[i].offline_flag == 0) { // 更新 sensor_status[4] 的 bit6~bit4 sensor_status[4] |= (1 << bit_positions[i]); // 置位(在线)** } else { sensor_status[4] &= ~(1 << bit_positions[i]); // 清零(掉线)** } } } } void check_co_line(void) { uint32_t current_ms = HAL_GetTick(); if(system_level != SYSTEM_LEVEL_0) { char offline_info[10]; // 用于存储所有掉线传感器的编号 int len = 0; // 记录当前已存储的字符数 int printed = 0; // 用于记录是否打印过掉线信息 printf("check CO current_ms %d\n", current_ms); //连续多少秒 没有收到CO传感器数值, 写0到屏幕和平台 uint8_t bit_positions[] = {0, 1, 2}; // 1号传感器对应 bit0,2号对应 bit1,3号对应 bit2 for(uint8_t i=0; i= CHECK_INTERVAL_MS) { uint32_t cu_cou_ms = current_ms - g_prevdata_co[i].count_ms; printf("check CO %d current-count_ms %d\n", i, cu_cou_ms); g_prevdata_co[i].recv_flag = 0; g_prevdata_co[i].offline_flag = 1; sensor_data_buffer.co_valid[i] = 0; memset(sensor_dwin_data_buffer.co_data[i], 0, sizeof(sensor_dwin_data_buffer.co_data[i])); memset(sensor_data_buffer.co_data[i], 0, sizeof(sensor_data_buffer.co_data[i])); // g_prevdata_co[i].count_ms = current_ms; // 如果尚未打印掉线信息 if (!printed) { printed = 1; } // 将掉线传感器编号追加到 offline_info len += snprintf(offline_info + len, sizeof(offline_info) - len, "%d", i + 1); // 如果不是最后一个,添加逗号 if (i < MAX_CO_NODE_NUM - 1) { len += snprintf(offline_info + len, sizeof(offline_info) - len, ","); } sensor_status[4] &= ~(1 << bit_positions[i]); // 清零 掉线** } if (g_prevdata_co[i].offline_flag == 0) { // 更新 sensor_status[4] 的 bit2~bit0 sensor_status[4] |= (1 << bit_positions[i]); // 置位 在线** } else { sensor_status[4] &= ~(1 << bit_positions[i]); // 清零 掉线** } } // 如果有掉线传感器信息,打印并换行 if (printed) { // printf("offline_co[%s]\r\n", offline_info); } } } void check_h2_line(void) { uint32_t current_ms = HAL_GetTick(); printf("check h2 current_ms %d\n", current_ms); if(system_level != SYSTEM_LEVEL_0) { char offline_info[10]; // 用于存储所有掉线传感器的编号 int len = 0; // 记录当前已存储的字符数 int printed = 0; // 用于记录是否打印过掉线信息 //连续多少秒 没有收到H2传感器数值, 写0到屏幕和平台 uint8_t bit_positions[] = {4, 5, 6}; // 1号传感器对应 bit0,2号对应 bit1,3号对应 bit2 for(uint8_t i=0; i < MAX_H2_NODE_NUM; i++) { if(current_ms - g_prevdata_h2[i].count_ms >= CHECK_INTERVAL_MS) { uint32_t cur_cou_ms = current_ms - g_prevdata_h2[i].count_ms; printf("check h2 %d current-count_ms %d\n", i, cur_cou_ms); g_prevdata_h2[i].recv_flag = 0; g_prevdata_h2[i].offline_flag = 1; sensor_data_buffer.h2_valid[i] = 0; memset(sensor_dwin_data_buffer.h2_data[i], 0, sizeof(sensor_dwin_data_buffer.h2_data[i])); memset(sensor_data_buffer.h2_data[i], 0, sizeof(sensor_data_buffer.h2_data[i])); // g_prevdata_h2[i].count_ms = current_ms; // 如果尚未打印掉线信息 if (!printed) { printed = 1; } // 将掉线传感器编号追加到 offline_info len += snprintf(offline_info + len, sizeof(offline_info) - len, "%d", i + 1); // 如果不是最后一个,添加逗号 if (i < MAX_H2_NODE_NUM - 1) { len += snprintf(offline_info + len, sizeof(offline_info) - len, ","); } sensor_status[5] &= ~(1 << bit_positions[i]); // 清零 掉线** } if (g_prevdata_h2[i].offline_flag == 0) { // 更新 sensor_status[5] 的 bit6~bit4 sensor_status[5] |= (1 << bit_positions[i]); // 置位 在线** } else { sensor_status[5] &= ~(1 << bit_positions[i]); // 清零 掉线** } } // 如果有掉线传感器信息,打印并换行 if (printed) { // printf("offline_h2[%s]\r\n", offline_info); } } } void DWIN_CHECK(void) { // if(system_level != previous_dwin_warning_state_level) // previous_dwin_warning_state_level // { // DWIN_stopsend_flag = false; if (system_level == SYSTEM_LEVEL_1) { vTaskDelay(pdMS_TO_TICKS(100)); SendHEXNDWIN(0x1002, 0x0001); // 1一级预警 // vTaskDelay(pdMS_TO_TICKS(100)); // DWIN_PLAY_MUSIC(0X00A0, 0X0201); vTaskDelay(pdMS_TO_TICKS(100)); SendHEXNDWIN(0x1004, 0x0001); // 气体供电打开 vTaskDelay(pdMS_TO_TICKS(100)); SendHEXNDWIN(0x1005, 0x0000); // 推杆供电关闭 vTaskDelay(pdMS_TO_TICKS(100)); // printf("DWIN send DWIN_WARNING_LEVEL_1_STATE \r\n"); } else if (system_level == SYSTEM_LEVEL_2) { vTaskDelay(pdMS_TO_TICKS(100)); SendHEXNDWIN(0x1002, 0x0002); // 2二级报警 vTaskDelay(pdMS_TO_TICKS(20)); DWIN_PLAY_MUSIC(0X00A0, 0X0301); vTaskDelay(pdMS_TO_TICKS(100)); SendHEXNDWIN(0x1004, 0x0001); // 气体供电打开 vTaskDelay(pdMS_TO_TICKS(100)); SendHEXNDWIN(0x1005, 0x0001); // 推杆供电打开 vTaskDelay(pdMS_TO_TICKS(100)); // printf("DWIN send DWIN_WARNING_LEVEL_2_STATE \r\n"); } else if(system_level == SYSTEM_LEVEL_0) { vTaskDelay(pdMS_TO_TICKS(100)); SendHEXNDWIN(0x1002, 0x0000); // 0正常状态 // vTaskDelay(pdMS_TO_TICKS(100)); // DWIN_PLAY_MUSIC(0X00A0, 0X0401); vTaskDelay(pdMS_TO_TICKS(100)); SendHEXNDWIN(0x1004, 0x0000); // 气体供电关闭 vTaskDelay(pdMS_TO_TICKS(100)); SendHEXNDWIN(0x1005, 0x0000); // 推杆供电关闭 vTaskDelay(pdMS_TO_TICKS(100)); // printf("DWIN send DWIN_WARNING_LEVEL_0_STATE \r\n"); } // previous_dwin_warning_state_level = system_level; //// DWIN_stopsend_flag = true; // } if (REGISTER_OK_start_flag) { SendHEXNDWIN(0x1013, 0x0001); // 显示联网图标 // printf("REGISTER_OK\n"); } else { SendHEXNDWIN(0x1013, 0x0000); // 取消联网图标 // printf("REGISTER_fail\n"); } } void DWIN_START_CHECK(void) { if(previous_dwin_warning_state_level != system_level) { if (system_level == SYSTEM_LEVEL_1) { vTaskDelay(pdMS_TO_TICKS(20)); SendHEXNDWIN(0x1002, 0x0001); // 1一级预警 vTaskDelay(pdMS_TO_TICKS(20)); DWIN_PLAY_MUSIC(0X00A0, 0X0201); vTaskDelay(pdMS_TO_TICKS(20)); SendHEXNDWIN(0x1004, 0x0001); // 气体供电打开 vTaskDelay(pdMS_TO_TICKS(20)); SendHEXNDWIN(0x1005, 0x0000); // 推杆供电关闭 vTaskDelay(pdMS_TO_TICKS(20)); // printf("DWIN send DWIN_WARNING_LEVEL_1_STATE \r\n"); } else if (system_level == SYSTEM_LEVEL_2) { vTaskDelay(pdMS_TO_TICKS(20)); SendHEXNDWIN(0x1002, 0x0002); // 2二级报警 vTaskDelay(pdMS_TO_TICKS(20)); DWIN_PLAY_MUSIC(0X00A0, 0X0301); vTaskDelay(pdMS_TO_TICKS(20)); SendHEXNDWIN(0x1004, 0x0001); // 气体供电打开 vTaskDelay(pdMS_TO_TICKS(20)); SendHEXNDWIN(0x1005, 0x0001); // 推杆供电打开 vTaskDelay(pdMS_TO_TICKS(20)); // printf("DWIN send DWIN_WARNING_LEVEL_2_STATE \r\n"); } else if (system_level == SYSTEM_LEVEL_0) { vTaskDelay(pdMS_TO_TICKS(20)); SendHEXNDWIN(0x1002, 0x0000); // 0正常状态 vTaskDelay(pdMS_TO_TICKS(20)); DWIN_PLAY_MUSIC(0X00A0, 0X0401); vTaskDelay(pdMS_TO_TICKS(20)); SendHEXNDWIN(0x1004, 0x0000); // 气体供电关闭 vTaskDelay(pdMS_TO_TICKS(20)); SendHEXNDWIN(0x1005, 0x0000); // 推杆供电关闭 vTaskDelay(pdMS_TO_TICKS(20)); // printf("DWIN send DWIN_WARNING_LEVEL_0_STATE \r\n"); } previous_dwin_warning_state_level = system_level; } } uint16_t calculate_crc16(uint8_t *data, uint16_t length) { uint16_t crc = 0xFFFF; for (uint16_t i = 0; i < length; i++) { crc ^= (uint16_t)data[i]; for (uint8_t j = 0; j < 8; j++) { if (crc & 0x0001) { crc >>= 1; crc ^= 0xA001; } else { crc >>= 1; } } } return crc; } void send_modbus_command(uint8_t sensor_address) // 发送MODBUS指令读取传感器数据 { uint8_t command[8]; command[0] = sensor_address; // 传感器地址 command[1] = 0x03; // 功能码:读取保持寄存器 command[2] = 0x00; // 起始地址高字节 command[3] = 0x00; // 起始地址低字节 command[4] = 0x00; // 读取寄存器数量高字节 command[5] = 0x02; // 读取寄存器数量低字节 uint16_t crc = calculate_crc16(command, 6); command[6] = crc & 0xFF; // CRC低字节 command[7] = (crc >> 8) & 0xFF; // CRC高字节 // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); HAL_UART_Transmit(&huart2, command, 8,1000); HAL_UART_Receive_DMA(&huart2, dataReceive2, BUFFER_SIZE2); // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); // 发送完成后拉低接收 } static inline float parse_modbus_float(uint8_t *data) // 解析 Modbus 数据并转换为浮点数 { return modbus_to_float(data); } float modbus_to_float(uint8_t *data) { float value = 0; uint8_t float_data[4]; float_data[0] = data[1]; float_data[1] = data[0]; float_data[2] = data[3]; float_data[3] = data[2]; memcpy(&value, float_data, sizeof(float)); return value; } void Check_DWIN_Button(void) { static uint8_t key_was_pressed = 0; // 标记是否处理过本次按键 static uint32_t press_time = 0; // 记录按下时间 GPIO_PinState pin_state = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7); uint32_t current_time = HAL_GetTick(); if (pin_state == GPIO_PIN_RESET) // 检测到按下(低电平) { if (key_was_pressed == 0) // 第一次按下,开始计时 { press_time = current_time; key_was_pressed = 1; } // 如果按下持续时间超过最大值5000ms,放弃本次 if ((current_time - press_time) > 5000) { key_was_pressed = 2; // 标记为超时,不再处理 printf("DWIN_Button press timeout!\n"); } } else // 松开(高电平) { if (key_was_pressed == 1) // 说明之前处于有效低电平阶段 { uint32_t press_duration = current_time - press_time; // 判断持续时间是否在 100ms ~ 5000ms 范围内 if (press_duration >= 100 && press_duration <= 5000) { // 满足条件,执行状态切换 if (dwin_power_state != dwin_power_opened) { dwin_power_state = dwin_power_opened; printf("Dwin_power_opened\n"); } else { dwin_power_state = dwin_power_closed; printf("Dwin_power_closed\n"); } } key_was_pressed = 0; // 重置,等待下一次检测 } else if (key_was_pressed == 2) { // 之前超时了,松开后也要重置 key_was_pressed = 0; } } } void control_actuator(bool enable) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, enable ? GPIO_PIN_SET : GPIO_PIN_RESET); } void control_gas_sensors(bool enable) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, enable ? GPIO_PIN_SET : GPIO_PIN_RESET); } void control_wifi_wakeup(bool enable) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, enable ? GPIO_PIN_RESET : GPIO_PIN_SET); } /** * @breaf 内部flash相关函数 */ void Read_parameter_From_Flash(void) // 从 Flash 读取 parameter { uint8_t *flash_ptr = (uint8_t *)FLASH_LAST_PAGE_ADDR; if (flash_ptr[0] == 0xFF ) { flash_data.controltransmit_flag = 0; }else{ flash_data.controltransmit_flag = flash_ptr[0]; } if (flash_ptr[1] == 0xFF ) { flash_data.temp_first_threshold = 60; }else{ flash_data.temp_first_threshold = flash_ptr[1]; } if (flash_ptr[2] == 0xFF ) { flash_data.temp_second_threshold = 100; }else{ flash_data.temp_second_threshold = flash_ptr[2]; } if (flash_ptr[3] == 0xFF ) { flash_data.pressure_threshold = 100; }else{ flash_data.pressure_threshold = flash_ptr[3]; } if (flash_ptr[4] == 0xFF ) { flash_data.co_threshold = 10; }else{ flash_data.co_threshold = flash_ptr[4]; } if (flash_ptr[5] == 0xFF ) { flash_data.h2_threshold= 10; }else{ flash_data.h2_threshold = flash_ptr[5]; } if (flash_ptr[6] == 0xFF) { flash_data.smallboard_upload_frequency = 1; }else{ flash_data.smallboard_upload_frequency = flash_ptr[6]; } if (flash_ptr[7] == 0xFF) { flash_data.heart_upload_frequency = 30; }else{ flash_data.heart_upload_frequency = flash_ptr[7]; } if (flash_ptr[8] == 0xFF) { flash_data.mainboard_upload_frequency = 1; }else{ flash_data.mainboard_upload_frequency = flash_ptr[8]; } if (flash_ptr[9] == 0xFF) { flash_data.sensoronline_upload_frequency = 60; }else{ flash_data.sensoronline_upload_frequency = flash_ptr[9]; } } void Read_terminal_From_Flash(void) // 从 Flash 读取 terminal终端ID和手机号 { uint8_t *flash_ptr = (uint8_t *)FLASH_SECOND_LAST_PAGE_ADDR; uint8_t read_terminalId[7]; // 用于存储从 Flash 读取的 terminalId uint8_t read_g_board_id[6]; // 用于存储从 Flash 读取的 g_board_id uint8_t read_version; memcpy(read_terminalId, flash_ptr, 7); // 读取前 7 字节为 terminalId memcpy(read_g_board_id, flash_ptr + 7, 6); // 读取接下来的 6 字节为 g_board_id memcpy(&read_version, flash_ptr + 13, 1); // 读取第 13 字节为 version bool terminalId_valid = true; for (int i = 0; i < 7; i++) { if (read_terminalId[i] == 0xFF) { terminalId_valid = false; break; } } if (terminalId_valid) { memcpy(terminalId, read_terminalId, sizeof(terminalId)); // 更新 terminalId 终端ID } else { // 如果未写入,保持默认值 uint8_t default_terminalId[7] = {0x20, 0x24, 0x00, 0x00, 0x00, 0x15, 0x00}; memcpy(terminalId, default_terminalId, sizeof(terminalId)); } bool g_board_id_valid = true; for (int i = 0; i < 6; i++) { if (read_g_board_id[i] == 0xFF) { g_board_id_valid = false; break; } } // 如果 g_board_id 未写入,则保持默认值 if (g_board_id_valid) { memcpy(g_board_id, read_g_board_id, sizeof(g_board_id)); // 更新 g_board_id 手机号 } else { // 如果未写入,保持默认值 uint8_t default_g_board_id[6] = {0x20, 0x24, 0x12, 0x04, 0x00, 0x15}; memcpy(g_board_id, default_g_board_id, sizeof(g_board_id)); } // 检查 version 是否有效(是否为 0xFF) bool version_valid = true; if (read_version == 0xFF) { version_valid = false; } // 如果 version 有效,更新 version;否则,保持默认值 if (version_valid) { // 更新 version flash_data.version = read_version; } else { // 如果未写入,保持默认版本号 flash_data.version = 1; } } void Save_parameter_To_Flash( uint8_t controltransmit_flag , uint8_t temp_first_threshold , uint8_t temp_second_threshold , uint8_t pressure_threshold , uint8_t co_threshold , uint8_t h2_threshold , uint8_t smallboard_upload_frequency , uint8_t heart_upload_frequency , uint8_t mainboard_upload_frequency, uint8_t sensoronline_upload_frequency) // 向 Flash 写入 parameter { uint8_t parameter[16]; uint8_t readparameterData[sizeof(parameter)]; parameter[0] = controltransmit_flag & 0xFF; parameter[1] = temp_first_threshold & 0xFF; parameter[2] = temp_second_threshold & 0xFF; parameter[3] = pressure_threshold & 0xFF; parameter[4] = co_threshold & 0xFF; parameter[5] = h2_threshold & 0xFF; parameter[6] = smallboard_upload_frequency & 0xFF; parameter[7] = heart_upload_frequency & 0xFF; parameter[8]= mainboard_upload_frequency & 0xFF; parameter[9] = sensoronline_upload_frequency & 0xFF; parameter[10] = 0; parameter[11] = 0; parameter[12] = 0; parameter[13] = 0; parameter[14] = 0; parameter[15] = 0; if (Flash_WriteRead(FLASH_LAST_PAGE_ADDR, parameter, sizeof(parameter), readparameterData) != SUCCESS) { printf("Failed to save Parameter to flash\n"); } else { // printf("Parameter saved to flash:\n"); // for (int i = 0; i < sizeof(parameter); i++) { // printf("[%d]: 0x%02X\n", i, parameter[i]); // } } } void Save_terminal_To_Flash(uint8_t* terminalId , uint8_t* g_board_id ,uint8_t version) // 向 Flash 写入 terminal { uint8_t parameter[16]; uint8_t readparameterData[sizeof(parameter)]; memcpy(parameter,terminalId, 7); memcpy(parameter + 7, g_board_id, 6); parameter[13] = version; memset(parameter + 14, 0, sizeof(parameter) - 14); if (Flash_WriteRead(FLASH_SECOND_LAST_PAGE_ADDR, parameter, sizeof(parameter), readparameterData) != SUCCESS) { printf("Failed to save Parameter to flash\n"); } else { } } void Save_W25_Tempaddress_To_Flash(void) // 存储W25Q128的写入地址 { uint32_t temp = W25_Tempaddress; Flash_ErasePages(FLASH_THIRD_LAST_PAGE_ADDR, 1); // 擦除1页 Flash_Write32(FLASH_THIRD_LAST_PAGE_ADDR, &temp, 1); // 写入1个32位数据 } void Save_version_To_Flash(void) { uint32_t version = 0x25051501; Flash_ErasePages(FLASH_FOURTH_LAST_PAGE_ADDR, 1); // 擦除1页 Flash_Write32(FLASH_FOURTH_LAST_PAGE_ADDR, &version, 1); // 写入1个32位数据 } void Save_wifior4G_flag_To_Flash(void) { uint32_t wifior4G = wifior4G_flag; // 4G为0,WIFI为1 Flash_ErasePages(FLASH_FOURTH_LAST_PAGE_ADDR, 1); // 擦除1页 Flash_Write32(FLASH_SIXTH_LAST_PAGE_ADDR, &wifior4G, 1); // 写入1个32位数据 } void Save_WIFI_To_Flash(void) { uint8_t wifi[40]; // 40个字节为账号密码 uint8_t readparameterData[40] = {0}; memcpy(wifi, wifi_config.ssid, 20); memcpy(wifi + 20, wifi_config.password, 20); if (Flash_WriteRead(FLASH_FIFTH_LAST_PAGE_ADDR, wifi, sizeof(wifi), readparameterData) != SUCCESS) { printf("Failed to save wifi to flash\n"); } else { printf("WiFi config saved to flash successfully\n"); } } void Load_WIFI_From_Flash(void) { uint8_t *flash_ptr = (uint8_t *)FLASH_FIFTH_LAST_PAGE_ADDR; uint8_t ssid[20]; // 40个字节,前20个字节为账号 uint8_t password[20]; // 后20个字节为密码 memcpy(ssid, flash_ptr, 20); memcpy(password, flash_ptr + 20, 20); bool ssid_valid = false; bool password_valid = false; for (int i = 0; i < 20; i++) { if (ssid[i] != 0xFF) { ssid_valid = true; break; } } for (int i = 0; i < 20; i++) { if (password[i] != 0xFF) { password_valid = true; break; } } if (ssid_valid) { memcpy(wifi_config.ssid, ssid, 20); } else { memset(wifi_config.ssid, 0, 20); strcpy((char *)wifi_config.ssid, "BATSURV"); // jiaLong Oliver-iphonePM BATSURV } if (password_valid) { memcpy(wifi_config.password, password, 20); } else { memset(wifi_config.password, 0, 20); strcpy((char *)wifi_config.password, "airlines"); // JL88888888 11111111 airlines } } void Read_Remaining_stack_space(void) { // 读取任务剩余栈空间 if (temp_pressureHandle != NULL) { UBaseType_t stackLeft = uxTaskGetStackHighWaterMark(temp_pressureHandle); printf("temp_pressureHandle stack remaining: %lu\n", stackLeft); } if (HighestLevelHandle != NULL) { UBaseType_t stackLeft = uxTaskGetStackHighWaterMark(HighestLevelHandle); printf("HighestLevelHandle stack remaining: %lu\n", stackLeft); } if (CommonHandle != NULL) { UBaseType_t stackLeft = uxTaskGetStackHighWaterMark(CommonHandle); printf("CommonHandle stack remaining: %lu\n", stackLeft); } if (check_sensorHandle != NULL) { UBaseType_t stackLeft = uxTaskGetStackHighWaterMark(check_sensorHandle); printf("check_sensorHandle stack remaining: %lu\n", stackLeft); } if (displayHandle != NULL) { UBaseType_t stackLeft = uxTaskGetStackHighWaterMark(displayHandle); printf("displayHandle stack remaining: %lu\n", stackLeft); } if (cloudHandle != NULL) { UBaseType_t stackLeft = uxTaskGetStackHighWaterMark(cloudHandle); printf("cloudHandle stack remaining: %lu\n", stackLeft); } if (SystemStatusHandle != NULL) { UBaseType_t stackLeft = uxTaskGetStackHighWaterMark(SystemStatusHandle); printf("SystemStatusHandle stack remaining: %lu\n", stackLeft); } } /** PA1 * @brief 读取电池电量 * @retval 电池电量 */ uint32_t ReadADCValue(void) { uint32_t adcValue = 0; const int numSamples = 10; // 样本数量 uint32_t totalAdcValue = 0; for (int i = 0; i < numSamples; i++) { HAL_ADC_Start(&hadc1); if (HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY) == HAL_OK) { totalAdcValue += HAL_ADC_GetValue(&hadc1); } HAL_ADC_Stop(&hadc1); } adcValue = totalAdcValue / numSamples; return adcValue; } uint8_t CalculateBatteryLevel(uint32_t adcValue,uint8_t *voltage) { float batteryVoltage = 0.0f; const float ADC_MAX_VALUE = 4095.0f; const float VREF = 3.3f; // ADC参考电压 const float MIN_BATTERY_VOLTAGE = 19.0f; // 电池完全放电电压 const float MAX_BATTERY_VOLTAGE = 24.2f; // 电池完全充电电压 // 将ADC值转换为电压值,计算电池电量 float voltageDividerRatio = 10.0f /(10.0f + 100.0f) ; // 分压100K/110K 0.909 batteryVoltage = ((float)adcValue / ADC_MAX_VALUE) * VREF/voltageDividerRatio + 1; *voltage = (uint8_t)(batteryVoltage); // 将电压转换为百分比 if (batteryVoltage <= MIN_BATTERY_VOLTAGE) return 0; // 电池电量低于或等于完全放电电压时,电量为0% else if (batteryVoltage >= MAX_BATTERY_VOLTAGE) return 100; // 电池电量高于或等于完全充电电压时,电量为100% else return (uint8_t)(((batteryVoltage - MIN_BATTERY_VOLTAGE) / (MAX_BATTERY_VOLTAGE - MIN_BATTERY_VOLTAGE)) * 100);// 计算电池电量百分比 } /** * @breaf 低功耗相关 */ void Enter_SleepMode(void) { // printf("Enter sleep\n"); __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); // 清除 PWR 相关标志 HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2); // 配置调压器为低功耗模式 HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); // 使能 SLEEP 模式(低功耗模式,CPU 休眠,外设仍然运行) } /* USER CODE END Application */