Member 13742069 Ответов: 1

Обработка указателей в C с помощью блока simulink 'S-function'


Среди моих слабых знаний в программировании я пишу этот код на языке Си, чтобы использовать его в S-функциональном блоке на Matlab/Simulink. Я пытался следовать той же логике, что и другие коды S-функций в C [timestwo.c] и написал следующий код. Однако, хотя я думаю, что "это работает" в моей симуляции, я не могу хорошо понять, как работает каждая строка выполнения внутри if-операторов. Например, при первом условии "если" я хочу сравнить два тока, входящих в это состояние. S-функциональный блок. В случае Snubber Current - *u0_Is[i] меньше Snubber Reference - *u1_Iref[i], то должен быть подан сигнал затвора (А1) к электронному устройству (IGBT). А теперь, что за идея писать *IGBT++ = 1 ?. Я хочу знать, если это правильно, чтобы увидеть *IGBT как вектор или массив, указывающий на переменную, хранящуюся в памяти, так что если я напишу *IGBT = 1, он сохранит этот " 1 " в этом месте?.

Заранее спасибо.

static void mdlOutputs(SimStruct *S, int_T tid)
{
    int_T             i;
    // Snubber Current
    InputRealPtrsType u0_Is = ssGetInputPortRealSignalPtrs(S, 0);
    // Triangle Reference
    InputRealPtrsType u1_Iref = ssGetInputPortRealSignalPtrs(S, 1);
    //  Voltage THY - colector/emisor
    InputRealPtrsType u2_Vce = ssGetInputPortRealSignalPtrs(S, 2);


    real_T            *IGBT = ssGetOutputPortRealSignal(S, 0);
    real_T            *THY =  ssGetOutputPortRealSignal(S, 1);
    int_T             width = ssGetOutputPortWidth(S, 0);
    int_T             width1 = ssGetOutputPortWidth(S, 1);


for (i=0; i<width; i++){

        if (*u0_Is[i] < *u1_Iref[i]){
            *IGBT++ = 1;
            if (*u2_Vce[i] >= 0.8 && (*u0_Is[i] < *u1_Iref[i]) ){
                *THY++ = 1;
            }
            else {
                *THY++ = 0;
            }
        }
        else {
            *IGBT++ = 0;
            *THY++ = 0;

        }
    }
}


Что я уже пробовал:

Удаление файла ++ знаки в выходных указателях, получающие тот же результат при построении графика.

1 Ответов

Рейтинг:
5

Jochen Arndt

Вы правы, *IGBT является указателем на массив размера width Доступ к элементам массива осуществляется с помощью разыменования указателей (*) или индекс ([]):

// These are similar and will set an array item to the assigned value
*IGBT = val;
IGBT[0] = val;

То ++ оператор будет увеличивать значение переменной. В вашем случае это постфиксный оператор (добавляемый к имени переменной), который будет увеличиваться после других операций:
*IGBT++ = val;
// is the same as
*IGBT = val;
IGBT = IGBT + 1;
Пропуск инкремента в вашем случае приведет только к установке первого элемента массива, который, вероятно, не является тем, что вы хотите.

Но вы можете упростить свой код, выполнив инкремент вне условий:
for (i=0; i<width; i++){
    if (*u0_Is[i] < *u1_Iref[i]){
        *IGBT = 1;
        if (*u2_Vce[i] >= 0.8 && (*u0_Is[i] < *u1_Iref[i]) ){
            *THY = 1;
        }
        else {
            *THY = 0;
        }
    }
    else {
        *IGBT = 0;
        *THY = 0;
        }
    }
    *IGBT++;
    *THY++;
}
или просто используйте индекс i вместо:
for (i=0; i<width; i++){
    if (*u0_Is[i] < *u1_Iref[i]){
        IGBT[i] = 1;
        if (*u2_Vce[i] >= 0.8 && (*u0_Is[i] < *u1_Iref[i]) ){
            THY[i] = 1;
        }
        else {
            THY[i] = 0;
        }
    }
    else {
        IGBT[i] = 0;
        THY[i] = 0;
        }
    }
}


CPallini

5.