Самый чистый способ хранить списки коэффициентов фильтра в заголовке C - PullRequest
0 голосов
/ 21 апреля 2010

У меня есть много (~ 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+ разных фильтра, которые хотят использовать разные типы фильтров, это не сработает.Я мог бы #undef мои 5 коэффициентов (A1-2, B0-2) в этом файле коэффициентов, но все равно кажется неправильным вставлять #include в коде.

Редактировать: Это для встроенного 8-битного процессора с очень маленьким (2-4K) кодовым пространством.Похоже, я не могу этого сделать, сохранив их в массиве структур, потому что занимаемое им пространство недопустимо.Даже объявляя их все константами, мой компилятор не будет «оптимизировать их», поэтому у меня останется тень более 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]  // ...

Ответы [ 2 ]

3 голосов
/ 21 апреля 2010

Поместите коэффициенты фильтра в массив структур. Вместо того чтобы беспокоиться о заголовочных файлах, я бы просто поместил объявление указателя массива в файлы .h и определил их в конкретном файле .c, на который вы ссылаетесь.

2 голосов
/ 22 апреля 2010

Вы можете использовать конкатенацию токенов, чтобы получить их в качестве параметров макроса.

#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. Тогда вы можете создавать более сложные вещи, как макросы. E.g.:

#define CROSSPRODUCT(type, rolloff, values) \
    B0(type, rolloff) * ((values)[0]) + \
    B1(type, rolloff) * ((values)[1]) + \
    ...

Вы также можете поместить свой код в другой файл и использовать TYPE и ROLLOFF. Затем просто #define TYPE и ROLLOFF и включите другой файл. Хотя я думаю, что предпочитаю использовать макрос.

...