exp() math.c i c не работает, если в цикле

В настоящее время я работаю над pid-регулятором для школьного проекта. Поскольку коронавирус закрыл школу, мы не можем получить оборудование для тестирования. Итак, я хочу смоделировать ПИД-регулятор на микропроцессоре (PSoC5LP). Итак, я реализую функцию, которая возвращает ступенчатую реакцию выбранного двигателя постоянного тока.

Когда я нахожу вывод передаточной функции «(-3,47 * exp (-6,36 * с) + 3,47))», я получаю правильный результат, если я определяю значение «s» вручную в коде. Но когда я устанавливаю s для увеличения в коде «неопределенная ссылка на «exp».

Кажется, проблема в том, что я не могу запустить exp в цикле, увеличивая его. попробовал это в другом проекте, где единственное, что происходит, это то, что цикл выполняется 10 раз и выводит exp() с количеством раз, когда цикл выполнялся (не работает)

float step_respons(){
    double s = 0.1;
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f \r\n", (-3.47*exp(-6.36*s)+3.47));
        pc_uart_PutString(outpurBuffer);
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f \r\n", (-3.47*exp(-6.36*1)+3.47));
        pc_uart_PutString(outpurBuffer);
    //These works just fine

    pc_uart_PutString("Loop:\r\n");

    for(s = 0.1; s < 2; s++){
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f %f \r\n", s,(-3.47*exp(-6.36*s)+3.47));
        pc_uart_PutString(outpurBuffer);
        //this does not work (if "s" is changed with a number it works fine.)

    };

    return 0;
};

Так что это работает, если я выбираю S вручную в цикле, но если он увеличивается, он останавливается. Я пытался использовать другую переменную и увеличивать ее, и она все еще не работает.

    for(s = 0.1; s < 2; s++){
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f %f \r\n", s,(-3.47*exp(-6.36*s)+3.47));
        pc_uart_PutString(outpurBuffer);

    };

не работает

    for(s = 0.1; s < 2; s++){
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f %f \r\n", s,(-3.47*exp(-6.36*1)+3.47));
        pc_uart_PutString(outpurBuffer);

    };

работает, но приращение результата не выполняется. Как вы можете видеть, единственные изменения, сделанные в цикле, - это «s», которые были определены как значение

double temp = 0.5;

    for(s = 0.1; s < 2; s++){
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f %f \r\n", s,(-3.47*exp(-6.36*temp)+3.47));
        pc_uart_PutString(outpurBuffer);    

    };

это работает

double temp = 0.5;

for(s = 0.1; s < 2; s++){
        snprintf(outpurBuffer, sizeof(outpurBuffer), "%f %f \r\n", s,(-3.47*exp(-6.36*temp)+3.47));
        pc_uart_PutString(outpurBuffer);    
        temp += 0.5;
    };

не Это ошибка: Build error: undefined reference to 'exp'

Журнал из вывода компилятора

Вероятно, вы не подключаете библиотеку, включающую функцию exp().


