难道这滤波器的实现做出正确的输出? [英] Is this filter implementation making correct output?

查看:104
本文介绍了难道这滤波器的实现做出正确的输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望具有定点算术有限脉冲响应。我放在一起这个计划,但我不知道这是正确的:

I want to make a finite impulse response with fixedpoint arithmetic. I put together this program but I'm not sure that it's correct:

    #include <stdio.h>
    #include "system.h"

    #define FBITS 16 /* number of fraction bits */
    const int c0 = (( 299<<FBITS) + 5000) / 10000; /* (int)(0.0299*(1<<FBITS) + 0.5) */
    const int c1 = ((4701<<FBITS) + 5000) / 10000; /* (int)(0.4701*(1<<FBITS) + 0.5) */
    /* Ditto for C3 and C2 */
    const int c2 = (( 4701<<FBITS) + 5000) / 10000; /* (int)(0.4701 *(1<<FBITS) + 0.5) */
    const int c3 = ((299<<FBITS) + 5000) / 10000; /* (int)(0.299*(1<<FBITS) + 0.5) */

    #define HALF (1 << (FBITS) >> 1) /* Half adjust for rounding = (int)(0.5 * (1<<FBITS)) */
    signed char input[4]; /* The 4 most recent input values */

    char get_q7( void );
    void put_q7( char );

    void firFixed()
    {
     int sum = c0*input[0] + c1*input[1] + c2*input[2] + c3*input[3];
     signed char output = (signed char)((sum + HALF) >> FBITS);
     put_q7(output);
    }

    int main( void )
    {   
        int i=0;
        int a;
        while(1)
        {    
         for (a = 3 ; a > 0 ; a--)
        {
          input[i] = input[i-1];
        }      
         input[0]=get_q7();           
         firFixed();
         i++;      
        } 
        return 0;
    }



#include <sys/alt_stdio.h>

char get_q7( void );

char prompt[] = "Enter Q7 (in hex-code): ";
char error1[] = "Illegal hex-code - character ";
char error2[] = " is not allowed";
char error3[] = "Number too big";
char error4[] = "Line too long";
char error5[] = "Line too short";

char get_q7( void )
{
    int c; /* Current character */
    int i; /* Loop counter */
    int num;
    int ok = 0; /* Flag: 1 means input is accepted */

    while( ok == 0 )
    {
        num = 0;
        for( i = 0; prompt[i]; i += 1 )
            alt_putchar( prompt[i] );

        i = 0; /* Number of accepted characters */
        while( ok == 0 )
        {
            c = alt_getchar();
            if( c == (char)26/*EOF*/ ) return( -1 );
            if( (c >= '0') && (c <= '9') )
            {
                num = num << 4;
                num = num | (c & 0xf);
                i = i + 1;
            }
            else if( (c >= 'A') && (c <= 'F') )
            {
                num = num << 4;
                num = num | (c + 10 - 'A');
                i = i + 1;
            }
            else if( (c >= 'a') && (c <= 'f') )
            {
                num = num << 4;
                num = num | (c + 10 - 'a');
                i = i + 1;
            }
            else if( c == 10 ) /* LF finishes line */
            {
                if( i > 0 ) ok = 1;
                else
                {    /* Line too short */
                    for( i = 0; error5[i]; i += 1 )
                        alt_putchar( error5[i] );
                    alt_putchar( '\n' );
                    break; /* Ask for a new number */
                }
            }
            else if( (c & 0x20) == 'X' || (c < 0x20) )
            {
                /* Ignored - do nothing special */
            }
            else
            {   /* Illegal hex-code */
                for( i = 0; error1[i]; i += 1 )
                    alt_putchar( error1[i] );
                alt_putchar( c );
                for( i = 0; error2[i]; i += 1 )
                    alt_putchar( error2[i] );
                alt_putchar( '\n' );
                break; /* Ask for a new number */
            }
            if( ok )
            {
                if( i > 10 )
                {
                    alt_putchar( '\n' );
                    for( i = 0; error4[i]; i += 1 )
                        alt_putchar( error4[i] );
                    alt_putchar( '\n' );
                    ok = 0;
                    break; /* Ask for a new number */
                }
                if( num >= 0 && num <= 255 )
                    return( num );
                for( i = 0; error3[i]; i += 1 )
                    alt_putchar( error3[i] );
                alt_putchar( '\n' );
                ok = 0;
                break; /* Ask for a new number */
            }
        }
    }
    return( 0 ); /* Dead code, or the compiler complains */
}
#include <sys/alt_stdio.h>

void put_q7( char );    /* prototype */

char prom[] = "Calculated FIR-value in Q7 (in hex-code): 0x";

char hexasc (char in)   /* help function */
{
    in = in & 0xf;
    if (in <=9 ) return (in + 0x30);
    if (in > 9 ) return (in - 0x0A + 0x41);
    return (-1);
}

void put_q7( char inval)
{
    int i; /* Loop counter */   
        for( i = 0; prom[i]; i += 1 )
            alt_putchar( prom[i] );
    alt_putchar (hexasc ((inval & 0xF0) >> 4));
    alt_putchar (hexasc (inval & 0x0F));
    alt_putchar ('\n');     
}

当我运行它,我不知道我是否可以得到确认当期的结果,你能不能帮我验证或更改程序,如果它有许多工作要做?

When I run it I'm not sure whether I get the currect results, can you help me verify or change the program if it has to be done?

FIR滤波器接收和发送的8位定点数在   通过标准的输入和输出Q7格式。记得输出   测量时间(滴答数)也以十六进制格式。继   psented在previous节的指导方针$ P $,你的程序应该调用   的getchar()读取Q7价值。应该调用的putchar()写   Q7价值。

the FIR-filter receives and sends 8-bit fixed-point numbers in the Q7-format via the standard input and output. Remember to output the measured time (number of ticks) also in hex format. Following the guidelines presented in the previous section, your program should call getchar() to read a Q7-value. should call putchar() to write a Q7-value.

的系数是

C0 = 0.0299 C1 = 0.4701 C2 = 0.4701 C3 = 0.299

c0=0.0299 c1=0.4701 c2=0.4701 c3=0.299

我previously有帮忙,但是我不知道它是否已经完成,我仍对这个答案的问题:的 C语言定点FIR滤波器?

I previously got help here but I'm not sure whether it is now complete and I still have questions about this answer: Fixedpoint FIR filter in C?

你能告诉我,如果我的程序是正确的?

Can you tell me if my program is correct?

推荐答案

从信息上的 Q(数字格式)在维基百科,你的常量是不正确的。

Judging from the information on Q (number format) at Wikipedia, your constants are not correct.

您提Q7格式,其对应于一个符号小数7小数位(总共8位)。重新present 0.0299作为Q7值,你乘以0.0299的128,得3.8272,这将被舍入到4。因此的0.0299作为Q7号码重新presentation是4同样,为0.4701,准确值为60.1728,这将重新由60 psented $ P $。

You mention Q7 format, which corresponds to a signed fractional number with 7 fractional bits (for 8 bits in total). To represent +0.0299 as a Q7 value, you'd multiply 0.0299 by 128, yielding 3.8272, which would be rounded to 4. Thus the representation of +0.0299 as a Q7 number is 4. Similarly, for +0.4701, the exact value is 60.1728, which would be represented by 60.

你的 firFixed()函数的第一个部分是好的。该部门,但是,需要通过128,和'半'将是64。因此,我认为你结束了:

The first part of your firFixed() function is fine. The division, though, needs to be by 128, and the 'half' will be 64. Thus, I think you end up with:

const int c0 = (0.0299 * 128 + 0.5);
const int c1 = (0.4701 * 128 + 0.5);
const int c2 = (0.4701 * 128 + 0.5);
const int c3 = (0.0299 * 128 + 0.5);

const int half = (0.5000 * 128 + 0.5);

enum { Q7_BITS = 7 };

void firFixed(void)
{
    int sum = c0*input[0] + c1*input[1] + c2*input[2] + c3*input[3];
    signed char output = (signed char)((sum + half) >> Q7_BITS);
    put_q7(output);
}

在另一方面,你也可以定义FBITS为16这将需要32位整型来存储它(因为你有16个小数位和一个符号位,17位计)。

On the other hand, you also define FBITS as 16. That would require 32-bit integer types to store it (because you'd have 16 fractional bits and a sign bit, for 17 bits in total).

#include <stdio.h>

const int c0 = (0.0299 * 128 + 0.5);
const int c1 = (0.4701 * 128 + 0.5);
const int c2 = (0.4701 * 128 + 0.5);
const int c3 = (0.0299 * 128 + 0.5);

const int half = (0.5000 * 128 + 0.5);

enum { Q7_BITS = 7 };

void put_q7(signed char out);
void firFixed(signed char input[4]);

void firFixed(signed char input[4])
{
    int sum = c0*input[0] + c1*input[1] + c2*input[2] + c3*input[3];
    signed char output = (signed char)((sum + half) >> Q7_BITS);
    put_q7(output);
}

void put_q7(signed char out)
{
    printf("out = %d\n", out);
}

int main(void)
{
    printf("c0 = c3 = %3d = 0x%.2X\n", c0, c0);
    printf("c1 = c2 = %3d = 0x%.2X\n", c1, c1);
    signed char data[] = { 27, 39, 69, 99, 82, 71, 42, 63 };
    for (size_t i = 0; i < sizeof(data) - 4; i++)
        firFixed(data + i);
    return 0;
}

未经验证的输出

我还没有花时间计算正确的输出。显示的结果看起来合理,但是这就像我会要求。

Unvalidated output

I've not spent time calculating the correct output. The results shown look plausible, but that's as much as I'll claim.

c0 = c3 =   4 = 0x04
c1 = c2 =  60 = 0x3C
out = 55
out = 83
out = 89
out = 76

这篇关于难道这滤波器的实现做出正确的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