Help with IIR filter

General discussion on mikroPascal PRO for dsPIC30/33 and PIC24.
Post Reply
Author
Message
lewjoubert
Posts: 68
Joined: 12 Apr 2006 11:55
Location: Gold Coast Australia
Contact:

Help with IIR filter

#1 Post by lewjoubert » 07 Jun 2016 04:10

Hello, I used the Filter Tool to generate the code below, but I cannot seem to get any response form the DAC. I have double checked connections, and have run some simple conversion code into the same hardware setup and it works fine.

I am attempting to get a bandpass at the output of the DAC.
I have attached an image of what I am hoping to see!!

Any ideas where I'm going wrong, or what is wrong with the code?

// This code was generated by filter designer tool by mikroElektronika
// Date/Time: 7/06/2016 11:17:38 AM
// Support info: http://www.mikroe.com

// Device setup:
// Device name: P30F4013
// Device clock: 008.000000 MHz
// Sampling Frequency: 22050 Hz
// Filter setup:
// Filter kind: IIR
// Filter type: Bandpass filter
// Filter order: 6
// Design method: Chebyshev type II

program IIR_Test;

const
BUFFER_SIZE = 8;
FILTER_ORDER = 6;

COEFF_B : array[FILTER_ORDER+1] of word = (0x2A57, 0xB182, 0x46FF, 0x0000, 0xB901, 0x4E7E, 0xD5A9);
COEFF_A : array[FILTER_ORDER+1] of word = (0x1000, 0xD1CB, 0x5A4B, 0x997D, 0x5641, 0xD5D6, 0x0DF2);

SCALE_B = 9;
SCALE_A = -3;

var
cnt0 : integer;
cnt1:integer;

// I made changes here to match the schematic provided in the help pages
loadPin : sbit at LATF4_bit; // DAC load pin
loadPinDir : sbit at TRISF4_bit; // DAC load pin
csPin : sbit at LATF5_bit; // DAC CS pin
csPinDir : sbit at TRISF5_bit; // DAC CS pin

//loadPin : sbit at LATF1_bit; // DAC load pin
//loadPinDir : sbit at TRISF1_bit; // DAC load pin
//csPin : sbit at LATF0_bit; // DAC CS pin
//csPinDir : sbit at TRISF0_bit; // DAC CS pin

inext: word; // Input buffer index
input: array[BUFFER_SIZE] of word; ydata; // Input buffer, has to be in Y data space due to DSP engine requirements
output: array[BUFFER_SIZE] of word; ydata; // Output buffer, has to be in Y data space due to DSP engine requirements

// This is ADC interrupt handler.
// Analogue input is sampled and the value is stored into input buffer.
// Input buffer is then passed through filter.
// Finally, the resulting output sample is sent to DAC.
procedure ADC1Int(); org IVT_ADDR_ADCINTERRUPT;
var CurrentValue: word;
begin // ADC interrupt handler
input[inext] := ADCBUF0; // Fetch sample

CurrentValue := IIR_Radix( SCALE_B, //
SCALE_A, //
@COEFF_B, // b coefficients of the filter
@COEFF_A, // a coefficients of the filter
FILTER_ORDER+1, // Filter order + 1
@input, // Input buffer
BUFFER_SIZE, // Input buffer length
@output, // Input buffer
inext); // Current sample

output[inext] := CurrentValue;

inext := (inext+1) and (BUFFER_SIZE-1); // inext = (inext + 1) mod BUFFER_SIZE;

csPin := 0; // CS enable for DAC
SPI1BUF := 0x3000 or CurrentValue; // Write CurrentValue to DAC ($3 is required by DAC)
//SPI1BUF := 0x3000 or 2048; // Write CurrentValue to DAC ($3 is required by DAC)

while (SPITBF_bit) do // Wait for SPI module to finish write operation
nop;

loadPin := 0; // Load data in DAC
delay_us(2);
loadPin := 1;

csPin := 1; // CS disable for DAC

//**** I placed this little LED routine here for a visual that interrupt was being accessed
inc(cnt0);
if cnt0 = 2000 then portb.3 := 1;
if cnt0 = 4000 then
begin
portb.3 := 0;
cnt0 := 0;
end;

ADIF_bit := 0; // Clear AD1IF
end;

// This is Timer1 interrupt handler.
// It is used to start ADC at
// periodic intervals.
procedure Timer1Int(); org IVT_ADDR_T1INTERRUPT;
begin // Timer1 interrupt handler
if (DONE_bit) then
begin // If ADC is not busy
SAMP_bit := 1; // Start new sample
end;
LATD := PORTD xor 0xFFFF; // You can put oscilloscope on PORTD
// to measure sampling frequency

