矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 2740|回复: 13

利用ADC采集的离散点精确估计幅值相位

[复制链接]
     
发表于 2024-4-15 15:59:31 | 显示全部楼层 |阅读模式
利用ADC对正弦波进行采样,获得其幅度和相位,是十分常见的需求。然而ADC采集的点是离散的,一个周期内,即便是采集100个点,也可能采集不到正弦波的顶点,更何况ADC有误差和抖动,因此不能直接用离散的点估计正弦波幅值。
因此本人设计了一种简单的暴力算法,在不要求速度的场合十分简单好用,其思路如下:
设离散的正弦波点为x[n]
一、利用正弦波点的最大值max(x[n])估计正弦波的幅值,作为初始幅值A
二、定义误差函数sum(x[n] - Asin(wt + k)),sum()表示求和
三、在k = [0, 3.14]内,取一千个k值,计算误差函数,误差最小的相位值代替初始相位值
四、在max(x[n])附近搜索,计算误差函数,误差最小的幅值代替初始幅值
五、重复三四步骤,直到误差不再减小
上述方法,利用误差函数,能够兼顾所有的数据点,因此精度很高。这种方法适合频率精确已知、噪音较小的ADC采集信号,对于干扰大、频率未知的信号,应该先设法滤波再用此法处理。
     
发表于 2024-4-15 16:55:38 | 显示全部楼层
本帖最后由 MF35_ 于 2024-4-15 16:59 编辑

没必要,根据数字相干检波算法计算就可以了
假设信号为S,每个周期采样N个点,每个采样点的值为Sn,n=0...N-1
然后对n=0...N-1的Sn*cos(2*pi*n/N)求和,得到S在x轴上的投影
然后对n=0...N-1的Sn*sin(2*pi*n/N)求和,得到S在y轴上的投影

根据x和y轴的投影关系,就可以计算出相位了,精度取决总采样数的大小,可以取比较大的N,采样单周期,也可以取比较小的N而通过采集M个周期得到M*N个点来提高精度,因此N只要满足奈奎斯特定理即可,M*N越大,相位精度越高

比较快速的计算是N=4,这样cos(2*pi*n/N)就是1、0、-1、0,sin(2*pi*n/N)就是0、1、0、-1,因此不需要乘法,每个周期只需要用其中两个采样点相减即可,想要提高精度只需要增加总采样个数就行,这才是简单粗暴
回复 支持 2 反对 0

使用道具 举报

     
 楼主| 发表于 2024-4-15 16:00:39 | 显示全部楼层
误差函数写错了,应该是sum[(x[n] - Asin(wt + k))^2],不平方的话正负抵消就不对啦
回复 支持 反对

使用道具 举报

     
发表于 2024-4-15 16:16:01 | 显示全部楼层
本帖最后由 量子隧道 于 2024-4-15 16:29 编辑

迭代也行,但是有更简单的方法。既然频率已知,那么以数字方式生成生成这个频率的复指数信号,即sin与cos,有时也称作I基和Q基,然后用这个信号与待测波形内积就行了。不需迭代,一个连乘加就搞定了。
积出来的两个数,就是待测波形在正弦轴和余弦轴上的投影,也即实虚部。再把它们从实虚格式转成模角格式就行了。
回复 支持 反对

使用道具 举报

     
发表于 2024-4-15 17:10:56 | 显示全部楼层
本帖最后由 量子隧道 于 2024-4-15 17:12 编辑

这玩意本质上就是希尔伯特空间求在基矢上的投影。待测数列是个矢量。sin和cos是基矢。求矢量在基矢上的投影。咋求?内积。mf35和我说的就是内积。内积是啥?乘加。
所以,用高等数学的概念做事,很多时候更简单。
回复 支持 反对

使用道具 举报

     
发表于 2024-4-16 09:27:31 | 显示全部楼层
量子隧道 发表于 2024-4-15 17:10
这玩意本质上就是希尔伯特空间求在基矢上的投影。待测数列是个矢量。sin和cos是基矢。求矢量在基矢上的投影 ...


