硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5229|回复: 16
收起左侧

[信号与系统] arm_fir_f32怎么进行实时ADC采样滤波

[复制链接]

2

主题

12

回帖

18

积分

新手上路

积分
18
发表于 2019-7-11 10:27:38 | 显示全部楼层 |阅读模式
大部分资料都是采集一串数据进行滤波,是否可以每采集一个数据进行滤波,输出一个数据,如果可以是什么思路
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106760
QQ
发表于 2019-7-11 11:20:32 | 显示全部楼层
ARM官方的FIR滤波器,IIR滤波器函数边计算边添加数据的方法,计算大量数据时有效降
http://www.armbbs.cn/forum.php?m ... 4732&fromuid=58
(出处: 安富莱电子论坛)
回复

使用道具 举报

2

主题

12

回帖

18

积分

新手上路

积分
18
 楼主| 发表于 2019-7-11 15:45:57 | 显示全部楼层
你这个帖子,早上我看过了,但是还是不太懂,而且你给的例子是28个采样点作为输入,28个点作为输出。那如果我的电机一直在运行,我想在一个中断里对电流进行滤波,采到28个点再输出也不现实啊
回复

使用道具 举报

2

主题

12

回帖

18

积分

新手上路

积分
18
 楼主| 发表于 2019-7-11 15:53:01 | 显示全部楼层
而且还有就是要用arm_fir_init_f32这个函数,我不能每次调用滤波函数就得初始化一次吧,所以看了两天依然比较迷糊
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106760
QQ
发表于 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个点即可
回复

使用道具 举报

2

主题

12

回帖

18

积分

新手上路

积分
18
 楼主| 发表于 2019-7-11 17:41:17 | 显示全部楼层
#define TEST_LENGTH_SAMPLES  1    /* 采样点数 */
#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[TEST_LENGTH_SAMPLES]; /* 采样点 */
static float32_t testOutput[TEST_LENGTH_SAMPLES]; /* 滤波后的输出 */
static float32_t firStateF32[BLOCK_SIZE + NUM_TAPS - 1];        /* 状态缓存,大小numTaps + blockSize - 1*/

/* 低通滤波器系数 通过fadtool获取*/
const float32_t firCoeffs32LP[NUM_TAPS] = {
   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[0];
    outputF32 =&testOutput[0];
    inputF32 = &wang_Input;
    arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32LP[0], &firStateF32[0], 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没有定义
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106760
QQ
发表于 2019-7-11 17:53:20 | 显示全部楼层
冷雨未凝 发表于 2019-7-11 17:41
#define TEST_LENGTH_SAMPLES  1    /* 采样点数 */
#define BLOCK_SIZE           1     /* 调用一次arm_ ...

numBlocks = TEST_LENGTH_SAMPLES/BLOCK_SIZE = 1,你的for循环就处理1个点吗? 你好歹也要采集100个点处理一波啊。

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

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

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

使用道具 举报

2

主题

12

回帖

18

积分

新手上路

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

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

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


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

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106760
QQ
发表于 2019-7-11 18:38:38 | 显示全部楼层
程序举例。
比如你每次处理10个,也就是
blockSize = 10;
arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32LP[0], &firStateF32[0], blockSize);

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

比如你每次处理5个,也就是
blockSize = 5;
arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32LP[0], &firStateF32[0], blockSize);

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


比如你每次处理2个,也就是
blockSize = 2;
arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32LP[0], &firStateF32[0], blockSize);

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


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

回复

使用道具 举报

2

主题

12

回帖

18

积分

新手上路

积分
18
 楼主| 发表于 2019-7-11 20:41:24 | 显示全部楼层
感谢,我再看看!
回复

使用道具 举报

2

主题

12

回帖

18

积分

新手上路

积分
18
 楼主| 发表于 2019-7-11 21:13:33 | 显示全部楼层
太感谢你了,回答的的及时又细致,以后买东西首先考虑你们家,顶一下!
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 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不一致,好像是随着时间变的,刚开始一小段时间是一致的;不知道您是否知道这个问题的原因,不胜感激。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106760
QQ
发表于 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是供连续采集使用的。
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 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初始化,并且还可以补偿延时的方法,不知道您有没有方法
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106760
QQ
发表于 2023-8-1 17:22:30 | 显示全部楼层
liangyan 发表于 2023-8-1 11:43
看了一下arm_fir_f32代码,找到原因了,为了补偿fir的固定延时问题,我人为将输入信号做了一个blockSize ...

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

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2023-8-1 18:57:25 | 显示全部楼层
eric2013 发表于 2023-8-1 17:22
我认为你可以提前采集几个点作为补偿就行。

比如输入当前数据,对应的是超前第(N-1)/2个;或者是当前输出对应采集数据的前(N-1)/2帧,采样率低的情况下延时会比较大吧,提前采集好像不能解决延时的问题
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-5 04:45 , Processed in 0.305266 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表