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

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

3天内不再提示

如何优化MCU SPI驱动程序以实现高ADC吞吐速率

jf_pJlTbmA9 来源:ADI智库 作者:ADI智库 2023-10-24 16:03 次阅读

随着技术的进步,低功耗物联网(IoT)和边缘/云计算需要更精确的数据传输。图1展示的无线监测系统是一个带有24位模数转换器(ADC)的高精度数据采集系统。在此我们通常会遇到这样一个问题,即微控制单元(MCU)能否为数据转换器提供高速的串行接口

本文描述了设计MCU和ADC之间的高速串行外设接口(SPI)关于数据事务处理驱动程序的流程,并简要介绍了优化SPI驱动程序的不同方法及其ADC与MCU配置。本文还详细介绍了SPI和直接存储器访问(DMA)关于数据事务处理的示例代码。最后,本文演示了在不同MCU(ADuCM4050、MAX32660)中使用相同驱动程序时ADC的吞吐率。

wKgaomUDx9yARouvAAJrkq1oa-s585.png

图1. 状态监控。

通用SPI驱动程序简介

通常,MCU厂商会在例程代码中提供通用的SPI驱动程序/API。通用SPI驱动程序/API通常可以涵盖大多数用户的应用,这些代码可能包含许多配置或判断语句。但在某些特定情况下,比如ADC数据采集,通用的SPI驱动程序可能无法满足ADC数据的全速的吞吐速率需求,因为通用的驱动程序中有过多的配置,而未使用的配置会产生额外的开销并导致时间延迟。

wKgaomUDx96AbO2tAAFGiAu06YQ924.png

图2. 通用API的配置。

设计思路与实践框架

我们通常会选择低功耗高性能的MCU作为主机通过SPI提取ADC的输出数据。但是,由于ADI的SPI驱动程序的数据事务处理命令存在冗余,因此数据输出速率可能被显著降低。为了充分释放ADC的潜在速率,本文使用ADuCM4050和AD7768-1进行实验并尝试可能的解决方案。尽管在使用默认滤波器的情况下,ADuCM4050的最大数据输出速率可达256 kHz,但在当前情况下,其速率被限制在8 kHz。提高输出速率的潜在解决方案包括删除不必要的命令以及激活DMA控制器。本文将在以下小节中介绍这些思路。

wKgZomUDx-CAKXf_AAJSJ8xyk_E905.png

图3. 不同ODR以及DRDY与SCLK之间的关系。

以MCU作为主机

ADuCM4050 MCU是一款主时钟速率为26 MHz的超低功耗微控制器,内核为ARM® Cortex®-M4F处理器。ADuCM4050配有三个SPI,每个SPI都有两个DMA通道(接收和发射通道)可与DMA控制器连接。DMA控制器和DMA通道可实现存储器与外设之间的数据传输。这是一种高效的数据分配方法,可将内核释放以处理其他任务。

以ADC作为从机

AD7768-1是一款24位低功耗、高性能的Σ-Δ ADC。其数据输出速率 (ODR)和功耗模式均可根据用户的要求进行配置。ODR由抽取系数和功耗模式共同决定,如表1中所示。

表1. 数据输出速率的功耗模式配置

wKgZomUDx-KAfFZ5AAGoq9w8Xew262.png

AD7768-1的连续读取模式也是该产品的一个重要特性。ADC的输出数据存储在寄存器0x6C中。一般而言,每次读/写操作之前,ADC寄存器中的数据都需要地址才可以访问,但是连续读取模式则支持在收到每个数据就绪信号后直接从0x6C寄存器提取数据。ADC的输出数据为24位的数字信号,对应的电压如表2 所示。

表2. 数字输出码和模拟输入电压

wKgaomUDx-SAVhfhAAGNLP-RwtQ214.png

引脚连接示意图

ADuCM4050和AD7768-1组成的数据事务处理示例模型的引脚连接如图4所示。

wKgaomUDx-aAIjpOAAFAuR9oAlQ190.png

图4. AD7768-1和ADuCM4050的接口引脚连接。

