基本是基于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