STM32的HAL库开发系列 - ADC基础知识

ADC时钟

ADC输入时钟ADC_CLK由PCLK2经过分频产生,最大值是36MHz,典型值为30MHz,分频因子由ADC通用控制寄存器ADC_CCR的ADCPRE[1:0]设置, 可设置的分频系数有2、4、6和8,注意这里没有1分频。对于STM32F407ZGT6我们一般设置PCLK2=HCLK/2=84MHz。 所以程序一般使用4分频或者6分频。

采样时间

ADC需要若干个ADC_CLK周期完成对输入的电压进行采样,采样的周期数可通过ADC 采样时间寄存器ADC_SMPR1和ADC_SMPR2中的SMP[2:0]位设置,ADC_SMPR2控制的是通道09,ADC_SMPR1控制的是通道1017。每个通道可以分别用不同的时间采样。其中采样周期最小是3个,即如果我们要达到最快的采样,那么应该设置采样周期为3个周期,这里说的周期就是1/ADC_CLK。

ADC的总转换时间跟ADC的输入时钟和采样时间有关,公式为:

Tconv = 采样时间 + 12个周期

当ADCCLK = 30MHz,即PCLK2为60MHz,ADC时钟为2分频,采样时间设置为3个周期,那么总的转换时为:Tconv = 3 + 12 = 15个周期 =0.5us。

一般我们设置PCLK2=84MHz,经过ADC预分频器能分频到最大的时钟只能是21M,采样周期设置为3个周期,算出最短的转换时间为0.7142us,这个才是最常用的。

ADC_InitTypeDef结构体定义在stm32f4xx_hal_adc.h文件内,具体定义如下:

typedef struct {
   uint32_t ClockPrescaler;        /*ADC时钟分频系数 */
   uint32_t Resolution;            /*ADC分辨率选择 */
   uint32_t DataAlign;             /*输出数据对齐方式 */
   uint32_t ScanConvMode;          /*扫描转换模式 */
   uint32_t EOCSelection;          /*转换结束标志使用轮询或者中断*/
   uint32_t ContinuousConvMode;    /*连续转换模式 */
   uint32_t NbrOfConversion;       /*规格转换序列数目 */
   uint32_t DiscontinuousConvMode; /*不连续采样模式 */
   uint32_t NbrOfDiscConversion;   /*不连续采样通道 */
   uint32_t ExternalTrigConv;      /*外部事件触发选择 */
   uint32_t ExternalTrigConvEdge;  /*外部事件触发极性 */
   uint32_t DMAContinuousRequests; /*DMA连续请求转换 */
} ADC_InitTypeDef;

ADC_ChannelConfTypeDef结构体定义在stm32f4xx_adc.h文件内,具体定义如下:

typedef struct {
   uint32_t       	 Channel;        /*ADC转换通道*/
   uint32_t          Rank;           /*ADC序列数目*/
   uint32_t          SamplingTime;   /*ADC采样时间*/
   uint32_t          Offset;         /*预留未用到,设为0即可*/
} ADC_HandleTypeDef;
  • Channel:ADC转换通道。
  • Rank:ADC序列数目
  • SamplingTime:ADC采样时间。

参考和引用:STM32F4xx参考手册、STM32F4xx规格书、野火开源项目、库帮助文档