您好,来宝为您解答以下问题,没有声音图标怎么调整声音图标,很多人还不知道声音图标,明天上去看看吧! 经常有报道称声音图标没了,人们在使用木马查杀工具后,突然发现笔记本的声音图标不见了,也就是右下角的小喇叭不见了,导致用户的笔记本没有声音。并且有时重启笔记本和隐藏显示图标的正常设置不起作用,那么如果笔记本的声音图标(音量图标)突然消失了怎么办?对于这些情况,我可以通过以下方式解决。 方式/步骤 1.…
乱空
2022-09-10 17:03:52
之前的文章分析了部分源码,可以发现任务、事件标志组、消息队列等的实现都是通过控制块的方法来操作的。
例如任务
有任务控制块TCB_t,风暴旗组
有风暴控制块、消息队列
带有消息队列控制块,软件定时器
有一个软件定时器控制块。
在使用它们之前,首先创建它们(显存分配资源),并返回一个控制块的句柄,然后可以通过句柄来操作对象。
基本原则
以这些机制为参考,我们可以模拟并实现一个简单的检测器,用于检测原始传感器数据。
我们先分析一下基本原理:
开始阶段
原始数据依次存储在mixer字段中,此时检测器输出有两种选择:
这两种方式仅在初始阶段有所不同,本文后续编码将采用方式二。
数据第一全混频器字段
数据继续存储在混合器字段中。刚好满的时候,整个链表的平均值可以估计为这个混合的结果。
幻灯片存放台
mixer列表第一次满后,需要覆盖并存储(达到滑动数据获取的效果)。
这里也有两种形式:
相对而言滤波器设计软件,Form 2的估计量较小,本文后续编码将采用方法2。
编码实现
我们看一下编码实现:
混音器控制块
参考设计方法,为我们的移动平均混频器设计一个控制块,这是一个包含混频器所需资源的结构。
/*滑动平均滤波器——结构体*/
typedef struct SlipAveFilter
{
u16 len; /*窗口宽度*/
u16 index; /*索引*/
u16 has; /*已有的数据个数*/
char isfull; /*数组数据是否已满*/
float *data; /*滤波器数组*/
float sum; /*求和*/
float res; /*滤波结果*/
} SAFiter_t;
创建一个混音器
参考设计方法,在使用检测器时,通过创建函数来创建混频器。创建完成后,会返回一个句柄,用于后续对混音器的操作。
/*
滑动平均滤波器——创建
len:滤波器的窗口宽度
返回创建的滤波器句柄
*/
SAFilterHandle_t SlipAveFilterCreate(u16 len)
{
if(len < 1)
{
len = 1;
}
//创建一个滤波器并初始化
SAFiter_t *newFilter;
newFilter = MALLOC(sizeof(SAFiter_t));
newFilter->data = MALLOC(len * sizeof(float));
newFilter->len = len;
newFilter->index = 0;
newFilter->has = 0;
newFilter->isfull = 0;
newFilter->sum = 0;
newFilter->res = 0;
return newFilter;
}
获取混合结果
参考设计方法中,获取混合结果时,将之前创建的混合器句柄作为参数传入滤波器设计软件,获取具体的混合数据。
/*
滑动平均滤波器——获取结果
SAFiter:滤波器句柄
input:未滤波的原始数据
返回滤波结果
*/
float GetSAFiterRes(SAFilterHandle_t SAFiter, float input)
{
SAFiter_t *pFilter = (SAFiter_t *)SAFiter;
if(!pFilter->isfull) /*还没有存满*/
{
pFilter->has++; /*求当前数组中已有数据数量*/
if(pFilter->has == pFilter->len)
{
pFilter->isfull = 1; /*标记数组已满*/
}
}
else /*已存满,覆盖写入*/
{
pFilter->sum -= pFilter->data[pFilter->index]; /*先移除最早的数据*/
}
/*写入新的数据*/
pFilter->data[pFilter->index] = input;
/*求当前数组中已有数据的总和*/
pFilter->sum += input;
/*更新下次数据的索引号*/
pFilter->index = (pFilter->index == pFilter->len - 1) ? 0 : pFilter->index + 1;
/*求当前数组中已有数据的平均值*/
pFilter->res = pFilter->sum / pFilter->has;
return pFilter->res;
}
使用示例
以陀螺仪的数据混合为例(参考相关介绍
),假设需要混合俯仰数据和滚动数据,使用方法是:
//滤波器句柄
SAFilterHandle_t SAFilter_pitch;
SAFilterHandle_t SAFilter_roll;
//创建2个滤波器
SAFilter_pitch = SlipAveFilterCreate(10);
SAFilter_roll = SlipAveFilterCreate(10);
//循环获取数据并滤波
while(1)
{
if(mpu_dmp_get_data(&pitch,&roll,&yaw,&accx,&accy,&accz,&gyrox,&gyroy,&gyroz)==0)
{
pitch_res = GetSAFiterRes(SAFilter_pitch,pitch);//pitch数据滤波结果
roll_res = GetSAFiterRes(SAFilter_roll,roll);//roll数据滤波结果
printf("pitch:%f,%f,roll:%f,%frn",pitch,pitch_res,roll,roll_res);//打印原始数据与滤波后的数据
}
vTaskDelay(1);
}
注意:mixer的句柄是一个void*指针,定义在mixer的头文件(.h)中:
#ifndef __FILTERS_H
#define __FILTERS_H
typedef unsigned short u16;
typedef void * SAFilterHandle_t;
SAFilterHandle_t SlipAveFilterCreate(u16 len);
float GetSAFiterRes(SAFilterHandle_t SAFiter, float input);
#endif
混合后的结果如下,红色为原始数据,红色为检测后的结果: