news 2026/4/23 14:28:23

最近在折腾一个传感器信号处理的项目,发现原始数据里总有些低频干扰挥之不去。得嘞,撸起袖子给STM32整了个FIR高通滤波器。咱不整那些虚的,直接上干货

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
最近在折腾一个传感器信号处理的项目,发现原始数据里总有些低频干扰挥之不去。得嘞,撸起袖子给STM32整了个FIR高通滤波器。咱不整那些虚的,直接上干货

STM32开发 FIR高通滤波器 STM32实现FIR有限冲击响应高通滤波器,自编代码,汉明窗,送MATLAB程序,代码注释详细

先别急着写代码,咱们得先搞定滤波器系数。掏出MATLAB,20阶高通滤波器走起:

order = 20; cutoff = 0.4; % 归一化截止频率 h = fir1(order, cutoff, 'high', hamming(order+1)); fprintf('{%.8ff, ', h(1:end-1)); fprintf('%.8ff}', h(end));

这段脚本直接生成汉明窗加权的滤波器系数,打印成C数组格式。注意这里截止频率别设太高,0.4对应实际采样频率的40%。比如采样率1kHz的话,截止就是200Hz。

接下来STM32这边,直接上硬核代码。先整个环形缓冲区管理输入数据:

#define FILTER_ORDER 20 float buffer[FILTER_ORDER+1]; uint8_t buf_index = 0; void push_sample(float new_sample) { buffer[buf_index] = new_sample; buf_index = (buf_index + 1) % (FILTER_ORDER+1); }

这个环形缓冲区的骚操作在于,每次新数据覆盖最老的数据,省去了数组整体移动的开销。注意FILTER_ORDER+1的缓冲区长度,刚好装下当前窗口的所有采样点。

卷积运算才是重头戏,直接手撸:

float fir_filter(float *coeffs) { float output = 0.0f; uint8_t index = buf_index; for(int i=0; i<=FILTER_ORDER; i++){ if(index == 0) index = FILTER_ORDER; output += coeffs[i] * buffer[index]; index--; } return output; }

这里倒着取缓冲区数据的操作是关键,因为新数据总在buf_index位置,老数据顺时针排列。用if判断代替取模运算,实测能省20%计算时间。

实际工程里记得把系数转成Q15格式,上ARM的DSP库加速:

#include "arm_math.h" arm_fir_instance_f32 fir; float fir_state[FILTER_ORDER + BLOCK_SIZE -1]; void filter_init() { arm_fir_init_f32(&fir, FILTER_ORDER+1, hamming_coeffs, fir_state, BLOCK_SIZE); } void process_block(float *input, float *output) { arm_fir_f32(&fir, input, output, BLOCK_SIZE); }

用DSP库的批处理模式,一次处理一个数据块,比单点处理快3倍不止。注意state数组要足够大,别溢出。

调试时遇到过坑:直接浮点运算在F103上慢成狗,后来切到CMSIS-DSP的定点库,Q15格式配合armfirq15,速度直接起飞。不过要小心系数缩放,搞不好就溢出。建议先用MATLAB验证定点化的误差:

q15_coeffs = int16(h * 32767);

最后在main函数里这么用:

while(1) { float raw = read_adc(); push_sample(raw); float filtered = fir_filter(coeffs); printf("%f\t%f\n", raw, filtered); }

实测效果拔群,50Hz工频干扰被干得服服帖帖。完整工程丢在Github了,需要自取。记住滤波器阶数不是越高越好,够用就行,STM32F4跑100阶滤波器照样轻松。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 17:07:17

企业级AI开发平台为何都采用PyTorch预装镜像方案?

企业级AI开发平台为何都采用PyTorch预装镜像方案&#xff1f; 在当今AI研发节奏日益加快的背景下&#xff0c;一个常见的工程困境正不断浮现&#xff1a;为什么两个开发者用着相同的代码和数据&#xff0c;训练结果却大相径庭&#xff1f;答案往往藏在一个看似无关紧要的地方—…

作者头像 李华
网站建设 2026/4/23 13:52:55

PyTorch-CUDA-v2.8镜像时间同步问题解决方案

PyTorch-CUDA-v2.8镜像时间同步问题解决方案 在现代AI训练系统中&#xff0c;一个看似微不足道的细节——容器内的时间偏差——却可能引发连锁反应&#xff1a;日志错乱、调度异常、监控失效。尤其当使用如 pytorch/pytorch:2.8.0-cuda11.8-cudnn8-runtime 这类广泛部署的官方镜…

作者头像 李华
网站建设 2026/4/23 17:24:58

COMSOL多孔介质相对渗透率曲线绘制案例:新手入门指南

comsol 多孔介质相对渗透率曲线绘制案例&#xff0c;适合新手入门打开COMSOL新建模型时&#xff0c;新手容易在茫茫多物理场中迷路。别慌&#xff0c;这次咱们只需要用到两个核心模块&#xff1a;多孔介质流和数学函数库。先选"多孔介质和地下水流"&#xff0c;然后在…

作者头像 李华
网站建设 2026/4/23 17:24:50

PyTorch梯度裁剪技巧:防止训练崩溃在CUDA-v2.8中应用

PyTorch梯度裁剪技巧&#xff1a;防止训练崩溃在CUDA-v2.8中应用 深度学习模型的规模在过去几年里呈指数级增长&#xff0c;从BERT到GPT系列&#xff0c;再到如今的大语言模型和多模态系统&#xff0c;参数量动辄数十亿甚至上千亿。这种复杂性带来的一个直接后果是——训练过程…

作者头像 李华
网站建设 2026/4/23 16:45:45

YOLOv11姿态估计实现:基于PyTorch-CUDA-v2.8深度学习框架

YOLOv11姿态估计实现&#xff1a;基于PyTorch-CUDA-v2.8深度学习框架 在智能视觉系统日益渗透工业检测、安防监控和人机交互的今天&#xff0c;如何快速构建一个高效、稳定且可扩展的姿态估计算法平台&#xff0c;已成为AI工程落地的关键挑战。尤其是在实时视频流处理场景中&am…

作者头像 李华
网站建设 2026/4/23 15:31:15

cuda安装后nvidia-smi无显示?PyTorch-CUDA-v2.8内置诊断工具

PyTorch-CUDA-v2.8 内置诊断机制&#xff1a;解决 nvidia-smi 无输出的完整方案 在深度学习开发中&#xff0c;一个看似简单却频繁困扰工程师的问题是&#xff1a;CUDA 显然已经安装&#xff0c;驱动也声称就绪&#xff0c;但运行 nvidia-smi 却没有任何输出&#xff0c;或者 P…

作者头像 李华