stm32 的模拟/数字转换器( ADC )是提供可选择多通道输入,逐次逼近型的模数转换器,分辨率为 12 位,即最大电压是0xfff(3.3V),转换公式为
V = ADC_GetConversionValue(ADC1) / 0xfff * 3.3
- STM32F103 系列最少都拥有 2 个 ADC,大容量系列的单片机拥有3个ADC;
- STM32 的 ADC 最大的转换速率为 1Mhz,也就是转换时间为 1us,不要让 ADC 的时钟超过 14M,否则将导致结果准确度下降。
ADC 的总转换时间:Tcovn=采样时间+12.5 个周期
采样时间是根据每个通道的 SMP 位的设置来决定的;当 ADCCLK=14Mhz 的时候,并设置 1.5 个周期的采样时间,则得到: Tcovn=1.5+12.5=14 个周期=1us。
因此我们一般采取RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置采样频率,最好不大于14Hz
- 固件库使用说明里面列举的关于ADC的函数:
ADC_DeInit 将外设 ADCx 的全部寄存器重设为缺省值
ADC_Init 根据 ADC_InitStruct 中指定的参数初始化外设 ADCx 的寄存器
ADC_StructInit 把 ADC_InitStruct 中的每一个参数按缺省值填入
ADC_Cmd 使能或者失能指定的 ADC
ADC_DMACmd 使能或者失能指定的 ADC 的 DMA 请求
ADC_ITConfig 使能或者失能指定的 ADC 的中断
ADC_ResetCalibration 重置指定的 ADC 的校准寄存器
ADC_GetResetCalibrationStatus 获取 ADC 重置校准寄存器的状态
ADC_StartCalibration 开始指定 ADC 的校准程序
ADC_GetCalibrationStatus 获取指定 ADC 的校准状态
ADC_SoftwareStartConvCmd 使能或者失能指定的 ADC 的软件转换启动功能
ADC_GetSoftwareStartConvStatus 获取 ADC 软件转换启动状态
ADC_DiscModeChannelCountConfig 对 ADC 规则组通道配置间断模式
ADC_DiscModeCmd 使能或者失能指定的 ADC 规则组通道的间断模式
ADC_RegularChannelConfig 设置指定 ADC 的规则组通道,设置它们的转化顺序和采样时间
ADC_ExternalTrigConvConfig 使能或者失能 ADCx 的经外部触发启动转换功能
ADC_GetConversionValue 返回最近一次 ADCx 规则组的转换结果
ADC_GetDuelModeConversionValue 返回最近一次双 ADC 模式下的转换结果
ADC_AutoInjectedConvCmd 使能或者失能指定 ADC 在规则组转化后自动开始注入组转换
ADC_InjectedDiscModeCmd 使能或者失能指定 ADC 的注入组间断模式
ADC_ExternalTrigInjectedConvConfig 配置 ADCx 的外部触发启动注入组转换功能
ADC_ExternalTrigInjectedConvCmd 使能或者失能 ADCx 的经外部触发启动注入组转换功能
ADC_SoftwareStartinjectedConvCmd 使能或者失能 ADCx 软件启动注入组转换功能
ADC_GetsoftwareStartinjectedConvStatus 获取指定 ADC 的软件启动注入组转换状态
ADC_InjectedChannleConfig 设置指定 ADC 的注入组通道,设置它们的转化顺序和采样时间
ADC_InjectedSequencerLengthConfig 设置注入组通道的转换序列长度
ADC_SetinjectedOffset 设置注入组通道的转换偏移值
ADC_GetInjectedConversionValue 返回 ADC 指定注入通道的转换结果
ADC_AnalogWatchdogCmd 使能或者失能指定单个/全体,规则/注入组通道上的模拟看门狗
ADC_AnalogWatchdongThresholdsConfig 设置模拟看门狗的高/低阈值
ADC_AnalogWatchdongSingleChannelConfig对单个 ADC 通道设置模拟看门狗
ADC_TampSensorVrefintCmd 使能或者失能温度传感器和内部参考电压通道
ADC_GetFlagStatus 检查制定 ADC 标志位置 1 与否
ADC_ClearFlag 清除 ADCx 的待处理标志位
ADC_GetITStatus 检查指定的 ADC 中断是否发生
ADC_ClearITPendingBit 清除 ADCx 的中断待处理位
以下代码根据固件库修改而来
附上详细代码:
#include "adc.h"
/**
* @brief ADC1_Init program
* @param None
* @retval None
*/
void ADC1_Init(void)
{
/* Private variables ---------------------------------------------------------*/
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
/* System clocks configuration ---------------------------------------------*/
RCC_Configuration();
/* GPIO configuration ------------------------------------------------------*/
GPIO_Configuration();
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel14 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
}
/**
* @brief Configures the different system clocks.
* @param None
* @retval None
*/
void RCC_Configuration(void)
{
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置采样频率,最好不大于14Hz
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);
}
/**
* @brief Configures the different GPIO ports.
* @param None
* @retval None
*/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure PB.2 (ADC Channel8) as analog input -------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
float ADC1_Read(void)//读取ADC1的电压值
{
float adc_num = 0.0;
u8 i = 0;
for(i=0;i<8;i++)//多次取值取平均
{
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //开启软件
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC )==0);//等待转换完成
adc_num += ADC_GetConversionValue(ADC1)*3.3/0xfff; //数值转换
}
return adc_num/8;
}