前言
工欲善其事,必先利其器。对于与现实世界相接轨的数字信号处理来说,最重要的当属ADC和DAC器件了。所以我们需要熟悉stm32的外设,至少得把ADC和DAC跑起来,同时把CMSIS-DSP库用起来~
1.ADC的采样率&转换时间
总的来说,ADC完成一次完整的采样转换过程所需要的时间有如下几个因素决定:
- ADC时钟频率
- 所配置的ADC分辨率(量化bit数),精度越高越慢
- 采样保持时间(单位为cycles)
- SAR ADC (逐次逼近ADC)的转换速度
比如说,如果ADC的时钟频率为40MHz,那么周期为25ns,即对应一个cycle的时间;
现在设置ADC分辨率为12位,对应的ADC转换速度为12.5个cycle,设置采样保持时间为2.5个cycle。
那么可计算得ADC完整地完成一次模数转换所需的时间是375ns。如果让ADC连续不断地进行转换,此时理论最高采样率为2.666MHz。
同时需要注意:如果我们配置ADC进行连续转换(Continuous conversion),并且设置DMA接收数据的话,那么ADC一经启动就会以这个采样率不断地进行转换。
2.固定vs可变采样率
显然,在一个数模转换系统中,固定采样率将会是一个十分鸡肋的致命弱点…
比如说,如果ADC的采样率固定为1MHz,然后我们在RAM中开辟了长度为1000的存储空间(buffer)用来接收ADC采样的数据,那么仅需1ms,这个buffer就会被ADC传来的数据填满。如果我们此时想要采集频率为50Hz的低频信号,这个buffer只能存下该信号的1/20个周期的数据。。。
这时有2种解决方法,第一种是加长存储buffer,但这会让内存爆炸,况且在MCU上我们并没有多少内存可用。第二种则是更为明智的做法——降低采样率。比如降低采样率到10kHz,现在要填满1000个点的buffer需要100ms,这段时间内我们可以采集5个周期的频率为50Hz的信号波形数据。通过 可变采样率 就可以在内存开销不变的情况下,极大拓展信号采集、分析的频段范围。
3.可变采样率的实现
32的ADC不仅可以用软件触发,也可以由硬件触发;而且触发源多种多样,可以选择单片机内部的外设信号,也可以选择使用外部IO输入的信号上升/下降沿,这为我们的设计带来了极大的灵活性。
那么可变采样率的实现思路就非常清晰了:我们现在需要一个灵活可变的时间/频率基准作为ADC的触发信号。说到单片机内的时间基准,熟悉单片机的同学第一时间肯定能想到 定时器(Timer) 的存在吧~
我们可以用timer的 update event 作为ADC的触发源,也即ADC的 “采样时钟”。同时请注意,ADC的采样时钟与ADC时钟并不等同。之所以有这个区分是因为ADC架构的差异。在Sigma-Delta和SAR等架构的ADC中,ADC时钟是指整个ADC单元的工作时钟;而在标准高速ADC中,ADC器件只需要采样时钟。
值得注意的是,在采样时钟的上升或下降沿,ADC对信号进行转换并输出一个数据点,采样时钟与数据点是一一对应的关系,采样时钟的频率即是ADC的采样率。
而在SAR和Sigma-Delta这类ADC中,供给ADC的时钟是其中的数字逻辑器件工作的时钟,并不是ADC Core的时钟,此时ADC时钟频率与ADC的采样率并不等同,但是存在定量关系。
STM32配置DSP库
https://community.st.com/t5/stm32-mcus/configuring-dsp-libraries-on-stm32cubeide/ta-p/49637