Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.94/50: Рейтинг темы: голосов - 50, средняя оценка - 4.94
LoPuX
2 / 2 / 3
Регистрация: 03.05.2015
Сообщений: 63
1

БПФ для STM32F103

17.07.2015, 09:12. Просмотров 9377. Ответов 40
Метки нет (Все метки)

Здравствуйте, помогите подцепить БПФ на stm32. Есть некая библиотека DSP, не могу с ней разобраться. Можно ли просто функцию на C запихнуть? Я пробую, у меня почему-то не выходит. На компьютере выводит, а МК зависает. Код брал с https://ru.wikibooks.org/wiki/%D0%A0%D0 ... 1%8C%D0%B5. Может подскажете код, на C/С++, который точно заведется на МК? (с ассемблером я не дружу). Ну или скажите как этот DSP включить.
Делаю гитарный тюнер (в виде частотометра). Хотелось бы хотя бы 1024 отсчета. АЦП работает. Выводит результат на 7-сегментный индикатор.
На индикаторе будет частота, до десятой, поэтому точка.
Помогите пожалуйста.
0
Миниатюры
БПФ для STM32F103  
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.07.2015, 09:12
Ответы с готовыми решениями:

STM32F103:производительность 32бит БПФ выше, чем 16-битного?
Подбираю какой использовать вариант БПФ. С удивлением обнаружил: ...

Возможно ли преобразование в стиле БПФ для нелинейных чирпов
Пусть имеется источник сигналов с нелинейно меняющейся со временем частотой, например упрощенно...

STM32VLDISCOVERY в качестве программатора для stm32f103
Здравствуйте! Сегодня приехало вот это http://wvshare.com/product/EX-STM32-Q100a.htm И решил...

Самодельная отладочная плата для stm32f103
Запаял stm32f103 на плате - переходнике TQFP24-144. Расспаял питание, ресет, ноги бута. Пытаюсь...

Настройка OSC_OUT как GPIO для STM32f103
Добрый день. Контроллер STM32f103 тактируется от внешнего генератора, неиспользованный пин OSC_OUT...

40
raxp
10190 / 6573 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
17.07.2015, 09:19 2
Почему не пользуетесь официальной документацией?
Есть готовый "arm_fft_bin_example" от STM.
1
LoPuX
2 / 2 / 3
Регистрация: 03.05.2015
Сообщений: 63
18.07.2015, 17:40  [ТС] 3
raxp Спасибо за наводку. У меня возник вопрос testIndex это индекс максимального значения в массиве или что? Просто мне нужно узнать где максимум.
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "arm_math.h" 
 
#define TEST_LENGTH_SAMPLES 2048 
 
/* ------------------------------------------------------------------- 
* External Input and Output buffer Declarations for FFT Bin Example 
* ------------------------------------------------------------------- */ 
extern float32_t testInput_f32_10khz[TEST_LENGTH_SAMPLES]; 
static float32_t testOutput[TEST_LENGTH_SAMPLES/2]; 
 
/* ------------------------------------------------------------------ 
* Global variables for FFT Bin Example 
* ------------------------------------------------------------------- */ 
uint32_t fftSize = 1024; 
uint32_t ifftFlag = 0; 
uint32_t doBitReverse = 1; 
 
/* Reference index at which max energy of bin ocuurs */ 
uint32_t refIndex = 213, testIndex = 0; 
 
/* ---------------------------------------------------------------------- 
* Max magnitude FFT Bin test 
* ------------------------------------------------------------------- */ 
 
