大家好,我是专注分享职业规划/技术科普/智能生活有关原创文章的allen康哥。
今天介绍下嵌入式系统中常见的信号处理与滤波算法。
一、限幅滤波法:按键消抖场景原理
通过设定最大允许偏差值(A),若新采样值与历史值的差值超过阈值则视为噪声,保留旧值。该算法适合消除突发性脉冲干扰。
应用场景机械按键消抖:消除触点接触瞬间的抖动信号。
电机转速突变检测:防止因负载突变导致的异常值干扰控制逻辑。
代码实现
#define MAX_DELTA 5 // 最大允许偏差值
char limit_filter(char current_val) {
static char last_val;
if (abs(current_val - last_val) > MAX_DELTA)
return last_val; // 超出阈值则保留旧值
else
last_val = current_val;
return current_val;
}
二、中位值滤波:温度传感器去噪原理
对连续奇数次采样值排序后取中间值,有效抑制偶发干扰。
液位监测:过滤因流体波动引起的瞬时异常数据。
代码实现
#define N 7 // 奇数采样次数
char median_filter() {
char samples[N], temp;
for (int i=0; i<N; i++)
samples[i] = get_adc(); // 获取ADC采样值
// 冒泡排序取中值
for (int i=0; i<N-1; i++) {
for (int j=0; j<N-i-1; j++) {
if (samples[j] > samples[j+1]) {
temp = samples[j];
samples[j] = samples[j+1];
samples[j+1] = temp;
}
}
}
return samples[N/2]; // 返回中间值
}
三、滑动平均滤波:流量实时监测原理
维护固定长度的数据队列,计算窗口内数据的算术平均,动态响应变化。
应用场景流量计数据平滑:消除流体湍流引起的瞬时波动。
代码优化
#define WINDOW_SIZE 8 // 窗口长度
int moving_average() {
static int buffer[WINDOW_SIZE], index = 0;
buffer[index] = get_adc(); // 新数据入队
index = (index + 1) % WINDOW_SIZE; // 环形队列管理
int sum = 0;
for (int i=0; i<WINDOW_SIZE; i++)
sum += buffer[i];
return sum / WINDOW_SIZE; // 计算均值
}
四、卡尔曼滤波:姿态传感器数据融合原理
通过预测与校正机制,融合多传感器数据并动态估计系统状态。
代码实现
typedef struct {
float q; // 过程噪声方差
float r; // 测量噪声方差
float x; // 状态估计值
float p; // 估计误差协方差
float k; // 卡尔曼增益
} KalmanFilter;
float kalman_update(KalmanFilter *kf, float measurement) {
// 预测阶段
kf->p += kf->q;
// 更新阶段
kf->k = kf->p / (kf->p + kf->r);
kf->x += kf->k * (measurement - kf->x);
kf->p *= (1 - kf->k);
return kf->x;
}
五、一阶滞后滤波:电机电流平滑控制原理
通过加权系数α平衡新采样值与历史输出值,实现低计算量滤波。
温度PID控制:减少执行器频繁动作。
代码实现
#define ALPHA 0.3 // 平滑系数(0<α<1)
float first_order_filter(float new_sample) {
static float prev_output = 0;
prev_output = ALPHA * new_sample + (1 - ALPHA) * prev_output;
return prev_output;
}
选型建议资源受限场景(如8位MCU)优先选择限幅、中位值等轻量算法。动态系统控制(如无人机)推荐卡尔曼滤波,需平衡计算复杂度与精度。高频信号处理(如电机电流)采用一阶滞后或滑动平均滤波,避免相位延迟。
你好,我是Allen,CSDN博客专家,博客访问超千万。现任世界500强外企高级开发工程师,有多年国企和外企工作经验,擅长电子及嵌入式方向学习规划,简历优化及offer咨询,高考/考研咨询等,欢迎留言与我交流!