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

2024-05-06

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

框图在这里 https://i.stack.imgur.com/wz5ut.png

假设 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是一个长度为 float32 的数组FILTER_LEN用 0 初始化并且coeffs是一个长度为 float32 的数组FILTER_LEN用滤波器系数初始化。

我的问题是,这里发生了什么:

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

值如何存储在xDelay[1] or xDelay[2]? 他们的实现似乎工作正常,但我没有遵循旧数据如何被推回到 xDelay 数组中。


在 ssfir() 函数中,以下行对 xDelay 数组中的元素进行洗牌

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 如何获取正在访问 ASP.NET 应用程序的当前用户?

    为了获取系统中当前登录的用户 我使用以下代码 string opl System Security Principal WindowsIdentity GetCurrent Name ToString 我正在开发一个 ASP NET 应用程
  • 如何使用 C# 中的参数将用户重定向到 paypal

    如果我有像下面这样的简单表格 我可以用它来将用户重定向到 PayPal 以完成付款
  • 通过 CMIS (dotCMIS) 连接到 SP2010:异常未经授权

    我正在使用 dotCMIS 并且想要简单连接到我的 SP2010 服务器 我尝试用 C 来做到这一点 如下所示http chemistry apache org dotnet getting started with dotcmis htm
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