c - STM32 frequency identification giving wrong results using analog input - Stack Overflow

I am trying to use stm32f411 and libopencm3 with CMSIS DSP lib to identify sine wave generated by a fun

I am trying to use stm32f411 and libopencm3 with CMSIS DSP lib to identify sine wave generated by a function signal generator but without sucess, I just cant compreend what I am doing wrong, i know that is not the fft algorithm wrong because when I generate a sine wave with code I am getting right values, and a weird thing is happen that when i am putting 100hz i get 3.91hz and not random values.

I had tried a bunch of things like print the raw buffer and the values seem correct, the values range from 0 to 4095 like expected...

my code:

#include "arm_math.h"
#include "arm_const_structs.h"

#include <math.h>

#define SAMPLE_RATE 4000
#define BUFFER_SIZE 1024


arm_rfft_fast_instance_f32 fft_instance;


float  adc_buffer[BUFFER_SIZE];
float input_buffer[BUFFER_SIZE];
float output_buffer[BUFFER_SIZE];
float magnitude_buffer[BUFFER_SIZE / 2]; 

void adc_setup(void) {

    rcc_periph_clock_enable(RCC_GPIOA);
    rcc_periph_clock_enable(RCC_ADC1);


    gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1);
    gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO5);

    adc_power_off(ADC1);

    adc_disable_scan_mode(ADC1);
    adc_set_resolution(ADC1, ADC_CR1_RES_12BIT);
    adc_set_right_aligned(ADC1);

    adc_disable_external_trigger_regular(ADC1);
    adc_set_sample_time(ADC1, ADC_CHANNEL1, ADC_SMPR_SMP_84CYC);

    adc_set_regular_sequence(ADC1, 1, (uint8_t[]){ADC_CHANNEL1});

    adc_power_on(ADC1);

    

    for (int i = 0; i < 100000; i++) {
        __asm__("nop");
    }
}

void generate_sine_wave(void) {
    for (int i = 0; i < BUFFER_SIZE; i++) {
        float time = (float)i / SAMPLE_RATE; // Tempo da amostra
        input_buffer[i] = arm_sin_f32(2.0f * PI * TEST_FREQUENCY * time);
    }
}

void usart_setup(void) {

    rcc_periph_clock_enable(RCC_GPIOA);
    rcc_periph_clock_enable(RCC_USART2);


    gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2 | GPIO3);
    gpio_set_af(GPIOA, GPIO_AF7, GPIO2 | GPIO3);


    usart_set_baudrate(USART2, 115200);
    usart_set_databits(USART2, 8);
    usart_set_stopbits(USART2, USART_STOPBITS_1);
    usart_set_mode(USART2, USART_MODE_TX_RX);
    usart_set_parity(USART2, USART_PARITY_NONE);
    usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);


    usart_enable(USART2);
}

void usart_send_string(const char *str) {
    while (*str) {
        usart_send_blocking(USART2, *str++);
    }
}

void adc_sample(void) {
    for (int i = 0; i < BUFFER_SIZE; i++) {
        adc_start_conversion_regular(ADC1);
        while (!adc_eoc(ADC1));
        adc_buffer[i] = adc_read_regular(ADC1);
    input_buffer[i] = ((float)adc_buffer[i] / 4095);

    //generate_sine_wave();
    
    }
}
void fft_compute(float *inBuffer, float *outBuffer, int sizeBuffer) {
    arm_rfft_fast_init_f32(&fft_instance, sizeBuffer);
    
    arm_rfft_fast_f32(&fft_instance, inBuffer, outBuffer, 0);

    arm_cmplx_mag_f32(outBuffer, magnitude_buffer, sizeBuffer / 2);
}

float find_fundamental_frequency(float *fft_output, int buffer_size) {
    float max_value = 0.0f;
    int max_index = 0;
    for (int i = 1; i < buffer_size / 2; i++) { // Ignorar componente DC
        if (fft_output[i] > max_value) {
            max_value = fft_output[i];
            max_index = i;
        }
    }
    return (float)max_index * SAMPLE_RATE / BUFFER_SIZE;
}


int main(){
    rcc_clock_setup_pll(&rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_84MHZ]);
    usart_setup();
    adc_setup();

    char bufferMsg[50];


    while(1){
    adc_sample();

    fft_compute(input_buffer, output_buffer, BUFFER_SIZE);

    float frequency = find_fundamental_frequency(magnitude_buffer, BUFFER_SIZE);
    snprintf(bufferMsg, sizeof(bufferMsg), "frequencia: %.2f \r\n", frequency);
    usart_send_string(bufferMsg);
    
    for(int b =0; b < 500000; b++){
        __asm__("nop");
    }
        
    }    
    
    return 0;
}
 

sorry if sending the whole code is bad

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745252124a4618740.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信