//**** I placed this little LED routine here for a visual that interrupt was being accessed
inc(cnt1);
if cnt1 = 1500 then portb.9 := 1;
if cnt1 = 3000 then
begin
portb.9 := 0;
cnt1 := 0;
end;
T1IF_bit := 0; // Clear TMR1IF
end;

// Main program starts here.
// Firstly, hardware peripherals are initialized and then
// the program goes to an infinite loop, waiting for interrupts.
begin
TRISD := 0;
TRISF := 0; //I added this
// DAC setup
loadPinDir := 0; // LOAD pin
csPinDir := 0; // CS pin
csPin := 1; // Set CS to inactive
loadPin := 1; // Set LOAD to inactive

// SPI setup
SPI1_Init_Advanced(_SPI_MASTER, _SPI_16_BIT,_SPI_PRESCALE_SEC_1, _SPI_PRESCALE_PRI_1,
_SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH,
_SPI_ACTIVE_2_IDLE);

inext := 0; // Initialize buffer index
Vector_Set(input, BUFFER_SIZE, 0); // Clear input buffer
Vector_Set(output, BUFFER_SIZE, 0); // Clear output buffer

// I changed TRISB, ADPCFG here to match schematic in the help file
TRISB := 0x0002; // Use PORTB for input signal
//TRISB := 0xFFFF; // Use PORTB for input signal
ADCON1 := 0x00E2; // Auto-stop sampling, unsigned integer out
ADCON2 := 0x0000;
ADCON3 := 0x0202; // Sampling time= 3*Tad, minimum Tad selected
//ADPCFG := 0x0001; // Configure PORTB as ADC input port
ADCHS := 0x0002; // Sample input on RB1
ADCSSL := 0; // No input scan
ADPCFG := 0x0002; // Configure PORTB as analog ADC input port

// Interrupts setup
IFS0 := 0; // Clear interrupt flags
IFS1 := 0; // Clear interrupt flags
IFS2 := 0; // Clear interrupt flags
NSTDIS_bit := 1; // Nested interrupts DISABLED
INTCON2 := 0; // Other interrupt settings
T1IE_bit := 1; // Timer1 and
ADIE_bit := 1; // ADC interrupts ENABLED
T1IP0_bit := 1; // Timer1 interrupt priority level = 1
ADIP_1_bit := 1; // ADC interrupt priority level = 1

// Timer1 setup
PR1 := 0x005B; // Sampling ~= 22050 kHz. Value of PR1 is dependent on clock.
TON_bit := 1; // Timer1 ON, internal clock FCY, prescaler 1:1
ADON_bit := 1; // ADC On
SAMP_bit := 1; // Start Sampling
while (1) do ; // Infinite loop,
// wait for interrupts
end.
Attachments
bp.jpg
bp.jpg (23.09 KiB) Viewed 4883 times
DISCLAIMER: Content reflects the thoughts & opinions of my goldfish neighbour's mad dog; don't quote me on that; don't quote me on anything; hand wash only, tumble dry on low heat; do not bend or fold.

MicroMark
Posts: 181
Joined: 11 Feb 2011 17:22

Re: Help with IIR filter

#2 Post by MicroMark » 07 Jun 2016 16:07

lewjoubert wrote:
// Device setup:
// Device name: P30F4013
// Device clock: 008.000000 MHz
// Sampling Frequency: 22050 Hz
// Filter setup:
// Filter kind: IIR
// Filter type: Bandpass filter
// Filter order: 6
// Design method: Chebyshev type II
Your device clock setting could be the problem. Set at 8mhz, I think it should be 80mhz. You don't show your project configurations, so it may be set there?

User avatar
Aleksandar.Mitrovic
mikroElektronika team
Posts: 1697
Joined: 11 Mar 2015 12:48

Re: Help with IIR filter

#3 Post by Aleksandar.Mitrovic » 07 Jun 2016 16:52

Hi Mark,

Can you please send me IIR parameters which you have used?
Also, do you use maybe EasyPIC™ v7 for dsPIC30® with this MCU?

Best regards,
Aleksandar

MicroMark
Posts: 181
Joined: 11 Feb 2011 17:22

Re: Help with IIR filter

#4 Post by MicroMark » 07 Jun 2016 17:42

Aleksandar.Mitrovic wrote:Hi Mark,

Can you please send me IIR parameters which you have used?
Also, do you use maybe EasyPIC™ v7 for dsPIC30® with this MCU?

Best regards,
Aleksandar
lewjoubert, had the problem I was just trying to help

Mark

lewjoubert
Posts: 68
Joined: 12 Apr 2006 11:55
Location: Gold Coast Australia
Contact:

Re: Help with IIR filter

#5 Post by lewjoubert » 07 Jun 2016 23:33

Aleksandar.Mitrovic wrote:Hi Mark,

