目录

一、概述

1、ADC结构

2、STM32中ADC框图

3、ADC转换流程结构

4、转化模式

5、数据对齐

6、触发控制

7、转换时间

8、校准

 二、ADC单或多通道代码


一、概述

ADC(Analog-Digital Converter)模拟-数字转换器

  • ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁
  • 12位逐次逼近型ADC,1us转换时间
  • 输入电压范围:0~3.3V,转换结果范围:0~4095 
  • 18个输入通道,可测量16个外部(系列最多)和2个内部信号源
  • 规则组和注入组两个转换单元。规则组用于常规事件,注入组用于突发事件
  • 模拟看门狗自动监测输入电压范围
  • STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道
  • AD转换的步骤:采样,保持,量化,编码
  • 1、ADC结构

    以ADC0809芯片为例,通过地址锁存器进行控制通道选择开关,ADDA、B、C端的电平为000时,IN0通道选通;001,IN1通道选通,以此类推。ADC比较器是由时钟进行推进的。

     逐次逼近型ADC工作原理:

    首先,控制逻辑电路使N位寄存器最高位(Dn-1)置1,其余清零。经D/A转换后得到大小为VREF的模拟电压VN。将VN和Vx比较,若Vx>=VN,则保留Dn-1=1;若Vx<VN,则保留Dn-1=0;随后控制逻辑电路使N位寄存器次高位Dn-2置1,经D/A转换后再与Vx比较确定次高位的值,其余位类推,转换完成后,由锁存缓冲器进行输出。

    EOC是控制逻辑电路发出转换结束信号。VREF是当达到满量程时的最大电压。

    2、STM32中ADC框图

    如下图:

    注入通道组:最多可以选择4个通道。

    规则通道组:最多可以同时选择16个通道,但每次只能由一个通道进行转换,因为规则通道数据寄存器只有1个。

    开始转换触发可以由软件调用库函数进行启动,也可以由硬件资源进行器启动,利用主模式触发。

    ADCCLK时钟频率最大为14MHZ。

    3、ADC转换流程结构

    4、转化模式

  • 单次转换,非扫描模式
  •  连续转换,非扫描模式
  • 单次转换,扫描模式
  • 可以选择多个通道数目,一组转换完之后,发出转换结束信号EOC

  • 连续转换,扫描模式 
  • 5、数据对齐

    6、触发控制

    7、转换时间

    STM32 ADC的总转换时间为:     TCONV = 采样时间 + 12.5个ADC周期

    转换结束后,EOC会有硬件置1

    8、校准

     二、ADC单或多通道代码

    AD.c:

    #include "stm32f10x.h"                  // Device header
    
    
    void AD_Init(void)
    {
    	GPIO_InitTypeDef GPIO_InitStructure;
    	ADC_InitTypeDef ADC_InitStruct;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    	
    	RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //用RCC配置ADCCLK推动比较器
    	
    	//GPIO初始化
    	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN ;         //模拟输入,ADC专用通道
    	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
    	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA,&GPIO_InitStructure);
    	
    	
    	//初始化ADC,配置数据格式,模式
    	ADC_InitStruct.ADC_Mode=ADC_Mode_Independent ;       //独立
    	ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right  ;  //数据右对齐
    	ADC_InitStruct.ADC_ExternalTrigConv= ADC_ExternalTrigConv_None ;  //不用外部触发源,用软件触发
    	ADC_InitStruct.ADC_NbrOfChannel=1;              //单个通道
    	ADC_InitStruct.ADC_ScanConvMode=DISABLE;        //非扫描
    	ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;  //非连续
    	ADC_Init(ADC1,&ADC_InitStruct);
    	
    	//启动ADC
    	ADC_Cmd(ADC1,ENABLE);
    	
    	//校准
    	//初始化校准寄存器
    	ADC_ResetCalibration(ADC1);
    	while(ADC_GetResetCalibrationStatus(ADC1)==SET);  //开始校准,为0校准结束
    	//开始进行校准
    	ADC_StartCalibration(ADC1);
    	while(ADC_GetCalibrationStatus(ADC1)==SET);
    }
    
    uint16_t AD_GetValue(uint8_t ADC_Channel)
    {
       
    	ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5); //规则组通道配置
    	ADC_SoftwareStartConvCmd(ADC1,ENABLE);       //软件触发转换
    	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);  //等待转换结束
    	return ADC_GetConversionValue(ADC1);    //返回转换值
    }

    AD.h:

    #ifndef _AD_H
    #define _AD_H
    
    
    void AD_Init(void);
    
    uint16_t AD_GetValue(uint8_t ADC_Channel);
    
    
    
    
    #endif
    

    main.c:

    #include  "stm32f10x.h"                  // Device header
    #include  "OLED.h"
    #include  "delay.h"
    #include  "AD.h"
    
    
    
    uint16_t AD1,AD2,AD3;
    
    
    //float Voltage;
    
    
    int main(void)
    {
    	
       OLED_Init();
    	AD_Init();
    	OLED_ShowString(1,1,"AD1:");
    	OLED_ShowString(2,1,"AD2:");
    	//OLED_ShowString(3,1,"AD3:");
    	//OLED_ShowString(2,1,"Voltage:0.00V");
    	while(1) 
    	{
    	  AD1=AD_GetValue(ADC_Channel_0);
    	  AD2=AD_GetValue(ADC_Channel_1);
    	  //AD3=AD_GetValue(ADC_Channel_2);
    	  OLED_ShowNum(1,5,AD1,4);
    	  OLED_ShowNum(2,5,AD2,4);
    	  //OLED_ShowNum(3,5,AD3,4);
    	
    	}
    	
    }

    作者:GCC_a.out

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32-ADC模数转换

    发表回复