c - 检测正弦波的频率/周期

标签 c microcontroller avr trigonometry atmega

我只需要一些关于如何检测正弦波频率的指导。我通过 DtoA 转换器生成正弦波。现在,我将该信号通过 AtoD 传回以监视和验证输出。

我不知道如何检测正弦波的频率。显然,我应该从正弦波中获取周期并应用磁滞来补偿噪声。 任何提示都非常感激。谢谢。

最佳答案

如果这仅与正弦波有关,我会检查零交叉,并计算数百个周期的零交叉之间的平均时间,这将给出准确的半周期长度,据此,您可以计算频率。

(“零”可能并不重要,因为大多数 uC 仅具有 0-Vdd 范围 ADC 输入,因此在这种情况下零可能恰好是 Vdd/2...)

(非常简单)伪代码可能是

const zero = 0; //or vdd/2 if that's the case
while(cyclesSoFar<enoughCycles) {
    currentSample=adcRead();
    //detect zero crossing (needs hysteresis added)
    if((lastSample>zero&&currentSample<=zero) || (lastSample<zero&&currentSample>=zero) ) {
        period = getTicks()-ticksAtLastCrossing; //might have to check for over/underflow to get correct value
        avgPeriod = avgPeriod * (cyclesSoFar)/(cyclesSoFar+1) + period/(cyclesSoFar+1);
        cyclesSoFar++;
    }
    lastSample = currentSample;
}
freq = ticksFreq/(avgPeriod*2);

其中:enoughCycles是要测量的周期数,零是正弦波的DC偏移,ticksFreq是CPU的频率,即可用的最精确时间。当然,这是非常非常简化的,需要添加大量的绒毛和检查。

关于c - 检测正弦波的频率/周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13584644/

相关文章:

c - AVR C 编译器行为。内存管理

avr - AVR-GCC 是否可以与 16 位 AVR I/O 寄存器一起正常工作?

c - 错误 : unknown type name List when trying to create a Linked List

c++ - 在 Mac 上编写 C(和变体),并导出到 Mac 和 Windows

c - 如何将值从结构复制到字符数组

c - 为什么选择 Bitshift 运算符?

stm32中的Arduino millis()

c - InvalidateRect() 是否向子控件发送 WM_PAINT 消息?

c - 基准测试功能

c++ - 特定地址空间的预处理器指令