zoukankan      html  css  js  c++  java
  • stm32之ADC--光敏电阻

    外部通道ADCx_IN0--ADCx_IN15--通道选择取决于硬件选择是哪个通道,然后根据框架图,经过GPIO口--模拟输入

     

     ADC是12位,存储在16位数据寄存器里

    #include "main.h"
    /**************************
    函数名称:LDR_Init()
    函数功能:光敏电阻初始化
    函数参数:无
    函数返回值:无
    备注:PA3--模拟输入
    ADC1-IN3--通道3
    ****************************/
    void LDR_Init(void)
    {
    #if reg_progream  ---寄存器
    //1.使能时钟PA3 ADC1--ADCCLK时钟
    RCC->APB2ENR|=(1<<2)|(1<<9);
    //2.配置ADC1时钟,设置分频因子72M 分频后不能超过14M--6分频
    RCC->CFGR |=(2<<14);
    //3.PA3 --模拟输入
    GPIOA->CRL &=~(0xf<<(3*4));
    //4.配置ADC1:1.规则通道转换总数 2.转换顺序 3.采样时间
    ADC1->SQR1 &=~(0xf<<20);//只有一个光敏电阻--一个通道,转换一个
    ADC1->SQR3 |=(3<<0);//IN3通道3放在规则组中第一个转换
    ADC1->SMPR2 |=(0x7<<(3*3));//通道3采样时间--239.5周期
    //5.独立模式:000、禁用间断模式,不扫描模式
    ADC1->CR1 =0;
    //ADC1->CR1 |=(1<<8);//扫描模式
    ADC1->CR2 &=~(1<<1);//单次转换
    ADC1->CR2 &=~(1<<11);//右对齐--11位为0
    ADC1->CR2 |=(1<<20);//使用外部事件启动转换
    ADC1->CR2 |=(0x7<<17);//软件触发--SWSTART
    ADC1->CR2 |=(1<<23);//启用温度传感器
    //开启A/D转换
    ADC1->CR2 |=(1<<0);
    //复位校准
    ADC1->CR2 |=(1<<3);
    //等待校准寄存器被初始化
    while(ADC1->CR2 &(1<<3));//初始化校准完成,自动为0,退出whiile
    //A/D校准
    ADC1->CR2 |=(1<<2);
    //等待校准完成
    while(ADC1->CR2&(1<<2));
    #else        --库函数
    ADC_InitTypeDef ADC_InitStruct;
    GPIO_InitTypeDef GPIO_InitStruct;
    //1.使能时钟PA3 ADC1--ADCCLK时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
    //2.配置ADC1时钟,设置分频因子72M 分频后不能超过14M--6分频
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);        //ADC1两个时钟配置:1.RCC_ADCCLKConfig() 2.RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
    //RCC_ADCCLKConfig(RCC_CFGR_ADCPRE_DIV6);
    //3.PA3 --模拟输入
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3 ;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;
    //4.配置ADC1:1.规则通道转换总数 2.转换顺序 3.采样时间
    //只有一个光敏电阻--一个通道,转换一个
    //IN3通道3放在规则组中第一个转换
    //通道3采样时间--239.5周期+通道16--内部温度传感器(不使用可以不用配置)
    ADC_RegularChannelConfig(ADC1, ADC_Channel_3|ADC_Channel_6,1, ADC_SampleTime_239Cycles5);
    //5.独立模式:000、禁用间断模式,不扫描模式
    ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;
    ADC_InitStruct.ADC_ScanConvMode= ENABLE;//扫描模式
    ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;//单次转换
    ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right ;//右对齐--11位为0

    ADC_InitStruct.ADC_NbrOfChannel=1;//规则组中ADC转换通道数目--待转换的通道数
    ADC_InitStruct.ADC_ExternalTrigConv= ADC_ExternalTrigConv_None ;//库函数里不用再单独配置外部触发了直接配置软件触发--SWSTART即可
    ADC_Init(ADC1,&ADC_InitStruct);
    //开启A/D转换
    ADC_Cmd(ADC1, ENABLE);
    //复位校准
    ADC_ResetCalibration(ADC1);
    //等待校准寄存器被初始化
    while(ADC_GetResetCalibrationStatus(ADC1));//初始化校准完成,自动为0,退出whiile
    //A/D校准
    ADC_StartCalibration(ADC1);
    //等待校准完成
    while(ADC_GetCalibrationStatus(ADC1));
    //使能内部温度传感器------若不使用可以不用配置
    ADC_TempSensorVrefintCmd(ENABLE);
    #endif

    }

    void GZ_ADCValue(void)
    {
    #if reg_progream
    u16 gz_value;//光照的值
    //启动规则通道转换
    ADC1->CR2 |=(1<<22);
    //等待转换完成
    while((ADC1->SR &(1<<1))==0);
    gz_value=ADC1->DR;
    printf("gz_value=%d ",gz_value);

    #else
    u16 gz_value;//光照的值
    //启动规则通道转换
    ADC_SoftwareStartConvCmd(ADC1,ENABLE);
    //等待转换完成
    while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
    gz_value= ADC_GetConversionValue(ADC1);
    printf("gz_value=%d ",gz_value);

    #endif

    }
    //求内部温度传感器的值
    u16 Get_Adc(u8 ch)
    {
    u16 gz_value;//光照的值
    //启动规则通道转换
    ADC_SoftwareStartConvCmd(ADC1,ENABLE);
    //等待转换完成
    while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
    gz_value= ADC_GetConversionValue(ADC1);
    return gz_value;//把转换的AD值返回回去。
    }
    //得到的ADC内部温度传感器的采样值取10次求平均,
    u16 T_Get_Temp(void)
    {
    u16 temp_val=0;
    u8 i;
    for(i=0;i<10;i++)
    {
    temp_val+= Get_Adc(ADC_Channel_16); //TampSensor
    Delay_ms(5);
    }
    return temp_val/10;
    }
    //得到通道ch的转换平均值。取times次然后求平均。
    u16 T_Get_Adc_Average(u8 ch,u8 times)
    {
    u32 temp_val=0;
    u8 i;
    for(i=0;i<times;i++)
    {
    temp_val+=Get_Adc(ch);
    Delay_ms(5);
    }
    return temp_val/times;
    }
    //得到温度值
    short Get_Temprate(void) //获取内部温度传感器的温度值
    {
    u32 adcx;
    short result;
    double temperate;
    adcx=T_Get_Adc_Average(ADC_Channel_16,20); //通道16,读取20次
    temperate=(float)adcx*(3.3/4096); //得到的电压值。
    temperate=(1.43-temperate)/0.0043+25; //转换为温度值
    result=temperate*100;
    printf("result=%d ",result);
    return 0;
    }

  • 相关阅读:
    vs2015驱动开发中使用RtlStringCchPrintfW()报错
    windbg双机调试配置
    修改Windows默认调试器
    kong配置service和route实现简单API代理
    konga的初步使用
    Kong Admin API — 核心对象
    Kong的API管理方式
    kong的管理UI选择-konga
    Kong 安装
    关于kong | API Gateway
  • 原文地址:https://www.cnblogs.com/juan-4-14/p/12701730.html
Copyright © 2011-2022 走看看