CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

dsPIC30F4011 Filter with CCS

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
matthias
Guest







dsPIC30F4011 Filter with CCS
PostPosted: Thu Feb 26, 2009 2:37 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Feb 26, 2009 4:27 am     Reply with quote

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








PostPosted: Thu Feb 26, 2009 5:08 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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