本文讲述了ADC的基本原理以及如何使用,最后实践打开内部温度传感器读取芯片温度。
1.ADC的作用
信号可以分成连续信号和离散信号。连续信号变化缓慢,没有突变。离散信号可以只有有限几个值。连续和离散是指信号的幅度,也可以指信号的时间。可以说连续变化的信号就是模拟信号,离散变化的信号是数字信号。
模拟信号:电路简单,分辨率高,与实际电路情况较为吻合。
数字信号:以0,1方式存在,便于储存和交换。
因此ADC的构成了这两种信号的转换桥梁。
2.stm32中ADC的配置与使用
芯片:stm32F103C8T6
ADC为12位逐次逼近型,转换结果为2的12次方为0~4095
资源:ADC1,ADC2和10个外部输入通道(对应方式如下),以及2个内部信号源(内部温度传感器和内部参考电压)
ADC的基本结构
配置过程:
1.开启RCC中ADC
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//打开时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//时钟配置,ADC如何分频
若有GPIO(注意是模拟输入)
2.选择AD转换器的规则组或注入组(并对通道,序列,采样周期进行配置)
void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);//注入通道
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);//规则通道
这里采用的是规则通道
ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_239Cycles5);
补充:注入组相当于中断,可以打断规则组,规则通道的转换结果储存在规则数据寄存器 (ADC_DR)中,所有规则通道的转换结果均共用此规则数据寄存器。
关于采样时间:ADC装换步骤(采样,保持,量化,编码)
转换总时间:采样周期(最低1.5个周期)+ 12.5ADC周期(最低要求,因为需要保持数据)
那么最低时间为14个ADC采样周期,在1中ADC周期为14MHz,那么时间最快就为1微秒了。
3.配置ADC转换器
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC独立模式
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐方式(右对齐直接取数据)
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不开启ADC外部触发
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//持续
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//扫描
ADC_InitStructure.ADC_NbrOfChannel = 1;//通道数目(没开扫描就是1)
ADC_Init(ADC1, &ADC_InitStructure);
补充:转换方式(若单次转换,就只能手动EOC置1后再运行)
在扫描模式下,需要使用DMA来快速搬运数据,否则在下图只能拿到通道6的值了
4.对ADC上电和数据校准
ADC_Cmd(ADC1, ENABLE);//上电
//校准过程
ADC_ResetCalibration(ADC1);//复位校准
while (ADC_GetResetCalibrationStatus(ADC1) == SET);//等待复位校准
ADC_StartCalibration(ADC1);//开始校准
while (ADC_GetCalibrationStatus(ADC1) == SET);//等待校准
5.数据的读取
uint16_t AD_GetValue(void)
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//是否启动ADC转换
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);//当转换结束信号EOC为1
return ADC_GetConversionValue(ADC1);//返回通道最后ADC取值结果
}
3.实践(开启内部温度传感器)
在以上ADC初始化的基础代码上加以更改
1和2:选择ADC1_IN16输入通道和采样时间
ADC_RegularChannelConfig(ADC1,ADC_Channel_TempSensor,1,ADC_SampleTime_239Cycles5);
//打开16通道和取采样时间(时间长,数据比较稳定)
3.唤醒温度传感器
ADC_TempSensorVrefintCmd(ENABLE);//启用或禁用温度传感器和Vrefint通道。
4.设置ADON位启动ADC
ADC_Cmd(ADC1, ENABLE);
5.读取模拟值转化为电压值再转为温度值
得知V25和Avg_Slope的平均取值
因此在main函数中
ADValue = AD_GetValue();//同前面的ADC数据的读取构建函数
Voltage = (float)ADValue / 4095 * 3.3;//转换电压
temp = (1.43 - Voltage)/0.043 + 25;//转为温度
最后利用oled显示屏就可以读取相应温度了(最好在采取AD数据进行数据处理一波,取平均啥的)。