int32_t main(void) 
{ 
   
        arm_status status; 
        arm_cfft_radix4_instance_f32 S; 
        float32_t maxValue; 
         
        status = ARM_MATH_SUCCESS; 
         
        /* Initialize the CFFT/CIFFT module */  
        status = arm_cfft_radix4_init_f32(&S, fftSize,  
                                                                        ifftFlag, doBitReverse); 
         
        /* Process the data through the CFFT/CIFFT module */ 
        arm_cfft_radix4_f32(&S, testInput_f32_10khz); 
         
         
        /* Process the data through the Complex Magnitude Module for  
        calculating the magnitude at each bin */ 
        arm_cmplx_mag_f32(testInput_f32_10khz, testOutput,  
                                        fftSize);  
         
        /* Calculates maxValue and returns corresponding BIN value */ 
        arm_max_f32(testOutput, fftSize, &maxValue, &testIndex); 
         
        if(testIndex !=  refIndex) 
        { 
                status = ARM_MATH_TEST_FAILURE; 
        } 
         
        /* ---------------------------------------------------------------------- 
        ** Loop here if the signals fail the PASS check. 
        ** This denotes a test failure 
        ** ------------------------------------------------------------------- */ 
         
        if( status != ARM_MATH_SUCCESS) 
        { 
                while(1); 
        } 
 
    while(1);                             /* main function does not return */
}
Я думаю что так:
C++ (Qt)
1
2
3
4
5
6
7
8
int max = 0;
     int freq = 0;
     for(int i = 1; i < 1024; i++) {
        if(testOutput[i] > max) {
                max = testOutput[i];
                freq = i;
        }
     }
В итоге мне выдает freq=811.
В принципе где-то так (из 1024). Но какая частота дескеретизации? Как найти максимум?

Добавлено через 2 минуты
Там для пробы дается массив 10кГц с шумом.

Добавлено через 19 минут
И какая функция мне нужна из библиотеки DSP. Я так понимаю, у меня три варианта arm_rfft_q15, arm_rfft_q31, arm_rfft_f32. Где-то прочитал что от них зависит кол-во знаков после запятой. Получается что для меня это не важно, ведь АЦП выдает результат от 0 до 4095. т.е. целые числа.

Добавлено через 8 минут
Еще кое-что, по идее мне нужен DMA, чтобы получается АЦП забил допустим массив 2048 отсчетов, а потом произошло прерывание, так? Можно я буду выкладывать сюда все свои глупые вопросы и рассуждения, помогите мне закончить "проект".
0
raxp
18.07.2015, 21:39
  #4

Не по теме:

...STM это не ко мне, мы FFT на FPGA аппаратно реализуем, сразу на ПЧ.

0
ValeryS
Модератор
7482 / 5665 / 725
Регистрация: 14.02.2011
Сообщений: 19,367
Завершенные тесты: 1
18.07.2015, 22:16 5
Цитата Сообщение от LoPuX Посмотреть сообщение
И какая функция мне нужна из библиотеки DSP. Я так понимаю, у меня три варианта arm_rfft_q15, arm_rfft_q31, arm_rfft_f32. Где-то прочитал что от них зависит кол-во знаков после запятой. Получается что для меня это не важно, ведь АЦП выдает результат от 0 до 4095. т.е. целые числа.
что за библиотека?
я пользовался вот этой
три файла, три функции, на выборку 64 256 и 1024
написаны на асме, посему достаточно шустрые
Цитата Сообщение от LoPuX Посмотреть сообщение
Еще кое-что, по идее мне нужен DMA, чтобы получается АЦП забил допустим массив 2048 отсчетов, а потом произошло прерывание, так?
да
возьми прерывания для DMA
поищи, в сети много примеров
Цитата Сообщение от LoPuX Посмотреть сообщение
Но какая частота дескеретизации?
какую задашь такая и будет, прицепи АЦП к таймеру
0
Вложения
Тип файла: rar STM32F10x_DSP_Lib.rar (58.0 Кб, 74 просмотров)
ValeryS
Модератор
7482 / 5665 / 725
Регистрация: 14.02.2011
Сообщений: 19,367
Завершенные тесты: 1
18.07.2015, 22:21 6
Цитата Сообщение от LoPuX Посмотреть сообщение
Делаю гитарный тюнер (в виде частотометра). Хотелось бы хотя бы 1024 отсчета.
давай считать
допустим 10 кГц это предел
значит дискретизация как минимум 20 кГц
делим на 1024 получаем примерно 20 Гц селективность
о каких десятых речь идет?
Цитата Сообщение от LoPuX Посмотреть сообщение
На индикаторе будет частота, до десятой, поэтому точка.
0
LoPuX
2 / 2 / 3
Регистрация: 03.05.2015
Сообщений: 63
18.07.2015, 23:26  [ТС] 7
не, 10кГц это я про пример из arm_fft_bin_example. Там готовый массив на 10кГц, хотел найти эти 10кГц в спектре.

