|
|
View previous topic :: View next topic |
Author |
Message |
matthias Guest
|
dsPIC30F4011 Filter with CCS |
Posted: Thu Feb 26, 2009 2:37 am |
|
|
Hello Guys!
I'm working at a project for my school to develop Filter and Transformation Programs for the dsPIC30F4011. Currently I am working on a simple Low Pass, but it simple won't work the right way and i don't know why. The problem is that the Filter doesn't seem to calculate the value from the AD-Converter and the output doesn't work properly.
Here's the source code of my Filter:
Code: |
#include "30F4011_10.h"
#include <string.h>
#include <math.h>
#fuses XT, NOWDT, NOBROWNOUT
#use delay(clock=7372800)
#use standard_io(d)
#use rs232(baud=9600,UART2)
#define NCoef 2
#define DCgain 8
int16 NewSample;
static int16 x[NCoef+1]; //input samples
static int32 y[NCoef+1]; //output samples
int n;
int16 iir(int16 NewSample) {
int16 ACoef[NCoef+1] = {
8841,
17682,
8841
};
int16 BCoef[NCoef+1] = {
16384,
-18726,
6763
};
for(n=NCoef; n>0; n--) {
x[n] = x[n-1];
y[n] = y[n-1];
}
x[0] = NewSample;
y[0] = ACoef[0] * x[0];
for(n=1; n<=NCoef; n++)
y[0] += ACoef[n] * x[n] - BCoef[n] * y[n];
y[0] /= BCoef[0];
return y[0];
}
void main(){
setup_adc_ports(sAN2);
setup_adc( ADC_CLOCK_DIV_16 );
set_adc_channel(2);
delay_us(10);
while(true){
NewSample=read_adc();
printf("AD-Wert: %lu\n\r", NewSample);
printf("Filter: %lu\n\r", y[0]);
}
} |
I hope someone can help me, I'm really in trouble getting this thing working!
And please excuse if there are some mistakes in my english, I'm from austria and I've written this in a hurry ;)
Best regards, Matthias |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Feb 26, 2009 4:27 am |
|
|
Generally, an expression of the type int32 = int16*int16 doesn't give a correct 32 bit wide result. This is by design of the C standard, cause int16*int16 is calculated as int16 expression as well, and it will overflow if the result can't be represented by 16 bits.
The general C method is by type casting one term to int32 before multiplication, or use CCS specific make32() function.
Code: | y[0] += ACoef[n] * (int32)x[n] - BCoef[n] * (int32)y[n]; |
As a another remark. PCD is known to show incorrect results in some complex int32 expressions, particularly with indexes or pointers, you may want to check the assembly listing for correct evaluation. |
|
|
Guest
|
|
Posted: Thu Feb 26, 2009 5:08 pm |
|
|
You never call the iir() function. Even though it is declared, you never execute the code. Try this instead:
Code: |
while(true){
NewSample=read_adc();
result = iir(NewSample);
printf("AD-Wert: %lu\n\r", NewSample);
printf("Filter: %lu\n\r", result);
}
|
Also, use a different variable besides NewSample for the input value in the iir() function. Although it might not create an error in this instance, it is bad practice to use variables in this manner. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|