FFT using CMSIS for non mbed-os for smaller capacity chips with DAC output e.g. F303K8 to display FFT to an Oscilloscope with example to send to MAX7219 LED Array
Dependencies: MAX7219 mbed-dsp mbed
main.cpp
00001 #include "mbed.h" 00002 /*ADAFruit 8x8 LED Array driver chip SPI */ 00003 #include "max7219.h" 00004 /* Include arm_math.h mathematic functions */ 00005 #include "arm_math.h" 00006 /* Include mbed-dsp libraries */ 00007 #include "arm_common_tables.h" 00008 #include "arm_const_structs.h" 00009 #include "math_helper.h" 00010 00011 /* FFT settings */ 00012 #define SAMPLES 512 /* 256 real party and 256 imaginary parts */ 00013 #define FFT_SIZE SAMPLES / 2 /* FFT size is always the same size as we have samples, so 256 in our case */ 00014 00015 /* Global variables */ 00016 float32_t Input[SAMPLES]; 00017 float32_t sampler[SAMPLES]={0}; 00018 float32_t Output[FFT_SIZE]; 00019 bool trig=0; 00020 00021 /*Function Prototypes */ 00022 uint16_t convert_bar(uint16_t); 00023 void sample(); 00024 00025 /* MBED class APIs */ 00026 DigitalOut myled(LED1); 00027 AnalogIn myADC(A1); 00028 AnalogOut myDAC(A3); 00029 Ticker timer; 00030 00031 /* Other class APIs */ 00032 Max7219 max7219(D11, D12, D13, D10);//SPI0_MOSI, SPI0_MISO, SPI0_SCK, SPI0_SS); 00033 00034 void sample(){ 00035 trig=1; 00036 } 00037 00038 int main() { 00039 00040 uint8_t array[]={0x1F,0x14,0x10,0x00,0x1F,0x14,0x10,0x00,0x10,0x1F,0x10}; //text 'FFT' 00041 uint16_t array_size=sizeof(array); 00042 int16_t i,j; 00043 float maxValue; // Max FFT value is stored here 00044 uint32_t maxIndex; // Index in Output array where max value is 00045 00046 printf("FFT Example using 32F303K8 DAC output\r\n"); 00047 00048 max7219_configuration_t cfg = { 00049 .device_number = 1, 00050 .decode_mode = 0, 00051 .intensity = Max7219::MAX7219_INTENSITY_4, 00052 .scan_limit = Max7219::MAX7219_SCAN_8 00053 }; 00054 00055 max7219.init_device(cfg); 00056 max7219.enable_device(1); 00057 max7219.set_display_test(); 00058 max7219.clear_display_test(); 00059 max7219.display_all_off(); 00060 00061 for(j=-8;j<=array_size;j++){ 00062 for(i=1;i<=array_size;i++){ 00063 max7219.write_digit(1,9-i+j,array[i-1]); 00064 } 00065 wait_ms(100); 00066 max7219.display_all_off(); 00067 } 00068 00069 //arm_cfft_instance_f32 S; // ARM CFFT module 00070 //float maxValue; // Max FFT value is stored here 00071 //uint32_t maxIndex; // Index in Output array where max value is 00072 00073 while(1) { 00074 timer.attach_us(&sample,30); //30us 30,30 250KHz sampling rate ******** 00075 00076 for (i = 0; i < SAMPLES; i += 2) { 00077 while (trig==0){} 00078 trig=0; 00079 Input[i] = myADC.read() - 0.5f; //Real part NB removing DC offset 00080 Input[i + 1] = 0; //Imaginary Part set to zero 00081 } 00082 timer.detach(); 00083 // Init the Complex FFT module, intFlag = 0, doBitReverse = 1 00084 // NB using predefined arm_cfft_sR_f32_lenXXX, in this case XXX is 256 00085 arm_cfft_f32(&arm_cfft_sR_f32_len256, Input, 0, 1); 00086 00087 // Complex Magniture Module put results into Output(Half size of the Input) 00088 arm_cmplx_mag_f32(Input, Output, FFT_SIZE); 00089 00090 Output[0]=0; 00091 00092 00093 //Calculates maxValue and returns corresponding value 00094 arm_max_f32(Output, FFT_SIZE, &maxValue, &maxIndex); 00095 00096 00097 myDAC=1.0f; //SYNC here!! for Oscillscope at max DAC output for triggering purposes 00098 wait_us(20);//All FFT values will be lower since max scaling is 0.9 as below 00099 myDAC=0.0f;//set trigger level on oscilloscope between 0.9 to 1.0 (*3.3Volts) i.e. 3.0 to 3.3Volts 00100 00101 for (i=2; i<FFT_SIZE/2 ; i++){ 00102 myDAC=(Output[i]/maxValue)*0.9f; // All Values scaled to 0.0 to 0.9 for output to DAC 00103 // if (Output[i]>0.2){printf("%d %f\r\n",i,(Output[i]/maxValue)*0.9f);} 00104 wait_us(10); 00105 } 00106 myDAC=0.0f; 00107 00108 for (i=0; i<9;i++){ 00109 max7219.write_digit(1,9-i,convert_bar((uint16_t)(Output[i*16]*2.9f)));// 5.8f 00110 } 00111 } 00112 } 00113 00114 // Will take a number (numVal) 0 to 255 and return (converted) the next (lower) 2^n-1 value 00115 // to light up all LEDS as a bar graph representation 00116 uint16_t convert_bar(uint16_t numVal){ 00117 if (numVal>255){return 0;} 00118 uint16_t converted = 0; 00119 for (uint16_t i=1; i<=256 ; i*=2){ 00120 if ((numVal/(i)) >= 1){converted = (i-1);} 00121 } 00122 return converted; 00123 }
Generated on Tue Jul 12 2022 22:56:12 by 1.7.2