Да 1024 точек не то. Давайте пересчитаем. Вот что я думаю:
1) Частота дискретизации Fs = 2048 Гц.
2) Значит период дескретизации Ts = 1/Fs = 1/2048 c.
3) Количество отсчетов N = 2048
4) Значит выборка будет происходить за время t = N/Ts = 1 c.
5) Шаг частот будет f = 1/(N*Ts) = 1 Гц
6) Забиваю отсчеты нулями допустим по одному нулю. тогда отсчетов уже будет 4096 и шаг частот пол герца.
Метод забивания выборки нулями работает, результат не искажается проверял сто раз на компьютере. А еще можно было бы тремя нулями забить тогда отсчетов 8192 и шаг 0,25 Гц.
Знаю что это бутафория какая-то, ну да ладно, какая разница. Для настройки гитары даже думаю погрешность в 2 герца вообще не заметна (ну на первой-второй струне точно).
Вопрос становится в другом будет ли МК рассчитывать для стольких точек.

ValeryS Попробую подключить ваш файл. Поможете если что, а то я только недавно начал с stm32 знакомиться. И пусть будет 1024 отсчета и частота дескретизации 1024 Гц и шаг 1 Гц без точки вообщем, мне уже все равно, хоть что-то бы работало.
0
ValeryS
Модератор
7482 / 5665 / 725
Регистрация: 14.02.2011
Сообщений: 19,367
Завершенные тесты: 1
19.07.2015, 00:20 8
Цитата Сообщение от LoPuX Посмотреть сообщение
Частота дискретизации Fs = 2048 Гц.
значит максимальная измеряемая частота 1024 Гц
тут есть несколько путей
один из них,чисто теоретический,на практике не применял
это делать три замера одновременно
у STMок три АЦПухи, правда не у всех
одна допустим работает на частоте 1 кГц, ловит низкие,там как раз десятки нужны
вторая на 10 кГц,третья на 100, частоты можно поварьировать
второй
сделать генератор качающейся частоты, и его сигнал умножать на входной сигнал, при совпадении частот амплитуда резко возрастет, потом на выпрямитель и замерять постоянную составляющую, обычным АЦП, без преобразований
этакое аппаратное преобразование Фурье
Цитата Сообщение от LoPuX Посмотреть сообщение
Попробую подключить ваш файл.
он не мой тоже где то скачал
там есть одна особенность
функции работают с 32 битными массивами, так вот старшие 16 бит это мнимая составляющая комплексного числа, а младшие 16 это действительная часть

если у тебя это единичное производство , то советовал бы посмотреть в сторону STM32F4....
Во первых там частота выше до 168 мГц, во вторых на борту стоит модуль который может работать с числами с плавающей запятой
цена конечно на камни больше чем 103 серия, 500руб и выше

Добавлено через 4 минуты
Цитата Сообщение от LoPuX Посмотреть сообщение
4) Значит выборка будет происходить за время t = N/Ts = 1 c.
ты здесь получишь еще одну бяку
затухание колебаний тоже будут учитываться
палка о двух концах, чем больше замеров, тем больше время измерения,но выше селективность
чем меньше замеров тем меньше измерение,ниже селективность
если бы это была не струна, а допустим генератор
то можно было бы грубо оценить частоту, потом подогнать дескритизацию и точно замерять
но затухание все портит
0
LoPuX
2 / 2 / 3
Регистрация: 03.05.2015
Сообщений: 63
19.07.2015, 10:13  [ТС] 9
Цитата Сообщение от ValeryS Посмотреть сообщение
тут есть несколько путей
один из них,чисто теоретический,на практике не применял
это делать три замера одновременно
у STMок три АЦПухи, правда не у всех
одна допустим работает на частоте 1 кГц, ловит низкие,там как раз десятки нужны
вторая на 10 кГц,третья на 100, частоты можно поварьировать
Я не понял идею. Вот 6 струн, и пусть три АЦП у каждого разная ЧД. И как дальше?