ADC的复位信号引脚RST_1连接至MCU的GPIO28,而数据就绪信号引脚DRDY_1则连接至MCU的GPIO27。其余引脚则根据通用的SPI配置标准进行连接,其中MCU为主机,而ADC为从机。SDI_1接收MCU发送的ADC寄存器读/写命令,而DOUT_1则将ADC的输出数据发送至MCU。

数据事务处理的实现

中断数据事务处理

为实现连续数据事务处理,本文将MCU的GPIO27引脚(连接至ADC 的DRDY_1引脚)用作中断触发引脚。ADC将数据就绪信号发送至 GPIO27时会触发MCU包含数据事务处理命令的中断回调函数。如图5所示,数据采集必须在中断A和中断B之间的时间间隔内进行。

wKgZomUDx-eAEA91AABcqK8yY5Q599.png

图5. 两次中断的时间间隔。

利用ADI的SPI驱动程序可以在ADC和MCU之间轻松实现数据事务处理。但是,由于驱动程序内存在冗余命令,ADC的ODR会被限制在8 kHz。本文尽可能地精简了代码以加快ODR,将介绍实现DMA 数据事务处理的两种方法:基本模式的DMA事务处理和乒乓模式 的DMA事务处理。

基本模式的DMA事务处理

在实现每个DMA事务处理之前需要对SPI和DMA进行配置(参见图6 中的示例代码)。SPI_CTL为SPI配置,其值为0x280f,源于ADI的SPI 驱动程序的设定值。SPI_CNT为传输字节数。由于每个DMA事务处理只能发送固定的16位数据,因此SPI_CNT必须是2的倍数。本例设置SPI_CNT为4,以满足ADC的24位的输出数据要求。SPI_DMA寄存器为SPI的DMA使能寄存器,设定其值为0x5以使能DMA接收请求。命令pADI_DMA0->EN_SET=(1<<5)使能第五个通道的DMA,即SPI0 RX。

wKgZomUDx-mAb5USAAPD16rqJAA659.png

图6. 基本DMA事务处理模式的代码。

每个DMA通道都有一个DMA结构寄存器,如表3中所示。需要指出的是,这里的数据来源地址的结尾(即SPI0 Rx,亦即来源端指针SRC_END_PTR)在整个操作期间无需增加,因为Rx FIFO会自动 将寄存器中的数据推送出去。另一方面,数据目标地址的结尾(即目标端指针DST_END_PTR)根据ADI的SPI驱动程序的使用函数计算得出,即目标地址+ SPI_CNT -2。

表3. DMA结构寄存器

wKgaomUDx-uAZVcHAAC0I7pnPRk964.png

当前地址为内部数组缓冲区的地址。DMA控制数据配置CHNL_CFG 包括来源数据大小、来源地址增量、目标地址增量、剩余传输次数和DMA控制模式等设置,其值0x4D000011按照表4中所述的设置配置。

表4. 控制数据配置0x4D00011的DMA配置

wKgaomUDx-yAI9KeAAGMhac99iU352.png

SCLK时钟通过伪读取命令SPI_SPI0 -> RX启动,输出数据通过MISO 从ADC传至MCU。MOSI上其它的数据传输可以忽略不计。一旦完成 Rx的FIFO填充,DMA请求就会生成从而激活DMA控制器,以将数据从 DMA来源地址(即SPI0 Rx FIFO)传输至DMA目标地址(即内部数组的缓冲区)。值得注意的是,SPI_DMA=0x3时会生成Tc请求。

最后,通过将当前目标地址加4的方式将目标地址用于下一个4 字节的传输。

请注意,SPI0 DMA通道的pADI_DMA0->DSTADDR_CLR和pADI_ DMA0->RMSK_CLR必须在首次中断触发之前在主函数中设置。前一个为DMA通道目标地址减量使能清零寄存器,用于在增量模式下设置每次DMA传输后的目标地址移位(目标地址计算函数仅在增量模式下有效)。后一个为DMA通道请求屏蔽清零寄存器,用于将通道的DMA请求状态清零。

基本模式的DMA事务处理时间图如图7a所示。图中三个时隙分别代表DRDY信号、SPI/DMA设置和DMA数据事务处理。在该模式中,CPU的空闲时间较多,因此希望DMA控制器在处理数据传输时能将任务分配给CPU。

wKgZomUDx-6ARxkSAAEeNjmRWsA212.png

