(总结)STM32中的ADC的原理和应用(电位器,光敏传感器的使用)

!!!鸣谢轩哥的上课笔记!!!

一,ADC的基本原理

  • 概念:信号分为两种:模拟信号 + 数字信号,大多数传感器采集的都是模拟信号,比如温度、湿度、压力……. ,采集的模拟信号再转交给计算机进行处理,计算机处理的是数字信号,其中涉及到模拟量和数字量的转换,会使用模数转换器,也被称为ADC
  • 模拟信号:在时间和数值上均具有连续性
  • 数字信号:在时间和数值上均均有离散型
  • 二,ADC转换原理

  • 取样:取样频率一般是模拟信号的最高频率分量的频率的3~5倍
  • ​​​​​​​量化:将取样电压量化成数字量,并且数字量的大小只能是规定的最小数量单位的整数倍
  • 编码:将量化结果用代码(可以是二进制,也可以是其他进制)表示出来
  • 三,STM32f407 与 ADC

    (1)STM32中的ADC分析

     

    总结:

  • 有三个12位的ADC,每个ADC都有16个外部通道(通过查阅数据手册找到ADC通道对应的IO口)
  • 规则通道:就是普通通道,需要排队等待。本芯片中规则通道有16个
  • 规则数据寄存器(虽然有16位,但是最多只用到了12位):能存数据的寄存器只有1个
  • 注入通道:可以理解为VIP通道,无需排队等待。本芯片中规则通道有4个
  • 注入数据寄存器(虽然有16位,但是最多只用到了12位):能存数据的寄存器有4个
  • 通过设置转换精度位数来设置量化单位,转换精度位数越大,量化单位越小,精度更高
  • 当EOC标志成立,则说明转换结束,此时才可以读取寄存器中的值
  • (2)STM32中ADC的代码实现步骤(采集电位器的电压)

    1,准备工作(添加adc.c源文件)

    2,查阅adc.c源文件,知道基本步骤

    3,代码实现

    /**
    * @brief  电位器的初始化
    * @param  None	
    				  
    * @retval None
    */
    void ADC_Config(void)
    {
      ADC_CommonInitTypeDef ADC_CommonInitStructure;
    	GPIO_InitTypeDef GPIO_InitStructure;
      ADC_InitTypeDef ADC_InitStructure;
      
      //1.打开时钟  PA5  -- ADC12_IN5
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
      
      //2.配置GPIO的引脚 
      GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5;
      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;      //模拟模式
      GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL ;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
      
      //3.配置ADC外设的基本参数
      ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                      //独立模式
      ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;                   //分频系数   84MHZ/4 = 21MHZ 
      ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;       //不使用DMA
      ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;  
      ADC_CommonInit(&ADC_CommonInitStructure);
      
       
      //4.配置ADC外设的参数
      ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;                        //转换精度
      ADC_InitStructure.ADC_ScanConvMode = DISABLE;
      ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
      ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;   //不使用外部触发源
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                        //右对齐
      ADC_InitStructure.ADC_NbrOfConversion = 1;                                    //转换数量
      ADC_Init(ADC1, &ADC_InitStructure);
      
      //5.配置ADC的规则通道
      ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_3Cycles);
      
      //6.使能ADC
      ADC_Cmd(ADC1, ENABLE);
    }
    
    
    /**
      * @brief  程序的入口
      * @param  None
      * @retval None
      */
    int main(void)
    {
    	uint16_t val = 0;
      
    	//硬件的初始化
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置优先级分组 2bit抢占(0~3) 2bit响应(0~3)
    	USART1_Config(9600);   // 和PC端通信
      ADC_Config();          // 电位器的初始化
    	
      while(1)
      {	
        //开启ADC1的转换
        ADC_SoftwareStartConv(ADC1);
        
        //等待ADC转换结束
        while( ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
        
        //读取转换后的结果
        val = ADC_GetConversionValue(ADC1);
        
        //输出转换结果 0 ~ 4095
        printf("val = %d\r\n",val); 
        
        delay_ms(500);
      }
    }

            总结:

            电位器的初始化

    1. 打开ADC和GPIO时钟
    2. 配置GPIO引脚参数(模拟模式)
    3. 配置ADC外设的基本参数(独立模式、分频系数(84MHz/4 = 21MHz)、不使用DMA、取样延时周期)
    4. 配置ADC外设的参数(转换精度、对齐方式、不使用外部触发源、转换数量)
    5. 配置ADC的规则通道
    6. 使能ADC(这一步完成,代表已经具有ADC模数转换的能力)

            电位器的使用

    1. 开启ADC转换
    2. 循环判断EOC是否为SET
    3. 读取转换后的结果
    4. 输出结果

    (3)STM32中ADC的代码实现步骤(采集光敏电阻的数据,跟电位器操作基本一样)

    /**
    * @brief  ADC的初始化(光敏电阻)
    * @param  None	
    				  
    * @retval None
    */
    void ADC_Config(void)
    {
      ADC_CommonInitTypeDef ADC_CommonInitStructure;
      GPIO_InitTypeDef GPIO_InitStructure;
      ADC_InitTypeDef ADC_InitStructure;
      
      //1.打开时钟  PF7  -- ADC3_IN5
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
      
      //2.配置GPIO的引脚 
      GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;
      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;      //模拟模式
      GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL ;
      GPIO_Init(GPIOF, &GPIO_InitStructure);
      
      //3.配置ADC外设的基本参数
      ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                      //独立模式
      ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;                   //分频系数   84MHZ/4 = 21MHZ 
      ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;       //不使用DMA
      ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;  
      ADC_CommonInit(&ADC_CommonInitStructure);
      
       
      //4.配置ADC外设的参数
      ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;                        //转换精度
      ADC_InitStructure.ADC_ScanConvMode = DISABLE;
      ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
      ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;   //不使用外部触发源
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                        //右对齐
      ADC_InitStructure.ADC_NbrOfConversion = 1;                                    //转换数量
      ADC_Init(ADC3, &ADC_InitStructure);
      
      //5.配置ADC的规则通道
      ADC_RegularChannelConfig(ADC3, ADC_Channel_5, 1, ADC_SampleTime_3Cycles);
      
      //6.使能ADC
      ADC_Cmd(ADC3, ENABLE);
    }
    
    
    /**
      * @brief  程序的入口
      * @param  None
      * @retval None
      */
    int main(void)
    {
    	uint16_t val = 0;
      
    	//硬件的初始化
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置优先级分组 2bit抢占(0~3) 2bit响应(0~3)
    	USART1_Config(9600);   // 和PC端通信
    	ADC_Config();          // 电位器的初始化
    	
    	
    	GPIO_InitTypeDef  GPIO_InitStructure;
    	
    	//打开外设的时钟   LED --- PF9
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
    	
    	//配置引脚的参数
    	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_9;
    	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_OUT;
    	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    	GPIO_InitStructure.GPIO_PuPd 	= GPIO_PuPd_NOPULL;
    	
    	//初始化GPIO端口
    	GPIO_Init(GPIOF, &GPIO_InitStructure);
    	
    	
      while(1)
      {	
        //开启ADC1的转换
        ADC_SoftwareStartConv(ADC3);
        
        //等待ADC转换结束
        while( ADC_GetFlagStatus(ADC3,ADC_FLAG_EOC) == RESET);
        
        //读取转换后的结果
        val = ADC_GetConversionValue(ADC3);
        
        //输出转换结果 0 ~ 4095
        printf("val = %d\r\n",val); 
        
    	//天亮了关灯,否则关灯
    	if(val < 1000)
    	{
    		//关灯
    		GPIO_SetBits(GPIOF, GPIO_Pin_9);
    	}
    	else
    	{
    		//开灯
    		GPIO_ResetBits(GPIOF, GPIO_Pin_9);
    	}
    	  
        delay_ms(500);
    	  
    	  
      }
    }

    作者:100 Miles485

    物联沃分享整理
    物联沃-IOTWORD物联网 » (总结)STM32中的ADC的原理和应用(电位器,光敏传感器的使用)

    发表回复