1-ая 329,63 Гц // Здесь мерит первый АЦП
2-ая 246,94 Гц // ЧД допустим 1024 Гц

3-ая 196,00 Гц // второй
4-ая 146,83 Гц // ЧД 512Гц

5-ая 110,00 Гц //третий
6-ая 82,41 Гц // 256 Гц

У каждого разное число отсчетов. Я не понимаю...

Цитата Сообщение от ValeryS Посмотреть сообщение
если у тебя это единичное производство , то советовал бы посмотреть в сторону STM32F4....
Во первых там частота выше до 168 мГц, во вторых на борту стоит модуль который может работать с числами с плавающей запятой
цена конечно на камни больше чем 103 серия, 500руб и выше
Я так задолбался устал делать эту "отладочную плату" что пока больше ничего не хочу. Да и зачем мне плавающая точка, АЦП же выдает целые числа?

Цитата Сообщение от ValeryS Посмотреть сообщение
ты здесь получишь еще одну бяку
затухание колебаний тоже будут учитываться
Частота улетает и особенно быстро на басовых струнах. Но я думаю в спектре все равно основная частота доминирует. Буду почаще струну дергать
0
ValeryS
Модератор
7482 / 5665 / 725
Регистрация: 14.02.2011
Сообщений: 19,367
Завершенные тесты: 1
19.07.2015, 10:56 10
Цитата Сообщение от LoPuX Посмотреть сообщение
Да и зачем мне плавающая точка, АЦП же выдает целые числа?
А БПФ то с чем работает?
с комплексными числами
все эти умножения, сложения, квадраты, корни, работают с плавающей запятой
0
LoPuX
2 / 2 / 3
Регистрация: 03.05.2015
Сообщений: 63
19.07.2015, 16:22  [ТС] 11
ValeryS Спасибо понял.
Помоги, что за предупреждение?
warning: #223-D: function "cr4_fft_1024_stm32" declared implicitly

Добавлено через 1 час 49 минут
Сделал заголовочный файл с такой строчкой
C++ (Qt)
1
extern void cr4_fft_1024_stm32(void *pssOUT, void *pssIN, uint16_t Nbin);
Предупреждение ушло, а ничего не работает.

Добавлено через 3 минуты
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include "stm32f10x.h"
#include "table_fft.h"
#include "math.h"
#include "indicator.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stdlib.h"
#include "cr4_fft_1024_stm32.h"
 
#define N   1024 /*Number of points*/
#define Fs  1024
#define f   Fs/N //Step
uint32_t x[N],y[N]; /* input and output arrays */
uint16_t real[N], imag[N]; /* real and imaginary arrays */
 
 
uint16_t i = 0;
#define steady 2048
#define pi 3.14159265359
uint16_t max = 0;
uint16_t freq = 0;
 
int main() {
    
    ledInit();
 
for(i = 0; i < N; i++) {
    real[i] = steady + 800*sin(2*pi*300*i/Fs);
    imag[i] = 0;
}
 
for (i = 0; i < N; i++) {
    x[i] = (((uint16_t)(real[i])) | ((uint32_t)(imag[i]<<16)));
}
    
    cr4_fft_1024_stm32(y, x, N);    /*computes the FFT of the x[N] samples*/
 
 
for(i = 1; i < N/2; i++) {
    if(y[i] > max) {
        max = y[i];
        freq = i*f;
    }
}
 
while(1) {
        show(freq); //show result на индикатор
    }
    
}
У меня на индикаторе отображается 511 то бишь массив y[] пустой.

Добавлено через 55 минут
Неправильно написал:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
for(i = 1; i < N/2; i++) {
    if(y[i] > max) {
        max = y[i];
        freq = i;
    }
}
 
while(1) {
        show(freq*f); //show result на индикатор
    }
    
}
Не работает функция cr4_fft_1024_stm32()