图7. (a)基本模式DMA和(b)乒乓模式的时间图。

乒乓模式的DMA事务处理

在执行伪读取命令后,DMA控制器会开始数据事务处理,从而使得MCU的CPU处于空闲状态而不处理任何任务。如果能够让CPU和 DMA控制器同时工作,那么任务处理就从串行模式转变为并行模式。这样,就可以同时进行DMA配置(通过CPU)以及DMA数据事务处理(通过DMA控制器)。为实现这一思路,需要设置DMA控制器处于乒乓模式。乒乓模式将两组DMA结构进行了整合:主结构和备用结构。每次DMA请求时,DMA控制器会在两组结构之间自动切换。变量p的初始设置为0,其值表示是主DMA结构(p = 0) 还是备用DMA结构(p = 1)负责数据事务处理。如果p = 0,则在收到伪读取命令时启动主DMA结构进行数据事务处理,同时会为备用DMA结构分配值,使其在下一个中断周期内负责数据事务处理。如果p = 1,则主结构和备用结构的作用互换。当仅有主结构处于基本DMA模式时,在DMA事务处理期间对DMA结构的修改会失败。乒乓模式使得CPU能够访问和写入备用DMA结构,而DMA控制器可以读取主结构,反之亦然。如图7b所示,由于DMA的结构配置是在最后一个周期内完成的,因此在DRDY信号从ADC传送至 MCU后DMA数据事务处理可以被立即执行,使得CPU和DMA同时工作而无需等待。现在,ADC的ODR得到了提升空间,因为总的工作时间已大大缩短。

中断处理程序的优化

两次DRDY信号之间的时间间隔不仅包括了中断回调函数的命令执行时间,还包括了ADI的GPIO中断处理函数的命令执行时间。

当MCU启动时,CPU会运行启动文件(即startup.s)。所有事件的处理函数均在该文件中定义,包括GPIO中断处理函数。一旦触发GPIO中断,CPU就会执行中断处理函数(即ADI的GPIO驱动程序中的GPIO_A_INT_HANDLER和GPIO_B_INT_HANDLER)。通用的中断处理函数会在所有的GPIO引脚中搜索触发中断的引脚并清零其中断状态、运行回调函数。由于DRDY是本文应用的唯一中断信号,因此可以对函数进行简化以加快进程。可选的解决方案包括 (1)在启动文件中重新定位目标,以及(2)修改原始的中断处理函数。重新定位目标意味着自定义中断处理函数,并替换启动文件中的原始的中断处理函数。

而修改原始的中断处理函数只需要添加一个自定义的GPIO驱动程序。本文采用第二种方案修改原始的中断处理函数,如图8所示。该方案只将连接至DRDY的GPIO的引脚中断状态清零,并直接转到回调函数。请注意,这里需要通过取消选择build target中关于原始GPIO驱动函数的勾选框内容来隔离原始的GPIO驱动程序。

wKgZomUDx--AUzGJAAFEBW2UgyU758.png

图8. 嵌套矢量中断控制器(NVIC)。

结果

速率性能

假定现在需要读取200个24位的ADC输出数据,并且SPI位速率设置为13 MHz。将DRDY信号和SCLK信号的引脚连接至示波器,可以通过观察DRDY信号与SPI数据事务处理(亦即DMA事务处理)启动之间的时间间隔的方法可以量化本文所述的每种方法对速率的改善程度。这里将DRDY信号至SCLK信号开始的时间间隔记为∆t,那么对于13 MHz的SPI速率,测量得出的∆t为:

(a)基本模式DMA Δt = 3.754 μs

(b)乒乓模式DMA Δt = 2.8433 μs

(c)乒乓模式DMA(使用优化的中断处理函数)Δt = 1.694 μs

方法(a)和(b)可支持64 kHz的ODR,而方法(c)可支持128 kHz的ODR。这是因为方法(c)的∆t最短,从而使得SCLK信号能够更早结束。如果 SCLK信号(即数据事务处理)能在T/2之前完成(T为当前ADC的数据输出周期),则ODR可实现翻倍。这较之于原始的ADISPI驱动程序可以达到的8 kHz的ODR性能是一次巨大的进步。

