基本是基于python实现
- 英国大牛
- FIR滤波
- IIR滤波
- micropython的FIR滤波函数
- 中值滤波
英国大牛
国外大牛写的pyboard滤波器【汇编】:点击进入 国内某社区中研究参考:点击进入
#这是翻译文档:
# FIR滤波器在Arm Thumb汇编中的实现
# 作者: Peter Hinch
# Function arguments:
# r0 is an integer scratchpad array. Must be of length 3 greater than the # of coefficients.
# r0是一个整型暂存数组。长度必须比系数数组编号大3。
# r1 is an integer array of coefficients
# r1是抽头系数的整数数组
# 注意:
# fir(缓存区、系数、data)
# 缓存区第一个元素是样本长度,需要初始赋值
# 缓冲区第二个元素是对结果右移的位数(0-31)
# 其他参数必须为0
# 运行条件:
# 数组[2]保存着插入点地址 -- array[2] holds the insertion point address
# r2保存着新数据值 -- r2 holds the new data value
# 寄存器的使用(缓冲) -- Register usage (Buffer)
# r0 Scratchpad
# r2 new data value
# r3 ring buffer start
# r4 insertion point (post increment)
# r5 last location in ring buffer
# Register usage (filter)
# r0 accumulator for result
# r1 coefficient array
# r2 current coeff
# r3 ring buffer start
# r4 insertion point (post increment)
# r5 last location in ring buffer
# r6 data point counter
# r7 curent data value
# r8 scaling value
@micropython.asm_thumb
def fir(r0, r1, r2):
push({r8})
ldr(r7, [r0, 0]) # Array length
mov(r6, r7) # Copy for filter
mov(r3, r0)
add(r3, 12) # r3 points to ring buffer start
sub(r7, 1)
add(r7, r7, r7)
add(r7, r7, r7) # convert to bytes
add(r5, r7, r3) # r5 points to ring buffer end (last valid address)
ldr(r4, [r0, 8]) # Current insertion point address
cmp(r4, 0) # If it's zero we need to initialise
bne(INITIALISED)
mov(r4, r3) # Initialise: point to buffer start
label(INITIALISED)
str(r2, [r4, 0]) # put new data in buffer and post increment
add(r4, 4)
cmp(r4, r5) # Check for buffer end
ble(BUFOK)
mov(r4, r3) # Incremented past end: point to start
label(BUFOK)
str(r4, [r0, 8]) # Save the insertion point for next call
# *** Filter ***
ldr(r0, [r0, 4]) # Bits to shift ??????????
mov(r8, r0)
mov(r0, 0) # r0 Accumulator
label(FILT)
ldr(r7, [r4, 0]) # r7 Data point (start with oldest)
add(r4, 4)
cmp(r4, r5)
ble(NOLOOP1)
mov(r4, r3)
label(NOLOOP1)
ldr(r2, [r1, 0]) # r2 Coefficient
add(r1, 4) # Point to next coeff
mul(r2, r7)
mov(r7, r8)
asr(r2, r7) # Scale result before summing
add(r0, r2, r0)
sub(r6, 1)
bpl(FILT)
pop({r8})
FIR滤波
class filter:
def __init__(self,order,h):
self.order=order#滤波阶数
self.h=h#抽头系数
self.output=[]
def FIR_Filter(self,vi):
for i in range(len(vi)):
sum=0
if i < self.order:
for j in range(i):
sum=sum + self.h[j]*vi[i-j]
else:
for j in range(self.order):
sum=sum + self.h[j]*vi[i-j]
self.output.append(sum)
return self.output
原文参考链接:点击进入
IIR滤波
class filter:
def __init__(self, ):
pass
def IIR_Filter_I(self, input_array, a_weight, b_weight, Scale_Factors):
print(len(input_array))
arg_len = len(a_weight)
x = [0 for i in range(arg_len)]
y = [0 for i in range(arg_len)]
output_array = [0]
x[0] = input_array[0]
for index_vi in range(1, len(input_array)):
one_y = (x[0] * b_weight[0] + x[1] * b_weight[1] + x[2] * b_weight[2] + y[0] * a_weight[0] + y[1] * a_weight[
1] + y[2] * a_weight[2]) * Scale_Factors
x[2] = x[1]
x[1] = x[0]
x[0] = input_array[index_vi]
y[2] = y[1]
y[1] = y[0]
y[0] = one_y
output_array.append(one_y * Scale_Factors)
print(len(output_array))
return output_array
def IIR_Filter_II(self, vi):
pass
#python获取IIR系数
from scipy.signal import iirnotch
def filter_50():
fs = 500.0 # 采样频率(赫兹)
f0 = 50 # 从信号中去除的频率(Hz)
w0 = f0 / (fs / 2) # 归一化频率
Q= 30
b, a = iirnotch(w0, Q)
return(b,a)
参考链接:点击进入
micropython的FIR滤波函数
#include "stdint.h"
#include "stdio.h"
#include "py/obj.h"
#include "py/runtime.h"
//全局数组、长度、数据
//开始、 结束、 长度 、 head_start
//length length+1 length+2 length+3
void array_to_add(float *array_x,uint16_t array_length , float data_to_array)
{
uint16_t start = (int)array_x[array_length];
uint16_t end = (int)array_x[array_length+1];
//first chache
if(end == 0 && start == 0){
end = array_length-1;
array_x[end] = data_to_array;
}
//not first
else{
start += 1;
end += 1;
//state of end is bigest
if(end == array_length)
end = 0;
if(start == array_length)
start = 0;
array_x[end] = data_to_array;
}
array_x[array_length] = start;
array_x[array_length+1] = end;
}
//获取圆形缓冲区的对应正常序列值
float get_normal_seq_value(float *circle , uint16_t seq ,uint16_t data_length){
//获取相对起始的实际序列号
seq = (int)circle[data_length] + seq;
//转换成实际序列号
if (seq > (data_length-1) )seq = seq - data_length ;
return circle[seq];
}
typedef struct _FIR_obj_t
{
mp_obj_base_t base; //定义的对象结构体要包含该成员
uint16_t value1; //下面的成员,相当于类中的全局变量
uint16_t fir_head_len;
float out_data[303];
}FIR_obj_t;
//-------------------------------------------------------------------------------------
//定义初始化函数
STATIC mp_obj_t func_FIR_init(mp_obj_t self_in , mp_obj_t arg_head_len , const mp_obj_t arg_head)
{
//从第一个参数里面取出对象的指针
FIR_obj_t *self=MP_OBJ_TO_PTR(self_in);
float *self_out_data;
uint16_t len, i;
mp_obj_t *input_data = NULL;
size_t input_data_len = 0;
len = mp_obj_get_int(arg_head_len);
mp_obj_get_array(arg_head, &input_data_len, &input_data);
self_out_data = &(self->out_data);
self->fir_head_len = len;
//判断长度是否一致
if(len != input_data_len){
printf("Init Error Length inconsistency!\n ");
return mp_const_none;
}
//参数的存入
self_out_data[len] = 0;
self_out_data[len+1] = 0;
self_out_data[len+2] = len;
//进行out_data缓存区的初始化
for(i = 0 ; i < len ; i++)self_out_data[i] = 0;
//抽头系数的获取
for(i = 0 ; i < len ; i++)self_out_data[ len + 3 + i ] = mp_obj_get_float(input_data[i]);
return mp_const_none;
}
//注册函数
STATIC MP_DEFINE_CONST_FUN_OBJ_3(FIR_func_init,func_FIR_init);
//-------------------------------------------------------------------------------------
//定义滤波函数
STATIC mp_obj_t func_filter(mp_obj_t self_in , mp_obj_t data)
{
//从第一个参数里面取出对象的指针
FIR_obj_t *self=MP_OBJ_TO_PTR(self_in);
float *self_out_data;
int i , len;
float ret_val = 0 ;
self_out_data = &(self->out_data);
len = self->fir_head_len;
//删除数据缓冲区第一个数据,然后新数据添加到到末尾
array_to_add(&(self->out_data), len , mp_obj_get_float( data ));
//计算当前返回值
for(i=0; i < len ;i++){
ret_val = ret_val + (self_out_data[ len + 3 + i]) * ( get_normal_seq_value( &(self->out_data) , i ,len) );
}
return mp_obj_new_float(ret_val);
}
//注册函数
STATIC MP_DEFINE_CONST_FUN_OBJ_2(FIR_func_fir,func_filter);
//-------------------------------------------------------------------------------------
STATIC const mp_rom_map_elem_t FIR_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&FIR_func_init) },
{ MP_ROM_QSTR(MP_QSTR_fir), MP_ROM_PTR(&FIR_func_fir) }, //把我们定义的function对象添加到DICT中
};
//这个定义字典的宏定义
STATIC MP_DEFINE_CONST_DICT(FIR_locals_dict, FIR_locals_dict_table);
//-------------------------------------------------------------------------------------
const mp_obj_type_t FIR_type;
//类创建定义
STATIC mp_obj_t FIR_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args)
{
mp_arg_check_num(n_args, n_kw, 0, 0, true); //检查参数个数
FIR_obj_t*self=m_new_obj(FIR_obj_t); //创建对象,分配空间
self->base.type=&FIR_type; //定义对象的类型
return MP_OBJ_FROM_PTR(self); //返回对象的指针
}
//类的定义
const mp_obj_type_t FIR_type= {
.base={ &mp_type_type },
.name = MP_QSTR_FIR,
.make_new=FIR_make_new, //这个是我们新添加的make new属性
.locals_dict = (mp_obj_dict_t*)&FIR_locals_dict,
};
//-------------------------------------------------------------------------------------
中值滤波
def midfilter(data,shape = 3):
ret_data = []
data_len = len(data)
index = int((shape - 1)/2)
num = data_len - shape+1
for i in range(num):
filter_data = data[i:i + shape]
filter_data.sort()
mid_value = filter_data[index]
ret_data.append(mid_value)
return ret_data