Добавлено через 52 минуты
Хотя нет она работает, только показывает какую-то фигню, до 512 она неубывает, а потом она все ноль и ноль. В конце она снова возрастает что-ли. бред какой-то
0
Voland_
1694 / 1038 / 98
Регистрация: 04.01.2010
Сообщений: 3,517
20.07.2015, 08:18 12
Цитата Сообщение от LoPuX Посмотреть сообщение
warning: #223-D: function "cr4_fft_1024_stm32" declared implicitly
указанная функция нигде не определена.

ЗЫ: вообще, в ветке была уже подобная тема - там человек писал программку по определению частот нескольких струн и боролся за как можно короткий промежуток времени определения. Но сейчас я найти ее не могу.. Если кто-то наткнется или помнит - скиньте ссыль, я бы объединил темы.
0
Витальич
1274 / 1184 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
20.07.2015, 08:30 13
Как узнать частоту звука?
1
LoPuX
2 / 2 / 3
Регистрация: 03.05.2015
Сообщений: 63
20.07.2015, 11:42  [ТС] 14
Можно пока ничего не переносить. Я хочу прийти к готовому проекту в этой теме.
0
LoPuX
2 / 2 / 3
Регистрация: 03.05.2015
Сообщений: 63
23.07.2015, 14:31  [ТС] 15
На данный момент получилось подключить из библиотеки CMSIS-DSP пример "arm_fft_bin_example".
Работает хорошо и правильно. Файл на ассемблере работает тоже, но выводит неправильные результаты, не знаю почему.
Теперь буду пробовать работать без мнимой части, используя "Real FFT Functions"

Добавлено через 6 часов 48 минут
Кто нибудь знает, почему мой выводимый результат оказывается в 2 раза меньше?
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int main() {
 
    arm_rfft_instance_q15 S;
    arm_cfft_radix4_instance_q15 S_CFFT;
    
     for(i = 0; i < SAMPLE; i++) {
            Input[i] = steady + 800*sin(2*pi*300*i/Fs);
     }       
     
    arm_rfft_init_q15(&S, &S_CFFT, FFT_SIZE, ifftFlagR, doBitReverse);
    arm_rfft_q15(&S, Input, Output);
     
     for (i=0; i<SAMPLE; i++) {
            Output[i]<<=10;
     }   
     
    arm_cmplx_mag_q15(Output, Input, FFT_SIZE); 
     
    ledInit();
     
    for(i = 0; i < SAMPLE; i++) {
        if(Input[i] > max) {
            max = Input[i];
            freq = i;
        }
    }
 
    while(1) show((uint16_t)(10*freq*f));    
 
}
Вроде забиваю 300-стами герцами
C++ (Qt)
1
Input[i] = steady + 800*sin(2*pi*300*i/Fs);
, а в итоге показывает 150. Очень странно. В итоге в конце приходится домножать не на 10, а на 20.

Добавлено через 11 минут
При умножении сигнала на окно Хэмминга, спектр становится ближе к истине, но погрешность все-равно есть. Наверно идеально точного результата все равно не добиться никак. Ладно попробую теперь цеплять DMA. И еще про забивку сигнала нулями сейчас напишу...

Добавлено через 12 часов 32 минуты
ValeryS, а как при умножении я буду иметь скачок амплитуды?
Цитата Сообщение от ValeryS Посмотреть сообщение
второй
сделать генератор качающейся частоты, и его сигнал умножать на входной сигнал, при совпадении частот амплитуда резко возрастет, потом на выпрямитель и замерять постоянную составляющую, обычным АЦП, без преобразований
этакое аппаратное преобразование Фурье
Я понял что большой точности с БПФ мне не добиться никак, но до ± 10 Гц я точно подстрою. А что если потом использовать другой режим, с ГКЧ.
Т.е. допустим я подстраиваю третью струну 196,00 Гц. Сперва использую БПФ, настраиваю примерно до этого уровня. Дальше ГКЧ. Пусть на нем частота гуляет от 186 до 206 Гц. Как-бы два промежутка:
(186-...-196-...-206) если скачок амплитуды будет в первом промежутке (186-..частота струны..-196) значит нужно подтянуть струну.
Вот только я не знаю, можно ли сделать ГКЧ на самом микроконтроллере, например через ШИМ, было бы удобно. И потом мне нужен умножитель. Почитал что есть аналоговый умножитель. Но будет ли всплеск амплитуды, если синус умножается на синус, получается синус квадрат, который мало чем отличается от синуса обычного.
Расскажите мне правильно ли я рассуждаю, и как это должно выглядеть в теории? Получу ли я большую точность?

