# Структуры данных ## Основные файлы | Файл | Назначение | |---|---| | `Core/Inc/ad_parameter_identification.h` | режимы, команды, измерения, параметры двигателя | | `Core/Src/ad_parameter_identification.c` | логика запуска, блокировки, fault, valid-mask | | `Core/Inc/ad_inverter.h` | команда и состояние TIM1/inverter слоя | | `Core/Src/ad_inverter.c` | PWM-тесты и начальные алгоритмы `Rs/Ls/Ll` | | `Core/Inc/ad_board.h` | чтение ADC и удобные функции запуска | | `Core/Src/ad_board.c` | распиновка ADC IHM08M1 и board loop | | `Core/Inc/ad_debug.h` | `g_ad_debug` для Keil Watch | | `Core/Inc/simulink_interface.h` | входная/выходная шина и пакет телеметрии | ## Измерения ```c typedef struct { float ia_A; float ib_A; float ic_A; float ia_rms_A; float ib_rms_A; float ic_rms_A; float vdc_V; float va_V; float vb_V; float vc_V; float speed_rpm; float torque_Nm; float temperature_C; uint32_t timestamp_us; uint32_t status_flags; float slip_percent; } AD_Measurements_t; ``` | Поле | Источник | |---|---| | `ia_A` | `PA0 / ADC1_IN1 / PhA` | | `ib_A` | `PC1 / ADC1_IN7 / PhB` | | `ic_A` | `PC0 / ADC1_IN6 / PhC` | | `ia_rms_A` | IIR RMS phase A current | | `ib_rms_A` | IIR RMS phase B current | | `ic_rms_A` | IIR RMS phase C current | | `va_V`, `vb_V`, `vc_V` | estimated phase voltages from TIM1 duty and DC-link voltage | | `torque_Nm` | estimated torque, Nm; uses valid `J/B` with speed, otherwise electrical power fallback; if no speed sensor is present, the fallback uses the inverter electrical frequency and `pole_pairs` | | `slip_percent` | induction-motor slip in percent: `(n_sync - speed_rpm) / n_sync * 100`, where `n_sync = 60 * electrical_frequency_Hz / pole_pairs` | | `temperature_C` | STM32 internal temperature sensor, ADC1 channel 16 | | `vdc_V` | `PA1 / ADC1_IN2 / BUSV`, усреднение и IIR-фильтр | | `timestamp_us` | `HAL_GetTick() * 1000` | | `status_flags` | флаги измерений и защит | ## Параметры двигателя ```c typedef struct { float Rs_ohm; float Rr_ohm; float Ls_H; float Lr_H; float Lm_H; float Ll_H; float J_kg_m2; float B_Nm_s; float pole_pairs; float nominal_voltage_V; float nominal_current_A; float nominal_frequency_Hz; float nominal_power_W; float nominal_speed_rpm; uint32_t valid_mask; } AD_MotorParameters_t; ``` `valid_mask` обязательно проверять перед использованием параметра: | Бит | Значение | |---|---| | `AD_MOTOR_PARAM_VALID_RS` | действителен `Rs_ohm` | | `AD_MOTOR_PARAM_VALID_RR` | действителен `Rr_ohm` | | `AD_MOTOR_PARAM_VALID_LS` | действителен `Ls_H` | | `AD_MOTOR_PARAM_VALID_LR` | действителен `Lr_H` | | `AD_MOTOR_PARAM_VALID_LM` | действителен `Lm_H` | | `AD_MOTOR_PARAM_VALID_LL` | действителен `Ll_H` | | `AD_MOTOR_PARAM_VALID_J` | действителен `J_kg_m2` | | `AD_MOTOR_PARAM_VALID_B` | действителен `B_Nm_s` | Текущий алгоритм реально выставляет только `RS`, `LS` и `LL`. ## Команда ```c typedef struct { uint8_t enable; uint8_t test_mode; uint8_t reset_faults; uint16_t pwm_polarity_flags; uint16_t pwm_timing_mode; uint16_t motor_control_type; uint16_t rotation_ramp_time_ms; float pwm_duty_limit; float rotation_frequency_Hz; float rotation_modulation; float current_limit_A; float voltage_limit_V; float undervoltage_limit_V; float speed_limit_rpm; float temperature_limit_C; } AD_Command_t; ``` `pwm_polarity_flags` управляет полярностью TIM1 PWM: bit0 инвертирует `UH/VH/WH`, bit1 инвертирует `UL/VL/WL`. `pwm_timing_mode`: `0` = up-counting PWM, `1` = center-aligned PWM. `motor_control_type`: `0` = AD/sine, `1` = BLDC/6-step. `pwm_duty_limit` используется для одиночных PWM-тестов и измерительных импульсов. `rotation_frequency_Hz`, `rotation_modulation` и `rotation_ramp_time_ms` управляют режимом `AD_PARAM_ID_MODE_ROTATION_3HZ`; `0` означает значения по умолчанию `3.0 Hz`, `0.35` и `3000 ms`, частота зажимается в диапазон `0.1..200.0 Hz`. ## Состояние инвертора ```c typedef struct { uint8_t initialized; uint8_t pwm_running; uint8_t outputs_allowed_by_build; float duty_a; float duty_b; float duty_c; float electrical_frequency_Hz; float electrical_angle_rad; float requested_test_duty; float applied_test_duty; uint16_t pwm_polarity_flags; uint16_t pwm_timing_mode; uint8_t service_output; uint8_t service_pwm_running; uint8_t id_stage; } AD_InverterState_t; ``` | Поле | Смысл | |---|---| | `initialized` | выполнен `AD_Inverter_Init()` | | `pwm_running` | TIM1 PWM запущен | | `outputs_allowed_by_build` | сборка разрешает физические выходы | | `duty_a/b/c` | последние duty фаз или выбранного тестового канала | | `electrical_frequency_Hz` | current inverter electrical frequency for rotating PWM and torque estimation | | `electrical_angle_rad` | current inverter electrical angle for rotating PWM | | `service_output` | выбранный канал теста `UH..WL` или `ALL` | | `service_pwm_running` | активен сервисный PWM-тест | | `id_stage` | стадия измерительного алгоритма | ## Состояние идентификации | Флаг | Смысл | |---|---| | `AD_PARAM_ID_STATUS_ACTIVE` | режим активен | | `AD_PARAM_ID_STATUS_POWER_TEST_BLOCKED` | силовой тест заблокирован | | `AD_PARAM_ID_STATUS_POWER_STAGE_ARMED` | силовая часть программно разрешена | | `AD_PARAM_ID_STATUS_FAULT_LATCHED` | авария защёлкнута | | `AD_PARAM_ID_STATUS_TIMEOUT` | истекло время теста | | `AD_PARAM_ID_STATUS_LOCKED_ROTOR_BLOCKED` | locked-rotor режим не разрешён | | `AD_PARAM_ID_STATUS_SAFETY_LIMITS_UNKNOWN` | не заданы пределы тока или напряжения | | `AD_PARAM_ID_STATUS_DATA_VALID` | есть действительные данные | | `AD_PARAM_ID_STATUS_COMPLETE` | измерительный алгоритм завершён | | `AD_PARAM_ID_STATUS_PARTIAL_COMPLETE` | измерены не все параметры, но часть результата действительна | | `AD_PARAM_ID_STATUS_STEP_FAILED` | один из этапов измерения не получил достаточного сигнала/условий | | `AD_PARAM_ID_STATUS_LOCKED_ROTOR_SKIPPED` | этап locked-rotor пропущен, потому что он не разрешён | ## Сводная отладка ```c volatile AD_DebugView_t g_ad_debug; ``` `g_ad_debug` обновляется в `AD_Project_Loop()` и содержит копии `project`, `inverter`, `adc`, `measurements`, `motor_parameters`, `command`, `param_id_status`, `param_id_faults`, `param_id_mode`, `power_stage_allowed`, `test_running`, `tick_ms`.