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.
Help with IIR filter
-
- Posts: 68
- Joined: 12 Apr 2006 11:55
- Location: Gold Coast Australia
- Contact:
Help with IIR filter
- Attachments
-
- 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.
Re: Help with IIR filter
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?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
- Aleksandar.Mitrovic
- mikroElektronika team
- Posts: 1697
- Joined: 11 Mar 2015 12:48
Re: Help with IIR filter
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
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
Re: Help with IIR filter
lewjoubert, had the problem I was just trying to helpAleksandar.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
Mark
-
- Posts: 68
- Joined: 12 Apr 2006 11:55
- Location: Gold Coast Australia
- Contact:
Re: Help with IIR filter
Hi Aleksandar,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
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 (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.
-
- Posts: 68
- Joined: 12 Apr 2006 11:55
- Location: Gold Coast Australia
- Contact:
Re: Help with IIR filter
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
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.
Re: Help with IIR filter
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.
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.