wKgaomUDx_GAL3gQAARZrfiXE-g313.png

图9. (a)基本模式DMA、(b)乒乓模式以及(c)乒乓模式(使用优化的中断处理函数)的Δt。

使用MAX32660控制AD7768-1

使用主时钟速率为96 MHz的MCU MAX32660控制AD7768-1)时的结果如何?在该情况下,使用优化的中断处理函数的中断设置,可在不使用DMA函数的情况下实现256 kHz的数据输出速率。参见图10。

wKgaomUDx_OAG82cAAGw99vIph4544.png

图10. 不使用DMA时MAX32660的ODR。

结论

本文利用选定的ADC(AD7768-1)和MCU(ADuCM4050或MAX32660)通过 SPI实现了高速的数据事务处理。为实现速率优化的目标,本文简化了ADI的SPI驱动程序执行数据事务处理。此外本文提出,激活DMA控制器释放内核也可以加快连续数据事务处理的流程。在 DMA的乒乓模式下,DMA的配置时间可通过适当的调度来节省。在此基础上,还可以通过直接指定中断引脚的方式优化中断处理函数。在13 MHz的SPI位速率下,本文提出的方案的最佳性能可达到128 kSPS的ADC ODR。

表5. 使用ADuCM405和MAX32660实现的高速SPI连接

wKgZomUDx_SAWKpXAALdQtXjGe8837.png

来源:ADI智库

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理

审核编辑 黄宇

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

    关注

    146

    文章

    16017

    浏览量

    343627
  • adc
    adc
    +关注

    关注

    95

    文章

    5651

    浏览量

    539474
  • 数据采集
    +关注

    关注

    38

    文章

    4523

    浏览量

    112313
  • SPI
    SPI
    +关注

    关注

    17

    文章

    1615

    浏览量

    89600
  • 驱动程序
    +关注

    关注

    19

    文章

    770

    浏览量

    47234