person Viktor T    schedule 27.04.2020    source источник
comment
@ user2864740 двойной шаг ни для чего не используется. что я имею в виду под непеременной, если я выберу число, например 0,5 или 0,75   -  person user2864740    schedule 28.04.2020
comment
Покажите пример обоих случаев. Неясно, точно что меняется. Это должно быть минимальное воспроизведение — возможно, даже одиночный вызов snprintf в случаях OK и сбоев. Связана ли петля? Если нет, удалите его. Включение полной ошибки компилятора (копирование и вставка) также обычно рекомендуется.   -  person Viktor T    schedule 28.04.2020
comment
@user2864740 user2864740 я включил еще несколько примеров того, что работает, а что нет. Также включены выходные данные компилятора.   -  person user2864740    schedule 28.04.2020
comment
Большое улучшение. Сохраняется ли та же проблема, если удалить цикл? Этот процесс заключается в поиске минимального тестового/примерного случая.   -  person Viktor T    schedule 28.04.2020
comment
@user2864740 user2864740 проблема в том, что я хочу, чтобы он зацикливался, он должен зацикливаться. Единственный другой способ - вручную вызвать все разные значения S =, которые я хочу, что будет около 100 строк одного и того же кода.   -  person user2864740    schedule 28.04.2020
comment
Желание цикла не связано с созданием минимального теста. Как только будет найден минимальный тестовый пример, устраните проблему, а затем вернитесь к соответствующему контексту.   -  person Viktor T    schedule 28.04.2020
comment
--------------- Начало сборки: 28.04.2020 01:34:42 Проект: Plotterkode, Конфигурация: ARM GCC 5.4-2016-q2-update Отладка ------ --------- Этап генерации кода актуален. Шаг компиляции актуален, никакой работы не требуется. arm-none-eabi-ar.exe -rs .\CortexM3\ARM_GCC_541\Debug\Plotterkode.a .\CortexM3\ARM_GCC_541\Debug\cy_em_eeprom.o .\CortexM3\ARM_GCC_541\Debug\CyDmac.o .\CortexM3\ARM_GCC_541\ Debug\CyFlash.o .\CortexM3\ARM_GCC_541\Debug\CyLib.o .\CortexM3\ARM_GCC_541\Debug\cyPm.o .\CortexM3\ARM_GCC_541\Debug\CySpc.o .\CortexM3\ARM_GCC_541\Debug\cyutils.o . \CortexM3\ARM_GCC_541\Отладка\pc_uart.o .\CortexM3\ARM_GCC_541\Отладка\pc_uart_PM.o .\CortexM3\ARM_GCC_541\Отладка\pc_uart_INT.o .\CortexM3\ARM_GCC_541\Отладка\pc_uart_BOOT.o .ARM\CortexDeb34\ \pc_uart_IntClock.o .\CortexM3\ARM_GCC_541\Debug\isr_pc_uart.o .\CortexM3\ARM_GCC_541\Debug\Pin_adc_input.o .\CortexM3\ARM_GCC_541\Debug\MISO.o .\CortexM3\ARM_GCC_541\Debug\MOSI.o CortexM3\ARM_GCC_541\Отладка\SCLK.o .\CortexM3\ARM_GCC_541\Отладка\pot_adc_sar.o .\CortexM3\ARM_GCC_541\Отладка\pot_adc_sar_INT.o .\CortexM3\ARM_GCC_541\Отладка\pot_adc_sar_PM.o .\\CortexDecc_1\ ui_spi.o .\CortexM3\ARM_GCC_541\Отладка\ui_spi_PM.o .\CortexM3\ARM_GCC_541\Отладка\ui_spi _INT.o .\CortexM3\ARM_GCC_541\Отладка\pot_adc_sar_IRQ.o .\CortexM3\ARM_GCC_541\Отладка\pot_adc_sar_theACLK.o .\CortexM3\ARM_GCC_541\Debug\ui_spi_IntClock.o .\CortexM3\ARM_CortexMortex3p\541_Debug \ARM_GCC_541\Отладка\motor_pwm_PM.o .\CortexM3\ARM_GCC_541\Отладка\Clock.o .\CortexM3\ARM_GCC_541\Отладка\pin_pwm_x.o .\CortexM3\ARM_GCC_541\Отладка\pin_pwm_y.o .\CortexM3\4ARM_Debug5 .o .\CortexM3\ARM_GCC_541\Debug\pin_border.o .\CortexM3\ARM_GCC_541\Debug\isr_border.o .\CortexM3\ARM_GCC_541\Debug\pin_led.o .\CortexM3\ARM_GCC_541\Debug\isr_goal_left.o .\CortexM3 ARM_GCC_541\Отладка\pin_goal_right.o .\CortexM3\ARM_GCC_541\Отладка\pin_goal_left.o .\CortexM3\ARM_GCC_541\Отладка\isr_goal_right.o .\CortexM3\ARM_GCC_541\Отладка\isr_ui_spi.o .\CuxortexM3\51ARM_GCC o .\CortexM3\ARM_GCC_541\Debug\CyBootAsmGnu.o arm-none-eabi-ar.exe: создание .\CortexM3\ARM_GCC_541\Debug\Plotterkode.a arm-none-eabi-gcc.exe -Wl, --start- группа -o C:\Users\Vikto\Desktop\plottercode\Plotterkode.cydsn\Corte xM3\ARM_GCC_541\Отладка\Plotterkode.elf .\CortexM3\ARM_GCC_541\Отладка\main.o .\CortexM3\ARM_GCC_541\Отладка\cyfitter_cfg.o .\CortexM3\ARM_GCC_541\Отладка\cymetadata.o .\CortexM3\ARM_DeGCC_541 Cm3Start.o .\CortexM3\ARM_GCC_541\Debug\Plotterkode.a "C:\Program Files (x86)\Cypress\PSoC Creator\4. 2\PSoC Creator\psoc\content\cycomponentlibrary\CyComponentLibrary.cylib\CortexM3\ARM_GCC_541\Debug\CyComponentLibrary.a" -mcpu=cortex-m3 -mthumb -L Generated_Source\PSoC5 -Wl,-Map,.\CortexM3\ARM_GCC_541\ Debug/Plotterkode.map -T Generated_Source\PSoC5\cm3gcc.ld -specs=nano.specs -u _printf_float -Wl, --gc-sections -u_printf_float -g -ffunction-sections -Og -ffat-lto-objects -Wl, --end-group .\CortexM3\ARM_GCC_541\Debug\main.o: в функции _7_exp' collect2.exe: ошибка: ld вернул 1 статус выхода Команда "arm-none-eabi-gcc.exe" не удалась с кодом выхода ' 1' --------------- Ошибка сборки: 28.04.2020 01:34:42 ---------------   -  person user2864740    schedule 28.04.2020


Ответы (1)


Это работает в том случае, когда вы передаете ему литерал (или значение, которое компилятор может вывести), потому что компилятор вычисляет значение и помещает его в код.

https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

Я считаю, что exp () включен в «libm», поэтому добавление -Wl,-lm (или как-то еще вы указываете libm в своей системе сборки) должно это исправить.

И если он уже есть, попробуйте поместить его в конец списка.

Как [s] устанавливается в непеременную? В любом случае, -Wl,-lm может быть лучше, чем что-то вроде _2_ (где _3_ было ранее присвоено подходящее значение).

person Russ Schultz    schedule 28.04.2020