在开发过程中,我们有时需要得到某个引脚的电压值,通过改变电阻等方式,电压值不是恒定的,所以我们需要用的ADC转换来得到实时的电压值。
当需要采集外部信号时,外部信号多数为模拟信号,如电压、电流、温度、压力等,而单片机只能处理数字信号,这时便需要一个将模拟信号转换为数字信号的介质——模数转换器(ADC)。
模拟量转换为数字量:采样 保持 量化 编码
采样:将一个时间上连续变化的模拟量转换为时间上离散变化的模拟量;
保持:将采样的结果存储起来,直到下一次采样;
量化:将采样电平归化为与之接近的离散数字电平;
编码:将量化后的结果按照一定数制形式表示;
在编码中:将采样电平(模拟值)转换为数字值时,可通过直接比较型与间接比较型。
直接比较型:就是将输入模拟信号直接与标准的参考电压比较,从而得到数字量。常见的有并行ADC与逐次比较型ADC。
间接比较型:输入模拟量不是直接与参考电压比较,而是将二者变为中间的某种物理量在进行比较,然后将比较所得的结果进行数字编码。常见的有双积分ADC。
1.2 ADC转换原理
1) 逐次逼近型ADC
采用逐次逼近法的 AD 转换器是有一个比较器、DA 转换器、缓冲寄存器和控 制逻辑电路组成,如下图所示:
基本原理是:从高位到低位逐次试探比较,就像用天平秤物体,从重到轻逐 级增减砝码进行试探。逐次逼近法的转换过程是:初始化时将逐次逼近寄存器各 位清零,转换开始时,先将逐次逼近寄存器最高位置 1,送入 DA 转换器,经 DA 转换后生成的模拟量送入比较器,称为 U0,与送入比较器的待转换的模拟量 Ux 进行比较,若 U0<Ux,该位 1 被保留,否则被清除。然后再将逐次逼近寄存器次 高位置 1,将寄存器中新的数字量送 DA 转换器,输出的 U0 再与 Ux 比较,若 U0<Ux, 该位 1 被保留,否则被清除。重复此过程,直至逼近寄存器最低位。转换结束后, 将逐次逼近寄存器中的数字量送入缓冲寄存器,得到数字量的输出。逐次逼近的 操作过程是在一个控制电路的控制下进行的。
在STM32中,我们在使用adc时应在工程中添加adc的环境,然后配置我们需要的引脚初始化,然后再配置对应的ADC。
OLED
模拟量转换为数字量:采样 保持 量化 编码
采样:将一个时间上连续变化的模拟量转换为时间上离散变化的模拟量;
保持:将采样的结果存储起来,直到下一次采样;
量化:将采样电平归化为与之接近的离散数字电平;
编码:将量化后的结果按照一定数制形式表示;
在编码中:将采样电平(模拟值)转换为数字值时,可通过直接比较型与间接比较型。
直接比较型:就是将输入模拟信号直接与标准的参考电压比较,从而得到数字量。常见的有并行ADC与逐次比较型ADC。
间接比较型:输入模拟量不是直接与参考电压比较,而是将二者变为中间的某种物理量在进行比较,然后将比较所得的结果进行数字编码。常见的有双积分ADC。
我们不需要自己写OLED的头文件与源文件,我们应该学会站在前人的肩膀上,直接用已经写完的oled的程序就好了,但是我们需要根据自己的需要,在建模程序上完成自己所需要的字模或者照片。
.c文件
#include "stm32f10x.h"
#include "adc.h"
void ADC_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef ADC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
ADC_InitStruct.ADC_ContinuousConvMode=ENABLE;
ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;
ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;
ADC_InitStruct.ADC_NbrOfChannel=1;
ADC_InitStruct.ADC_ScanConvMode=DISABLE;
ADC_Init(ADC1,&ADC_InitStruct);
ADC_Cmd(ADC1,ENABLE);
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
}
.h文件
#ifndef _ADC_H
#define _ADC_H
#include "stdint.h"
void ADC_init(void);
#endif
|