STM32的ADC以及内部温度传感器
STM32自带1至3个ADC模块,采样精度达到了12位。在STM32F103RBT6中,ADC1和ADC2共用一组管脚。总体编程思路如下:初始化RCC相关,使能系统时钟,使能功能模块如ADC、DMA的时钟。GPIO相关初始化,比如常用的指示灯,ADC的引脚要设置为输入。NVIC向量中断的配置,因为这里使用了DMA中断和中断服务程序编写(下例中暂不使用)。DMA配置(下例中暂不使用)。ADC初始
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_InitStructure );
}
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)=V25−VSENSEAvg_Slope+25 温度(^{\circ}C) = \frac{V_{25}-V_{SENSE}}{Avg\_Slope} + 25 温度(∘C)=Avg_SlopeV25−VSENSE+25
其中V25V_{25}V25是VSENSEV_{SENSE}VSENSE在25∘C25^{\circ}C25∘C时的数值;Avg_SlopeAvg\_SlopeAvg_Slope是温度与VSENSEV_{SENSE}VSENSE曲线的平均斜率(单位是mV/∘CmV/^{\circ}CmV/∘C或μV/∘C\mu V/^{\circ}CμV/∘C)。V25V_{25}V25、VSENSEV_{SENSE}VSENSE的典型值分别为1.431.431.43、4.3mV/∘C4.3mV/^{\circ}C4.3mV/∘C,则TEMP = (1.43 - Vsense)/0.0043 + 25
。
补充说明:
STM32
的ADC
可以分为注入组(Injected Channel
)和规则组(Regular Channel
),规则组放的是常规情况下的检查所需要的数据,注入组放的是特殊情况下的检查所需要的数据(或者是特殊数据),也可以说规则组是主程序,而注入组是中断程序。- 如果你的
ADC_CLK
越小,即你的AD
转换速度越慢,那么AD
转换的精度就越高。 - 注意
STM32
的ADC
功能的触发模块(可允许外部触发,也可以允许内部定时器触发)。 STM32
的ADC
转换模式:单次(对单个端口只转换一次)、连续(对端口连续转换多次)、扫描(对多个端口进行扫描)和中断。- 自动注入(
IAUTO
)将规则组与注入组规为一组。
更多推荐
所有评论(0)