定制化PSoC实现8通道SAR ADC采样16通道
扫描二维码
随时随地手机看文章
通过ADC进行信号采样是MCU应用的常见任务,这可以将连续模拟信号转换为一系列离散的数字数据供MCU处理。在某些应用中,单个ADC需要以高采样率对多个通道进行采样。例如电源监测系统的管理子系统需要对多个稳压电源的输出进行采样,以监测系统的工作状态;再如在基于传感器的应用中,MCU需要对多个传感器进行采样以实现系统反馈。
我们有位客户想使用一片赛普拉斯的PSoC4实现用1MSps采样率采样16个通道的设计,16个通道的总采样时长不能超过19μs。但PSoC4内置的多路复用器(SARMUX)只支持8个通道。本文将介绍如何通过PSoC内部的可编程模块克服这一设计难题。
分析设计需求
首先我们需要仔细分析设计需求。客户把16个输入的完整采样视为一个采样周期。如图1所示,一个采样周期的最大时长限制为19μs。每个采样周期之间可使用中断服务请求(ISR)存储采样结果。
图1:对16通道采样的时序。
若要用一个8通道SAR来实现这个目标,我们需要使用PSoC4片内的通用可编程数字模块(UDB)实现定制设计。该设计使用PSoC4片内的数字信号互联(DSI)实现多路复用器切换采样通道,并且在采样周期结束时将采样结果缓冲在基于数据通路(datapath)的FIFO中,然后通过中断服务子程序(ISR)全部读取出来。
数据通路是UDB模块中最灵活的部分。每个UDB模块包含一个数据通路,每个数据通路包含一个具有多个寄存器的8位ALU。UDB结构和数据通路功能的详细介绍请参阅PSoC4技术参考手册。每个数据通路可实现一个8字节FIFO。我们需要四个FIFO来缓冲16个12位SAR采样结果。
图2:16通道SAR采样。
图2显示的是基于DSI的多路复用器,能在多个输入之间自动切换当前的采样通道。图3显示的是硬件FIFO的概览图。
图3:用于缓冲采样结果的四个8字节FIFO。
配置SAR组件
SAR被配置成单端模式采样单个输入通道,输入电压范围在0~Vdd之间,1MSps采样率。在收到采样触发信号后,SAR就开始输入信号采集,采集结束后产生一个“SDONE”信号,该信号被送入DSI网络,并被命名为“ADC_SDONE”。PSoC Creator标准组件库中提供的SAR组件无法支持输出采样结果到DSI总线上。因此,我们需要把SAR组件导入到项目中并加以修改,如图4中的红色部分所示。
图4:详细设计—修改SAR组件。
图5所示的是SAR组件的输出连接。在SAR_Start函数之后,我们还需要添加一行代码,使得SAR能将采样结果输出到DSI网络,如下所示:
// start SAR component and wait for conversion trigger
SAR_Start();?
// enable SAR sampling result output on DSI
*((reg32 *)(SAR_SAR_CHAN_CONFIG_IND + (uint32)(0 << 2))) |=
SAR_DSI_OUT_EN;
图5:详细设计—SAR的输出连接。
基于DSI的多路复用器
如图6中蓝色部分所示,通过DSI控制的硬件多路复用器取代SARMUX,以用于切换16个通道。采用SWITCH_CLK时钟触发Count7单元,以生成通道选择信号,这样每次通道转换可分为两个阶段:信号采集和转换。
图6:基于DSI的MUX和触发信号生成。
信号采集完成之后,信号将保持在SAR中,此时可切换输入通道。因此用于显示信号采集阶段完成的SDONE可用于通道切换。实际上,SWITCH_CLK是基于DSI信号“ADC_SDONE”(SDONE)定义的时钟,其设置见图6的“cydwr”页面。
图7:设计范围资源的时钟定义。
Count7单元属于定制组件,不在标准组件库的范围内。它是一个递减计数器,输出当前的计数器值给DSI。其默认值初始值为0x7F。因此通道选择的范围是从#15到#0。在主程序中添加以下代码实现对Count7的控制。
/* Enter critical section */
interruptState = CyEnterCriticalSection();
/* Set the Count Start bit */
MYCOUNT7_AUX_CTL |= (1 << 5);
/* Exit critical section */
CyExitCriticalSection(interruptState);
// set default value of count7 as 0x7F
MYCOUNT7_COUNTER = MYCOUNT7_PERIOD;
生成SAR的采样触发
第1步:在完成当前采样工作之前生成下一个触发信号
由于针对SAR只有一个实际输入,因此一旦完成对当前通道的采样,SAR就需要为下一次采样触发信号。许多信号都适用于此目的,但触发信号选择应遵循以下两个规则:
1. 在触发信号和当前采样完成之间不应存在间隔,甚至触发信号可以提前发生,这样就可以降低延迟。
2. 触发信号必须确保不会破坏当前采样工作。
根据上述规则,可选择SDONE和EOC用于触发。但使用EOC将使每通道采样时间至~1.4μs,这是因为触发信号上升沿时刻和SAR开始采样之间存在开销。SAR需要至少5个SARADC_CLK时钟来将DSI触发信号转换为信号采样开始。我们的设计要求更加苛刻。EOC信号与SARADC_CLK上升沿同步。在穿过DSI网络,并到达SAR的SOC(开始转换)之后,就已经略滞后于采样时钟的上升沿。因此,它需要6个SARADC_CLK时钟或大约340ns触发产生耗时。
我们必须寻求另一种触发信号。幸运的是在SAR工作时,其可存储一个触发信号,但仅限一个,用于下一次扫描。因此我们可以使用SDONE触发转换。让触发产生耗时与SAR转换时间并行,SAR就可在当前转换完成之前存储该触发事件。现在对16通道的采样我们能有1μs的转换时间(见图12中的SDONE周期)。
第2步:在每次采样周期结束时暂时停止触发信号生成
在每次采样周期结束时,我们需要暂时停止触发信号生成,否则持续不断的采样将使FIFO溢出。如图6的红色部分所示,在选择通道0时,需关闭同步的D触发器(DFF)以暂时停止触发器输出。而在FIFO被ISR清空后,则需使用0x7F重置Count7单元,从而重新启用DFF输出。同时,应使用固件触发的方式在新周期中开始第一通道的采样,如图8所示。
图8:SAR ADC时序。
FIFO控制
UDB可配置为8字节FIFO,用于存储来自DSI网络的数据。图9显示了配置数据通路的概览图。FIFO时钟将数据采样到FIFO。F0 Load和F1 Load负责启用或禁用FIFO。两个状态信号可提示FIFO Full事件。
图9:针对8字节FIFO的数据路径配置。
图10所示的是FIFO的工作时序。12位SAR结果分别存储在LSB_FIFO和MSB_FIFO中。Count7单元可对从15到0的通道进行排序。因此通道15到8存储于FIFO上部,通道7到0存储于FIFO下部。加载信号根据FULL状态和启用信号而生成。
图10:FIFO时序。
最后四个通道的结果一旦存储完毕后就会触发ISR读取FIFO。FIFO Enable使用Count7单元的位(如图11的红色部分所示),同时该位也与SWITCH_CLK(SDONE)同步。这样可确保EN变化不会破坏FIFO采样。
图11:为FIFO生成EN的详细设计。
设计测试
图12所示的是一个采样周期。十六个SDONE和EOC脉冲表示通道转换。十六个FIFOCLK和一个FIFO的FULL信号可对最后四个结果进行缓冲,用于说明FIFO的工作状态。请注意,SDONE和FIFOCLK之间的间隔是1μs。
图12:测试结果——一个采样周期中的信号。
图13是多个采样周期的波形。将数据从FIFO存储到SRAM的两个周期之间的间隔是大约9.56μs。
图13:测试结果——多个采样周期。