Can you please send me IIR parameters which you have used?
Also, do you use maybe EasyPIC™ v7 for dsPIC30® with this MCU?

Best regards,
Aleksandar
Hi Aleksandar,

Hope you can help :)
I have attached an image of the IIR parameters,

no I am not using EasyPIC™ v7,

Here is the config:
<?xml version="1.0"?>
<MCU_DEVICE_FLAGS>
<DEVICE>
<DEVICE_NAME>P30F4013</DEVICE_NAME>
<SETTINGS>
<COUNT>13</COUNT>
<SETTING0>
<NAME>Oscillator</NAME>
<DESCRIPTION>HS</DESCRIPTION>
</SETTING0>
<SETTING1>
<NAME>Clock Switching and Monitor</NAME>
<DESCRIPTION>Sw Disabled, Mon Disabled</DESCRIPTION>
</SETTING1>
<SETTING2>
<NAME>WDT Prescaler B</NAME>
<DESCRIPTION>1:16</DESCRIPTION>
</SETTING2>
<SETTING3>
<NAME>WDT Prescaler A</NAME>
<DESCRIPTION>1:512</DESCRIPTION>
</SETTING3>
<SETTING4>
<NAME>Watchdog Timer</NAME>
<DESCRIPTION>Disabled</DESCRIPTION>
</SETTING4>
<SETTING5>
<NAME>POR Timer Value</NAME>
<DESCRIPTION>64ms</DESCRIPTION>
</SETTING5>
<SETTING6>
<NAME>Brown Out Voltage</NAME>
<DESCRIPTION>Reserved</DESCRIPTION>
</SETTING6>
<SETTING7>
<NAME>PBOR Enable</NAME>
<DESCRIPTION>Enabled</DESCRIPTION>
</SETTING7>
<SETTING8>
<NAME>Master Clear</NAME>
<DESCRIPTION>Disabled</DESCRIPTION>
</SETTING8>
<SETTING9>
<NAME>General Code Segment Write Protect</NAME>
<DESCRIPTION>Disabled</DESCRIPTION>
</SETTING9>
<SETTING10>
<NAME>General Segment Code Protection</NAME>
<DESCRIPTION>Disabled</DESCRIPTION>
</SETTING10>
<SETTING11>
<NAME>Comm Channel Select</NAME>
<DESCRIPTION>Use PGC/EMUC and PGD/EMUD</DESCRIPTION>
</SETTING11>
<SETTING12>
<NAME>Background Debug</NAME>
<DESCRIPTION>Disabled</DESCRIPTION>
</SETTING12>
</SETTINGS>
</DEVICE>
</MCU_DEVICE_FLAGS>
Attachments
IIR.jpg
IIR.jpg (113 KiB) Viewed 4865 times
DISCLAIMER: Content reflects the thoughts & opinions of my goldfish neighbour's mad dog; don't quote me on that; don't quote me on anything; hand wash only, tumble dry on low heat; do not bend or fold.

lewjoubert
Posts: 68
Joined: 12 Apr 2006 11:55
Location: Gold Coast Australia
Contact:

Re: Help with IIR filter

#6 Post by lewjoubert » 09 Jun 2016 02:51

Since my previous post, I found I had set ADCHS incorrectly. After setting it to ADCHS := 0x0001 and also changed the clock to a 40mHz crystal, the xtal specified in the example code/schematic supplied is 10mHz.

Now at least I get something out of the DAC, not very nice but something within the bandpass frequencies as selected.

The signal output is an ugly looking bumpy thing, full of harmonics and sounds terrible!!

Any ideas where to go from here to get a good clean output?

PS:
As a matter of interest, the code generated by the Filter Tool had a little error, it generates ADIP1_bit instead of ADIP_1_bit as per the definitions. Not a train wreck, just something to be aware of :?
DISCLAIMER: Content reflects the thoughts & opinions of my goldfish neighbour's mad dog; don't quote me on that; don't quote me on anything; hand wash only, tumble dry on low heat; do not bend or fold.

MicroMark
Posts: 181
Joined: 11 Feb 2011 17:22

Re: Help with IIR filter

#7 Post by MicroMark » 09 Jun 2016 18:16

Maybe this ebook can help

http://learn.mikroe.com/ebooks/dspicpascalprogramming/

Study section 15 on filters, notice they have clock set to 80mhz, not 8mhz

You should re-install the 10mhz crystal and set your project clock configuration "XT PLL 8x" and make the "oscillator frequency [MHz]" to 80.00000. You will find this setting in the IDE pull down menu "edit project"

In the "filter design tool" change the device clock to 80.0000mhz

For any kind of DSP work you need very fast clock speeds. And all the calculations are based on timing so your filter will only be right if the sample rate is correct.

Post Reply

Return to “mikroPascal PRO for dsPIC30/33 and PIC24 General”