stm32的ADC

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 }
View Code
原文地址:https://www.cnblogs.com/arthurtech/p/7390487.html