>

Hello World!

  • Hello World!

  • Hello World!

  • Hello World!

  • Hello World!

  • Hello World!

  • Hello World!

  • Hello World!

  • Hello World!

  • Hello World!

数字滤波器笔记(一)

数字滤波器笔记(一) 基础 数字信号处理时常用角频率($rad/s$)。它和物理频率的转换关系如下: $$ ω=2π \frac{f_s}{f} $$ 其中$f_s$为采样频率,$f$为物理频率。 数字滤波器的分类 经典滤波器 经典滤波器主要包括低通、高通、带通、带阻和全通滤波器。经典滤波器假定输入信号$x(n)$的有效信号和噪声分布在不同频段,当$x(n)$通过一个线性滤波系统之后,噪声能被很好的消减。然而当有效信号和噪声的频带重叠,传统滤波器将无能为力。 经典滤波器的幅频特性响应示意图: 数字滤波器的幅频特性相对于$π$对称,以$2π$为周期。周期性是采样过程的直接结果。当对连续信号进行采样时,信号的频谱会以采样频率$f_s$(对应数字角频率$2π$ 为周期进行延拓和叠加。 现代滤波器 现代滤波器主要包括维纳滤波器、卡尔曼滤波器、线性预测器等。现代滤波器将有效信号和噪声都视为随机信号,并使用统计方法推导出最佳的估值算法。 无限脉冲响应(IIR) FIR滤波器的输出仅仅是当前和过去输入样本的加权和。它的冲激响应在有限时间内衰减为零。 IIR滤波器的系统函数: $$ H(z)=\sum_{n=0}^{N-1}h(n)z^{-n} $$ IIR滤波器存在反馈环路,不具有线性相位特性,且频率选择性越好的非线性特性越显著。 有限脉冲响应(FIR) IIR滤波器的输出不仅依赖于当前和过去的输入样本,还依赖于过去的输出样本。它的冲激响应理论上会无限持续下去。 FIR滤波器的系统函数: $$ H(z)=\frac{\sum_{i=0}^Mb_iz^{-i}}{1-\sum_{l=1}^Na_lz^{-l}} $$ FIR滤波器不存在反馈环路,具有线性相位特性。 频域滤波器 有时噪声将在时域下难以处理,如信号频段内的强窄带干扰。然而这种干扰在频域下却很容易识别。频域滤波器正是将信号转换到频域进行处理,然后再转换回时域。 滤波器的特征参数 通带内允许的最大衰减$α_p$与阻带内允许的最小衰减$α_s$: $$ \alpha_{\mathrm{p}}=20\lg\frac{|H(\mathrm{e}^{\mathrm{j}\omega_{\mathrm{0}}})|}{|H(\mathrm{e}^{\mathrm{j}\omega_{\mathrm{p}}})|}\mathrm{dB}=-20\lg|H(\mathrm{e}^{\mathrm{j}\omega_{\mathrm{p}}})|(\mathrm{dB}) \\alpha_{\mathrm{s}}=20\lg\frac{|H(\mathrm{e}^{\mathrm{j}\omega_{0}})|}{|H(\mathrm{e}^{\mathrm{j}\omega_{\mathrm{s}}})|}\mathrm{dB}=-20\lg|H(\mathrm{e}^{\mathrm{j}\omega_{\mathrm{s}}})|(\mathrm{dB}) $$ 其中$\mid H(\mathrm{e}^{\mathrm{j}\omega_0})\mid$归一化为$1$。当$\frac{\mid H(\mathrm{e}^{\mathrm{j}\omega_{0}})\mid}{\mid H(\mathrm{e}^{\mathrm{j}\omega_{p}})\mid}=\frac{\sqrt{2}}{2}=0.707$时,$α_p=3dB$,称此时的$ω_p$为该低通滤波器的$3dB$通带截止频率。在信号处理中,3 dB 截止频率通常被认为是信号能量减半的点。 有限字长效应 在数字系统中主要有三种由于有限字长而引起误差的 因素。 模/数(A/D)转换器把模拟输入信号转换成一组离散电平时产生的量化效应; 用有限位二进制数表示系数时产生的量化效应; 在数字运算过程中,为限制位数进行的尾数处理和为防止溢出而压缩信号电平的有限 字长效应。 量化过程可以等效为在无限精度的数上叠加一个噪声: $$ x’(n)=Q[x(n)]=x(n)+e(n) $$ 滤波器运算中的字长效应 为什么不增加字长来保证运算过程不产生截尾或者舍入操作? 对于数字滤波器或较为复杂的电路系统来讲,通常会用到反馈网络,这样每一次闭环运算都会增加一部分字长,循环运算下去势必要求越来越多的寄存器资源,长的增加是单调增加的,也就是说,随着运算的持续,所需寄存器资源是无限增加的。 考虑一个一阶数字滤波器,系统函数为: $$ H(z)=\frac{1}{1+0.5z^{-1}} $$ 在无限精度运算的境况下,差分方程为: $$ y(n)=-0.5y(n-1)+x(n) $$ 在定点数运算中,每次乘加运算后都必须对尾数进行舍入或截尾处理,即量化处理,而 量化过程是一个非线性过程,处理后相应的非线性差分方程变为: $$ w(n)=Q[-0.5w(n-1)+x(n)] $$

May 9, 2025 · 1 min

常用电路

# 电源类 TL431基准电压源 输入电压必须大于输出电压1.2V以上。 $V_{ref}=2.495V$ $I_{ref}$非常小,只有2-4μA。 电阻$R_1$与$R_2$越精密,输出电压越准确。 带载电流1-100mA,$I_{KA} = V_{in}/R_{in}$。 $V_{KA}$的对地电容必须大于10uf。 典型应用: 2.5V电压基准

October 28, 2024 · 1 min

简单了解向量搜索

前言 最近看了篇文章,了解到了Vector Search。什么是Vector Search?来看看GPT的解释: 向量搜索是一种利用向量表示数据,并基于向量之间的相似性进行搜索的技术。它不同于传统的基于关键词的搜索,能够捕捉数据之间更深层次的语义关系,从而提高搜索的准确性和效率。 相较于基于关键词的搜索,将文本、图片等非数值型数据转换为向量形式,更能发现数据的特征,并发现数据之间的相似性。 至于如何将非数值型数据转换为向量,来开下面这个例子: 用“1”表示“是”,用“0”表示“否” 交通工具 轮子数量 有引擎吗 陆地上运动吗 最大承载人数 汽车 $4$ $1$ $1$ $4$ 自行车 $2$ $0$ $1$ $1$ 三轮车 $3$ $0$ $1$ $1$ 摩托车 $2$ $1$ $1$ $1$ 帆船 $0$ $0$ $0$ $20$ 轮船 $0$ $0$ $0$ $1000$ 把非数值型数据转换为向量,实际上就是把这些数据的特征用数值表示。比如对于汽车来说,它在这个例子中对应的向量就是$(4,1,1,4)$。 基础理论 向量之间的相似性 观察向量$\vec{a}$,$\vec{b}$和$\vec{p}$,哪个向量与$\vec{p}$更“相似”?向量$\vec{a}$与$\vec{p}$有着相同的方向,但模长更小;而$\vec{b}$与$\vec{p}$有着相同的模长,但方向只是相近。如果相似指的是方向上的相似,那么$\vec{a}$与$\vec{p}$更相似。而如果相似指的是模长,那么$\vec{b}$与$\vec{p}$更相似。 在矢量搜索中,很少单独根据模长来判断两个向量是否相似。相似性通常取决于方向,或者方向和模长。 相似性的评估方法 评估两个向量是否相似,通常有四种数学方法: 欧式距离:直接计算两个向量“箭头”的直线距离。 $d(\vec{a}, \vec{p}) = \sqrt{\sum_{i=1}^{n} (a_i - p_i)^2}$ $a_i$表示$\vec{a}$的第$i$个分量 曼哈顿距离:计算两个点之间沿着坐标轴行走的距离。 $d_1(\vec{a}, \vec{p}) = \sum_{i=1}^{n} |a_i - p_i|$ $a_i$表示$\vec{a}$的第$i$个分量 点积:将相同维度的分量相乘再相加。 $\vec{a} \cdot \vec{p} = \sum_{i=1}^{n}(a_i b_i)$ 余弦值:两个向量夹角的、余弦值。 $\cos(\theta) = \frac{\vec{a} \cdot \vec{b}}{|\vec{a}| |\vec{b}|}$ 这四种方法中,欧氏距离是最常用的,而曼哈顿距离与欧氏距离相似,应用这两种方法得到的结果通常也相似。而当需要评估相似性的向量模长一致时,使用余弦值是更好的方法,因为它只与夹角相关。点积与余弦值类似,但在需要大量计算的情况下,点积通常有着更好的性能。 简单的例子 由于在屏幕上呈现二维向量较为方便,因此选取前言中的“轮子数量”与“有引擎吗”作为特征。得到4个向量,分别是$(4,1),(2,0),(3,0),(2,1)$,它们在图上呈现为: 随后分别计算摩托车与自行车、三轮车、汽车的相似性:...

September 8, 2024 · 2 min

制作简单Magisk模块:音量阶数30阶

前言 手机默认音量阶数只有15阶,经常出现加一阶太大,减一阶又太小的情况。为了解决这个问题,可以制作一个Magisk模块,将音量阶数细分到30阶。以此来解决上述问题。 简单Magisk模块 Magisk模块的结构 为了将音量阶数修改为30阶,需要的东西其实非常少: MoudleName.zip │ ├── 📁META-INF │ └── 📁com │ └── 📁google │ └── 📁android │ ├── 📄update-binary │ └── 📄updater-script │ ├── 📄module.prop ├── 📄system.prop │ META-INF:Magisk官方提供,无需更改。 module.prop:模块信息。 system.prop:用来修改系统的build.prop。 module.prop的作用 module.prop id=<string> name=<string> version=<string> versionCode=<int> author=<string> description=<string> 名称 说明 id 模块唯一标识符 version 模块版本号 versionCode 模块版本标识,必须为整数 author 模块作者 description 模块描述 system.prop的作用 为了修改音量阶数为30阶,需要借由system.prop修改build.prop。system.prop中的配置会被替换到build.prop中的对应配置。 system.prop ro.config.media_vol_steps=29 ro.config.vc_call_vol_steps=29 ro.config.alarm_vol_steps=29 ro.config.system_vol_steps=29 ro.config.media_vol_default=10 // 开机时默认的音量大小,10表示10阶 小结 将打包成zip的模块安装到手机后重启,音量阶数便会被修改为30阶,并且初始音量大小为最大音量的1/3。经过测试,本人的手机(Redmi Note 12 Turbo, HyperOS)最多将音量阶数调整为30阶,超过这个数,修改就会无效。 更多关于Magisk模块的信息 一个功能丰富的Magisk模块的结构 module....

September 6, 2024 · 1 min

MSP430之时钟频率设置

写完这篇文章过了两天我才知道原来把官方例程下载下来可以用图形界面设置时钟。我是🐷 简介 MSP430有三个时钟,分别是MCLK、SMCLK、ACLK。 MCLK:主系统时钟。MCLK是CPU的运行时钟,MCLK频率越高,CPU运行越快,同时功耗越高。 SMCLK:子系统时钟。SMCLK可以提供给需要高速时钟的外设(如ADC、定时器。 ACLK:辅助时钟。辅助时钟的频率一般很低,功耗小,可以一直开启。 这三个时钟可由五个时钟源经过分频后提供,分别是XT1CLK、XT2CLK、VLOCLK、REFCLK、DCOCL。 XT1CLK(低频/高频时钟源):XT1CLK可以作为内部FLL模块的参考时钟,且它是FLL模块(频锁环模块)的默认参考时钟。FLL时钟除锁频之外还可以对时钟进行倍频或分频。 XT2CLK(高频时钟源):XT2CLK可以作为FLL的内部参考时钟。 VLOCLK(低频内部时钟源) REFCLK(低频时钟源,内部的参考时钟源):可以作为内部FLL的参考时钟。 DCOCLK(片内数字控制时钟源):通过内部FLL模块稳定,一般为1MHz。 其中XT1CLK、XT2CLK可由外部晶振提供。片内时钟源受温度影响大,频率一般不会很准确。 设置MSP430F5529的时钟 目的是将MCLK、SMCLK设置为XT2CLK(外部晶振 4Mhz)经过倍频后得到的24Mhz时钟;将ACLK设置为XT1CLK(外部晶振 32.768Khz)。 芯片的默认电压低,不足以支持高速的时钟频率,所以首先提升电压: PMM_setVCore(PMM_CORE_LEVEL_3); 设置XT1CLK与XT2CLK引脚为复用功能: GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,GPIO_PIN4 + GPIO_PIN5); GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,GPIO_PIN2 + GPIO_PIN3); 设置XT1CLK与XT2CLK外接晶振的频率: UCS_setExternalClockSource(32768,4000000); 开启XT1CLK与XT2CLK: UCS_turnOnLFXT1WithTimeout(UCS_XT1_DRIVE_0,UCS_XCAP_3,50000); UCS_turnOnXT2WithTimeout(UCS_XT2_DRIVE_4MHZ_8MHZ,50000); 将XT1CLK作为ACLK时钟源,XT2CLK作为FLL参考时钟源: UCS_initClockSignal(UCS_ACLK,UCS_XT1CLK_SELECT,UCS_CLOCK_DIVIDER_1) UCS_initClockSignal(UCS_FLLREF,UCS_XT2CLK_SELECT,UCS_CLOCK_DIVIDER_1); 提升MCLK的频率: UCS_initFLLSettle(24000, 6); // 6*4Mhz = 24Mhz 最后开启时钟源中断: SFR_clearInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT); SFR_enableInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT); 但我还有一个疑问,就是为什么不用使用UCS_initClockSignal函数将XT2CLK作为MCLK和SMCLK的时钟源,或者说将FLL参考时钟源设置为MCLK和SMCLK的时钟。我不这么做MCLK和SMCLK照样会被设置为XT2CLK倍频后的时钟。如果有大神知道原因,希望能留评论告诉我。 完整代码 clock.h #ifndef __CLOCK_H__ #define __CLOCK_H__ #include "driverlib.h" #define UCS_XT1_TIMEOUT 50000 #define UCS_XT2_TIMEOUT 50000 #define UCS_XT1_CRYSTAL_FREQUENCY 32768 #define UCS_XT2_CRYSTAL_FREQUENCY 4000000 #define UCS_MCLK_DESIRED_FREQUENCY_IN_KHZ 24000 #define UCS_MCLK_FLLREF_RATIO 6 void Clock_Init(void); #endif clock....

July 12, 2024 · 1 min