Куча всего.

Добавлена интерполяция по таблице датчиков
Структурирован проект в матлаб
This commit is contained in:
2025-11-14 18:03:44 +03:00
parent e4f05bdf6a
commit 2cdcebeffa
10 changed files with 172 additions and 60 deletions

View File

@@ -26,8 +26,61 @@
#include <windows.h>
#include <process.h>
#include <intrin.h>
#include "mex.h"
static unsigned long long get_timer_frequency(void)
{
#ifdef USE_CPU_TIMER
HKEY hKey;
DWORD frequency = 0;
DWORD size = sizeof(DWORD);
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
if (RegQueryValueExA(hKey, "~MHz", NULL, NULL, (LPBYTE)&frequency, &size) == ERROR_SUCCESS) {
RegCloseKey(hKey);
return (unsigned long long)frequency * 1000000ULL; // MHz -> Hz
}
RegCloseKey(hKey);
}
#elif defined(USE_QPF_TIMER)
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
return frequency.QuadPart;
#endif
}
static double ticksToNanoseconds(unsigned long long start, unsigned long long end)
{
#if defined(USE_CPU_TIMER) || defined(USE_QPF_TIMER)
unsigned long long elapsed = end - start;
unsigned long long frequency = get_timer_frequency();
return (double)elapsed * 1e9 / (double)frequency;
#endif
}
static void InitializeHighPrecisionTimer(void)
{
#ifdef USE_QPF_TIMER
QueryPerformanceFrequency(&hmcu.dTimer.Frequency);
hmcu.dTimer.TimerResolutionNs = 1e9 / (double)(hmcu.dTimer.Frequency);
#endif
}
static unsigned long long read_timer(void)
{
#ifdef USE_CPU_TIMER
return __rdtsc();
#elif defined(USE_QPF_TIMER)
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
return counter.QuadPart;
#endif
}
#define MDL_UPDATE ///< для подключения mdlUpdate()
/**
* @brief Update S-Function at every step of simulation
@@ -40,12 +93,32 @@
*/
static void mdlUpdate(SimStruct* S, int_T tid)
{
// Расчет периода (время между вызовами)
if (hmcu.dTimer.call_count > 0 && hmcu.dTimer.SFuncPrevTime != 0) {
hmcu.dSFuncPeriod = ticksToNanoseconds(
hmcu.dTimer.SFuncPrevTime,
hmcu.dTimer.SFuncStartTime) / 1000.0; // в микросекундах
}
// Сохраняем текущее время для следующего расчета периода
hmcu.dTimer.SFuncPrevTime = hmcu.dTimer.SFuncStartTime;
// Текущий вызов становится началом S-Function
hmcu.dTimer.SFuncStartTime = read_timer();
// get time of simulation
time_T TIME = ssGetT(S);
//---------------SIMULATE MCU---------------
// Измерение времени выполнения MCU_Step_Simulation
hmcu.dTimer.MCUStepStartTime = read_timer();
MCU_Step_Simulation(S, TIME); // SIMULATE MCU
hmcu.dTimer.MCUStepEndTime = read_timer();
//------------------------------------------
// Расчет времени выполнения в микросекундах
hmcu.dMCUStepTime = ticksToNanoseconds(
hmcu.dTimer.MCUStepStartTime,
hmcu.dTimer.MCUStepEndTime) / 1000.0;
}//end mdlUpdate
/**
@@ -59,6 +132,20 @@ static void mdlUpdate(SimStruct* S, int_T tid)
static void mdlOutputs(SimStruct* S, int_T tid)
{
SIM_writeOutputs(S);
// Измерение времени окончания выполнения mdlOutputs
hmcu.dTimer.SFuncEndTime = read_timer();
// Общее время выполнения S-Function в микросекундах
if (hmcu.dTimer.SFuncStartTime)
{
hmcu.dSFuncTime = ticksToNanoseconds(
hmcu.dTimer.SFuncStartTime,
hmcu.dTimer.SFuncEndTime) / 1000.0;
}
// Накопление статистики
hmcu.dTimer.call_count++;
}//end mdlOutputs
#define MDL_CHECK_PARAMETERS /* Change to #undef to remove function */
@@ -158,6 +245,9 @@ static void mdlInitializeSizes(SimStruct* S)
*/
static void mdlStart(SimStruct* S)
{
// Инициализация высокоточного таймера
InitializeHighPrecisionTimer();
SIM_Initialize_Simulation(S);
}
#endif // MDL_START

