冷雨未凝 发表于 2019-7-11 10:27:38

arm_fir_f32怎么进行实时ADC采样滤波

大部分资料都是采集一串数据进行滤波,是否可以每采集一个数据进行滤波,输出一个数据,如果可以是什么思路

eric2013 发表于 2019-7-11 11:20:32

ARM官方的FIR滤波器,IIR滤波器函数边计算边添加数据的方法,计算大量数据时有效降
http://www.armbbs.cn/forum.php?mod=viewthread&tid=14732&fromuid=58
(出处: 安富莱电子论坛)

冷雨未凝 发表于 2019-7-11 15:45:57

你这个帖子,早上我看过了,但是还是不太懂:'(,而且你给的例子是28个采样点作为输入,28个点作为输出。那如果我的电机一直在运行,我想在一个中断里对电流进行滤波,采到28个点再输出也不现实啊

冷雨未凝 发表于 2019-7-11 15:53:01

而且还有就是要用arm_fir_init_f32这个函数,我不能每次调用滤波函数就得初始化一次吧,所以看了两天依然比较迷糊:dizzy:

eric2013 发表于 2019-7-11 16:05:55

冷雨未凝 发表于 2019-7-11 15:45
你这个帖子,早上我看过了,但是还是不太懂,而且你给的例子是28个采样点作为输入,28个点作为输出。那 ...
1、arm_fir_init_f32仅需调用一次
2、28是滤波器阶数,跟你每次处理的blockSize 没有关系,你仅需保证你采集的数据连续即可,采集 blockSize个数据给fir处理即可,如此反复。
blockSize 要大于1个点即可

冷雨未凝 发表于 2019-7-11 17:41:17

#define TEST_LENGTH_SAMPLES1    /* 采样点数 */
#define BLOCK_SIZE         1   /* 调用一次arm_fir_f32处理的采样点个数 */
#define NUM_TAPS             29   /* 滤波器系数个数 */

uint32_t blockSize = BLOCK_SIZE;
uint32_t numBlocks = TEST_LENGTH_SAMPLES/BLOCK_SIZE;            /* 需要调用arm_fir_f32的次数 */
static float32_t testInput; /* 采样点 */
static float32_t testOutput; /* 滤波后的输出 */
static float32_t firStateF32;      /* 状态缓存,大小numTaps + blockSize - 1*/

/* 低通滤波器系数 通过fadtool获取*/
const float32_t firCoeffs32LP = {
   0.005243253894f, 0.006002899725f,0.00823883526f,0.01184130926f,0.01663149334f,
   0.0223704353f,0.02877106704f,0.03551265225f,0.04225695878f,0.04866531491f,
    0.05441570282f,   0.0592190288f,0.06283371896f,0.06507793814f,0.06583877653f,
    0.06507793814f,0.06283371896f,   0.0592190288f,0.05441570282f,0.04866531491f,
    0.04225695878f,0.03551265225f,0.02877106704f,   0.0223704353f,0.01663149334f,
    0.01184130926f,0.00823883526f, 0.006002899725f, 0.005243253894f
};        

float32_t wang_my_lowpass(float32_t wang_Input)
{
/* 实现FIR滤波 */
    uint16_t j;
    arm_fir_instance_f32 S;
        float32_t*inputF32, *outputF32,wang_Output;

/* 初始化指针 */
    inputF32 =&testInput;
    outputF32 =&testOutput;
    inputF32 = &wang_Input;
    arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32LP, &firStateF32, blockSize);
for(j=0; j < numBlocks; j++)
                                {
                                        arm_fir_f32(&S, inputF32 + (j * blockSize), outputF32 + (j * blockSize), blockSize);
                                }       

return *outputF32;
}
这是我写的低通滤波的程序,每次电流采样一个点,作为float32_t wang_my_lowpass(float32_t wang_Input)的入口参数,然后输出一个值送入DAC观测。但是写的不对,我就很疑惑了,请问您能细致的解答一下吗,如果把arm_fir_init_f32放在float32_t wang_my_lowpass(float32_t wang_Input)外面会报错说S, inputF32, outputF32没有定义

eric2013 发表于 2019-7-11 17:53:20

冷雨未凝 发表于 2019-7-11 17:41
#define TEST_LENGTH_SAMPLES1    /* 采样点数 */
#define BLOCK_SIZE         1   /* 调用一次arm_ ...
numBlocks = TEST_LENGTH_SAMPLES/BLOCK_SIZE = 1,你的for循环就处理1个点吗? 你好歹也要采集100个点处理一波啊。

前面不说了,BLOCK_SIZE 要大于1个点。

