我正在嵌入式微控制器(TMS320F28069)上编程,这是一个32位浮点MCU。 我正在浏览一些示例项目,其中一个项目对ADC采样数据实现了一个简单的FIR滤波器。
这里的框图
假设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() 函数中,以下行打乱 xDelay 数组中的元素
*xold-- = *x--; // delay line update
该行位于 for 循环中,因此 [1] 元素被复制到 [2] 中,然后 [0] 元素被复制到 [1],因为尽管 for 循环计数,但 x 和 xold 指针会递减