gpt4 book ai didi

用 C 语言实现 FIR 滤波器的循环缓冲区

转载 作者:行者123 更新时间:2023-11-30 15:35:56 33 4
gpt4 key购买 nike

我正在嵌入式微 Controller (TMS320F28069) 上进行编程,这是一个 32 位浮点 MCU。我正在研究一些示例项目,其中一个在 ADC 采样数据上实现了一个简单的 FIR 滤波器。

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() 函数中,以下行对 xDelay 数组中的元素进行洗牌

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

该行位于 for 循环中,因此 [1] 元素被复制到 [2],然后 [0] 元素被复制到 [1],因为尽管有 for 循环计数,x 和 xold 指针还是递减向上

关于用 C 语言实现 FIR 滤波器的循环缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22749058/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com