通俗解释高速AD采集中数据的缓存
***现今最普通的数字示波器带宽已经能达到50M100M,高带宽的更可以达到1G8G。如此高的带宽下,可以采集的信号的最高频率也大幅增加。根据Nyquist采样定理,为了较精确还原出原始信号的波形,其采样率至少大于等于原始信号中心频率的2倍,因此输入频率越高,也就需要越高的采样率。
在ADC中,采样率小于等于转换速率,一般认为转换速率在数值上等于采样率,其单位为SPS。以12位、1MSPS的ADC为例,其采样频率为1MHz,全速运行下,如果MCU在ADC每一次转换后都处理其转换数据,那么留给MCU的处理时间仅有1/1M=1us,显然没有一款MCU可以在1us内完成数据处理、运算、显示等过程,比如MCU需要使用5us来完成上述过程,那么在这5us中,将会有大约7.5字节的数据丢失,这是任何数据采集系统都不能容忍的,因此,发展出了数据缓存技术。
如今高级MCU中大都集成直接内存存取器(DMA),其作用相当于与内核并行执行,可以将外设的数据不通过内核直接搬运至内存中,省去了内核处理数据的时间。想一想,如果开辟一个缓存数组,应用DMA将AD转换后的数据源源不断地存进RAM中,再定期处理数据,不是能为MCU节省很多时间用于处理吗?但这里存在两个问题:
一、数组的大小
如何确定缓存数组的大小?这个问题要依靠所用ADC的采样率和你处理程序所需要的时间,打个比方,假设还是12Bit、1MSPS的ADC,单片机处理我的运算、显示等程序需要3.5ms的时间,为留有裕量,我选择了周期为5ms的定时器中断,那么在这5ms中,大概有0.005s·12bit·1MHz=60Kb的数据流,因此我至少开辟一个大小为60Kb的数组来存储这些数据。这样,如果再将数组设大些,假设ADC存满这个数组需要10ms,那么在5ms中断后,MCU将会处理截止到本次5ms时数组中所有的数据,在处理时,DMA仍在不停地搬运数据填充数组,那么当第二个5ms中断到来时,前5ms的数据就会和上一次的数据衔接上,没有任何一个数据被丢失掉。
二、只用数组真的行吗
在上述方法中,我们使用的是普通的数组作为缓存,但只是用普通的数组缓冲,真的可行吗?当然,如果只是缓存,那是没问题的,问题是我们需要处理数组内的数据,但普通的数组会打乱我们的处理顺序或者说时序。
如图一个容量为10的数组中有10个数,这十个数中,数字10的时间最靠后,假设是10s,那么当第11个数(11s)再进来时,挤掉的是数组中第一个数,而其他数没有变,此时没法断定时间越靠后的数据在数组中的位置是靠前还是靠后,就会造成数据紊乱,无法进行处理。
如果我们换用FIFO(先进先出队列),这个问题就可以得到解决,在FIFO中,先进入的数据也是最先被挤出去的,因此,数据流在FIFO中的排列顺序永远是一定的,这样就为数据处理带来极大的方便。比如在示波器应用里,假设FIFO中存有一三角波波形[0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1,0],这个FIFO数据被显示在了LCD屏上,就是一个三角波,当下一个数据-1到来时,FIFO中最后一个数据0被挤掉,变为[-1,0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1],在LCD上表现为相位右移,连续下去就相当于我们在示波器荧屏上看到的现象:交流波形在向右移动!
原文链接:https://blog.csdn.net/qq_40807206/article/details/85086817