收藏 人收藏

    评论

    相关推荐

    怎么编写Framebuffer驱动程序

    Framebuffer 驱动程序框架 分为上下两层: fbmem.c:承上启下 实现、注册 file_operations 结构体 把 APP 的调用向下转发到具体的硬件驱动程序
    的头像 发表于 03-22 09:13 158次阅读
    怎么编写Framebuffer<b class='flag-5'>驱动程序</b>

    使用TSIP驱动程序(Azure RTOS)的TLS实现示例

    电子发烧友网站提供《使用TSIP驱动程序(Azure RTOS)的TLS实现示例.pdf》资料免费下载
    发表于 01-31 10:13 3次下载
    使用TSIP<b class='flag-5'>驱动程序</b>(Azure RTOS)的TLS<b class='flag-5'>实现</b>示例

    ch341a驱动程序无法使用

    随着计算机技术的不断发展,各种外部设备的驱动程序成为了保证硬件正常工作的重要一环。然而,有时我们可能会遇到ch341a驱动程序无法使用的问题。本文将详细解释该问题的原因,并提供详实、细致的解决方法
    的头像 发表于 12-26 14:17 1326次阅读

    能否用MCU访问非标准SPI接口?

    当前许多精密模数转换器(ADC)具有串行外设接口(SPI)或某种串行接口,用以与包括微控制器单元(MCU)、DSP和FPGA在内的控制器进行通信。控制器写入或读取ADC内部寄存器并读取
    的头像 发表于 12-23 12:25 522次阅读
    能否用<b class='flag-5'>MCU</b>访问非标准<b class='flag-5'>SPI</b>接口?

    ADC中的吞吐速率如何理解,它与采样速率是否等同呢?

    ADC中的吞吐速率如何理解,它与采样速率是否等同呢?从网上查了些,但是解释的不太清晰。望能解答,谢谢!!!
    发表于 12-19 06:31

    MCU(M4)通过SPI连接AD7689,期望可以用4KHz的速率依次轮询ADC的每个通道,用哪种采样模式较好?

    MCU(M4)通过SPI连接AD7689,期望可以用4KHz的速率依次轮询ADC的每个通道(4*8=32K),用哪种采样模式较好?如果不希望CPU干预模式(操控CNV信号),直接用DM
    发表于 12-12 06:46

    linux驱动程序的主要流程和功能

    驱动程序是用于控制和管理硬件设备的软件模块,它主要负责与设备进行交互,通过操作设备的寄存器和接口,实现对硬件的控制和访问。在Linux系统中,驱动程序实现与硬件设备交互的一个关键部分
    的头像 发表于 12-08 14:56 778次阅读

    利用SPI控制器控制nRF24L01射频模块的驱动程序设计

    电子发烧友网站提供《利用SPI控制器控制nRF24L01射频模块的驱动程序设计.pdf》资料免费下载
    发表于 11-06 16:34 1次下载
    利用<b class='flag-5'>SPI</b>控制器控制nRF24L01射频模块的<b class='flag-5'>驱动程序</b>设计

    嵌入式Linux的摄像头驱动程序设计与实现

    电子发烧友网站提供《嵌入式Linux的摄像头驱动程序设计与实现.pdf》资料免费下载
    发表于 10-12 09:31 1次下载
    嵌入式Linux的摄像头<b class='flag-5'>驱动程序</b>设计与<b class='flag-5'>实现</b>

    如何编写ADX122驱动程序

    大概是能看的出来兼容adx112的,采用的是spi的接口,在这个章节我们主要讲是如何编写驱动程序,所以先跳过一些重要信息。
    发表于 08-02 14:59 583次阅读
    如何编写ADX122<b class='flag-5'>驱动程序</b>?

    几种常见的单片机驱动程序设计模式

    单片机开发人员需要掌握的一项基本技能是,了解如何编写驱动程序。在嵌入式系统中,通常有两种类型的驱动程序:单片机外围设备驱动程序和通过I2C,SPI或UART等接口连接的外部设备
    的头像 发表于 07-10 11:09 3280次阅读
    几种常见的单片机<b class='flag-5'>驱动程序</b>设计模式

    如何优化MCU SPI驱动程序实现ADC吞吐速率

    本文利用选定的ADC(AD7768-1)和MCU(ADuCM4050或MAX32660)通过SPI实现了高速的数据事务处理。为实现
    的头像 发表于 06-12 15:26 473次阅读
    如何<b class='flag-5'>优化</b><b class='flag-5'>MCU</b> <b class='flag-5'>SPI</b><b class='flag-5'>驱动程序</b>以<b class='flag-5'>实现</b>高<b class='flag-5'>ADC</b><b class='flag-5'>吞吐</b><b class='flag-5'>速率</b>

    有谁知道SD驱动程序运行和管理文件结构以及对SD闪存的写入操作是否可能实现这种吞吐率?

    。 有谁知道 SD 驱动程序运行和管理文件结构以及对 SD 闪存的写入操作是否可能实现这种吞吐率? 我担心驱动程序会对整体数据速率造成的开销
    发表于 06-05 09:27

    【世说设计】优化MCU SPI驱动程序实现ADC吞吐速率

    单元(MCU)能否为数据转换器提供高速的串行接口。本文描述了设计MCUADC之间的高速串行外设接口(SPI)关于数据事务处理驱动程序的流程
    的头像 发表于 05-22 10:00 356次阅读
    【世说设计】<b class='flag-5'>优化</b><b class='flag-5'>MCU</b> <b class='flag-5'>SPI</b><b class='flag-5'>驱动程序</b>以<b class='flag-5'>实现</b>高<b class='flag-5'>ADC</b><b class='flag-5'>吞吐</b><b class='flag-5'>速率</b>

    优化MCU SPI驱动程序实现ADC吞吐速率

    随着技术的进步,低功耗物联网(IoT)和边缘/云计算需要更精确的数据传输。图1展示的无线监测系统是一个带有24位模数转换器(ADC)的高精度数据采集系统。在此我们通常会遇到这样一个问题,即微控制单元(MCU)能否为数据转换器提供高速的串行接口。
    的头像 发表于 05-08 14:52 461次阅读
    <b class='flag-5'>优化</b><b class='flag-5'>MCU</b> <b class='flag-5'>SPI</b><b class='flag-5'>驱动程序</b>以<b class='flag-5'>实现</b>高<b class='flag-5'>ADC</b><b class='flag-5'>吞吐</b><b class='flag-5'>速率</b>