??STM32
自带1
至3
个ADC
模块采样精度达到12
位。在STM32F103RBT6
中,ADC1
和ADC2
共用一组管脚。总体编程思路如下:
- 初始化
RCC
相关系统时钟相关,使能功能模块如ADC
、DMA
的时钟。 GPIO
常用指示灯等相关初始化,ADC
引脚应设置为输入。NVIC
由于这里使用了向量中断的配置DMA
编制中断和中断服务程序(下例暂不使用)。DMA
配置(下例暂不使用)。ADC
初始化。
??如下:
通道 | ADC1 | ADC2 | ADC3 |
---|---|---|---|
通道0 |
PA0 |
PA0 |
PA0 |
通道1 |
PA1 |
PA1 |
PA1 |
通道2 |
PA2 |
PA2 |
PA2 |
通道3 |
PA3 |
PA3 |
PA3 |
通道4 |
PA4 |
PA4 |
PF6 |
通道5 |
PA5 |
PA5 |
PF7 |
通道6 |
PA6 |
PA6 |
PF8 |
通道7 |
PA7 |
PA7 |
PF9 |
通道8 |
PB0 |
PB0 |
PF10 |
通道9 |
PB1 |
PB1 |
|
通道10 |
PC0 |
PC0 |
PC0 |
通道11 |
PC1 |
PC1 |
PC1 |
通道12 |
PC2 |
PC2 |
PC2 |
通道13 |
PC3 |
PC3 |
PC3 |
通道14 |
PC4 |
PC4 |
|
通道15 |
PC5 |
PC5 |
|
通道16 |
温度传感器 | ||
通道17 |
内部参考电压 |
??以下是使用参考代码的参考代码ADC1
的IN0
脚:
void ADC_GPIO_Init ( void ) {
GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE ); GPIO_DeInit ( GPIOA ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; /* 模拟输入 */ GPIO_Init ( GPIOA, &GPIO_InitStruture );
}
void ADC_configuration ( void ) {
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; /* 独立模式 */
ADC_InitStructure.ADC_ScanConvMode = DISABLE; /* 连续多通道模式 */
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; /* 单次转换 */
/* 转换由软件而不是外部触发启动 */
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; /* 右对齐 */
ADC_InitStructure.ADC_NbrOfChannel = 1; /* 扫描通道数 */
ADC_Init ( ADC1, &ADC_InitStructure );
// ADC_RegularChannelConfig( ADC1, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5 );
ADC_Cmd ( ADC1, ENABLE ); /* 使能或者失能指定的ADC */
ADC_ResetCalibration ( ADC1 ); /* 重置指定的ADC的校准寄存器 */
while ( ADC_GetResetCalibrationStatus ( ADC1 ) ); /* 等待校准寄存器初始化 */
ADC_StartCalibration ( ADC1 ); /* 开始校准 */
while ( ADC_GetCalibrationStatus ( ADC1 ) ); /* 等待校准完成 */
ADC_SoftwareStartConvCmd ( ADC1, ENABLE ); /* 使能指定的ADC的软件转换启动功能 */
}
u16 GetADCValue ( u8 ADC_Channel ) {
/* ADC_Channel_x 0~17 */
u16 adc_value;
ADC_RegularChannelConfig ( ADC1, ADC_Channel, 1, ADC_SampleTime_7Cycles5 );
ADC_SoftwareStartConvCmd ( ADC1, ENABLE ); /* 使能指定的ADC的软件转换启动功能 */
/* 检查制定ADC标志位是否置为1,ADC_FLAG_EOC是转换结束标志位 */
while ( ADC_GetFlagStatus ( ADC1, ADC_FLAG_EOC ) == RESET );
adc_value = ADC_GetConversionValue ( ADC1 );
return adc_value; /* 返回最近一次ADCx规则组的转换结果 */
}
当使用内部温度传感器时,需要使能温度传感器通道:
ADC_TempSensorVrefintCmd ( ENABLE );
温度传感器通道号是ADC_Channel_16
,此通道的采样时间调到最大,来保证精度。温度的计算公式如下:
温 度 ( ∘ C ) = V 25 − V S E N S E A v g _ S l o p e + 25 温度(^{\circ}C) = \frac{V_{25}-V_{SENSE}}{Avg\_Slope} + 25 温度(∘C)=Avg_SlopeV25−VSENSE+25
其中 V 25 V_{25} V25是 V S E N S E V_{SENSE} VSENSE在 2 5 ∘ C 25^{\circ}C 25∘C时的数值; A v g _ S l o p e Avg\_Slope Avg_Slope是温度与 V S E N S E V_{SENSE} VSENSE曲线的平均斜率(单位是 m V / ∘ C mV/^{\circ}C mV/∘C或 μ V / ∘ C \mu V/^{\circ}C μV/∘C)。 V 25 V_{25} V25、 V S E N S E V_{SENSE} VSENSE的典型值分别为 1.43 1.43 1.43、 4.3 m V / ∘ C 4.3mV/^{\circ}C 4.3mV/∘C,则TEMP = (1.43 - Vsense)/0.0043 + 25
。
:
STM32
的ADC
可以分为注入组(Injected Channel
)和规则组(Regular Channel
),规则组放的是常规情况下的检查所需要的数据,注入组放的是特殊情况下的检查所需要的数据(或者是特殊数据),也可以说规则组是主程序,而注入组是中断程序。- 如果你的
ADC_CLK
越小,即你的AD
转换速度越慢,那么AD
转换的精度就越高。 - 注意
STM32
的ADC
功能的触发模块(可允许外部触发,也可以允许内部定时器触发)。 STM32
的ADC
转换模式:单次(对单个端口只转换一次)、连续(对端口连续转换多次)、扫描(对多个端口进行扫描)和中断。- 自动注入(
IAUTO
)将规则组与注入组规为一组。