Richards PIC Blog

Icon

Just another WordPress.com site

Very Basic Code for 2nd order IIR Filter in ‘C’

This code shows an IIR 2nd order section.

 H(z)=\frac{b_0+b_2z^{-2}}{1+a_1z^{-1}+a_2z^{-2}} 

The numerator coefficients are b=[1 0 -1];

The Denominator Coeffs are a=[1 -2rcos(\theta) r^2]; r=.8; th=pi/3;

For implementation in integer arithmetic in the PIC thte coeffs become:

b=[127 0 -128];    a=[ 127 -110 104];

The code is given followed by output from the WATCH table, which shows the response to an impulse input magnitude 50.

Then a MATLAB simulation is presented which gives the exact same integer values for the example.

Code:

 //
// Example C code for 2nd order IIR filter
//
// RGH 2012  richard.hayes@dit.ie

#include <p18f4620.h>

void main(void)
{
int yint;    // temp variable for 16 bit multiply result
char b0=127, b1=0, b2=-128, a1=-111, a2=82;
char x=50, x1=0, x2=0, y=0, y1=0, y2=0;

int bit_shift = 7;
int dc_shift = 128;

int voltage;
char datain[13]={128+50,128,128,128,128,128,128,128,128,128,128,128,128};
char dataout[13];

int i=0;

// Operating Loop
//x=50;
//i=0;
while (i<12)
{
x=datain[i]-dc_shift;    // Remove DC level from a/d i/p
//Implement the filter and crudely update the 'past' input and output x and y values
yint = (int)b0*x+(int)b1*x1+(int)b2*x2-(int)a1*y1-(int)a2*y2;
y=(char)(yint>>bit_shift);  //  8- bit result from filter. Note type casting
y2 = y1;
y1 = y;
x2 = x1;
x1 = x;
dataout[i]=y;    // Save output; this will be output to D/A
x=0;
i=i+1;

}
}

WATCH TABLE variable dataout

Update    Symbol Name       Hex    Decimal      Binary

dataout
[0]                     0x31      49          00110001
[1]                     0x2A      42          00101010
[2]                     0xD3     -45          11010011
[3]                     0xBE     -66          10111110
[4]                     0xE3     -29          11100011
[5]                     0x11      17          00010001
[6]                     0x21      33          00100001
[7]                     0x11      17          00010001
[8]                     0xF9      -7          11111001
[9]                     0xEF     -17          11101111
[10]                    0xF5     -11          11110101
[11]                    0x01       1          00000001
[12]                    0x00       0          00000000
b0                      0x7F     127          01111111

Now compare these results with the output from the following MATLAB programme:

% Simulation of integer operation of IIR filter
% The filter is implemented in 'C' for the PIC18
% The aim is to 'exactly match the integer behaviour
% of the microcontroller
clear all
b0=127; b1=0; b2=-127; a1=-111; a2=82;
x1=0; x2=0;  y1=0; y2=0;
x=50;
i=0;
for i=0:20
yint(i+1) = b0*x + b1*x1 + b2*x2  - a1*y1 - a2*y2    ;
y(i+1)=floor(yint(i+1)/(128));
y2 = y1;y1 = y(i+1);    x2 = x1;x1 = x;
x=0;
i=i+1;
%pause
end
i=0:20;
subplot(2,1,1);stem(i,y)
subplot(2,1,2);stem(i,yint)

MATLAB Output:
49,42,-45,-66,-29,17,33,17,-7,-17,-11,1,7,5,-1,-5,-4,-1,1,1,0,…

Filed under: Digital Filters,

Leave a comment

Pages