stm32--ADC

1.电压输入管脚(VREF-到VREF+),VREF-和VSS届地,VREF+和VDDA届正,0-3.3V
2.16个可以采集的通道,对应不同的IO脚
3.16个通道可分为两组,规则通道可以被注入通道打断
4.进入通道触发源
5.ADC时钟,有APB2提供,最大14Mhz采样周期最小是1.5个ADCCLK(1us),通常用12M,最小1.7us
规则通道使用多通道则一个通道传输玩就输出再接下一个
7.触发中断

1开启时钟
2
设置ADC分频系数
3初始化ADC
4
使能并校验
5*读取转换值

ADC1的通道1引脚是PA1,连接在滑动变阻器上,这个实验就是利用AD转换来读取滑动变阻器电压

adc.c

#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)); //等待重置完成
    ADC_StartCalibration(ADC1); //开始校验
    while(ADC_GetCalibrationStatus(ADC1));//等待校验完成
    
    //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)); //等待转换完成
        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);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值