0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何从Raspberry Pi Pico的模数转换器捕获数据计算?

电子设计 来源:电路城 作者:电路城 2021-04-28 10:42 次阅读

了解如何在Raspberry Pi Pico上以高达500 kHz的频率采样并根据捕获的数据计算快速傅立叶变换。

硬件部件:

Raspberry Pi Pico× 1个

在此项目中,我们将使用一些特殊功能以极快的速度从Raspberry Pi Pico的模数转换器ADC)捕获数据,然后对数据进行快速傅立叶变换。这是许多项目的常见任务,例如涉及音频处理或广播的项目。

很可能您已经有了一个想要从中收集数据的传感器。就我而言,我有一个麦克风连接到Pico的A0输入。如果您只是来这里学习,则可以使模拟输入悬空而无任何连接。

您可以在GitHub上找到完整程序。

1.背景

Raspberry Pi Pico如此有用的一个主要原因是其众多的硬件功能使处理器从执行常规I / O任务中解放出来。在我们的例子中,我们将使用Pico的直接内存访问(DMA)模块。这是一项硬件功能,可以自动化任务,涉及以极快的速度将大量数据进出内存到IO。

可以将DMA模块配置为在准备好样本后立即将它们从ADC中取出。以最快的速度,您可以在高达0.5 MHz的频率下采样!

收集所有这些数据后,您可能需要对其进行一些处理。一个常见的任务是将您的信息从时域转换到频域以进行进一步处理。就我而言,我有一个麦克风,我想从该麦克风收集音频样本,然后计算样本中包含的最大频率分量。最常用的算法是快速傅立叶变换。

2. ADC采样代码

如果您还没有这样做,我强烈建议您在GitHub上克隆Raspberry Pi的pico-examples库。这是我用来开始的所有采样代码的地方。以下代码的很大一部分来自此存储库中的dma_capture示例。

我将介绍软件的一些关键要素,以解释发生了什么。您可以在“代码”部分找到完整的程序。

// set sample rate

adc_set_clkdiv(CLOCK_DIV);

这条线确定ADC收集样本的速度。“ clkdiv”是指时钟分频,它使您可以分割48 MHz基本时钟,以更低的速率进行采样。目前,一个样本需要96个循环来收集。这样得出的最大采样率是每秒48、000、000个循环/每个样本96个循环=每秒500、000个样本。

为了降低采样速度,可以增加时钟分频。将CLOCK_DIV设置为960将使每个样本的循环数增加10倍,从而每秒产生50000个样本。您猜到了,将CLOCK_DIV设置为9600可以得到每秒5 000个样本。

void sample(uint8_t *capture_buf) {

adc_fifo_drain();

adc_run(false);

dma_channel_configure(dma_chan, &cfg,

capture_buf, // dst

&adc_hw-》fifo, // src

NSAMP, // transfer count

true // start immediately

);

gpio_put(LED_PIN, 1);

adc_run(true);

dma_channel_wait_for_finish_blocking(dma_chan);

gpio_put(LED_PIN, 0);

}

该功能实际上是从ADC收集样本。处理器复位ADC,排空缓冲区,然后开始采样。它还将在采样期间打开LED,以便您查看正在发生的情况。

3. FFT代码

// get NSAMP samples at FSAMP

sample(cap_buf);

// fill fourier transform input while subtracting DC component

uint64_t sum = 0;

for (int i=0;i《NSAMP;i++) {sum+=cap_buf[i];}

float avg = (float)sum/NSAMP;

for (int i=0;i《NSAMP;i++) {fft_in[i]=(float)cap_buf[i]-avg;}

上面的这一部分用ADC的采样填充cap_buf数组,然后对其进行预处理以进行傅立叶变换库。对于许多应用程序,在对数据进行傅里叶变换之前,先从数据序列中减去平均值是有利的。否则,任何直流电平(信号偏移会超过零)将导致输出频点接近零而具有巨大的幅度。我使用的库KISS FFT期望信号具有浮点类型,因此我在减去均值的同时也转换了样本。

// compute fast fourier transform

kiss_fftr(cfg , fft_in, fft_out);

// compute power and calculate max freq component

float max_power = 0;

int max_idx = 0;

// any frequency bin over NSAMP/2 is aliased (nyquist sampling theorum)

for (int i = 0; i 《 NSAMP/2; i++) {

float power = fft_out[i].r*fft_out[i].r+fft_out[i].i*fft_out[i].i;

if (power》max_power) {

max_power=power;

max_idx = i;

}

}

float max_freq = freqs[max_idx];

printf(“Greatest Frequency Component: %0.1f Hz\n”,max_freq);

下一部分将计算FFT,然后计算输出数据中的最大频率分量。FFT的输出是复数值,因此要获得可用的功率值,可以取复结果的大小。

还要注意的是,与其循环遍历FFT的所有NSAMP输出值,我们仅对NSAMP / 2进行装箱。由于奈奎斯特采样定理,任何大于采样率1/2的频率都将被混叠在一起,因此这些bin对我们没有用。这是信号处理的基本结果,如果您不熟悉,则值得进一步研究!

就音频而言,人耳通常可以听到高达20 kHz左右的频率。我使用的CLOCK_DIV值为960,产生的采样率为50 kHz。因此,我可以捕获的最大非混叠频率为25 kHz,这应该绰绰有余!

// BE CAREFUL: anything over about 9000 here will cause things

// to silently break. The code will compile and upload, but due

// to memory issues nothing will work properly

#define NSAMP 1000

