【问题标题】:how to offload precise ADC oversampling with RISC-V GD32VF103CBT6 Development Board如何使用 RISC-V GD32VF103CBT6 开发板卸载精确的 ADC 过采样
【发布时间】:2020-07-08 15:37:19
【问题描述】:

我希望使用RISC-V GD32VF103CBT6 Development Board 制作一个非常基本的音频效果设备。我已经设法用另一个 MCU 进行了一些基于硬件中断的采样,但我对 RISC-V 板的文档有点困惑。 Chapter 11 in the user manual。我一点也不知道如何将那里的指令转换为实际的 C/C++ 代码。可悲的是,他们的github repo 几乎没有任何示例,而且似乎也没有处理高速采样。 this github repo 中还有一个数据表,但我也无法在其中找到任何具体的代码示例或说明。

我想做的是:

  • 执行用户手册中描述的校准,必须先于采样操作。
  • 利用其过采样功能从外部引脚收集音频信号电压的 12 位音频样本,以高采样率将多个 12 位样本汇总为单个 16 位样本。最终,我希望以 16 位 48khz-96khz 采样音频。
  • 我需要帮助指示 MCU 使用其内置硬件功能收集这些样本。
  • 我想连续采样,尽可能多地卸载到内置硬件功能,这样我就可以留出足够的处理开销来进行一些信号处理以获得简单的效果。

第 11.4.1 节明确说明

在开始 A/D 转换之前应进行校准。 校准由软件通过设置位 CLB=1 来启动。在整个校准序列期间,CLB 位保持为 1。一旦校准完成,它就会被硬件清零。 内部模拟校准可以通过设置ADC_CTL1寄存器的RSTCLB位来复位。

Calibration software procedure:
1) Ensure that ADCON=1.
2) Delay 14 ADCCLK to wait for ADC stability
3) Set RSTCLB (optional)
4) Set CLB=1.5.Wait until CLB=0.

问题 1:如何按照这些说明设置这些内存寄存器。我需要一个代码示例,制造商没有提供。

问题 2:我如何在 C/C++ 中delay 14 ADDCCLK。似乎循环将非常低效。我应该打电话给sleep() 吗?对 ADDCCLK 的任何解释也很有帮助。

这似乎也很重要,但我不知道它预示着什么:

时钟控制器提供的ADCCLK时钟为同步APB2时钟。 RCU 控制器有一个专用于 ADC 时钟的可编程预分频器。

不确定但我认为这是我想要的转换模式:

连续转换模式

此模式可以在常规频道组上运行。当 ADC_CTL1 寄存器中的 CTN 位置位时,将启用连续转换模式。在此模式下,ADC 在 RSQ0[4:0] 中指定的通道上执行转换。当 ADCON 设置为高电平时,一旦相应的软件触发或外部触发有效,ADC 就会对指定通道进行采样和转换。转换数据将存储在 ADC_RDATA 寄存器中。

在常规频道上进行连续转换的软件程序。为了摆脱检查,可以使用 DMA 来传输转换后的数据:

1.Set the CTN and DMA bit in the ADC_CTL1 register
2.Configure RSQ0 with the analog channel number
3.Configure ADC_SAMPTx register
4.Configure ETERC and ETSRC bits in the ADC_CTL1 register if in need
5.Prepare the DMA module to transfer data from the ADC_RDATA.
6.Set the SWRCST bit, or generate an external trigger for the regular group

【问题讨论】:

  • @KamilCuk 我已经编辑了帖子以删除评论。 SO 和 SE 的挑剔程度非常惊人。
  • 如果有人投票结束某个问题,难道不鼓励给出应该结束该问题的理由吗?
  • how to set the registers and collect the samples on this specific platform 一切都在手册中。 11.8.ADC registers 显示寄存器地址。您可以通过取消引用地址来手动控制它们,例如。 *(volatile uint32_t*)0x40012404 |= 1 << 23; 将设置RWDEN ADC0 寄存器的ADC_CTL0 位(如果我数正确的话)。您只需写入指定的内存地址 - 这就是您与硬件通信的方式。您的问题非常广泛——您问如何控制寄存器、如何设计整个应用程序、如何选择 ADC 模式以及如何延迟。研究数据表。
  • 通常供应商分发整个 HAL 以与硬件进行通信并进行抽象。搜索 github for that mcu 会得到很多点击,包括许多为 rust 编写的 HAL 似乎很受欢迎,但也有 ag whole standard library for that mcu by risc-mcu。在里面你可以找到例子和a calibration function for example。 Github 如果满是代码。
  • 我建议从这个问题中删除 DMA。您肯定想将它用于高速采样,但它本身将是一两个问题。

标签: c++ c microcontroller sampling hardware-acceleration


【解决方案1】:

ADCCLK 指 ADC 的输入时钟。可以看看你的数据表。大多数 µC 都有一个 µC 时钟架构的框图,通常有一个主系统时钟,然后不同的外设有一个您可以编程的预分频器,它将系统时钟除以 2 的某个幂。

所以14 ADCCLK 周期意味着它不是 14 个 CPU 周期,而是 14 个 ADC-Input-Clock 边沿。 例如,如果 ADC 预分频器设置为 64,那么您必须等待 64*14 个 CPU 时钟周期。

如何等待:
大多数情况下(我不知道您的设备上是否存在这种情况)外围设备有一个忙标志,只要当前操作正在进行,就会设置该标志。所以也许你可以轮询这个标志(例如while (ADC0_FLAGS & ADC_ISBUSY);)。

另一个选项可能是检查是否有中断表示您的操作已完成。但至少对于校准来说,最简单的方法是开始校准并使用waitdelay 函数,这只是浪费一点时间。

我个人会在系统启动时开始校准,然后进行其他初始化工作。设置结束时可能会延迟几毫秒,以确保板上的所有组件都正确上电。之后ADC应该已经完成​​了很长时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-20
    • 2014-11-05
    • 1970-01-01
    • 2020-06-02
    • 2019-07-07
    相关资源
    最近更新 更多