首页 > 编程知识 正文

rc滤波器,有源滤波器分类

时间:2023-05-06 18:51:25 阅读:141979 作者:2903

在以前的几篇文章中,虽然分析了FreeRTOS的部分源代码,但是发现FreeRTOS的任务、事件标志群、消息队列等的实现是在控制块上操作的。

例如任务中有任务控制块TCB_t,

事件标志组具有事件控制块EventGroup_t,

消息队列中有消息队列控制块Queue_t。

软件计时器包括软件计时器控制块Timer_t。

在使用它们之前,创建“内存分配资源”并返回控制块句柄,然后可以通过句柄操纵对象。

基本原理可以借鉴FreeRTOS的这一机制,模仿实现一个简单的滤波器来对传感器的原始数据进行滤波。

让我们先分析一下基本原理:

将滑动平均过滤器窗口宽度设置为5。 数组允许您使用index,指示以下数据存储在数组中的位置的初始状态: 过滤器数组均为0,索引指向数组的开头位置

开始阶段

原始数据依次存储在滤波器数组中,此时的滤波器输出有两种选择。

方式1 :数组既然还没有满,就不输出过滤结果的方式2 :数组还没有满,但是已经计算了几个数的平均值可以作为过滤器输出的方式在初期阶段只有差别,但是本文的后续编码采用的是方式2。

数据第1次存满滤波器数组

当数据继续存储在过滤器数组中,正好填满时,可以计算整个数组的平均值,作为此次的过滤结果。

滑动存储阶段

过滤器数组第一次满后,需要进行复盖保存(实现滑动获取数据的效果。

这里也有两种方法:

方式1 )将新的数据(a5 )复写存储在最早的数据(a0 )中,遍历数组进行加法运算,求出平均值作为输出方式2 )借用上次的加法数据sum ) a0~a4 ),从sum中提取最早的数据(a0 )

编码实现让我们来看看编码的实现。

滤波器控制块

借鉴FreeRTOS的设计方式,为我们的滑动平均滤波器设计控制块,即包含滤波器所需资源的结构。

/*滑动平均滤波器——结构*/typedefstructslipavefilter { u 16 len; /*窗口宽度*/u16索引; /*索引*/u16 has; /*现有数据数*/char isfull; /*数组数据已满*/float *data; /*过滤器数组*/float sum; */float res; /*过滤结果*/} SAFiter_t;创建滤波器

参考FreeRTOS的设计方法,在使用过滤器时,您可以通过创建函数来创建过滤器,然后通过返回句柄来操作过滤器。

/*滑动平均过滤器——创建len :过滤器的窗口宽度是创建的过滤器句柄*/safilterhandle _ tslipavefiltercreate (u 16 len ) if ) len ) len=1; 创建//过滤器并初始化SAFiter_t *newFilter; newfilter=malloc(sizeof ) Safiter_t ); new filter-data=malloc (len * sizeof ) float ); newFilter-len=len; 新过滤器索引=0; newFilter-has=0; newFilter-isfull=0; 新过滤器- sum=0; newFilter-res=0; 返回新过滤器; } 获取滤波结果

借鉴FreeRTOS的设计方式,在获取过滤器结果时,传递以前创建的过滤器句柄作为参数,实现特定过滤器数据的获取。

/*滑动平均过滤器——的获取结果SAFiter :过滤器句柄input :未被过滤的原始数据是过滤结果*/floatgetsafiterres (safilterhandle _ tsaf ITER,floatgetsafiter,floaf ITER ) pfilter-isfull(/*尚未满(/) pfilter-has; /*当前数组中已存在的数据数*/if(pfilter-has==pfilter-len ) {pFilter-isfull=1; /*标记数组已满*/}}else /*已满。 重写*/{ p filter-sum-=p filter-data [ p filter-index ]; /*首先删除旧数据*/}/*并写入新数据*/p filter-data [ p filter-index ]=input; /*计算当前数组中现有数据的总和*/pFilter-sum =input; /*是否更新下一次数据的索引号*/p filter-index=(p filter-index==p filter-len-1 )? 0 : p过滤器索引1; /*确定当前数组中现有数据的平均值*/p filter-RES=p filter-sum/p filter-has; return pFilter-res; }使用案例以MPU6050陀螺仪数据过滤为例(参考相关介绍MPU6050姿态求解1-DMP方法)假设需要过滤pitch和roll数据,则使用:

2定义过滤器句柄2创建过滤器循环以获取数据,并过滤//过滤器句柄SAFilterHandle_t SAFilter_pitch; SAFilterHandle_t SAFilter_roll;//创建两个过滤器sa filter _ pitch=slipavefiltercreate (10 ); sa filter _ roll=slipavefiltercreate (10; //while(1) if ) MPU_DMP_get_data(pitch、roll、yaw、accx、accy、accz、gyrox、gyroy、gyroz )==循环地将数据转换为//roll数据过滤结果printf(pitch:%f,%f,roll:%f,%frn )、pitch、pitch_res、roll、roll_res //打印原始数据和过滤后的数据) }vtaskdelay(1; }过滤后的结果是蓝色为原始数据,橙色为过滤后的结果。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。