需要指出的最后一点代码是NSAMP或收集的样本数。在信号处理中,在较高和较低数量的样本之间存在一个基本的权衡。更多的样本将花费更长的时间来收集和处理,但是会产生更高分辨率的傅里叶变换。更少的样本将导致更短的采样周期和更快的处理,但是您的傅立叶变换将更加精细。

对于Pico,我发现分配过多的内存会导致难以调试的失败。如果您将NSAMP设置得太大,您的Pico将没有足够的内存来分配给保存样本的阵列。该代码仍然可以编译和上传,但是您可能会得到一些奇怪的行为。在我的示例中,将NSAMP保持在9000以下似乎很好。

3.编译和上传

如果尚未下载,请下载Raspberry Pi Pico入门。这是一个坚实的资源,可为您提供设置构建系统,编译C / C ++代码并将其上传到Pico所需的一切。

以下所有说明均适用于macOS / Linux,但我想Windows上的CMake也有类似的过程。

要编译我的代码,请先在GitHub上下载我的存储库。

导航到adc_fft目录

创建一个名为“ build”的目录

在其中导航,然后键入“ cmake 。./”

输入“ make”,如果正确安装了Pico构建系统,则所有内容均应编译

将您的Pico放入引导加载程序模式,然后将adc_fft.uf2文件拖放到出现的驱动器

那应该是全部!您可以通过USB监视程序的输出。它将在从A0采样的数据中输出最大频率分量,并且LED应该快速闪烁。
责任编辑:pj

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 处理器
    +关注

    关注

    68

    文章

    18038

    浏览量

    221547
  • adc
    adc
    +关注

    关注

    95

    文章

    5629

    浏览量

    538916
  • 模数转换器
    +关注

    关注

    25

    文章

    2287

    浏览量

    125776
收藏 人收藏

    评论

    相关推荐

    数模和模数转换器

    数模和模数转换器数模和模数转换器能将模拟量转换为数字量的电路称为模数转换器,简称A/D转换器或ADC;能将数字量
    发表于 09-16 15:59

    NXP 高速模数转换器

    NXP 高速模数转换器
    发表于 08-14 12:34

    SAR模数转换器AD7989-1和AD7989-5

    。 PulSAR组合包括18位和16位模数精密转换器,吞吐速率100 kSPS到1 MSPS.  以上两款模数转换器均提供一条丰富多样的引脚兼容型性能升级/降级途径,适用于多种市场,
    发表于 11-29 11:09

    AD7944 14位PulSAR模数转换器

    EVAL-AD7944FMCZ,评估板,用于评估AD7944 14位PulSAR模数转换器。板载组件包括高精度,缓冲带隙5V基准电压源(ADR435),基准电压缓冲(AD8032),带两个
    发表于 04-10 10:35

    5962-9581501HXA高端AD模数转换器

    AD10242TZ/883B高端AD模数转换器IC ADC 12BIT 41MSPS DL 68CLCC5962-9581501HXA高端AD模数转换器IC ADC 12BIT 2 CH
    发表于 07-15 11:10

    什么是光学模数转换器?原理是什么?有哪些技术指标?

    什么是光学模数转换器?光学模数转换器的主要技术指标光学模数转换器的研究进展光学模数转换器的应用
    发表于 04-20 06:52

    Raspberry Pi Pico是什么

    Waveshare给您介绍一款树莓派家族的新成员,Raspberry Pi Pico 是一款低成本,高性能的微控制开发板,具有灵活数字接口。硬件上,采用
    发表于 07-14 07:02

    模数转换器(ADC)的配置有哪些流程?

    模数转换器(ADC)是什么?模数转换器(ADC)的配置有哪些流程?配置流程的代码是什么?
    发表于 07-14 08:43

    STM32之ADC模数转换器介绍

    ADC模数转换器是什么?ADC模数转换器的相关寄存有哪些?
    发表于 11-08 08:47

    什么是模数转换器

    什么是模数转换器
    发表于 01-24 07:46

    模数转换器的相关资料分享

    模数转换器(Analog To Digital Converter)简称ADC(也可以写成A/D),是指将连续变化的模拟信号转换为离散的数字信号的器件。 直接存储存取技术(Direct
    发表于 02-07 08:29

    使用raspberry pi Pico的原因

    使用raspberry pi Pico的原因在硬件产品(单片机)的开发中我们往往需要借助一些额外的仪器/设备进行产品的辅助测试, 假设我们需要一个IO+ADC类型辅助设备, 以往的做法是 原理图
    发表于 02-07 09:16

    Raspberry Pi 4/3B的Pico开发板

    英国 Raspberry Pi 设计的全新微控制芯片。”控制电器到操作灯光显示Raspberry
    发表于 07-26 07:14

    为什么我们需要模数转换器?哪个ADC转换器更好?

    完成模数转换。为什么我们需要模数转换器计算机软件、无线电和数字图像采集都需要ADC转换器的辅助,即人类数字化的浪潮推动了ADC
    发表于 02-15 18:16

    适用于Raspberry Pi 4的Raspberry Pi Pico开发板

    电子发烧友网站提供《适用于Raspberry Pi 4的Raspberry Pi Pico开发板.zip》资料免费下载
    发表于 07-22 09:27 6次下载
    适用于<b class='flag-5'>Raspberry</b> <b class='flag-5'>Pi</b> 4的<b class='flag-5'>Raspberry</b> <b class='flag-5'>Pi</b> <b class='flag-5'>Pico</b>开发板