美文网首页
stm32---ADC

stm32---ADC

作者: 飞向深空 | 来源:发表于2019-08-08 18:11 被阅读0次

adc.c

图片1.png
#include "adc.h"

void ADCx_Init()
{
    
    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    
    //1*时钟开启并配置ADC分频系数
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA,ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);//6分频,72/6=12Mhz,函数在rcc.h中
    
    //2*GPIO配置
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模式是模拟输入
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    
    //3*ADC初始化并使能
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC模式:单通道模式
    ADC_InitStructure.ADC_ScanConvMode = DISABLE; //非扫描模式
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //关闭连续转换,变单次转换
    ADC_InitStructure.ADC_NbrOfChannel = 1; //通道数是1
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //禁止外部触发检测,使用软件触发
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采样数据在寄存器中右对齐
    ADC_Init(ADC1,&ADC_InitStructure); //初始化    
    ADC_Cmd(ADC1,ENABLE); //开启ADC
    
    //4*重置校验寄存器并开始校验**
    ADC_ResetCalibration(ADC1); //重置校验寄存器
    while(ADC_GetResetCalibrationStatus(ADC1)); //等待重置完成,重置完返回0
    ADC_StartCalibration(ADC1); //开始校验
    while(ADC_GetCalibrationStatus(ADC1));//等待校验完成,校验完返回0
    
    //5*开始AD转换
    ADC_SoftwareStartConvCmd(ADC1,ENABLE);
    
}


/*******************************************************************************
* 函 数 名         : Get_ADC_Value
* 函数功能         : 获取通道ch的转换值,取times次,然后平均,以提高数据的可靠性  
* 输    入         : ch:通道编号
                     times:获取次数
* 输    出         : 通道ch的times次转换结果平均值
*******************************************************************************/

//6*获得转换后数字
u16 Get_ADC_Value(u8 ch,u8 times)
{
    u8 t=0;
    u32 temp_val=0;
    ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5); //ADC1,ADC 通道,239.5 个周期,提高采样时间 可以提高精确度
    
    for(t=0;t<times;t++) //10次
    {
        ADC_SoftwareStartConvCmd(ADC1,ENABLE); //开始转换
        while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)); //等待转换完成,转换完成返回1
        temp_val += ADC_GetConversionValue(ADC1);  //times次值累加
        
    }
    
    return temp_val/times; //返回转换后数字,ADC1 最大为 12 位精度, 所以返回值类型为 u16 即可
}

adc.h

#ifndef _adc_H
#define _adc_H

#include "system.h"

void ADCx_Init(void);
u16 Get_ADC_Value(u8 ch,u8 times);


#endif


main.c

#include "systick.h"
#include "led.h"
#include "system.h"
#include "key.h"
#include "usart.h"
#include "adc.h"

int main()
{
    u8 i=0;
    u16 Value; //得到的AD的值
    float Vol; //滑动百变阻器点压
    SysTick_Init(72);  //系统时钟初始
    LED_INIT(); 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
    USART1_Init(9600);
    ADCx_Init();
    while(1)
    { 
        i++;
        if(i%20==0) //200ms变换一次
        {
            led1=!led1;
        }
        
        if(i%50==0) //500ms采集一次
        {
            Value = Get_ADC_Value(ADC_Channel_1,10);
            printf("检测到的AD值为%d\r\n",Value);
            Vol = (float)Value*(3.3/4096);/*我们使用的 ADC1 为 12 位转换精度,最大值为 2^12 即 4096, 
                                而 ADC 的参考电压 VREF+为 3.3V,所以知道 AD 转换值就可以计算对应的电压值*/
            printf("变阻器电压值为%.2f\r\n",Vol);
        }
        
        delay_ms(10);
    }
}

相关文章

网友评论

      本文标题:stm32---ADC

      本文链接:https://www.haomeiwen.com/subject/dulfjctx.html