在单片即应用中,有的时候需要连续处理 ADC所采集到的数据,比如将它们不间断的传输到网络上。但是,如果在这个过程中,处理数据的时间随机波动,就有可能会出现丢失数据的现象。根据 TI 公司的一份技术报告,提出了 乒乓DMA模式,ADC采集的数据由DMA分别传输到内存的一个数据缓冲区。CPU 可以连续处理另外缓冲区内的数据。当 ADC的数据填充完一个数据缓冲区之后,便切换到另外一个数据缓冲区。CPU便可以处理另外一个缓冲区内的数据。由于是整批次处理数据,所以这种方式可以避免 ADC采集过程中丢失数据的现象。下面对此方式进行测试。
在上午实验中STM32F103单片机平台上进行测试,这个平台原来适用于 CCD 数据采集用的。下面就直接利用这个单片机测试一下 DMA 乒乓缓冲区的功能。首先测量一下 STM32单片机ADC转换速率。
在 STM32 数据手册中,给出了 ADC每隔通道的转换时间计算公式。那就是采样始终再加上12.5 个 ADC 时钟,便是 ADC 一次转换所需要的时间。
▲ 图1.1.1 STM32 ADC转换时间
下面通过示波器测量 单片机实际 ADC采样时间。设置单片机的 ADC时钟。为 10.666MHz。根据 STM32单片机数据手册要求,这个时间频率必须小于 14MHz。 设置单片机的采样时间,这里选择为 28.5个时钟,那么,每隔ADC转换时间就是28.5 加上 12.5,等于41 可时钟。
设置ADC的DMA通道,每次转换结束之后,通过 DMA将转换结果传到到内存中 ADC 缓冲区,ADC 缓冲区的长度为 128个数据,禁止 DMA 中途中断,这样,只有到 DMA 传输了整个 数据缓冲区之后,产生一次中断。在中断程序中,切换单片机 LED管脚的电平。因此通过测量 LED 管脚高电平的时间长度,便反应了 128个ADC转换所需要的时间。
为了实现乒乓DMA缓冲区,在DMA 中断程序中,根据中断次数是偶数还是奇数,将 DMA中的内存地址修改为 缓冲数组1,或者缓冲数组2。这样便可以在每次 ADC 采集完一组缓冲区之后,进行切换,并对已经采集到的数据集中进行处理。
经过测试,上面这种切换的方式工作正常。由此,我们能够实现了 ADC 缓冲区的乒乓切换模式。
本文测试了在 STM32单片机中的乒乓缓冲区的模式。通过在 ADC 的 DMA传输中断程序中,来回切换DMA 的内存地址,便可以来回对所采集到的数据进行处理,而不用担心遗漏数据。
DMA 乒乓 切换: https://dev.ti.com/tirex/explore/node?node=A__AGTNfDbVXbEdVyShrms1sA__MSPM0-SDK__a3PaaoK__LATEST
火星大王: 其实可以不用显式切换DMA缓冲区,可以利用DMA的循环传输和半传输中断,这样一旦DMA启动,如果是半传输完成中断,说明缓冲区的前半部分数据已经采集好了,CPU可以处理前半部分,此时DMA可以继续向后采集缓冲区的后半部分;
如果触发传输完成中断,说明后半部分采集好了,CPU可以处理缓冲区的后半部分数据,同时,由于循环传输的存在,DMA此时会自动重新开始采集缓冲区的前半部分数据,以此循环往复。
使用此法一旦配置完成,CPU就不再需要关闭DMA或者修改DMA的任何配置,只需要等待中断触发然后处理数据就好了,同时由于半传输和传输中断的标志位是不同的标志位,也不再需要维护额外的状态信息。