2014-03-30 114 views
0

我正在對32位浮點MCU的嵌入式微控制器(TMS320F28069)進行編程。我正在回顧一些示例項目,其中一個實現了ADC採樣數據上的簡單FIR濾波器。針對FIR濾波器的循環緩衝區實現C

Block diagram here

假設ADC緩衝區有10個元素。假設過濾器的長度爲3(FILTER_LEN=3)。過濾器的實現非常簡單,它從延遲鏈的末尾開始並移動到開頭。

float32 ssfir(float32 *x, float32 *a, Uint16 n) 
{ 

Uint16 i;         // general purpose 
float32 y;         // result 
float32 *xold;        // delay line pointer 

/*** Setup the pointers ***/ 
    a = a + (n-1);      // a points to last coefficient 
    x = x + (n-1);      // x points to last buffer element 
    xold = x;       // xold points to last buffer element 

/*** Last tap has no delay line update ***/ 
    y = (*a--)*(*x--); 

/*** Do the other taps from end to beginning ***/ 
    for(i=0; i<n-1; i++) 
    { 
     y = y + (*a--)*(*x);   // filter tap 
     *xold-- = *x--;     // delay line update 
    } 

/*** Finish up ***/ 
    return(y); 

} 

現在,這裏是如何實現ADC循環緩衝區。

//--------------------------------------------------------------------- 
interrupt void ADCINT1_ISR(void)    // PIE1.1 @ 0x000D40 ADCINT1 
{ 
static float32 *AdcBufPtr = AdcBuf;     // Pointer to ADC data buffer 
static float32 *AdcBufFilteredPtr = AdcBufFiltered; // Pointer to ADC filtered data buffer 

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;  // Must acknowledge the PIE group 

//--- Manage the ADC registers  
    AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;  // Clear ADCINT1 flag 

//--- Read the ADC result: 
    *AdcBufPtr = ADC_FS_VOLTAGE*(float32)AdcResult.ADCRESULT0; 

//--- Call the filter function 
    xDelay[0] = *AdcBufPtr++;     // Add the new entry to the delay chain 
    *AdcBufFilteredPtr++ = ssfir(xDelay, coeffs, FILTER_LEN); 

//--- Brute-force the circular buffer 
    if(AdcBufPtr == (AdcBuf + ADC_BUF_LEN)) 
    { 
     AdcBufPtr = AdcBuf;      // Rewind the pointer to the beginning 
     AdcBufFilteredPtr = AdcBufFiltered;  // Rewind the pointer to the beginning 
    } 

} 

xDelay是長度FILTER_LEN的FLOAT32陣列以0初始化,並且coeffs是長度FILTER_LEN的FLOAT32陣列與所述濾波器係數初始化。

我的問題是,這到底是怎麼回事:

//--- Call the filter function 
    xDelay[0] = *AdcBufPtr++;     // Add the new entry to the delay chain 
    *AdcBufFilteredPtr++ = ssfir(xDelay, coeffs, FILTER_LEN); 

如何有史以來值獲取存儲在xDelay[1]xDelay[2]? 他們的實現似乎工作正常,但我沒有按照舊的數據被推回到xDelay數組。

在ssfir
+0

很難說明沒有看到代碼的其餘部分,比如xDelay初始化和所有被引用的地方。它只是在ISR中設置一次,它應該如何運作。 – cwhelms

+0

xDelay全局聲明爲'float32 xDelay [FILTER_LEN] = {0.0,0.0,0.0};' – SPieiga

回答

1

()函數下面的行混洗的xDelay數組中的元素

*xold-- = *x--;     // delay line update 

行是for循環使[1]元素被複制到[2],則[ 0]元素被複制到[1],因爲x和xold指針遞減,儘管for循環遞增了