数字滤波器跟模拟器滤波器一个道理。

就帮你这么多吧,你再捋捋。

冷雨未凝 发表于 2019-7-11 18:26:40

那采集100个点不就造成很大的时间延迟了吗,假如电流采样频率为16K,每次采100个点进行处理,执行完滤波函数后同时出来100个电流点,那还怎么观测呢。所以不太理解,我看也有好多人问这个问题,不知道您有没有对应的程序可以让我学习一下,教程中的都是不规则波形已经给出了,然后采样滤波,这个我懂,这一种动态的还是不太理解

eric2013 发表于 2019-7-11 18:31:38

冷雨未凝 发表于 2019-7-11 18:26
那采集100个点不就造成很大的时间延迟了吗,假如电流采样频率为16K,每次采100个点进行处理,执行完滤波函 ...

每次采集100个,处理一次即可,一次采集一直处理即可,可以一直这么处理下去,这么说明白了

eric2013 发表于 2019-7-11 18:38:38

程序举例。
比如你每次处理10个,也就是
blockSize = 10;
arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32LP, &firStateF32, blockSize);

然后你的程序每次采集够10个,调用一次。
rm_fir_f32(&S, xxx, xxx, blockSize)。
static/image/hrline/4.gif
比如你每次处理5个,也就是
blockSize = 5;
arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32LP, &firStateF32, blockSize);

然后你的程序每次采集够5个,调用一次。
rm_fir_f32(&S, xxx, xxx, blockSize)。

static/image/hrline/4.gif
比如你每次处理2个,也就是
blockSize = 2;
arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32LP, &firStateF32, blockSize);

然后你的程序每次采集够2个,调用一次。
rm_fir_f32(&S, xxx, xxx, blockSize)。


不要将blockSize设置为1即可,要大于1个点,老板DSP库有这个要求

冷雨未凝 发表于 2019-7-11 20:41:24

感谢,我再看看!

冷雨未凝 发表于 2019-7-11 21:13:33

太感谢你了,回答的的及时又细致,以后买东西首先考虑你们家,顶一下!

liangyan 发表于 2023-7-31 15:43:44

本帖最后由 liangyan 于 2023-7-31 16:21 编辑

eric2013 发表于 2019-7-11 18:38
程序举例。
比如你每次处理10个,也就是
blockSize = 10;

你好,我测试的时候存在一个问题:每次执行arm_fir_f32之前初始化arm_fir_init_f32一下结果就与matlab的结果一致,如果只在开始初始化arm_fir_init_f32的话,结果就与matlab不一致,好像是随着时间变的,刚开始一小段时间是一致的;不知道您是否知道这个问题的原因,不胜感激。

eric2013 发表于 2023-8-1 09:12:42

liangyan 发表于 2023-7-31 15:43
你好,我测试的时候存在一个问题:每次执行arm_fir_f32之前初始化arm_fir_init_f32一下结果就与matlab的 ...

初始化一次arm_fir_init_f32,然后一直调用arm_fir_f32是供连续采集使用的。

liangyan 发表于 2023-8-1 11:43:45

eric2013 发表于 2023-8-1 09:12
初始化一次arm_fir_init_f32,然后一直调用arm_fir_f32是供连续采集使用的。

看了一下arm_fir_f32代码,找到原因了,为了补偿fir的固定延时问题,我人为将输入信号做了一个blockSize大小的滑窗移动,每次滑窗当前一个数据,输出取第(N-1)/2个数来补偿延时的问题,但是arm_fir_f32函数里pState也做了同样的滑窗操作(只是输出没有取第(N-1)/2个数);因此造成结果不对(需要每次清空pState结果就对了);现在需要考虑的是不要每次调用arm_fir_f32前做arm_fir_init_f32初始化,并且还可以补偿延时的方法,不知道您有没有方法

eric2013 发表于 2023-8-1 17:22:30

liangyan 发表于 2023-8-1 11:43
看了一下arm_fir_f32代码,找到原因了,为了补偿fir的固定延时问题,我人为将输入信号做了一个blockSize ...

我认为你可以提前采集几个点作为补偿就行。

liangyan 发表于 2023-8-1 18:57:25

eric2013 发表于 2023-8-1 17:22
我认为你可以提前采集几个点作为补偿就行。

比如输入当前数据,对应的是超前第(N-1)/2个;或者是当前输出对应采集数据的前(N-1)/2帧,采样率低的情况下延时会比较大吧,提前采集好像不能解决延时的问题
页: [1]
查看完整版本: arm_fir_f32怎么进行实时ADC采样滤波