【17.STM32F40x ADC介绍及代码配置】

一、ADC介绍

是Analog-to-Digital Converter的缩写。指的是模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。AD转换就是模数转换,也可以是整流。顾名思义,就是把模拟信号转换成数字信号。

模拟量可以是电压、电流等电信号,也可以是压力、温度、湿度等非电信号。

A/D转换后,输出的数字信号可有8位、10位、12位、14位和16位等。

二、ADC基本原理

一般分为四个步骤进行,即取样、保持、量化和编码。而且前两个步骤(取样和保持)在电路中完成,后两个步骤(量化和编码)在ADC中完成。

三、ADC常用类型

积分型、逐次逼近型、并行比较型/串并行型、调制型和电容阵列逐次比较型及压频变换型。

四、STM32F4x ADC外部通道和引脚对应关系图如下

【17.STM32F40x ADC介绍及代码配置】_第1张图片

五、ADC引脚功能说明

 【17.STM32F40x ADC介绍及代码配置】_第2张图片

六、ADC框图说明

【17.STM32F40x ADC介绍及代码配置】_第3张图片

七、STM32 ADC通道组

(1)规则通道组:相当正常运行的程序。最多16个通道。规则通道和它的转换顺序在ADC_SQRx寄存器中选择,规则组转换的总数应写入ADC_SQR1寄存器的L[3:0]中;

(2)注入通道组:相当于中断。最多4个通道。 注入组和它的转换顺序在ADC_JSQR寄存器中选择。注入组里转化的总数应写入ADC_JSQR寄存器的L[1:0]中;

(3)通道组流程图如下:

 【17.STM32F40x ADC介绍及代码配置】_第4张图片

八、单次转换和连续转换

   (1)单次转换内容如下图:

【17.STM32F40x ADC介绍及代码配置】_第5张图片

   (2)多次转换内容如下图:

【17.STM32F40x ADC介绍及代码配置】_第6张图片

   (3)多次转换中涉及的自动注入内容如下图:

【17.STM32F40x ADC介绍及代码配置】_第7张图片

九、扫描模式内容如下图

【17.STM32F40x ADC介绍及代码配置】_第8张图片

(1)单次扫描:触发一次,把设定的转换通道依次转换一次;

(2)单次不扫描:触发一次,把设定的第一个通道转换一次;

(3)连续扫描:触发一次,把设定的通道转换依次转换一次,然后又回到第一个转换重新启动一轮转换,如此循环;

(4)连续不扫描:触发一次,不停的对第一个通道进行转换。

十、ADC代码配置(注意:本文中以ADC1为例

(1)ADC1初始化函数:

void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);

(2)开启GPIOC/ADC1时钟代码:

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);   //使能ADC1时钟
	 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);  //使能GPIOC时钟

(3)IO口初始化代码:

    GPIO_InitTypeDef  GPIO_ADC1_Init;  //定义GPIOC结构体变量
	GPIO_ADC1_Init.GPIO_Mode = GPIO_Mode_AN;  //模拟输入
	GPIO_ADC1_Init.GPIO_Pin  = GPIO_Pin_0;    //0引脚
	GPIO_ADC1_Init.GPIO_Speed = GPIO_Fast_Speed; //50MH翻转速度(数据的速度)
	GPIO_ADC1_Init.GPIO_PuPd  = GPIO_PuPd_NOPULL; //无上下拉(浮空)
	GPIO_Init(GPIOC,&GPIO_ADC1_Init);

(4)ADC1初始化代码配置

	ADC_InitTypeDef  ADC1_vol_Init;
	ADC1_vol_Init.ADC_ContinuousConvMode   = DISABLE;     //单次转换
	ADC1_vol_Init.ADC_DataAlign            = ADC_DataAlign_Right;  //右对齐
 // ADC1_vol_Init.ADC_ExternalTrigConv     = ; //外部线触发
	ADC1_vol_Init.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //无触发源选择 
	ADC1_vol_Init.ADC_NbrOfConversion      = 1;              //通道数选择
	ADC1_vol_Init.ADC_Resolution           = ADC_Resolution_12b;//精度选择12位
	ADC1_vol_Init.ADC_ScanConvMode         = DISABLE;          //失能扫描
	ADC_Init(ADC1, &ADC1_vol_Init);

(5)ADC通用寄存器初始化配置

    ADC_CommonInitTypeDef ADC1_CommonInit;
	ADC1_CommonInit.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;//DMA是否使能
	ADC1_CommonInit.ADC_Mode =ADC_Mode_Independent;//单个ADC工作,ADC模式选择(独立、协同等)
	ADC1_CommonInit.ADC_Prescaler =ADC_Prescaler_Div4;//预分频,84MHZ/4=21MHZ  <= 36MHZ
	ADC1_CommonInit.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;//两次采样间隔时间(一般最大)
	ADC_CommonInit(&ADC1_CommonInit);

(6)使能ADC1和设置通道和采样时间代码

	ADC_Cmd( ADC1, ENABLE);  //使能ADC1
	ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_480Cycles); //设置通道和采样时间(规则组通道)1:序列号

(7)编写获取光照影响电压值函数