View File

@@ -37,7 +37,7 @@ const int inOffsets[IN_PORT_NUMB] = {
*/
const int outLengths[OUT_PORT_NUMB] = {
THYR_PORT_1_WIDTH,
OUT_PORT_2_WIDTH,
PM_PORT_2_WIDTH,
OUT_PORT_3_WIDTH
};
/**

View File

@@ -47,6 +47,10 @@
//#define DEKSTOP_CYCLES_FOR_MCU_APP 0xFFFF ///< number of for() cycles after which MCU thread would be suspended
//#define MCU_CORE_CLOCK 150000000 ///< MCU clock rate for simulation
// Выбор Timer
//#define USE_QPF_TIMER
#define USE_CPU_TIMER
// Parameters of S_Function
// INPUT/OUTPUTS PARAMS START
#define IN_PORT_NUMB 2
@@ -55,7 +59,7 @@
#define OUT_PORT_NUMB 3
#define THYR_PORT_1_WIDTH 6
#define OUT_PORT_2_WIDTH 6
#define PM_PORT_2_WIDTH 16
#define OUT_PORT_3_WIDTH 16
// INPUT/OUTPUTS PARAMS END
@@ -95,12 +99,12 @@
#define OFFSET_IN_ARRAY_2 (OFFSET_IN_ARRAY_1 + ADC_PORT_1_WIDTH)
/// === Полный размер буфера ===
#define TOTAL_OUT_SIZE (THYR_PORT_1_WIDTH + OUT_PORT_2_WIDTH + OUT_PORT_3_WIDTH)
#define TOTAL_OUT_SIZE (THYR_PORT_1_WIDTH + PM_PORT_2_WIDTH + OUT_PORT_3_WIDTH)
/// === Смещения массивов (внутри общего буфера) ===
#define OFFSET_OUT_ARRAY_1 0
#define OFFSET_OUT_ARRAY_2 (OFFSET_OUT_ARRAY_1 + THYR_PORT_1_WIDTH)
#define OFFSET_OUT_ARRAY_3 (OFFSET_OUT_ARRAY_2 + OUT_PORT_2_WIDTH)
#define OFFSET_OUT_ARRAY_3 (OFFSET_OUT_ARRAY_2 + PM_PORT_2_WIDTH)
// INPUT/OUTPUTS AUTO-PARAMS END
@@ -129,9 +133,24 @@ extern const int inOffsets[IN_PORT_NUMB];
#define CREATE_SUSPENDED 0x00000004
typedef void* HANDLE; ///< MCU handle typedef
typedef struct
{
unsigned long long Frequency; ///< Частота таймера
double TimerResolutionNs; ///< Разрешение таймера в наносекундах
unsigned long long SFuncPrevTime; ///< Время предыдущего вызова S-Function
unsigned long long SFuncStartTime; ///< Начало выполнения S-Function
unsigned long long SFuncEndTime; ///< Окончание выполнения S-Function
unsigned long long MCUStepStartTime; ///< Начало MCU_Step_Simulation
unsigned long long MCUStepEndTime; ///< Окончание MCU_Step_Simulation
// Statistics
long call_count; ///< Количество вызовов
}SIM_HighPrecisionTimer;
/**
* @brief MCU handle Structure definition.
* @note Prefixes: h - handle, s - settings, f - flag
* @note Prefixes: h - handle, s - settings, f - flag, d - debug info
*/
typedef struct {
// MCU Thread
@@ -147,6 +166,12 @@ typedef struct {
double SystemClockDouble; ///< Счетчик в формате double для точной симуляции системных тиков С промежуточными значений
double sSystemClock_step; ///< Шаг тиков для их симуляции, в формате double
double sSimSampleTime; ///< Период дискретизации симуляции
SIM_HighPrecisionTimer dTimer; ///< Высокоточный таймер
double dSFuncPeriod; ///< Период вызова S-Function в микросекундах
double dSFuncTime; ///< Время "выполнения" S-Function (от начала Update до конца Outputs) в микросекундах
double dMCUStepTime; ///< Время выполнения приложения в микросекундах
}SIM__MCUHandleTypeDef;
extern SIM__MCUHandleTypeDef hmcu; // extern для видимости переменной во всех файлах

View File

@@ -8,7 +8,7 @@
#define PIN_READ(_verbname_) (_verbname_##_GPIO_Port->ODR & (_verbname_##_Pin)) ? 1 : 0
void ThyristorWrite(real_T* Buffer)
void Write_Thyristors(real_T* Buffer, int ind_port)
{
int pwm1_pin = PIN_READ(PWM1);
int pwm2_pin = PIN_READ(PWM2);
@@ -18,14 +18,38 @@ void ThyristorWrite(real_T* Buffer)
int pwm6_pin = PIN_READ(PWM6);
WriteOutputArray(pwm1_pin, 0, 0);
WriteOutputArray(pwm2_pin, 0, 1);
WriteOutputArray(pwm3_pin, 0, 2);
WriteOutputArray(pwm4_pin, 0, 3);
WriteOutputArray(pwm5_pin, 0, 4);
WriteOutputArray(pwm6_pin, 0, 5);
WriteOutputArray(pwm1_pin, ind_port, 0);
WriteOutputArray(pwm2_pin, ind_port, 1);
WriteOutputArray(pwm3_pin, ind_port, 2);
WriteOutputArray(pwm4_pin, ind_port, 3);
WriteOutputArray(pwm5_pin, ind_port, 4);
WriteOutputArray(pwm6_pin, ind_port, 5);
}
void Write_PowerMonitor(real_T* Buffer, int ind_port)
{
int nn = 0;
for (int i = 0; i < 3; i++)
{
WriteOutputArray(pm.U[i], ind_port, nn++);
}
for (int i = 0; i < 3; i++)
{
WriteOutputArray(pm.ZC_Detected[i], ind_port, nn++);
}
for (int i = 0; i < 3; i++)
{
WriteOutputArray(pm.F[i], ind_port, nn++);
}
for (int i = 0; i < 3; i++)
{
WriteOutputArray(pm.I[i], ind_port, nn++);
}
for (int i = 0; i < 2; i++)
{
WriteOutputArray(pm.T[i], ind_port, nn++);
}
}
/**
* @brief Функция для записи входов в приложение МК
* @param u - массив входных значений
@@ -49,41 +73,13 @@ void app_readInputs(const real_T* Buffer) {
*/
void app_writeOutputBuffer(real_T* Buffer) {
// USER APP OUTPUT START
//ThyristorWrite(Buffer);
for (int i = 0; i < 2; i++)
{
WriteOutputArray(pm.ZC_Detected[i], 0, i);
}
for (int i = 0; i < 2; i++)
{
WriteOutputArray(pm.zc.Channel[i].DebounceCounter, 0, i+2);
}
//ThyristorWrite(Buffer, 0);
Write_PowerMonitor(Buffer, 1);
extern ADC_Periodic_t adc;
for(int i = 0; i < 6; i++)
{
WriteOutputArray(pm.adc.Data[i], 1, i);
}
for (int i = 0; i < 3; i++)
{
WriteOutputArray(pm.U[i], 2, i);
}
for (int i = 0; i < 3; i++)
{
WriteOutputArray(pm.ZC_Detected[i], 2, i + 3);
}
for (int i = 0; i < 3; i++)
{
WriteOutputArray(pm.I[i], 2, i + 6);
}
for (int i = 0; i < 3; i++)
{
WriteOutputArray(pm.F[i], 2, i + 9);
}
WriteOutputArray(hmcu.dSFuncPeriod, 2, 12);
WriteOutputArray(hmcu.dSFuncTime, 2, 13);
WriteOutputArray(hmcu.dMCUStepTime, 2, 14);
// USER APP OUTPUT END
}

Binary file not shown.