其实楼主的做法类似我们中学的时候用高中代数求解微积分问题,属于理解简单,操作复杂的方法,而直接用高等数学的方法,属于理解困难,但操作方便的方法,写出的算法效率更高
回复 支持 反对

使用道具 举报

     
发表于 2024-4-16 09:49:00 | 显示全部楼层
这不就是离散傅里叶变换吗,自己弄个excel按公式算一下就出来

http://www.crystalradio.cn/forum ... ead&tid=1954474

回复 支持 反对

使用道具 举报

     
发表于 2024-7-1 14:40:50 | 显示全部楼层
MF35_ 发表于 2024-4-15 16:55
没必要,根据数字相干检波算法计算就可以了
假设信号为S,每个周期采样N个点,每个采样点的值为Sn,n=0... ...

请问这个跟DFT变换有啥联系么?
回复 支持 反对

使用道具 举报

     
发表于 2024-7-1 15:12:20 | 显示全部楼层
本帖最后由 MF35_ 于 2024-7-1 15:15 编辑
world_all 发表于 2024-7-1 14:40
请问这个跟DFT变换有啥联系么?



点和线的关系

假如对一个未知频谱的信号采样,为了知道信号的组成,需要对期望频谱内每个离散的频点使用这个算法,最后得到一个离散的频谱,这就是DFT

而如果信号频率已知,需要测量信号的幅度和相位,只需要针对这个频点使用这个算法就可以了

你可以理解为这个算法是DFT的基础,DFT就是对一个采样率列多次(每次一个频点)使用这个算法,这个算法是点,DFT是线。DFT算法就是用一个参数可变的过滤器,通过调整参数,从信号采样序列中分辨出每一个频率的特性,如果我们只关心其中一个频率的特性,只需要对采样序列使用一个特定参数的过滤器即可。

而FFT则不同,FFT是进行了优化的DFT算法,而这个优化的原理是针对正个频谱的,所以FFT算法在这种对已知频率单独求解的场合没有任何意义
回复 支持 反对

使用道具 举报

     
发表于 2024-7-1 16:50:17 | 显示全部楼层
MF35_ 发表于 2024-7-1 15:12
点和线的关系

假如对一个未知频谱的信号采样,为了知道信号的组成,需要对期望频谱内每个离散的频 ...

谢谢老师解答
回复 支持 反对

使用道具 举报

     
发表于 2025-1-4 12:19:49 | 显示全部楼层
MF35_ 发表于 2024-4-15 16:55
没必要,根据数字相干检波算法计算就可以了
假设信号为S,每个周期采样N个点,每个采样点的值为Sn,n=0... ...

请教老师下,这个算待测信号(频率已知)的幅度是不是  Q = Sn * SIN(2*pi*n/N)  ,  I=Sn * COS(2*pi*n/N)运算后,求和取平均值Q1,I1,然后 幅度= 2*根号下(Q1*Q1 + I 1* I1), 我按照这个方法,在matlab上是可以求得幅度 ,但移植至到单片机上,算出来的幅度比matlab上的少了2百多个数字,是哪里出了问题呢?
回复 支持 反对

使用道具 举报

     
发表于 2025-1-5 08:37:03 | 显示全部楼层
采集100個點也太少了,怎麽也得1024個以上吧?只要被測波形的頻率沒有快速變動,過采樣是最簡單最粗暴也是最好的方法。
回复 支持 反对

使用道具 举报

     
发表于 2025-1-9 11:36:29 | 显示全部楼层
world_all 发表于 2025-1-4 12:19
请教老师下,这个算待测信号(频率已知)的幅度是不是  Q = Sn * SIN(2*pi*n/N)  ,  I=Sn * COS(2*pi*n/ ...

你单片机用的是float还是double,用double试一下,如果你用了整型,很可能是溢出丢失
回复 支持 反对

使用道具 举报

     
发表于 2025-1-9 15:03:57 | 显示全部楼层
没太明白楼主的意图。
是测量正弦波的峰值?相位是指相对另一个正弦波的吧?
如果是对信号采样、处理,那就要符合奈奎斯特采样定理,或者是带通采样定理。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-27 15:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表