stm32有1-3个ADC,这些ADC可以独立使用,也可以使用双重模式(可以提高采样率)。
stm32的ADC是12位逐次逼近型模拟/数字转换器。有18个通道,可以测量16个外部信号源+2个内部信号源。这18个通道被分为2个通道组:规则通道组(最多包含16个通道) & 注入通道组(最多包含4个通道)。规则通道组相当于正常运行的程序,而注入通道组相当于中断。后者的可以打算前者的转换。
各通道的转换模式包括:单次、连续、扫描、间断。
在“ADCCLK=14MHz,采样周期=1.5*ADC时钟周期”的前提下,ADC的转换速率=1MHz(MAX),即1us。
这里稍作分析,疑问如下:
ADCCLK=14MHz ---> T_ADC=1/14us ---> 1.5*T_ADC=3/28us,就是说采样周期=3/28us。而转换速率=1us,那么是否意味着剩下的25/28us时间用于采样后的逐次逼近计算?
解释如下:T_covn=采样时间+12.5个周期。
当ADCCLK=14MHz时,设置1.5个周期的采样时间,则有T_covn=1.5+12.5=14个周期,即1us。
ADC的基准电压:开发板使用的芯片设计有外部参考电压,Vref+、Vref-。基准电压确定后,stm32据此设定采样量程。例如,Vref+接3.3V,Vref-接0V,则stm32的采样量程范围是0-3.3V。
ADC_SQR1寄存器中的L[3:0],描述意义是“规则通道序列长度”,这里所谓的长度表示什么意思?
解释如下:如前所述stm32的ADC有18个通道(16个外部信号源+2个内部信号源)。如果要使用这18个通道(不必全使用,可以只使用其中一个或几个),则必须要分配通道对应的规则通道序列(0-15)。比如,现在需要使用ADC1的通道1,并将其设置为规则组(对应地,也可以设置为注入组),那么可以将其对应到规则组序列1中。这样,在程序中通过SWSTART启动规则组转换的时候,才会转换通道1的值。否则,是不会转换的。
配置ADC1的通道1:独立模式,单次转换,软件控制开启,右对齐。代码如下:
1 void Adc_Init(void) 2 { 3 //IO config 4 RCC->APB2ENR |= 1<<2; //PORTA时钟使能 5 GPIOA->CRL &= ~(0xf<<4); //PA1=模拟输入模式 6 7 RCC->APB2ENR |= 1<<9; //ADC1时钟使能 8 RCC->APB2RSTR |= 1<<9; //ADC1接口复位 9 RCC->APB2RSTR &= ~(1<<9); //ADC1接口复位结束 10 11 //ADC预分频设置. ADCCLK=PCLK2/6=72/6=12MHz. ADCCLK必须<=14MHz,否则会导致转换精度下降 12 RCC->CFGR &= ~(3<<14); 13 RCC->CFGR |= 2<<14; 14 15 ADC1->CR1 &= ~(0xf<<16); //独立模式 16 ADC1->CR1 &= ~(1<<8); //扫描模式关闭 17 ADC1->CR2 &= ~(1<<1); //单次转换模式 18 ADC1->CR2 |= 7<<17; //用于规则组的外部事件选择:SWSTART(软件控制模式) 19 ADC1->CR2 |= 1<<20; //开启规则通道转换 20 ADC1->CR2 &= ~(1<<11); //右对齐 21 ADC1->SQR1 &= ~(0XF<<20); //规则通道序列长度:1个转换。1个转换在规则序列中 也就是只转换规则序列1?? 22 23 //通道1的采样时间设置 24 ADC1->SMPR2 &= ~(7<<3); //通道1采样时间清空 25 ADC1->SMPR2 |= 7<<3; //通道1采样时间=239.5周期,外加12.5个周期,共252个周期。即转换周期252/12=21us。 26 27 ADC1->CR2 |= 1<<0; //开启ADC并启动转换,ADON=1 28 29 //复位校准,并等待校准结束。该位由软件设置以开始校准,在校准寄存器被初始化后由硬件清除 30 ADC1->CR2 |= 1<<3; //使能复位校准,初始化校准寄存器 31 while(ADC1->CR2 & 1<<3); //等待校准结束 32 33 //AD校准,并等待校准结束。该位由软件设置以开始校准,并在校准结束时由硬件清除 34 ADC1->CR2 |= 1<<2; //开启AD校准 35 while(ADC1->CR2 & 1<<2); //等待校准结束 36 }