digital filter preinstalled in codewarrior 10.7 ?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

digital filter preinstalled in codewarrior 10.7 ?

883 Views
philippadolph
Contributor II

Hello,

i working with a TWR-K60F120M Evaluationboard.

I build a continuous single ended adc Measurement and all works fine. With the dma function i don't have to burden the µC with the measurement. My problem is that i can't find any components for digital filtering and i have problems to use the CMSIS Lib of ARM. I looking for a way to use a Moving average on my measured value without programm the code myself.

0 Kudos
5 Replies

534 Views
philippadolph
Contributor II

My ADC measurement saves 32768 values via dma in a array and all works fine and the change of my coeffs work also from float to int16_t.

Here my code for fir

//DEFINES
#define TEST_LENGTH_SAMPLES 16384
#define BLOCK_SIZE 32
#define NUM_TAPS 29
//COEFFICIENTS fir1(28,1/5) mathlab
float32_t Coeffs[NUM_TAPS]={
        0.0011 , 0.0021 , 0.0032 , 0.0031 , -0.0000 , -0.0071 , -0.0165 , -0.0233 , -0.0200 , 0.0000 , 0.0386 , 0.0906 , 0.1441 ,
        0.1845 , 0.1995 , 0.1845 , 0.1441 , 0.0906 , 0.0386 , 0.0000 , -0.0200 , -0.0233 , -0.0165 , -0.0071 , -0.0000 , 0.0031 ,
        0.0032 , 0.0021 , 0.0011
        
};
//
uint16_t numblocks=TEST_LENGTH_SAMPLES/BLOCK_SIZE;
//NUMBER OF SAMPLES
uint32_t blocksize=BLOCK_SIZE;
//COEFFICIENTS int16_t
int16_t Coeffsq15[NUM_TAPS];
//FIR Output
int16_t output_fir[TEST_LENGTH_SAMPLES];
//STATE buffer
int16_t firstate[BLOCK_SIZE+NUM_TAPS];

....

int main(void)
/*lint -restore Enable MISRA rule (6.3) checking. */
{

....

arm_fir_instance_q15 S;
    uint16_t i;

....

//FIR
    arm_float_to_q15(Coeffs,Coeffsq15,29);
    arm_fir_init_q15(&S,29,&Coeffsq15[0],&firstate[0],blocksize);

for (;;)
    {
        if(DMA_complete==TRUE)
        {
            for(i=0;i<numblocks;i++)
            {
                arm_fir_q15(&S,Messwertarray+(i*blocksize),output_fir+(i+blocksize),blocksize);
            }
        }

If i debug my system jumps in a hardfault. What am i doing wrong?

0 Kudos

534 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Philipp,

I suspect that the code is incorrect.

 arm_fir_q15(&S,Messwertarray+(i*blocksize),output_fir+(i+blocksize),blocksize);

Pls check if the address of Messwertarray and output_fir is correct.

I suspect you should use this line.

 arm_fir_q15(&S,Messwertarray+(i*blocksize*sizeof(int16_t)),output_fir+(i*blocksize*sizeof(int16_t)),blocksize);

Pls have a check.

BR

Xiangjun Rong

0 Kudos

534 Views
philippadolph
Contributor II

xiangjun.rong here my project

i can use the library , i found my problem with the implantation.

but i don't know how to use the q15 fir function probably

0 Kudos

534 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Philipp,

I am glad to hear you have fixed the library issue.

Regarding the q15 FIR digital filter, I suppose you have to acquire the coefficents array with matlab or the other tools based on the application requirements, if the coefficents array is float type, and the absolute maximum element is greater than 1, you can divide each element of the coefficents with the absolute maximum element, in this way all the coeffiecnts in the array ranges from -1 to +1.

You can use the macro to transform the coeeicents to Q15.

#define FRAC16(x) 32768*x
#define TAPNUMBER 20
#define BLOCKSIZE 1
#define TOTAL_POINTS 100
#define Q15_OFFSET 0x4000

int16_t lpFilterCoefficent[TAPNUMBER]=
{
FRAC16(4.45556640625000e-003),
FRAC16(1.44042968750000e-002),
FRAC16(2.54516601562500e-002),
FRAC16(3.69873046875000e-002),
FRAC16(4.84619140625000e-002),
FRAC16(5.92041015625000e-002),
FRAC16(6.86950683593750e-002),
FRAC16(7.63244628906250e-002),
FRAC16(8.16650390625000e-002),
FRAC16(8.44116210937500e-002),
FRAC16(8.44116210937500e-002),
FRAC16(8.16650390625000e-002),
FRAC16(7.63244628906250e-002),
FRAC16(6.86950683593750e-002),
FRAC16(5.92041015625000e-002),
FRAC16(4.84619140625000e-002),
FRAC16(3.69873046875000e-002),
FRAC16(2.54516601562500e-002),
FRAC16(1.44042968750000e-002),
FRAC16(4.45556640625000e-003)
};

const arm_fir_instance_q15 sFirStru;
int16_t FirState[TAPNUMBER+BLOCKSIZE];

int16_t temp,temp1;

void main()

{

.....................

arm_fir_init_q15(&sFirStru,TAPNUMBER,&lpFilterCoefficent[0],&FirState[0],BLOCKSIZE);

arm_fir_fast_q15(&sFirStru,&temp,&temp1,1);

}

In the code, the temp is the latest sample(Note if the sample is in 16 bits, you should logic right shift one bit, because the MSB is regarded as sign. In other words, the MSB should be zero), temp1 is the filtered result. Generally, the arm_fir_fast_q15() should be put in the ADC ISR.

Hope it can help you

BR

xiangJun Rong

0 Kudos

534 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Philipp,

I suggest you can use FIR digital filter, if you want to perform Moving average, it is okay to use digital filter by setting the digital coefficents as the same value.

I think you have to do digital filtering, currently, what is your problem? You can post you code, I can help you to fix the issue.

BR

Xiangjun Rong

0 Kudos