最清洁的方式来存储C头中的滤波器系数列表
问题描述:
我有很多(〜100左右)滤波器系数借助一些Matlab和Excel计算出来,我想将它们转储到一个通用的头文件中,但我不确定要做到这一点的最佳方法是什么。我开始了像这样:最清洁的方式来存储C头中的滤波器系数列表
#define BUTTER 1
#define BESSEL 2
#define CHEBY 3
#if FILT_TYPE == BUTTER
#if FILT_ROLLOFF == 0.010
#define B0 256
#define B1 512
#define B2 256
#define A1 467
#define A2 -214
#elif FILT_ROLLOFF == 0.015
#define B0 256
#define B1 512
// and so on...
但是,如果我这样做,他们都推到一个头,我需要包括它之前设置在我的源代码的条件语句(FILT_TYPE
,FILT_ROLLOFF
),这似乎有点讨厌。更重要的是,如果我有2种不同的过滤器需要不同的滚降/过滤器类型,它将无法工作。我可以在这个系数文件中使用我的5个系数(A1-2,B0-2),但是它仍然看起来是错误的,不得不在代码中插入一个#include
。
编辑: 这是一个非常小的(2-4K)代码空间的嵌入式8位处理器。我似乎无法通过将它们存储到结构数组中来实现这一点,因为它消耗的空间是不可接受的。即使声明它们都是不变的,我的编译器不会'优化它们',所以我留下了超过1.2K额外二进制数据的阴影。
以下不起作用。
typedef struct {
int16_t b0, b1, b2, a1, a2;
} filtCoeff;
const filtCoeff butter[41] = {
{256,512,256,467,-214},
{256,512,256,444,-196},
{255,512,255,422,-179},
// ...
};
const filtCoeff bessel[41] // ...
答
您可以使用令牌串联将它们设置为参数一个宏。
#define BUTTER 1
#define BESSEL 2
#define CHEBY 3
#define ROLLOFF_0_010 1
#define ROLLOFF_0_015 2
// BUTTER, ROLLOFF_0_010
#define B0_11 256
#define B1_11 512
#define B2_11 256
#define A1_11 467
#define A2_11 -214
// BUTTER, ROLLOFF_0_015
#define B0_12 256
#define B1_12 512
// ...
#define B0_(type, rolloff) (BO_##type##rolloff)
#define B1_(type, rolloff) (B1_##type##rolloff)
#define B2_(type, rolloff) (B2_##type##rolloff)
#define A1_(type, rolloff) (A1_##type##rolloff)
#define A2_(type, rolloff) (A2_##type##rolloff)
/*
* This two level define is so that the parameters to these macros
* get run through the macro process. That is, B1_(BUTTER, ROLLOFF_0_010)
* evaluates as B1_BUTTERROLLOFF_0_010, while B1(BUTTER, ROLLOFF_0_010)
* evaluates as B1_11 and thus as 256.
*/
#define B0(type, rolloff) B0_(type, rolloff)
#define B1(type, rolloff) B1_(type, rolloff)
#define B2(type, rolloff) B2_(type, rolloff)
#define A1(type, rolloff) A1_(type, rolloff)
#define A2(type, rolloff) A2_(type, rolloff)
B1(BUTTER, ROLLOFF_0_015)
现在等效512
。然后你可以用宏来构建更复杂的东西。例如: -
#define CROSSPRODUCT(type, rolloff, values) \
B0(type, rolloff) * ((values)[0]) + \
B1(type, rolloff) * ((values)[1]) + \
...
你也可以把你的代码在另一个文件中,并使用TYPE
和ROLLOFF
。然后只需#define
TYPE
和ROLLOFF
并包含其他文件。我认为我更喜欢使用宏。
答
将滤波器系数放入一个结构数组中。我只想将数组指针的声明放在.h
文件中,并将它们定义在链接的特定.c
文件中。
虽然这排除了一些可能的优化,但它绝对是一个更干净的解决方案。 – xtofl 2010-04-21 19:26:50
忘了提及这是针对小型8位嵌入式目标,所以40个滚降* 3个类型* 5个coeffs * 2个字节= 1200个字节的数据消耗掉了我大部分的Flash。 – 2010-04-21 19:57:50