Добавлено через 4 часа 7 минут
Ну да Генератор такой сделать на МК вроде можно, только на выход нужно будет наверно конденсаторов влепить.
А вот про умножение я не найду информации. Мне не понятно как там с фазой будет обстоять дело, если в какой-то момент частота частота генератора совпадет с частотой струны, а она окажется в противофазе то что... Если кто знает подскажите. или может какая литература есть. И почему на мои вопросы никто не отвечает
0
LoPuX
2 / 2 / 3
Регистрация: 03.05.2015
Сообщений: 63
24.07.2015, 21:28  [ТС] 16
Что-то я все не пойму как с этим DMA работать.
Вот код
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include "stm32f10x.h"
#include "Adc.h"
 
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
__IO uint16_t ADCConvertedValue;
 
void RCC_Configuration(void);
void GPIO_Configuration(void);
 
void ADC_DMA_Init(void) {
  RCC_Configuration();
  GPIO_Configuration();
 
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
 
  DMA_Cmd(DMA1_Channel1, ENABLE);
  
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);
  
  ADC_DMACmd(ADC1, ENABLE); 
  
  ADC_Cmd(ADC1, ENABLE);    
  
  ADC_ResetCalibration(ADC1);        
  
  while(ADC_GetResetCalibrationStatus(ADC1));       
  
  ADC_StartCalibration(ADC1);   
  
  while(ADC_GetCalibrationStatus(ADC1));    
     
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);       
    
}
 