u16 ADC1_SY(void){

	  //规则组设置通道及转换顺序,转换时间
     ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_480Cycles); //设置通道和采样时间(规则组通道)1:序列号
	 ADC_SoftwareStartConv(ADC1);      //软件触发

	 //判断规则组测量转换是否完成
	 while( ADC_GetFlagStatus( ADC1, ADC_FLAG_EOC) != SET ){;} //读取SoftwareStart位是否置1
	 ADC_ClearFlag(ADC1,ADC_FLAG_EOC);  //清规则组转换完成标志位

	 return ADC_GetConversionValue( ADC1);//读取AD值
}

(8)编写获取ADC平均值函数

u16 GetAverageADCValue(void){

  u16 adcValue[10]; // 存储10次ADC转换结果的数组
  u16 averageValue = 0; // 平均值
  ADC1_Init();  // 调用ADC1初始化

  // 进行10次采样
  for (int i = 0; i < 10; i++) {
    adcValue[i] = ADC1_SY(); // 获取ADC转换结果
  }

  // 取中间两次转换结果,计算平均值
  averageValue = (adcValue[4] + adcValue[5]) / 2;
  return averageValue;
}

十一、代码汇总

ADC1.c

#include "adc1.h"

void ADC1_Init(void){

  //使能GPIOC/ADC1时钟  
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);  使能GPIOC时钟

	
	//IO口初始化
	GPIO_InitTypeDef  GPIO_ADC1_Init;  //定义GPIOC结构体变量
	GPIO_ADC1_Init.GPIO_Mode = GPIO_Mode_AN;  //模拟输入
	GPIO_ADC1_Init.GPIO_Pin  = GPIO_Pin_0;    //0引脚
	GPIO_ADC1_Init.GPIO_Speed = GPIO_Fast_Speed; //50MH翻转速度(数据的速度)
	GPIO_ADC1_Init.GPIO_PuPd  = GPIO_PuPd_NOPULL; //无上下拉(浮空)
	GPIO_Init(GPIOC,&GPIO_ADC1_Init);
	
	//ADC1初始化
	ADC_InitTypeDef  ADC1_vol_Init;
	ADC1_vol_Init.ADC_ContinuousConvMode   = DISABLE;     //单次转换
	ADC1_vol_Init.ADC_DataAlign            = ADC_DataAlign_Right;  //右对齐
 // ADC1_vol_Init.ADC_ExternalTrigConv     = ; //外部线触发
	ADC1_vol_Init.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //无触发源选择 
	ADC1_vol_Init.ADC_NbrOfConversion      = 1;              //通道数
	ADC1_vol_Init.ADC_Resolution           = ADC_Resolution_12b;//精度选择12位
	ADC1_vol_Init.ADC_ScanConvMode         = DISABLE;          //失能能扫描
	ADC_Init(ADC1, &ADC1_vol_Init);
	
	//ADC通用寄存器初始化配置
	ADC_CommonInitTypeDef ADC1_CommonInit;
	ADC1_CommonInit.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;//DMA是否使能
	ADC1_CommonInit.ADC_Mode =ADC_Mode_Independent;//单个ADC工作,ADC模式选择(独立、协同等)
	ADC1_CommonInit.ADC_Prescaler =ADC_Prescaler_Div4;//预分频,84MHZ/4=21MHZ  <= 36MHZ
	ADC1_CommonInit.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;//两次采样间隔时间(一般最大)
	ADC_CommonInit(&ADC1_CommonInit);
	
	//启动ADC
	ADC_Cmd( ADC1, ENABLE);  //使能ADC1
	ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_480Cycles); //设置通道和采样时间(规则组通道)1:序列号

}

u16 ADC1_SY(void){

	  //规则组设置通道及转换顺序,转换时间
     ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_480Cycles); //设置通道和采样时间(规则组通道)1:序列号

	 ADC_SoftwareStartConv(ADC1);      //软件触发

	 //判断规则组测量转换是否完成
	 while( ADC_GetFlagStatus( ADC1, ADC_FLAG_EOC) != SET ){;} //读取SoftwareStart位是否置1
	 ADC_ClearFlag(ADC1,ADC_FLAG_EOC);  //清规则组转换完成标志位
	 return ADC_GetConversionValue( ADC1);//读取AD值
}


u16 GetAverageADCValue(void){

  u16 adcValue[10]; // 存储10次ADC转换结果的数组
  u16 averageValue = 0; // 平均值

  // 初始化ADC1
  ADC1_Init();

  // 进行10次采样
  for (int i = 0; i < 10; i++) {
    adcValue[i] = ADC1_SY(); // 获取ADC转换结果
  }

  // 取中间两次转换结果,计算平均值
  averageValue = (adcValue[4] + adcValue[5]) / 2;

  return averageValue;
}


ADC1.h

#ifndef _ADC1_H_
#define _ADC1_H_
#include "stm32f4xx.h"

void ADC1_Init(void);
u16 ADC1_SY(void);
u16 GetAverageADCValue(void);

#endif

Main.c

#include "delay.h"

#include "usart1.h"

#include "adc1.h"

int main{

    Delay_Init(168);

    Usart1_Init(115200);//波特率、频率

    ADC1_Init();

    printf("程序已启动\r\n");   //验证串口是否可行

    while(1){

              //光照影响电压值

            float V = ADC1_SY()*3.3/4096;  //计算并打印电压值的浮点型结果

            printf("V = %.2f\r\n",V);

            u16 B = ADC1_SY();

            printf("B = %u\r\n",B);  

            Delay_ms(500);

      }

}

十二、编程思路

   【17.STM32F40x ADC介绍及代码配置】_第9张图片

你可能感兴趣的:(STM32F40x,c#)