[uquote="Мурик",url="/forum/viewtopic.php?p=3497552#p3497552"]Сможете легко перенести программу скажем с PIC16 на STM32? [/uquote]
Ну я могу представить себе что вон тот Гёрцель писаный под AVR с гитхаба и на STM32 взлетит без особых изменений. Единственное что там придется поменять - как/откуда он сэмплы берет. Однако ж сам Гёрцель останется тем же самым. Правда в конкретно с тем кодом так делать не рекомендуется, автор очень в духе гитхаба лицензию указать вообще забыл и формально любой кто так сделает - как бы пират.
[uquote="YS",url="/forum/viewtopic.php?p=3498706#p3498706"]Ну, человек просил пример кода под ARM с целочисленной арифметикой - вот, ровно оно. Код будет выполняться и на M3, они совместимы.[/uquote]
Пример кода чего он просил? Видимо БПФ. А там что? Где там БПФ?
К тому же он просил для Cortex-M0, а не для ARM7.
[uquote="YS",url="/forum/viewtopic.php?p=3498706#p3498706"]А так по FFT много хороших публикаций есть.[/uquote]
Вот и почитайте хотя-бы сами, чтобы знать что такое БПФ.
И гуглом думаю все умеют пользоваться.....
[uquote="YS",url="/forum/viewtopic.php?p=3498839#p3498839"]А там - пример реализации ядра БПФ, элемента вычисления под названием "бабочка". Это, собственно, самый интересный этап БПФ.[/uquote]
Ну так это - малая часть. Да и не особо оптимально написанная. А всё остальное, как пишет автор - на си.
Если хочется ассемблера, можно взять любой пример на си, скомпилить его для нужного ядра с максимальной оптимизацией, взять листинг и дальше допиливать оптимизировать его вручную.
Хехе, вот теперь я посоветую вам почитать хотя бы тот труд, ссылку на который я приводил. Производительность БПФ в основном определяется как раз реализацией "бабочки". Это основная часть.
можно взять любой пример на си, скомпилить его для нужного ядра с максимальной оптимизацией, взять листинг и дальше допиливать оптимизировать его вручную.
Ну удачи, удачи...
Разница между теорией и практикой на практике гораздо больше, чем в теории.
И вот интересно - среди кидания ссылок, требований подтянуть матчасть, обвинений друг друга в некомпетентности и других забавных проявлений человеческих недостатков кто-нибудь осмелится представить кусок кода на Си, т.е. подпрограммку, которая будет рассчитывать ДПФ целочисленного массива 12-битных данных, длинной хотя бы в 128 отсчётов.
Это не претензия.
Просто много говорится о ДПФ, обсуждаются возможности оптимизации, целочисленной реализации, бит-реверсной адресации какой-то абстрактной химеры, которой по-факту еще и нет.
Вот я, много ненужных сообщений назад, представил код, в котором есть такая подпрограммка - DFT.
Может попробует её совершенствовать, а не болтать без дела. Авось кому-нибудь и поможем.
Код компьютерный, писался для научных целей, но возможностей для оптимизации - вагон. Да еще и основная идея явно проглядывается.
Заодно посмотрим, кто в языке Си и ДПФ разбирается.
Ваши предложения, коллеги! Спойлерint DFT(FILE *SOURSE, FILE *SPECTR)
{
long k;
long n;
short temp;
double WN;
double wk;
double c;
double s;
double *XR;
double *XI;
COMPLEX *x;
x = (COMPLEX*)malloc(BUFFER*sizeof(COMPLEX));
XR = (double*)malloc(BUFFER*sizeof(double));
XI = (double*)malloc(BUFFER*sizeof(double));
[uquote="Repytw",url="/forum/viewtopic.php?p=3500490#p3500490"]Код компьютерный, писался для научных целей, но возможностей для оптимизации - вагон.[/uquote]Если мне не изменяет память, одна из классический лаб по матану на 2-м курсе это запрограммировать ДПФ и БПФ, измерить разницу в скорости вычисления. Всё уже изобретено до нас.
Если эта тема еще кому-то интересна.
Пример реализации 128-точечного ДПФ для 12-битных данных (по задумке от АЦП). Без float и double.
Пример опять-таки для ПК, но перенести его для приложений на ARM не составляет проблемы. Спойлер#include <stdio.h>
#define BUFFER 128 /*ДЛИНА БУФЕРА ДАННЫХ*/
int XR[BUFFER]; /*МАССИВ РЕЗУЛЬТАТОВ ДЕЙСТВИТЕЛЬНЫХ СОСТАВЛЯЮЩИХ ДПФ*/
int XI[BUFFER]; /*МАССИВ РЕЗУЛЬТАТОВ КОМПЛЕКСНЫХ СОСТАВЛЯЮЩИХ ДПФ*/
int RESULT[BUFFER]; /*МАССИВ РЕЗУЛЬТАТОВ ОПРЕДЕЛЕНИЯ АМПЛИТУДНОГО СПЕКТРА*/
/***********ПОДПРОГРАММА РАСЧЕТА ДПФ**************/
/*АРГУМЕНТЫ: 1 - указатель на массив входных данных
2 - указатель на массив результатов расчёта*/
void DFT(int *INPUT, int *OUTPUT)
{
/*****ОБЪЯВЛЯЕМ КУЧКУ НУЖНЫХ ПЕРЕМЕННЫХ*****/
short n;
short k;
short temp;
signed int c;
signed int s;
/*****ВНЕШНИЙ ЦИКЛ ВЫЧИСЛЕНИЙ**************/
for(k=0; k<BUFFER/2; ++k)
{
XR[k] = 0;
XI[k] = 0;
for(n = 0; n<BUFFER; ++n)
{
temp = n*k;
temp %= BUFFER;
c = COS[temp];
s = SIN[temp];
XR[k] += INPUT[n]*c;
XI[k] -= INPUT[n]*s;
}
/*ОПРЕДЕЛЯЕМ ДИСКРЕТНЫЙ СПЕКТР АМПЛИТУД ИССЛЕДУЕМОГО СИГНАЛА*/
XR[k] >>= 16;
XI[k] >>= 16;
OUTPUT[k] = XR[k]*XR[k] + XI[k]*XI[k];
/*ЗДЕСЬ БЫ ПО УМУ КОРЕНЬ OUTPUT ПОСЧИТАТЬ, ТОЛЬКО ЭТО МНЕ НЕ
ПОД СИЛУ БЕЗ ЗНАЧИТЕЛЬНЫХ ЗАТРАТ РЕСУРСОВ */
}
}
/*************КОНЕЦ ПОДПРОГРАММЫ РАСЧЁТА ДПФ***************/
Эээ, весь вопрос в этой теме (как я его понимаю) - в эффективной реализации быстрого преобразования Фурье.
Алгоритм обычного дискретного преобразования Фурье элементарен, там и понимать особо нечего - это просто расчет скалярных произведений входного сигнала на набор опорных частот, для каждой в двух вариантах, сдвинутых на 90° (синус и косинус, чтобы знать фазу).
Фактически это набор проекций сигнала на оси в некотором пространстве, ортами которого выступают ортогональные функции. Точно так же можно раскладывать хоть по функциям Уолша. Внезапно, из прямоугольников можно синтезировать синус!
Так что с обычным ДПФ все просто. А вот как реализуются ускоренные алгоритмы - это неочевидно и предмет для дискуссий.
Разница между теорией и практикой на практике гораздо больше, чем в теории.