void RCC_Configuration(void) {
#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
  
  RCC_ADCCLKConfig(RCC_PCLK2_Div2); /* ADCCLK = PCLK2/2 */
#else
  RCC_ADCCLKConfig(RCC_PCLK2_Div4); /* ADCCLK = PCLK2/4 */
#endif
  /* Enable peripheral clocks ------------------------------------------------*/
  /* Enable DMA1 clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 
  /* Enable ADC1 and GPIOC clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
}
 
/**/
 
void GPIO_Configuration(void) {
  GPIO_InitTypeDef GPIO_InitStructure;
 
  /* Configure PC.04 (ADC Channel14) as analog input -------------------------*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}
Насколько я понимаю значения с АЦП хранятся в переменной ADCConvertedValue минуя процессор. И наверно она принимает эти значения с частотой тактируемой шины. Значит во первых мне нужно изменить частоту тактирования. И забить ADCConvertedValue в массив. Но как забивать в массив минуя процессор я не понимаю.

Добавлено через 4 минуты
И мне нужно прерывание по заполнению массива. Так можно?
0
ValeryS
Модератор
7482 / 5665 / 725
Регистрация: 14.02.2011
Сообщений: 19,367
Завершенные тесты: 1
25.07.2015, 11:18 17
Цитата Сообщение от LoPuX Посмотреть сообщение
А вот про умножение я не найду информации. Мне не понятно как там с фазой будет обстоять дело, если в какой-то момент частота частота генератора совпадет с частотой струны, а она окажется в противофазе то что...
А ничего
увеличится амплитуда и появится постоянная составляющая
смотри
sin(a)*sin(a)=sin2(a)
-sin(a)*sin(a)=-sin2(a)
все тоже самое, только знак поменялся
еще раз порекомендую
"Руководство программиста по работе со звуком" Кинтцель Тим
http://www.books.ru/books/rukovodstv...o-zvukom-8612/
очень наглядно расписан принцип Фурье, есть еще глава про цифровые фильтры, может они лучше подойдут

с Ассемблерными файлами разобрался?
нужно их подключить в проект
Могу скинуть свой проект в Keil, но это не рабочий проект, а так помойка, пробовал всякие подходы и в результате там черт ногу сломит

Добавлено через 1 минуту
Цитата Сообщение от LoPuX Посмотреть сообщение
И мне нужно прерывание по заполнению массива. Так можно?
можно
смотри в сторону DMA прерывание есть по заполнению массива и по заполнению половины массива, удобно для кольцевых буферов
0
LoPuX
2 / 2 / 3
Регистрация: 03.05.2015
Сообщений: 63
25.07.2015, 12:16  [ТС] 18
Цитата Сообщение от ValeryS Посмотреть сообщение
А ничего
увеличится амплитуда и появится постоянная составляющая
смотри
sin(a)*sin(a)=sin2(a)
-sin(a)*sin(a)=-sin2(a)
Амплитуда же не увеличивается, максимум 1.
Цитата Сообщение от ValeryS Посмотреть сообщение
с Ассемблерными файлами разобрался?
Нет, почему-то выходной массив y[N] не тот. Пик я там видел (прогонкой по индексам), но был он совсем не там, где нужно. В итоге подключил эту библиотеку http://www.keil.com/pack/doc/CMSIS/DSP/html/index.html работает. Но ассемблерный файл я еще помучаю, только не сейчас.
Я уже писал, но повторюсь. до меня дошло, что большой точности я не добьюсь никак. Вот даже идеальную функцию синуса с частотой 300 герц забиваю в массив, а на выходе 302,7. А с АЦП результат конечно же будет еще хуже.
Так вот, пришла идея, (оцените ):
1) Примерно подтянуть струну до нужной частоты с помощью БПФ.
2) Второй режим: создаю на ШИМ идеальную синусоиду с частотой струны, которая должна быть.
3) Сигнал с ШИМа и звук с гитары подаю на смеситель.
4) На выход смесителя ставлю ФНЧ
5) Считаю частоту биений.
Ну как?
0
ValeryS
Модератор
7482 / 5665 / 725
Регистрация: 14.02.2011
Сообщений: 19,367
Завершенные тесты: 1
25.07.2015, 12:57 19
Цитата Сообщение от LoPuX Посмотреть сообщение
Второй режим: создаю на ШИМ идеальную синусоиду с частотой струны, которая должна быть.
для этого есть, у 103, -DAC
можешь получить чистую синусоиду,без шим
ну или почти чистую,ступеньки от дескритизации все равно будут
но например на 720 итерациях, я их на осциллографе не наблюдал

Добавлено через 2 минуты
Цитата Сообщение от LoPuX Посмотреть сообщение
Амплитуда же не увеличивается, максимум 1.
это если единичная амплитуда в реальности же если меньше 1 уменьшится,1 останется, больше 1 увеличится
но самое главное, появится постоянная составляющая, рисунок будет как у двухполупериодного выпрямителя
0
LoPuX
2 / 2 / 3
Регистрация: 03.05.2015
Сообщений: 63
25.07.2015, 13:10  [ТС] 20
Цитата Сообщение от ValeryS Посмотреть сообщение
это если единичная амплитуда в реальности же если меньше 1 уменьшится,1 останется, больше 1 увеличится
но самое главное, появится постоянная составляющая, рисунок будет как у двухполупериодного выпрямителя
А ну да, если 2sin(a)*3sin(a), то 6. понял
а если сдвиг фаз 90. то что? 2sin(a+90)*3sin(a) = 0, если sin(a)=1.
0
25.07.2015, 13:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.07.2015, 13:10

БПФ на STM32
Друзья, может быть кто-то может подсказать, где достать библиотеку для прямого и обратного Быстрого...

БПФ STM32F4
Доброго времени суток! Раскуриваю БПФ на STM32F4, люди добрые, если у кого есть собранный проект...

БПФ. Как найти фазы гармоник
-- Добрый день! Мучаю вибрацию на stm32f373 (М4 с FPU) под Кокосом. Есть входной сигнал вибрации...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru