我想用定点算法进行有限脉冲响应。我把这个程序放在一起,但我不确定它是否正确:
#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');
}
当我运行它时,我不确定我是否得到了当前的结果,如果必须这样做,你能帮助我验证或更改程序吗?
FIR滤波器接收并发送8位定点数 Q7格式通过标准输入和输出。记得输出 测量时间(刻度数)也以十六进制格式表示。以下 在上一节中提出的指导方针,您的计划应该致电 getchar()读取Q7值。应该调用putchar()来编写一个 Q7-值。
系数
c0 = 0.0299c1 = 0.4701c2 = 0.4701c3 = 0.299
我以前在这里得到了帮助,但我不确定它现在是否完整,我仍然对此答案有疑问:Fixedpoint FIR filter in C?
你能告诉我我的节目是否正确吗?
答案 0 :(得分:2)
根据维基百科上Q (number format)的信息,您的常数不正确。
您提到Q7格式,它对应于带有7个小数位的有符号小数(总共8位)。要将+0.0299表示为Q7值,您需要将0.0299乘以128,得到3.8272,将四舍五入为4.因此+0.0299作为Q7数的表示为4.类似地,对于+0.4701,确切的值为60.1728,由60表示。
firFixed()
功能的第一部分很好。但是,除法需要为128,而“半”将为64.因此,我认为你最终得到:
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位)。
#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;
}
我没有花时间计算正确的输出。显示的结果看似合理,但这与我声称的一样多。
c0 = c3 = 4 = 0x04
c1 = c2 = 60 = 0x3C
out = 55
out = 83
out = 89
out = 76