Подскажите, пожалуйста, как включить сабж в кейле? Пробовал так [R0] и так @R0, не катит. На сайте кейла по запросам addressing modes и indirect addressing ничего толкового.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Чтоб не создавать ещё тему, спрошу здесь. Нижеприведённый код описывает перемножение с накоплением массива с замерами сигнала по массивам синусов и косинусов, затем вычисляется значение амплитуды.
Получается что-то вроде БПФ с фильтрацией. Впрочем, теория не важна. Запинка случилась там, где в коде вопросительные знаки. Дело в том, что по инструкции SMLAL заполняются два регистра ядра - старшее и младшее слово. По VMOV окончательные суммы передаются в FPU. Далее нужно взять квадраты этих чисел, сложить и взять из них корень. Однако команды FPU работают только с одиночными регистрами, а суммы, с которыми требуется проводить операции, лежат в двух каждая. Есть какой-нибудь способ обойти это в асме, или придётся вылезать в С? Судя по осциллографу, получается приличная экономия: 40 мкс в чистом асме против 100 для того же алгоритма в С (хотя кто знает, может с костылями то же получится?).
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Мне не совсем понятен код. Сначала ты выполняешь целочисленное умножение 32х32=64. А потом кладешь целочисленный же результат в регистр FPU. Если я не ошибаюсь, то VMOV просто копирует данные, она не переведет целочисленное значение в формат IEEE754. Это твоего вопроса не касается, просто непонятка.
Ну а что касается вопроса - я вижу несколько вариантов. Первое - оставить все как есть и использовать программную конвертацию int64 во float. Не знаю, есть ли такая функция в компиляторе или нет. Естесственно о скорости можно забыть. Хотя... Надо эксперементировать. Второе - если твои операнды в сумме (я про длину) меньше 64 бит, то можно использовать не 32х32=64, а 32х32=32 умножение. Результат, опять же, придется переводить во float. Но здесь уже легче, ибо компилятор стопроцентно поддерживает такое преобразование, а самое главное, что есть аппаратная инструкция конвертации VCVT (почитай про нее в даташите).
Однако команды FPU работают только с одиночными регистрами, а суммы, с которыми требуется проводить операции, лежат в двух каждая.
... сам то понял, что написал? FPU работает через стек. Чтобы избежать ненужных вопросов посоветую старую книжку - "Архитектура и программирование арифметического сопроцессора" Григорьев В.Л. Хотя там описан i8087, но принцип тот же.
сам то понял, что написал? FPU работает через стек.
Ну так-то он все правильно сказал. В Cortex-M4 есть регистры R0...Rn, которые могут быть операндами целочисленных инструкций, и регистры S0...Sn, которые могут быть операндами FPU инструкций. Причем здесь стек мне не совсем понятно.
.....Однако команды FPU работают только с одиночными регистрами, а суммы, с которыми требуется проводить операции, лежат в двух каждая. Есть какой-нибудь способ обойти это в асме, или придётся вылезать в С?
... речь шла о VPUSH,VPOP ....может не совсем понятно выразился - пардон.
Всем спасибо. Действительно, VMOV просто копирует данные, в итоге получается фигня. Процедуру разделил вылазкой в С, т.е. из кода вызывается сначала MAC, потом операции с корнем. Зато передаётся всё как нужно.
Позже оказалось, что суперская точность тут не нужна (код по работе, проталкиваю STM32 как более современный), и результат MAC можно сдвинуть вправо, оставив только старшие разряды в одном 32-битном регистре. SMLAL остаётся на месте, просто потом производятся манипуляции с двумя регистрами результата.
Итого: +4 мкс из-за лишних телодвижений, и всё равно STM уделывает XC166) У обоих время преобразования в районе 80-90 мкс (на два канала), при том, что стм обрабатывает массив из 100 измерений по каналу, а с166 - из 39.
Как видно, сначала данные из регистров вытаскиваются в массив int, потом преобразуются и попадают в массив float. Казалось, почему бы передачу типа не сделать в вызове процедуры Ampl, да и вообще, обойтись без массивов? Однако компилятор ни то, ни другое не проглатывает (w1 не изменяется вообще), а вот как приведено - работает. В чём тут может быть дело? К слову, если сделать не массив f1, а две переменные int, то даже из регистров данные не вытаскиваются.
К сожалению, у меня нет под рукой компилятора, чтобы посмотреть в чем проблема. Но какая-то она странная, ведь так не должно быть. Посмотри что за ассемблер он генерирует из твоей Си-вставки. И может быть вообще ее убрать? Я же нашел ассемблерную инструкцию конвертации во float, чего ее не использовать?
То компилятор должен давать предупреждение - отсутствие предварительной декларации функции Ampl. Без этого компилятор не знает, какие типы аргументов у функции и предполагает, что Вы подсовываете правильные типы. Необходимо сделать h файл в который поместить декларацию. float Ampl(float, float); Включить этот h айл в c файл. После этого преобразования типов должны выполняться компилятором неявно. И вообще выносить декларации в h файлы - это правильный стиль. Когда нибудь это спасет Вас от поиска непонятного поведения в течение нескольких дней.
И вообще выносить декларации в h файлы - это правильный стиль. Когда нибудь это спасет Вас от поиска непонятного поведения в течение нескольких дней.
Это точно. Я как-то раз два дня подряд мучался. Оказывается не включил H-файл. Главное компилятор, зараза, не сказал ни слова, обычно то они предупреждают о таком, дескать "Function declared implicitly".
Переменная w1 в дебаге не меняет значения, с которым была инициализирована. Я было подумал, что компилятор понимает, что раз я кручусь в бесконечном цикле, и далее нигде переменную не вызываю, то и обрабатывать её не стоит. Видоизменил код, чтоб цикл выполнялся конечное число раз, а w1 дальше вызывалась. Но ничего не изменилось. Если же я вызываю функцию до цикла, в самом main, то w1 изменяется. Что тут не так? Кроме того, изменяя код функции, при работе цикла я вижу изменение по времени, т.е. код-то вроде как работает. Почему тогда w1 не меняется? Или это дебагер гадит и не показывает?
P.S. Проверил диодом:
Код:
if (w1>(float)100500) STM_EVAL_LEDOn(LED5);
Похоже, всё-таки дебагер. Досадно. Ну хоть переменная меняется на самом деле.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения