Dima1060 0 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Здравствуйте! Помогите разобраться с DSP на STM32F429. Никогда раньше этой темой не занимался, не понимаю в какую сторону начинать копать. Задача такая: мне нужно генерировать белый шум, фильтровать его разными фильтрами и выдавать на аудио ЦАП (48 кГц). Фильтры нужны режекторный второго порядка и полосовой, четвертого порядка, с БИХ. Фильтры я посчитал в матлабе, приготовился уже реализовывать в целочисленной арифметике. Но в этом процессоре есть блок вычислений с плавающей точкой. Я с этим никогда дела не имел. В референс мануале описание этого блока не нашел. Есть некая библиотека CMSIS DSP, в которой реализованы фильтры, но я так понял она мне не подойдет, поскольку там какая то странная структура реализованного IIR фильтра и работает он с какими то блоками данных. А мне надо просто сгенерировать Х, посчитать Y, запомнить Х-1 и Y-1 для следующего отчета. Скажите, какое преимущество мне даст работа с float и вообще, могу ли я так просто, без всяких библиотек взять и расписать свои фильтры во float? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Скажите, какое преимущество мне даст работа с float и вообще, Сам Матлаб может дать вам характеристики фильтра с учетом квантования. Целочисленная порой сильно уступает ПТ даже одинарной точности. могу ли я так просто, без всяких библиотек взять и расписать свои фильтры во float? Я вообще написал фильтр на asm //--------------------------------------------- // fpu_iir //--------------------------------------------- .thumb .thumb_func .global fpu_iir .type fpu_iir, %function fpu_iir: .cfi_startproc cbnz r1, fpu_iir_load bx lr fpu_iir_load: push {r0-r4, lr} VPUSH {s0-s7} // load f VLDR.F32 s1, [r3, #0] // G VLDR.F32 s2, [r3, #4] // a1 VLDR.F32 s3, [r3, #8] // a2 VLDR.F32 s4, [r3, #12] // b VLDR.F32 s5, [r3, #16] // tn-1 VLDR.F32 s6, [r3, #20] // tn-2 fpu_iir_loop: // load ldr r4, [r0], #4 // s0 <- x VMOV.F32 s0, r4 // calc tn VMUL.F32 s7, s1, s0 // G * x VFMS.F32 s7, s2, s5 // -a1 * tn-1 VFMS.F32 s7, s3, s6 // -a2 * tn-2 // calc y VADD.F32 s0, s7, s6 // tn-2 VFMA.F32 s0, s4, s5 // b * tn-1 // save t VMOV.F32 s6, s5 // tn-2 VMOV.F32 s5, s7 // tn-1 // y -> r0 VMOV.F32 r4, s0 // store str r4, [r2], #4 subs r1, #1 bne fpu_iir_loop VSTR.F32 s5, [r3, #16] // tn-1 VSTR.F32 s6, [r3, #20] // tn-2 VPOP {s0-s7} pop {r0-r4, pc} .size fpu_iir, .-fpu_iir .cfi_endproc Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Я вообще написал фильтр на asm На asm то понятно, компилятор никуда не денется. А на Си если писать, для операций с float надо что-то настраивать, подключать? Или просто задать коэффициенты float a,b; float x,y; и пошел их перемножать, складывать, вычитать, а компилятор сам подставит нужные команды, для работы с плавающей точкой? Под компилятором я подразумеваю Keil. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба А на Си если писать, для операций с float надо что-то настраивать, подключать? Ничего не надо настраивать, только ядро правильное указать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Ничего не надо настраивать, только ядро правильное указать. Да, я попробовал перемножить два int-a и два float-a, посмотрел дизассемблер, там отличие только в том, что в первом случае команда MULS, а во втором VMUL.F32 Судя из статьи, VMUL.F32 выполняется за 1 такт, как и обычное умножение. Круто! Тогда у меня еще один вопрос, на входе у меня генератор белого шума, который выдает int, а на выходе, для ЦАП мне надо 24-битное число. Как в первом случае быстро преобразовать int (сдвинутый на 6 разрядов, чтобы на входе тоже было 24 бита) во float, а во втором случае float в int? И я правильно понимаю, что используя float вместо int я нисколько не потеряю в скорости выполнения программы? Даже выиграю, с учетом того, что не надо будет масштабировать результат? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Как в первом случае быстро преобразовать int (сдвинутый на 6 разрядов, чтобы на входе тоже было 24 бита) во float, а во втором случае float в int? Поделить/перемножить с требуемым масштабным коэффициентом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Как в первом случае быстро преобразовать int (сдвинутый на 6 разрядов, чтобы на входе тоже было 24 бита) во float, а во втором случае float в int? Сдвиг на 6 разрядов можно заменить на умножение на константу 2^6. Эту константу можно внедрить в коэффициенты фильтра. Есть команды МК для преобразований int во float и обратно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Есть команды МК для преобразований int во float и обратно. какие? где можно про них подробней почитать? Сдвиг на 6 разрядов можно заменить на умножение на константу 2^6 То есть, сдвиг на 6 разрядов выполняется за 6 тактов, а умножение на константу - за один, хитро. Но деление на константу выполняется за 14 тактов Еще у меня в фильтре получается очень большое соотношение частоты дискретизации и частоты среза. Чтобы правильно посчитать фильтр надо иметь высокую точность. Как прикинуть, хватит ли мне float-а, зная порядок коэффициентов фильтра? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба какие? Еще у меня в фильтре получается очень большое соотношение частоты дискретизации и частоты среза. Чтобы правильно посчитать фильтр надо иметь высокую точность. Как прикинуть, хватит ли мне float-а, зная порядок коэффициентов фильтра? Насколько мой склероз помнит - тут нужно ресэмплинг делать и использовать CIC фильтры, длиннющие FIR/IIR в данном случае совсем не гуд. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Насколько мой склероз помнит - тут нужно ресэмплинг делать и использовать CIC фильтры, длиннющие FIR/IIR в данном случае совсем не гуд. Как это обойти - другой вопрос. В матлабе я рассчитал коэффициенты длиной 13 бит Quantized Numerator. Одновременно там рассчитываются некие идеальные коэффициенты Reference numerator, которые получаются длиннее. Так вот у меня вопрос, как прикинуть, нельзя ли эти Reference numerator записать в виде float, хватит ли точности float? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Так у флоат 23 бита мантиссы, как оно может быть менее точным, чем 13 бит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Так у флоат 24 бита мантиссы, как оно может быть менее точным, чем 13 бит? Чтобы оперировать 13-битными числами мне пришлось считать фильтр на пониженной частоте квантования, а потом ее повышать. А для float я хочу сразу делать фильтр на высокой частоте квантования. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Понятно. Математик из меня никакой, может просто промоделируете в Матлабе или SystemVue это? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Понятно. Математик из меня никакой, может просто промоделируете в Матлабе или SystemVue это? Я не знаю как заставить считать матлаб во float. Свои фильтры, целочисленные, я в маткад моделировал. Но там все понятно, раз коэффициенты 13 бит, такая точность и будет. А как там точность float задать я не знаю. Ну запишу я в свою модель идеальные коэффициенты из матлаба, он их посчитает как то, может с двойной точностью. А контроллер то будет с одинарной точностью считать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 25 августа, 2016 Опубликовано 25 августа, 2016 · Жалоба Не знаю что и сказать, SystemVue позволяет считать и флоат и дабл и фиксед с любой точностью коэфф. и кол-ва бит. Матлаб, уверен, тоже. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться