Быстрое преобразование Фурье на Си
- KT315B
- Сверлит текстолит когтями
- Сообщения: 1269
- Зарегистрирован: Пт июл 21, 2006 15:05:19
- Откуда: плод воображения
- Контактная информация:
Быстрое преобразование Фурье на Си
Всем привет! Есть низкочастотный сигнал - усиленный и отфильтрованный (полосовой фильтр 3Гц, усиление 60дБ) с датчика фотоплетизмографа (оптический датчик пульса человека). Есть задача этот пульс измерять. Выделение пиков и измерение интервалов между ними я уже реализовал. Так же хочу попробовать применить здесь БПФ для выделения основной частоты (пульса) из сигнала. Требований к лютому быстродействию нет. Посоветуйте как написать сие на Си или ткните носом в пример, где можно с этим всем ознакомиться. Выполнятся все будет на Cortex-M0 64МГц. Спасибо! )
R2AIV 73!
- Реклама
Re: Быстрое преобразование Фурье на Си
Книга Айфинчера Цифровая обработка сигналов - практический подход. Страница 195 - можно взять за пример.
Добавлено after 2 minutes 29 seconds:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <dos.h>
#include <time.h>
#include <direct.h>
#define BUFFER 32768
#define PI 3.141592654
int DFT(FILE *SOURSE, FILE *SPECTR);
time_t t;
struct tm* ATM;
typedef struct {
double real;
double imag;
double modulus;
double angle;
} COMPLEX;
int main(void)
{
FILE *SOURSE;
FILE *DESTINATION;
char TEMP_STR[255];
char NAME_INPUT_FILE[]="C:\\OST\\";
char NAME_OUTPUT_FILE[]="C:\\TEXT\\";
char END_INPUT_FILE[]=".bin";
char END_OUTPUT_FILE[]="_OSTSPR.dat";
char COUNT_STR[5];
short count=0;
short temp;
short *temp2=&temp;
int i,j, cykle;
t=time(NULL);
for(cykle=653;cykle<654;cykle++)
{
count = cykle;
/****Формирование имен файлов назначения************************/
itoa(count,COUNT_STR,10); //перевод целого числа в литерал
strcpy(TEMP_STR, NAME_INPUT_FILE);
strcat(TEMP_STR, COUNT_STR);
strcat(TEMP_STR,END_INPUT_FILE); //формирование адреса входного файла
time(&t);
ATM = localtime(&t);
printf("%s\t%d:%d:%d\n",TEMP_STR,ATM->tm_hour, ATM->tm_min, ATM->tm_sec);
/***********Открытие файла для чтения***************************/
if (fopen_s(&SOURSE,TEMP_STR, "rb"))
{
printf("Cannot open sourse file...\n");
_getch();
return 0;
}
strcpy(TEMP_STR, NAME_OUTPUT_FILE);
strcat(TEMP_STR, COUNT_STR); //формирование имени выходного файла
strcat(TEMP_STR, END_OUTPUT_FILE);
if (fopen_s(&DESTINATION,TEMP_STR, "w"))
{
printf("Cannot open destination file...\n");
_getch();
return 0;
}
rewind(SOURSE);
DFT(SOURSE, DESTINATION);
fclose(DESTINATION);
fclose(SOURSE);
}
_getch();
return 0;
}
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));
rewind(SOURSE);
for(k=0; k<BUFFER;k++)
{
fread(&temp, 2 , 1 ,SOURSE);
x[k].real = (double)1.0*temp;
x[k].imag = 0;
}
WN = 2*PI/BUFFER;
for(k=0;k<BUFFER;++k)
{
XR[k]=0.0;
XI[k]=0.0;
wk = k*WN;
for(n=0;n<BUFFER;++n)
{
c = cos((double)n*wk);
s = sin((double)n*wk);
XR[k]=XR[k]+x[n].real*c+x[n].imag*s;
XI[k]=XI[k]-x[n].real*s+x[n].imag*c;
if(n==(BUFFER-10))
temp =0;
}
}
for(k=0;k<BUFFER;++k)
{
x[k].real=XR[k];
x[k].imag=XI[k];
x[k].modulus =sqrt(x[k].real*x[k].real+x[k].imag*x[k].imag);
x[k].angle = atan(x[k].imag/x[k].real);
}
for(k=0;k<BUFFER/2;k++)
{
fprintf(SPECTR, "%d\t%f\n", k, x[k].modulus/BUFFER);
}
free(x);
free(XR);
free(XI);
}
Добавлено after 2 minutes 29 seconds:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <dos.h>
#include <time.h>
#include <direct.h>
#define BUFFER 32768
#define PI 3.141592654
int DFT(FILE *SOURSE, FILE *SPECTR);
time_t t;
struct tm* ATM;
typedef struct {
double real;
double imag;
double modulus;
double angle;
} COMPLEX;
int main(void)
{
FILE *SOURSE;
FILE *DESTINATION;
char TEMP_STR[255];
char NAME_INPUT_FILE[]="C:\\OST\\";
char NAME_OUTPUT_FILE[]="C:\\TEXT\\";
char END_INPUT_FILE[]=".bin";
char END_OUTPUT_FILE[]="_OSTSPR.dat";
char COUNT_STR[5];
short count=0;
short temp;
short *temp2=&temp;
int i,j, cykle;
t=time(NULL);
for(cykle=653;cykle<654;cykle++)
{
count = cykle;
/****Формирование имен файлов назначения************************/
itoa(count,COUNT_STR,10); //перевод целого числа в литерал
strcpy(TEMP_STR, NAME_INPUT_FILE);
strcat(TEMP_STR, COUNT_STR);
strcat(TEMP_STR,END_INPUT_FILE); //формирование адреса входного файла
time(&t);
ATM = localtime(&t);
printf("%s\t%d:%d:%d\n",TEMP_STR,ATM->tm_hour, ATM->tm_min, ATM->tm_sec);
/***********Открытие файла для чтения***************************/
if (fopen_s(&SOURSE,TEMP_STR, "rb"))
{
printf("Cannot open sourse file...\n");
_getch();
return 0;
}
strcpy(TEMP_STR, NAME_OUTPUT_FILE);
strcat(TEMP_STR, COUNT_STR); //формирование имени выходного файла
strcat(TEMP_STR, END_OUTPUT_FILE);
if (fopen_s(&DESTINATION,TEMP_STR, "w"))
{
printf("Cannot open destination file...\n");
_getch();
return 0;
}
rewind(SOURSE);
DFT(SOURSE, DESTINATION);
fclose(DESTINATION);
fclose(SOURSE);
}
_getch();
return 0;
}
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));
rewind(SOURSE);
for(k=0; k<BUFFER;k++)
{
fread(&temp, 2 , 1 ,SOURSE);
x[k].real = (double)1.0*temp;
x[k].imag = 0;
}
WN = 2*PI/BUFFER;
for(k=0;k<BUFFER;++k)
{
XR[k]=0.0;
XI[k]=0.0;
wk = k*WN;
for(n=0;n<BUFFER;++n)
{
c = cos((double)n*wk);
s = sin((double)n*wk);
XR[k]=XR[k]+x[n].real*c+x[n].imag*s;
XI[k]=XI[k]-x[n].real*s+x[n].imag*c;
if(n==(BUFFER-10))
temp =0;
}
}
for(k=0;k<BUFFER;++k)
{
x[k].real=XR[k];
x[k].imag=XI[k];
x[k].modulus =sqrt(x[k].real*x[k].real+x[k].imag*x[k].imag);
x[k].angle = atan(x[k].imag/x[k].real);
}
for(k=0;k<BUFFER/2;k++)
{
fprintf(SPECTR, "%d\t%f\n", k, x[k].modulus/BUFFER);
}
free(x);
free(XR);
free(XI);
}
Re: Быстрое преобразование Фурье на Си
Гуглить CMSIS DSP lib
Там как раз и фурье преобразования есть, при этом заточенный под АРМ, с учетом особенности реализации ядра ( в коде видны дириктивы условной компиляции).
Есть некторые особенности при использовании "длинного" фурье и использования внешенй памяти, но до 8000 точек все и так работает прекрасно.
Там как раз и фурье преобразования есть, при этом заточенный под АРМ, с учетом особенности реализации ядра ( в коде видны дириктивы условной компиляции).
Есть некторые особенности при использовании "длинного" фурье и использования внешенй памяти, но до 8000 точек все и так работает прекрасно.
- KT315B
- Сверлит текстолит когтями
- Сообщения: 1269
- Зарегистрирован: Пт июл 21, 2006 15:05:19
- Откуда: плод воображения
- Контактная информация:
Re: Быстрое преобразование Фурье на Си
Проблема была решена как раз CMSIS DSP, спасибо всем ответившим. Айфинчера в закладки!
R2AIV 73!
- Реклама
Re: Быстрое преобразование Фурье на Си
А это вообще нормально - когда человек спрашивает про cortex M0 - вываливать ему писючные реализации, которые требуют всего ничего - double?! С которым на M0 не богато. У него FPU нет! А бывает что-нибудь такое integer-only и под не сильно жадной лицензией? (cmsis мне ни к чему, спасибо). Было бы интересно посмотреть какой-нибудь доходчивый пример как это делать нормально, в integer only. Делал же народ раньше АОНы, на Z80 аж?! Без всяких гребаных даблов и <math.h> с полновесной реализацией синуса да еще на убогом 8-битнике. Или это искусство утрачено?
Re: Быстрое преобразование Фурье на Си
Это искусство не утрачено. В тех АОНах применяли алгоритм Гёрцеля. Да, это фактически усеченное преобразование Фурье в виде рекурсивного фильтра. Однако оно не позволяет построить спектр сигнала - только обнаружить известные гармоники (понять, есть или нет заданная гармоника в спектре, и, если есть, какая у нее относительная энергия). Для АОНа (декодирование DTMF) это самое то. Но собственно преобразование Фурье не заменит.Или это искусство утрачено?
Чем не устраивает CMSIS? Или вы путаете ее с StdPeriphLib/STM32Cube?
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Re: Быстрое преобразование Фурье на Си
[uquote="YS",url="/forum/viewtopic.php?p=3491998#p3491998"]
А, вот оно что! А есть на примете аккуратный маленький сишный код показывающий как это делать, простой для понимания? А так я готов поклясться что где-то мне и целочисленное преобразование фурье попадалось. Но тогда оно мне было совсем ни к чему т.к. я от всего этого был далек. А тут занес меня черт в STM32, у него ADC есть, так уже несколько интереснее, однако.
Это искусство не утрачено. В тех АОНах применяли алгоритм Гёрцеля. Да, это фактически усеченное преобразование Фурье в виде рекурсивного фильтра. Однако оно не позволяет построить спектр сигнала - только обнаружить известные гармоники (понять, есть или нет заданная гармоника в спектре, и, если есть, какая у нее относительная энергия). Для АОНа (декодирование DTMF) это самое то. Но собственно преобразование Фурье не заменит.[/uquote]Или это искусство утрачено?
А, вот оно что! А есть на примете аккуратный маленький сишный код показывающий как это делать, простой для понимания? А так я готов поклясться что где-то мне и целочисленное преобразование фурье попадалось. Но тогда оно мне было совсем ни к чему т.к. я от всего этого был далек. А тут занес меня черт в STM32, у него ADC есть, так уже несколько интереснее, однако.
Например, мутной лицензией по которой это можно использовать только с STM32 (в случае STM32), так что если вдруг захочется МК сменить - ой! Есть какая-то открытая реализация, но чудесатая и требующая для сборки аж питон. Ну и просто жуткая огроменная либа, я не фанат такого. В общем нафиг такое счастье - меня интересует core алгоритма, а не обвязка под конкретную платформу, ее я и сам сделаю как мне там удобнее. А вот на математику под мелкие ресурсы всегда интересно посмотреть.Чем не устраивает CMSIS? Или вы путаете ее с StdPeriphLib/STM32Cube?
Re: Быстрое преобразование Фурье на Си
И все таки путаете теплое с мягким...
Re: Быстрое преобразование Фурье на Си
Т.е. Вы возмущены тем, что я представил пример кода с реализацией ДПФ, в котором всё достаточно просто и понятно для анализа и переработки, не для ВАШИХ НУЖД И ТРЕБОВАНИЙ (integer only), а для требований совершенно иного человека, который назвал тему "Быстрое преобразование Фурье на Си"?linuxdude писал(а):А это вообще нормально - когда человек спрашивает про cortex M0 - вываливать ему писючные реализации, которые требуют всего ничего - double?! С которым на M0 не богато. У него FPU нет! А бывает что-нибудь такое integer-only и под не сильно жадной лицензией? (cmsis мне ни к чему, спасибо). Было бы интересно посмотреть какой-нибудь доходчивый пример как это делать нормально, в integer only. Делал же народ раньше АОНы, на Z80 аж?! Без всяких гребаных даблов и <math.h> с полновесной реализацией синуса да еще на убогом 8-битнике. Или это искусство утрачено?
Я правильно понимаю?
Ну, извините.
Re: Быстрое преобразование Фурье на Си
Не столько возмущен, сколько сильно удивлен, чтоли. Потому что в описании было сказано "Cortex M0", у которого FPU нет и поэтому алгоритму с даблами там нечего ловить в чистом виде, так что почитав описание я ожидал увидеть все-таки что-то более похожее на код который M0 запустить потом сможет, чтоли. Перетаскивание алгоритма с даблов на целочисленные операции - возможно кто-то и делает для таких алгоритмов одной левой, конечно. Но говоря за себя я бы предпочел увидеть пример в целых числах. Попробовал поискать по гитхабу, но там тоже как назло даблы попадаются. И предлагавший погуглить - тоже ссылки дал на алгоритмы с даблами. Ну вот я забодался и откоментил. Извините, если получилось слишком агрессивно.
Re: Быстрое преобразование Фурье на Си
Кода там на пять строчек. Тут понятно объяснено и разжевано, как и что делать.А есть на примете аккуратный маленький сишный код показывающий как это делать, простой для понимания?
https://www.embedded.com/design/configu ... -Algorithm
https://www.st.com/content/ccc/resource ... 446805.pdf
Но имейте в виду, алгоритм Гёрцеля хорош только тогда, когда надо узнать относительные амплитуды отдельных известных гармоник. Для построения спектра он менее эффективен, чем БПФ.
Таки да, вы все путаете.Например, мутной лицензией по которой это можно использовать только с STM32 (в случае STM32), так что если вдруг захочется МК сменить - ой!
1. CMSIS разрабатывается по благословению компании ARM Inc, разрабочика ядра. Оно конечно может быть и запрещается лицензией использовать реализации CMSIS для других контроллеров - но это и не имеет смысла, потому что CMSIS заточена именно под ARM Cortex (не под STM32, а именно под ядро!).
Вы знаете, как расшифровывается CMSIS? Cortex Microcontroller Interface Standard.
CMSIS будет работать на любых контроллерах с ядром ARM Cortex - и от ST, и от других производителей.
Это отличный вариант, потому что она будет использовать все возможности ускорения, специфичные для этого ядра.
2. StdPeriphLib и Cube - вот эти да, заточены именно под конкретную реализацию системы на ядре ARM Cortex в виде STM32. Да, их я сам не использую, потому что они не дают преимуществ, но привязывают к одной реализации.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Re: Быстрое преобразование Фурье на Си
Работа с регистрами периферии не привязывает?YS писал(а):StdPeriphLib и Cube - вот эти да, заточены именно под конкретную реализацию системы на ядре ARM Cortex в виде STM32. Да, их я сам не использую, потому что они не дают преимуществ, но привязывают к одной реализации.
- SIM31
- Это не хвост, это антенна
- Сообщения: 1363
- Зарегистрирован: Чт апр 04, 2013 22:22:57
- Откуда: Белгород, РФ
Re: Быстрое преобразование Фурье на Си
[uquote="linuxdude",url="/forum/viewtopic.php?p=3497249#p3497249"]Не столько возмущен, сколько сильно удивлен, чтоли. Потому что в описании было сказано "Cortex M0", у которого FPU нет и поэтому алгоритму с даблами там нечего ловить в чистом виде[/uquote]
Речь о частотах около 1 Гц? Быстродействие там вообще не нужно. Справятся и 8-битные МК. Ну будет не 20 тактов вычисление, а 2000 и что?
Речь о частотах около 1 Гц? Быстродействие там вообще не нужно. Справятся и 8-битные МК. Ну будет не 20 тактов вычисление, а 2000 и что?
Re: Быстрое преобразование Фурье на Си
[uquote="YS",url="/forum/viewtopic.php?p=3497284#p3497284"]Кода там на пять строчек. Тут понятно объяснено и разжевано, как и что делать.[/uquote] О да, вижу. По такому объяснению даже относительно понятно как это в целых числах сделать, я так понимаю что надо сделать нечто типа умножения на сколько-то, чтобы оперировать потом целыми числами - получится загрубленный вариант плавучки умноженный на что-то, но ничего принципиально не поменяется.
Во вторых, мне совершенно не импонирует сильно завязываться на конкретное процессорное ядро. На мой вкус, половина смысла си - все-же в портабельности кода. Я конечно понимаю что фирме ARM очень не хотелось бы чтобы я соскочил с их ядер, а конкретному STMicro не хотелось бы чтобы я использовал к тому же чьи-то еще чипы, но куда они по моему мнению могут пойти с такими пожеланиями - я думаю некоторые уже догадались.
В третьих, чисто по человечески у меня к фирме ARM очень отдельные счеты за Mali GPU, так что по мере того как новоиспеченные стартапы наклепают чего-то типа RISC-V...
В четвертых, по жизни мне нравится аккуратный, маленький, простой в восприятии код. CMSIS на это ни разу не похож. Мне от STM32 нужна маленькая предсказуемая понятная штука
Надеюсь, это расставляет точки над i и мне больше не придется объяснять это. Мне в рамках топика интересны все же алгоритмы, а не поучения как правильно кодить под STMы по чьему-то мнению. К даблам была лишь чисто техническая претензия - в том что даже если это получится завести, это жутко неэффективно на таком процессоре в таком виде.
upd: нашел целочисленного герцеля в результате - https://github.com/OmaymaS/DTMF-Detecti ... July2014.c
Я уж понял - там надо вычисления делать на каждую частоту которую пытаемся найти. И если хочется приличное разрешение в широком диапазоне... вычислений будет много. Однако для обнаружения DTMF/АОН/подобных это и правда выглядит неплохо. И да, я припоминаю bin'ы в чем-то типа АОНа, видимо я видел как раз это. Но в виде ассемблера в всю идею вычислений врубиться все же тяжело.Но имейте в виду, алгоритм Гёрцеля хорош только тогда, когда надо узнать относительные амплитуды отдельных известных гармоник. Для построения спектра он менее эффективен, чем БПФ.
Ну во первых, "стандарт" ничто без реализации. И под конкретный STM32 я бы не сказал что то что я видел вызвало мой восторг. Не нравится мне такое.1. CMSIS разрабатывается по благословению компании ARM Inc, разрабочика ядра. Оно конечно может быть и запрещается лицензией использовать реализации CMSIS для других контроллеров - но это и не имеет смысла, потому что CMSIS заточена именно под ARM Cortex (не под STM32, а именно под ядро!).
Во вторых, мне совершенно не импонирует сильно завязываться на конкретное процессорное ядро. На мой вкус, половина смысла си - все-же в портабельности кода. Я конечно понимаю что фирме ARM очень не хотелось бы чтобы я соскочил с их ядер, а конкретному STMicro не хотелось бы чтобы я использовал к тому же чьи-то еще чипы, но куда они по моему мнению могут пойти с такими пожеланиями - я думаю некоторые уже догадались.
В третьих, чисто по человечески у меня к фирме ARM очень отдельные счеты за Mali GPU, так что по мере того как новоиспеченные стартапы наклепают чего-то типа RISC-V...
В четвертых, по жизни мне нравится аккуратный, маленький, простой в восприятии код. CMSIS на это ни разу не похож. Мне от STM32 нужна маленькая предсказуемая понятная штука
И в гробу я видал удовольствие чтобы ARM навязывал мне какие либо "стандарты", если уж на то пошло.Вы знаете, как расшифровывается CMSIS? Cortex Microcontroller Interface Standard.
В конечном итоге я предпочту более generic код допускающий мысль что фирму ARM вместе с их ядрами можно послать куда подальше.Это отличный вариант, потому что она будет использовать все возможности ускорения, специфичные для этого ядра.
[/quote] Я знаю 2 реализации CMSIS под STM32. Одна запрещает мне менять поставщика, а ее лицензия в результате даже не OSI-compatible (то-есть допустим открытую прошивку, проходящую под определения OSI - релизнуть на этом невозможно в принципе). А вторая кривая и аж требует для сборки питон, что издевательство над здравым смыслом. Да, я осознаю что это некий tradeoff - но это мой вполне осознанный выбор, на который у меня есть некоторые причины. Часть из которых я озвучил, если уж вы настаиваете.2. StdPeriphLib и Cube - вот эти да, заточены именно под конкретную реализацию системы на ядре ARM Cortex в виде STM32. Да, их я сам не использую, потому что они не дают преимуществ, но привязывают к одной реализации.
Надеюсь, это расставляет точки над i и мне больше не придется объяснять это. Мне в рамках топика интересны все же алгоритмы, а не поучения как правильно кодить под STMы по чьему-то мнению. К даблам была лишь чисто техническая претензия - в том что даже если это получится завести, это жутко неэффективно на таком процессоре в таком виде.
А там вон по ссылочке дали пример который потенциально можно прямо в IRQ после получения сэмпла гонять. По своему интересно: так не надо здоровенный буфер под сэмплы, насколько я понимаю. В этом случае скорость - не пустой звук. Надолго вклиненое прерывание да еще с плавучкой - да чур меня, я потом в глаза не смогу смотреть тем кто на Z80 чудеса вытворял.Речь о частотах около 1 Гц? Быстродействие там вообще не нужно. Справятся и 8-битные МК. Ну будет не 20 тактов вычисление, а 2000 и что?
upd: нашел целочисленного герцеля в результате - https://github.com/OmaymaS/DTMF-Detecti ... July2014.c
Re: Быстрое преобразование Фурье на Си
Нет. Потому что парадигма доступа к регистрам одинакова на всех МК с одной архитектурой (в нашем случае Фон-Неймановской).Работа с регистрами периферии не привязывает?
Если что, я говорю не о заучивании регистров и битов в них (это вообще бессмысленно), а о самом подходе. Если человек учился работать с StdPeriphLib, то он может работать только с STM32, потому что этот API существует только под STM32. Ну, если только ЭТО никто не портирует на другие архитектуры, как портируют API Arduino.
С другой стороны, если человек представляет, как все работает на уровне регистров, то освоение нового чипа (от другого производителя, например) займет у него в районе недели (при наличии документации).
Есть два варианта. Первый - переписать формулу с использованием дробей и преобразовать ее к виду, удобному для вычислений. Второй - классическая фиксированная точка. Она действительно сводится к умножению на некоторое число и введению особых правил умножения и деления. Как правило число, на которое умножают, стараются делать степенью двойки, чтобы умножения и деления свелись к сдвигам. Соответственно, дробная часть получает вид m/(2^n).По такому объяснению даже относительно понятно как это в целых числах сделать, я так понимаю что надо сделать нечто типа умножения на сколько-то, чтобы оперировать потом целыми числами
Bin - это обозначение частотного отсчета. Оно применяется и для FFT.И да, я припоминаю bin'ы в чем-то типа АОНа, видимо я видел как раз это.
А алгоритм Гёрцеля, к слову, - реализация DFT для одного частотного отсчета в виде рекурсивного фильтра.
Вы опять путаете CMSIS и StdPeriphLib. Я призываю вас погуглить различия.Ну во первых, "стандарт" ничто без реализации. И под конкретный STM32 я бы не сказал что то что я видел вызвало мой восторг.
Тогда используйте KISS FFT. Не завязана ни на что, не использует неочевидных трюков.Во вторых, мне совершенно не импонирует сильно завязываться на конкретное процессорное ядро.
Тогда просто не используйте их ядро...И в гробу я видал удовольствие чтобы ARM навязывал мне какие либо "стандарты", если уж на то пошло.
Боюсь, вам придется погуглить, чтобы уяснить отличия StdPeriphLib и CMSIS.Надеюсь, это расставляет точки над i и мне больше не придется объяснять это.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Re: Быстрое преобразование Фурье на Си
[uquote="YS",url="/forum/viewtopic.php?p=3497428#p3497428"]Нет. Потому что парадигма доступа к регистрам одинакова на всех МК с одной архитектурой (в нашем случае Фон-Неймановской).
Если что, я говорю не о заучивании регистров и битов в них (это вообще бессмысленно), а о самом подходе. Если человек учился работать с StdPeriphLib, то он может работать только с STM32, потому что этот API существует только под STM32. Ну, если только ЭТО никто не портирует на другие архитектуры, как портируют API Arduino.
С другой стороны, если человек представляет, как все работает на уровне регистров, то освоение нового чипа (от другого производителя, например) займет у него в районе недели (при наличии документации).[/uquote]
Однозначно абсолютная истина.
После плодотворной работы на уровне регистров с stm32 , старт с другими арм микроконтроллерами занимает совсем немного времени.
NRF52, GD32, HС32, SYNWIT
Дольше всего пришлось с последними двумя, ибо здесь приходится переводить документацию с китайского.
А адептам облегчалок - все и вся всегда будет долго и трудно...
YS, бесполезно с красноглазым спорить, он на своей волне ...
Если что, я говорю не о заучивании регистров и битов в них (это вообще бессмысленно), а о самом подходе. Если человек учился работать с StdPeriphLib, то он может работать только с STM32, потому что этот API существует только под STM32. Ну, если только ЭТО никто не портирует на другие архитектуры, как портируют API Arduino.
С другой стороны, если человек представляет, как все работает на уровне регистров, то освоение нового чипа (от другого производителя, например) займет у него в районе недели (при наличии документации).[/uquote]
Однозначно абсолютная истина.
После плодотворной работы на уровне регистров с stm32 , старт с другими арм микроконтроллерами занимает совсем немного времени.
NRF52, GD32, HС32, SYNWIT
Дольше всего пришлось с последними двумя, ибо здесь приходится переводить документацию с китайского.
А адептам облегчалок - все и вся всегда будет долго и трудно...
YS, бесполезно с красноглазым спорить, он на своей волне ...
Re: Быстрое преобразование Фурье на Си
[uquote="YS",url="/forum/viewtopic.php?p=3497428#p3497428"]Нет. Потому что парадигма доступа к регистрам одинакова на всех МК с одной архитектурой (в нашем случае Фон-Неймановской)[/uquote] Для лично себя я решил что буду использовать относительно абстрактный подход. Грубо говоря, дергаем send_uart(), а как он для конкретной платформы реализован - второй вопрос. В регистры полезет он. Если caller'а перетащить даже на совсем другую железку, он ничего не заметит покуда там send_uart() реализован. Это наверное чем-то похоже на идею с cmsis, только в отличие от ARM цель обратная: не залипать сильно на 1 ядро и периферию, тогда как фирме ARM было бы удобно ровно наоборот. Зато так неудобно мне - залипание на такую фирму как ARM видится мне делом чреватым и неудобным, они конкретными примерами показали что при случае что-нибудь прищемят и больно. Я не хочу чтобы прихоти маркетингового отдела фирмы ARM могли меня ставить в позу.

