Кто любит RISC в жизни, заходим, не стесняемся.
Пт ноя 09, 2018 23:37:49
Если эта тема еще кому-то интересна.
Пример реализации 128-точечного ДПФ для 12-битных данных (по задумке от АЦП). Без float и double.
Пример опять-таки для ПК, но перенести его для приложений на ARM не составляет проблемы.
Спойлер
#include <stdio.h>
#define BUFFER 128 /*ДЛИНА БУФЕРА ДАННЫХ*/
int XR[BUFFER]; /*МАССИВ РЕЗУЛЬТАТОВ ДЕЙСТВИТЕЛЬНЫХ СОСТАВЛЯЮЩИХ ДПФ*/
int XI[BUFFER]; /*МАССИВ РЕЗУЛЬТАТОВ КОМПЛЕКСНЫХ СОСТАВЛЯЮЩИХ ДПФ*/
int RESULT[BUFFER]; /*МАССИВ РЕЗУЛЬТАТОВ ОПРЕДЕЛЕНИЯ АМПЛИТУДНОГО СПЕКТРА*/
/***МАССИВ 12-БИТНЫХ ВХОДНЫХ ДАННЫХ КОТОРЫЕ МЫ ЯКОБЫ ПОЛУЧАЕМ ОТ АЦП***/
int DATA[] = {
4096, 7502, 7880, 4895, 1200, 79, 2529, 6372,
8192, 6372, 2529, 79, 1200, 4895, 7880, 7502,
4096, 690, 312, 3297, 6992, 8113, 5664, 1820,
0, 1820, 5664, 8113, 6992, 3297, 312, 690,
4096, 7502, 7880, 4895, 1200, 79, 2529, 6372,
8192, 6372, 2529, 79, 1200, 4895, 7880, 7502,
4096, 690, 312, 3297, 6992, 8113, 5664, 1820,
0, 1820, 5664, 8113, 6992, 3297, 312, 690,
4096, 7502, 7880, 4895, 1200, 79, 2529, 6372,
8192, 6372, 2529, 79, 1200, 4895, 7880, 7502,
4096, 690, 312, 3297, 6992, 8113, 5664, 1820,
0, 1820, 5664, 8113, 6992, 3297, 312, 690,
4096, 7502, 7880, 4895, 1200, 79, 2529, 6372,
8192, 6372, 2529, 79, 1200, 4895, 7880, 7502,
4096, 690, 312, 3297, 6992, 8113, 5664, 1820,
0, 1820, 5664, 8113, 6992, 3297, 312, 690
};
/*******МАССИВ 12-БИТНЫХ КОСИНУСОВ ДЛЯ 128 ТОЧЕЧНОГО ДПФ*********/
/*****ЭТО - КОНСТАНТЫ, ПОЭТОМУ ИХ ЛУЧШЕ БЫ СОХРАНИТЬ ВО FLASH****/
signed int COS[] = {
2048, 2046, 2038, 2026, 2009, 1987, 1960, 1928,
1892, 1851, 1806, 1757, 1703, 1645, 1583, 1518,
1448, 1375, 1299, 1220, 1138, 1053, 965, 876,
784, 690, 595, 498, 400, 301, 201, 100,
0, -100, -201, -301, -400, -498, -595, -690,
-784, -876, -965, -1053, -1138, -1220, -1299, -1375,
-1448, -1518, -1583, -1645, -1703, -1757, -1806, -1851,
-1892, -1928, -1960, -1987, -2009, -2026, -2038, -2046,
-2048, -2046, -2038, -2026, -2009, -1987, -1960, -1928,
-1892, -1851, -1806, -1757, -1703, -1645, -1583, -1518,
-1448, -1375, -1299, -1220, -1138, -1053, -965, -876,
-784, -690, -595, -498, -400, -301, -201, -100,
0, 100, 201, 301, 400, 498, 595, 690,
784, 876, 965, 1053, 1138, 1220, 1299, 1375,
1448, 1518, 1583, 1645, 1703, 1757, 1806, 1851,
1892, 1928, 1960, 1987, 2009, 2026, 2038, 2046
};
/*******МАССИВ 12-БИТНЫХ СИНУСОВ ДЛЯ 128 ТОЧЕЧНОГО ДПФ***********/
/*****ЭТО - КОНСТАНТЫ, ПОЭТОМУ ИХ ЛУЧШЕ БЫ СОХРАНИТЬ ВО FLASH****/
signed int SIN[] = {
0, 100, 201, 301, 400, 498, 595, 690,
784, 876, 965, 1053, 1138, 1220, 1299, 1375,
1448, 1518, 1583, 1645, 1703, 1757, 1806, 1851,
1892, 1928, 1960, 1987, 2009, 2026, 2038, 2046,
2048, 2046, 2038, 2026, 2009, 1987, 1960, 1928,
1892, 1851, 1806, 1757, 1703, 1645, 1583, 1518,
1448, 1375, 1299, 1220, 1138, 1053, 965, 876,
784, 690, 595, 498, 400, 301, 201, 100,
0, -100, -201, -301, -400, -498, -595, -690,
-784, -876, -965, -1053, -1138, -1220, -1299, -1375,
-1448, -1518, -1583, -1645, -1703, -1757, -1806, -1851,
-1892, -1928, -1960, -1987, -2009, -2026, -2038, -2046,
-2048, -2046, -2038, -2026, -2009, -1987, -1960, -1928,
-1892, -1851, -1806, -1757, -1703, -1645, -1583, -1518,
-1448, -1375, -1299, -1220, -1138, -1053, -965, -876,
-784, -690, -595, -498, -400, -301, -201, -100
};
/***********ПОДПРОГРАММА РАСЧЕТА ДПФ**************/
/*АРГУМЕНТЫ: 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 ПОСЧИТАТЬ, ТОЛЬКО ЭТО МНЕ НЕ
ПОД СИЛУ БЕЗ ЗНАЧИТЕЛЬНЫХ ЗАТРАТ РЕСУРСОВ */
}
}
/*************КОНЕЦ ПОДПРОГРАММЫ РАСЧЁТА ДПФ***************/
int main(void)
{
int k;
DFT(DATA, RESULT);
for(k=0;k<BUFFER/2;k++)
{
printf("%d\t%d\n", k, RESULT[k]);
}
_getch();
return 0;
}