目录
- 理论推导
- 产生测试信号
- sin_cal.c
- sin_cal.h
- 生成波形
- 一阶滤波器
- FirstOrderFilter.c
- FirstOrderFilter.h
- 测试
- 低通滤波器
- 高通滤波器
IAP15W4K58S4
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0
串口示波器:Vofa+ 1.3.10
理论推导
低通滤波器
见一阶RC低通滤波器的数学模型及算法实现 —— 奔跑的chanchanchan
Yn=A⋅Xn+(1−A)⋅Yn−1Y_n=A⋅X_n+(1−A)⋅Y_{n-1}Yn=A⋅Xn+(1−A)⋅Yn−1
A=ΔTRC+ΔT=ΔT12πf+ΔT=11+12πfΔTA=\frac{ΔT}{RC+ΔT}=\frac{ΔT}{\frac{1}{2πf}+ΔT}=\frac{1}{1+\frac{1}{2πfΔT}}A=RC+ΔTΔT=2πf1+ΔTΔT=1+2πfΔT11
高通滤波器
见一阶RC高通滤波器详解(仿真+matlab+C语言实现)—— 小麦大叔
Yn=A⋅Yn−1+A⋅(Xn−Xn−1)Y_n=A⋅Y_{n-1}+A⋅(X_n-X_{n-1})Yn=A⋅Yn−1+A⋅(Xn−Xn−1)
A=RCRC+ΔT=12πf12πf+ΔT=11+2πfΔTA=\frac{RC}{RC+ΔT}=\frac{\frac{1}{2πf}}{\frac{1}{2πf}+ΔT}=\frac{1}{1+2πfΔT}A=RC+ΔTRC=2πf1+ΔT2πf1=1+2πfΔT1
产生测试信号
sin_cal.c
#include "sin_cal.h"
#include <math.h>void sin_Init(sin_Type *Sin, float f, float delta_ms)
{Sin->angle = 0;Sin->delta = 2 * 3.141592653589793f * f * delta_ms / 1000.f;Sin->out = 0;
}float sin_cal(sin_Type *Sin)
{Sin->angle += Sin->delta;if (Sin->angle > 6.283185307179586f)Sin->angle -= 6.283185307179586f;Sin->out = sin(Sin->angle);return Sin->out;
}
sin_cal.h
#ifndef __SIN_CAL_H__
#define __SIN_CAL_H__typedef struct
{float angle;float delta;float out;
} sin_Type;void sin_Init(sin_Type *Sin, float f, float delta_ms); //f为设定的频率,delta_ms为时间间隔
float sin_cal(sin_Type *Sin);#endif
生成波形
初始化
//...
sin_Type Sin_1, Sin_2;
//...sin_Init(&Sin_1, 1, 5); //1 Hz的正弦波sin_Init(&Sin_2, 25, 5); //25 Hz的正弦波
//...
定时器中断周期为1ms,每5ms输出一次数据
extern sin_Type Sin_1, Sin_2;/********************* Timer0中断函数************************/
void timer0_int (void) interrupt TIMER0_VECTOR
{static int count = 0;float Data;if(++count >= 5){count = 0;sin_cal(&Sin_1);sin_cal(&Sin_2);Data = Sin_1.out+Sin_2.out;printf("%f\r\n", Data);}
}
如图,生成了1Hz和25Hz的混合波形:
一阶滤波器
FirstOrderFilter.c
#include "FirstOrderFilter.h"void fof_Init(fof_Type *fof, float f, float delta_ms, char HPForLPF)
{fof->in_old = 0;fof->out = 0;fof->type = HPForLPF;fof->a = 2 * 3.141592653589793f * f * delta_ms / 1000.f;if(!HPForLPF){fof->a = 1.f / fof->a;}fof->a = 1.f / (1.f + fof->a);
}float FirstOrderFilter(fof_Type *fof, float in)
{if(fof->type){fof->out = fof->a * fof->out + fof->a * (in - fof->in_old);fof->in_old = in;}elsefof->out = fof->a * in + (1 - fof->a) * fof->out;return fof->out;
}
FirstOrderFilter.h
#ifndef __FOF_H__
#define __FOF_H__typedef struct
{float a;float in_old;float out;char type;
} fof_Type;void fof_Init(fof_Type *fof, float f, float delta_ms, char HPForLPF); //f为截止频率,delta_ms为时间间隔,HPForLPF为类型选择
float FirstOrderFilter(fof_Type *fof, float in);#endif
测试
//...
fof_Type fof_1, fof_2;
//...fof_Init(&fof_1, 1, 5, 0); //低通滤波器,截止频率为1Hzfof_Init(&fof_2, 25, 5, 1); //高通滤波器,截止频率为25Hz
//...
extern fof_Type fof_1, fof_2;
extern sin_Type Sin_1, Sin_2;/********************* Timer0中断函数************************/
void timer0_int (void) interrupt TIMER0_VECTOR
{static int count = 0;float Data;if(++count >= 5){count = 0;sin_cal(&Sin_1);sin_cal(&Sin_2);Data = Sin_1.out+Sin_2.out;printf("%f, %f, %f\r\n", Data, FirstOrderFilter(&fof_1, Data), FirstOrderFilter(&fof_2, Data));}
}
下图为滤波效果
低通滤波器
对于低通滤波器,截止频率处的1Hz信号能量衰减至0.688,与12≈0.707\frac{1}{\sqrt{2}}≈0.70721≈0.707相差2.7%,
截止频率外的25Hz的信号经滤波已衰减至0.040
高通滤波器
对于高通滤波器,截止频率处的25Hz信号能量衰减至0.594,与12≈0.707\frac{1}{\sqrt{2}}≈0.70721≈0.707相差16%,
截止频率外的1Hz的信号经滤波已衰减至0.039