STM32输出的数据加载到Matlab中显示(快速傅立叶变换)

前言

最近在学习数字信号处理的内容,想把在stm32上通过傅立叶快速变换得到的幅频响应数据与在Matlab上直接计算的做比较,所以需要把在stm32上存储着计算结果的那个数组的数据导出来,再加载到Matlab上,下面是具体的操作。

具体实现

1、stm32的部分代码内容

//输入和输出缓冲
#define TEST_LENGTH_SAMPLES 1024
static float testInput_f32[TEST_LENGTH_SAMPLES*2];
static float testOutput_f32[TEST_LENGTH_SAMPLES];
static float testPhase_f32[TEST_LENGTH_SAMPLES];

//调用函数arm_cfft_f32计算幅频和相频
void arm_cfft_f32_app(void)
{
	uint16_t i;
	
	for(i=0; i<TEST_LENGTH_SAMPLES; i++)
	{
		/* 波形是由直流分量,50Hz正弦波组成,波形采样率1024,初始相位60° */
		testInput_f32[i*2] = 1 + cos(2*PI*50*i/1024 + PI/3);
		testInput_f32[i*2+1] = 0;
	}
	
	/* CFFT变换 */ 
	arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32, 0, 1);
	
	/* 求解模值  */ 
	arm_cmplx_mag_f32(testInput_f32, testOutput_f32, TEST_LENGTH_SAMPLES);
	
	/* 求相频 */
	PowerPhaseRadians_f32(testInput_f32, testPhase_f32, TEST_LENGTH_SAMPLES, 0.5f);
	
}

计算出的结果已经存储到testOutput_f32这个数组里面了,接下来就是要把这个数组里面的数据导出来。
STM32输出的数据加载到Matlab中显示(快速傅立叶变换)_第1张图片

2、以txt文本的格式导出内存中的数据

在Debug模式下输入如下名字导出数据

SAVE D:\data.txt 0x200126B4,0x200136B3

STM32输出的数据加载到Matlab中显示(快速傅立叶变换)_第2张图片
打开D盘,可以看到导出来的txt文档,打开就是一连串懵逼的数字,接下就是要处理这些数字了
STM32输出的数据加载到Matlab中显示(快速傅立叶变换)_第3张图片

3、处理txt文本里的数据

解析Hex格式:
1、把第一行和最后一行删掉
2、把每一行的前8个字符删掉,后2个字符删掉
3、留下中间32个字符,然后每隔8个加一个空格
我一般用 notepad++ 来编辑,操作比较方便,可以一次性对每行的内容进行任意删减和添加,编辑后如下图所示:
STM32输出的数据加载到Matlab中显示(快速傅立叶变换)_第4张图片
把编辑好的 data.txt 放到Matlab的 \Main\bin 目录里,方便直接在代码中打开。

4、Matlab的代码内容

这部分代码内容需要补一下对浮点数概念的理解,例如单精度浮点数它的组成是:1bit符号位 + 8bit阶码 + 23bit尾数,共32bit。

%在STM32计算的数据
fileId = fopen('./data.txt');
data1 = textscan(fileId,'%s');

result = zeros(1,1024);
for i = 1:1024
    a = data1{1,1}{i,1};
    b = a(1:2);
    c = a(3:4);
    d = a(5:6);
    e = a(7:8);
    f = [e,d,c,b];%因为stm32使用小端模式储存数据,对于32位数据aabbccdd,在内存中有低到高储存为ddccbbaa
    bin_all = dec2bin(hex2dec(f));
    while(length(bin_all)~=32)
        bin_all = ['0',bin_all];
    end
    
    bin_symbol = bin_all(1);    %1位为符号位
    dec_symbol = str2num(bin_symbol);  
    if(dec_symbol == 0)
        dec_symbol = 1;
    else
        dec_symbol = -1;
    end
    
    bin_str = bin_all(2:9);                 %2-9为阶码
    bin_man = bin_all(10:32);               %10-32为尾数
    dec_str = bin2dec(bin_str) - 127;       %阶码以移码的形式,需-127
    
    %分两种情况判断(阶码是正数还是负数)
    if(dec_str > 0)
        bin_man_int = ['1',bin_man(1:dec_str)]; %整数部分
        bin_man_dec = bin_man(dec_str+1:23);    %小数部分
    else
        bin_man_int = ['0'];                    %整数部分
        zero_str = char(zeros(1,abs(dec_str)));
        for j = 1:abs(dec_str)
              zero_str(j) = '0';
        end
        bin_man_dec = [zero_str,'1',bin_man(1:23)];    %小数部分
    end
    
    dec_int = bin2dec(bin_man_int);     %整数部分转换成10进制
    dec_dec = 0;    
    for j = 1:(23-dec_str)  %小数部分转换成10进制
        if(bin_man_dec(j) == '1')
            dec_dec = dec_dec + 2^(-j);
        end
    end
    
    result(i) = dec_symbol * (dec_int + dec_dec);   %解码好的内容
end


%在matlab计算的数据
Fs = 1024;   
N = 1024;
n = 0:N-1;
t = 0:1/Fs:1-1/Fs;
f = n*Fs/N;

x = 1 + cos(2*pi*50*t+pi/3);
y = fft(x,N);
mag = abs(y);
subplot(2,1,1);
plot(f,mag);
title('matlab计算 fft幅频响应');
xlabel('频率/Hz');
ylabel('幅度');

subplot(2,1,2);
plot(f,result);
title('stm32计算 fft幅频响应');
xlabel('频率/Hz');
ylabel('幅度');

5、运行的结果

可以看到在stm32上面使用官方的dsp库计算出来的结果跟在Matlab上计算的结果大致一样。
STM32输出的数据加载到Matlab中显示(快速傅立叶变换)_第5张图片

你可能感兴趣的:(算法,matlab,stm32)