Еще раз: если даже я захочу поюзать CMSIS - мне надо заинклюдить какую-то фактическую реализацию интерфейса и скомпилиться и слинковаться с этим. И вот в этом месте наступает задница. Потому что CMSIS от STM32 идет под несвободной лицензией (так что фирмварь в целом при всем желании не будет "open" - даже по довольно вольным определениям OSI), открытая реализация требует для сборки гребаный питон, а самому столько фигарить мне, скажем прямо, лень. Особенно с учетом лейтмотива "интерфейс к Cortex" когда я бы предпочел более нейтральный "интерфейс к микроконтроллерам". Жонглирование фактами нас ни к чему не приведет.
Я кстати очень неплохо представляю себе что есть Cortex M на уровне регистров. Без этого я не смог бы вообще не смог с их периферией поработатьС другой стороны, если человек представляет, как все работает на уровне регистров, то освоение нового чипа (от другого производителя, например) займет у него в районе недели (при наличии документации).
Ну я кажется такой трюк где-то и видел. И собственно когда мы говорим о проце без аппаратной плавучки, мне кажется логичным, чтобы пример алгоритма показывал бы как подобное делать, чтоли, а не втыкал пример из учебника, попутно навернув даблы. Почитать учебник можно и без радиокота, но сообразить как это потом в практическую реализацию трансформировать - может быть не очень просто.Есть два варианта. Первый - переписать формулу с использованием дробей и преобразовать ее к виду, удобному для вычислений. Второй - классическая фиксированная точка. Она действительно сводится к умножению на некоторое число и введению особых правил умножения и деления. Как правило число, на которое умножают, стараются делать степенью двойки, чтобы умножения и деления свелись к сдвигам. Соответственно, дробная часть получает вид m/(2^n).
Да я уж понял. И спектр с хорошим разрешением в широкой полосе так строить выглядит ресурсоемким начинанием. А вон та штука на гитхабе показала как герцеля сделать в виде, в котором его даже атмел прожует, целиком на целых числах, даже с готовым декодированием DTMF. Ну а кортекс прожует и подавно. И завязки на железку минимум - единственное отличие где, как и почему мы блок сэмплов надергали. В cortex его можно и DMA утащить с ADC. Это системоспецифично, но Гёрцель про это не узнает. И при переходе на другую железку достаточно будет переписать только тот кусок.А алгоритм Гёрцеля, к слову, - реализация DFT для одного частотного отсчета в виде рекурсивного фильтра.
Вы опять путаете CMSIS и StdPeriphLib. Я призываю вас погуглить различия.
Еще раз: если даже я захочу поюзать CMSIS - мне надо заинклюдить какую-то фактическую реализацию интерфейса и скомпилиться и слинковаться с этим. И вот в этом месте наступает задница. Потому что CMSIS от STM32 идет под несвободной лицензией (так что фирмварь в целом при всем желании не будет "open" - даже по довольно вольным определениям OSI), открытая реализация требует для сборки гребаный питон, а самому столько фигарить мне, скажем прямо, лень. Особенно с учетом лейтмотива "интерфейс к Cortex" когда я бы предпочел более нейтральный "интерфейс к микроконтроллерам". Жонглирование фактами нас ни к чему не приведет.
Во, это уже явно симпатичнее и показывает как делать ряд вещей в целых числах. Он правда уже на https://github.com/mborgerding/kissfft живет на самом деле. На самом деле мне пока и Герцеля хватит поразвлекаться, как мне кажется.Тогда используйте KISS FFT. Не завязана ни на что, не использует неочевидных трюков.
[/quote] С чего бы? Ядра у них достаточно неплохие, у чипов неплохое соотношение цена/качество и периферия. Это работает не так. Я не собираюсь вообше совсем грубо профакапить решение моих задач и пожеланий. Но - буду создавать запрос на конкурентов с более дружелюбной политикой фирмы. И по мере их вылезания - проголосую долларом за них. И вот в этот момент мне будет очень кстати если я смогу код перекинуть на другую платформу с минимумом возни. А при необходимости и денег в рамках краудфандинга тематическим стартапам подкину. Потому что политика фирмы ARM мне не нравится.Тогда просто не используйте их ядро...
А что - гуглить? Формальности это прекрасно. А когда вопрос в том что мы сегодня #include и линкуем - оно по факту на STM32 будет так как я сказал. А то что оно теоретически абстрактный интерфейс в вакууме - мне что, самому это выписывать? Оно мне не надо. И самозваные "стандарты" от таких фирм как ARM мне тоже не сильно нужны.Боюсь, вам придется погуглить, чтобы уяснить отличия StdPeriphLib и CMSIS.
Re: Быстрое преобразование Фурье на Си
В этом плане, да, только регистры и их биты разные.YS писал(а):Нет. Потому что парадигма доступа к регистрам одинакова на всех МК
Если нет, то это ничем не отличается от использования библиотек в плане переноса. С библиотеками даже проще.
Re: Быстрое преобразование Фурье на Си
Чтобы работать с периферией, не надо представлять себе как устроено ядро. Я, например, не стал разбираться, как устроен NVIC - когда надо, я вызываю функции CMSIS. NVIC_EnableIRQ(), например.Я кстати очень неплохо представляю себе что есть Cortex M на уровне регистров. Без этого я не смог бы вообще не смог с их периферией поработать
Ядро и периферия - разные вещи. Вы их стабильно путаете.
CMSIS будет работать на контроллерах разных производителей (с одним ядром) без изменений. Реализация CMSIS одна. Одни и те же файлы будут работать на STM32F100xx и на LPC1700. Фишка CMSIS именно в этом.Еще раз: если даже я захочу поюзать CMSIS - мне надо заинклюдить какую-то фактическую реализацию интерфейса и скомпилиться и слинковаться с этим.
А вот StdPeriphLib не будет работать.
CMSIS идет не от ST. CMSIS идет от ARM Inc.Потому что CMSIS от STM32 идет под несвободной лицензией (так что фирмварь в целом при всем желании не будет "open" - даже по довольно вольным определениям OSI), открытая реализация требует для сборки гребаный питон, а самому столько фигарить мне, скажем прямо, лень.
The Cortex Microcontroller Software Interface Standard (CMSIS) is a vendor-independent hardware abstraction layer for the Cortex®-M processor series and defines generic tool interfaces. The CMSIS enables consistent device support and simple software interfaces to the processor and the peripherals, simplifying software re-use, reducing the learning curve for microcontroller developers, and reducing the time to market for new devices.
- Introduction to CMSIS.
Что же до несвободности, то CMSIS поставляется под BSD-лицензией, и вообще она open source:
... This makes the whole mbed SDK completely open source with a mix of well known and understood permissive open source licenses: Apache and BSD.
- https://os.mbed.com/blog/entry/CMSIS-Co ... -Licensed/
Я погуглил за вас, не благодарите.
А что до отделения доступа к оборудованию от логики программы, так это вполне здраво.
Разница между теорией и практикой на практике гораздо больше, чем в теории.


