十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

FPGA实现三阶LC滤波器:移位运算替代乘法,系数和8~128选型全解析

FPGA实现三阶LC滤波器:移位运算替代乘法,系数和8~128选型全解析 摘要:本文面向FPGA开发者,讲解三阶LC滤波器如何通过设定系数将乘法替换为移位运算,系数和覆盖8~128(右移3~7位),直流增益恒为1。文章给出差分方程推导、稳定性条件及八分之一至一百二十八分之一各档位选型对比,帮助读者快速落地硬件实现。本文创新点:与常规数字滤波器实现相比,本文的创新主要体现在以下三个方面:一是将三阶LC滤波器的系数统一设定为 2 的幂次组合,使乘法运算完全退化为移位运算,在 8 位 MCU 和 FPGA 上均可零乘法器实现,显著降低硬件资源消耗;二是给出从八分之一到一百二十八分之一共五档可扩展的系数框架,覆盖从高速实时到高精度测量的完整应用谱系,并配套汇编与 C 语言双实现对比;三是结合极点分布、量化误差与实测数据,系统验证了反馈系数之和小于 1 这一稳定性判据在定点实现中的充分性,为工程选型提供了可直接复用的决策依据。文章目录:ATtiny26 八分之一三阶LC滤波器实现对比滤波器收敛性说明稳定性分析仿真验证各阶滤波器系数对比选型决策树总结参考资料三阶LC滤波器差分方程:y(n)=a0x(n)+a1x(n-1)+a2x(n-2)+b1y(n-1)+b2y(n-2)+b3y(n-3)将具体系数 a0=a1= 1,a = 2,b1 = b2 = 1,b3 = 2 代入上式,得到:y(n)=[a0x(n)+a1x(n-1)+a2x(n-2)+b1y(n-1)+b2y(n-2)+b3y(n-3) + 4) ] 3系数和为 8,即分子系数之和 1 + 1 + 2 = 4,分母反馈系数之和 1 + 1 + 2 = 4,两者相加为 8。为保证直流增益为 1,需将整体除以 8,即右移 3 位。实际上这里的系数,a0=a1 = 0.125,a2 = 0.25,b1=b2= 0.125,b3= 0.251,是极其稳定收敛的。为了快速收敛前三次采样可以赋初值。称之为八分之一三阶LC滤波器。同理如果系数a0=1,a1= 2,a = 5,b1 =1, b2 = 2,b3 = 5,就称之为十六分之一三阶LC滤波器。系数实际上系数 a0 = 0.0625,a1= 0.125,a2 = 0.3125,b1 =0.0625, b2= 0.125,b3 = 0.31251,是极其稳定收敛的。为了快速收敛前三次采样可以赋初值。同样的结构框架,得到三十二分之一三阶LC滤波器,和六十四分之一三阶LC滤波器,甚至更深度滤波比如高精度电子称,一百二十八分之一三阶LC滤波器。基于ATtiny26给出八分之一三阶LC滤波器的汇编语言代码和C语言代码对比分析。ATtiny26 八分之一三阶LC滤波器实现对比八分之一三阶LC滤波器的差分方程为:y(n)=[x(n)+x(n-1)+2x(n-2)+y(n-1)+y(n-2)+2y(n-3)+4] 3由于系数均为 2 的幂次组合,乘法可替换为移位运算,非常适合在 ATtiny26 这类 8 位 AVR 单片机上实现。下面分别给出汇编与 C 语言实现,并对比代码量、执行周期与资源占用。1. 汇编语言实现ATtiny26 为 8 位 AVR 内核,寄存器 R0~R31,其中 R26~R31 为 X/Y/Z 指针寄存器。输入采样 x(n) 为 8 位无符号数,中间累加结果需 16 位位宽,输出 y(n) 取高 8 位。汇编实现如下:;============================================= ; 八分之一三阶LC滤波器 - ATtiny26 汇编实现 ; 输入: R16 = x(n) (8位无符号采样) ; 输出: R17 = y(n) (8位无符号滤波结果) ; 占用: R16-R25, R0-R1 ;============================================= ; 数据区定义 (SRAM) ; x1,x2: 前两次输入 x(n-1), x(n-2) ; y1,y2,y3: 历史输出 y(n-1), y(n-2), y(n-3) ; 地址分配: ; x1 = 0x60, x2 = 0x61 ; y1 = 0x62, y2 = 0x63, y3 = 0x64 FILTER: ; 保存现场 PUSH R16 PUSH R17 PUSH R18 PUSH R19 PUSH R20 PUSH R21 PUSH R22 PUSH R23 PUSH R24 PUSH R25 PUSH R0 PUSH R1 ; 累加器清零 (R24:R25 = 16位累加器) CLR R24 CLR R25 ; 1) + x(n) (R16) ADD R24, R16 ADC R25, R0 ; R0=0, 进位扩展 ; 2) + x(n-1) (从SRAM读取) LDS R17, 0x60 ; R17 = x1 ADD R24, R17 ADC R25, R0 ; 3) + 2*x(n-2) (左移1位) LDS R17, 0x61 ; R17 = x2 LSL R17 ; R17 = 2*x2 ADD R24, R17 ADC R25, R0 ; 4) + y(n-1) LDS R17, 0x62 ; R17 = y1 ADD R24, R17 ADC R25, R0 ; 5) + y(n-2) LDS R17, 0x63 ; R17 = y2 ADD R24, R17 ADC R25, R0 ; 6) + 2*y(n-3) (左移1位) LDS R17, 0x64 ; R17 = y3 LSL R17 ; R17 = 2*y3 ADD R24, R17 ADC R25, R0 ; 7) + 4 (舍入偏置) ADIW R24, 4 ; R24:R25 += 4 ; 8) 3 (右移3位, 结果在R25高5位) ; 实际取 R25 作为输出, 相当于整体右移8位 ; 再右移3位, 即 R25 3 LSR R25 LSR R25 LSR R25 MOV R17, R25 ; R17 = y(n) ; 更新历史状态 ; y3 = y2, y2 = y1, y1 = y(n) LDS R18, 0x62 ; R18 = y1 LDS R19, 0x63 ; R19 = y2 STS 0x64, R19 ; y3 = y2 STS 0x63, R18 ; y2 = y1 STS 0x62, R17 ; y1 = y(n) ; x2 = x1, x1 = x(n) LDS R18, 0x60 ; R18 = x1 STS 0x61, R18 ; x2 = x1 STS 0x60, R16 ; x1 = x(n) ; 恢复现场 POP R1 POP R0 POP R25 POP R24 POP R23 POP R22 POP R21 POP R20 POP R19 POP R18 POP R17 POP R16 RET关键注释:累加器 R24:R25:16 位累加器,用于容纳 6 项系数之和(最大约 8×255=2040),避免 8 位溢出。ADC R25, R0:R0 恒为 0,用于将低字节进位扩展到高字节。LSL R17:左移 1 位实现 ×2 系数,对应 a2 和 b3 的系数 2。ADIW R24, 4:加 4 实现舍入偏置,使右移 3 位结果更接近真实除法。LSR R25 三次:对高字节右移 3 位,等效于整体结果右移 11 位(8 位低字节丢弃 + 3 位右移),实现除以 8。状态更新:先更新 y3←y2、y2←y1、y1←y(n),再更新 x2←x1、x1←x(n),保证下一拍历史值正确。2. C 语言实现使用 AVR-GCC 编写,采用 16 位无符号整数累加,逻辑与汇编完全一致,便于维护和移植:#include avr/io.h // 历史状态变量 (全局, 占用SRAM) static uint8_t x1, x2; // x(n-1), x(n-2) static uint8_t y1, y2, y3; // y(n-1), y(n-2), y(n-3) // 八分之一三阶LC滤波器 // 输入: x (8位无符号采样) // 输出: y (8位无符号滤波结果) uint8_t lc_filter_1_8(uint8_t x) { uint16_t acc; // 16位累加器 // 分子项: x(n) + x(n-1) + 2*x(n-2) acc = x; // + x(n) acc += x1; // + x(n-1) acc += (uint16_t)x2 1; // + 2*x(n-2) // 反馈项: y(n-1) + y(n-2) + 2*y(n-3) acc += y1; // + y(n-1) acc += y2; // + y(n-2) acc += (uint16_t)y3 1; // + 2*y(n-3) // 舍入偏置 + 右移3位 (除以8) acc = (acc + 4) 3; // 更新历史状态 y3 = y2; y2 = y1; y1 = (uint8_t)acc; x2 = x1; x1 = x; return (uint8_t)acc; }关键注释:uint16_t acc:16 位累加器,与汇编的 R24:R25 对应,防止 8 位溢出。(uint16_t)x2 1:先提升为 16 位再左移,实现 ×2 系数,避免 8 位溢
返回列表