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;
}

原文地址:https://www.cnblogs.com/juan-4-14/p/12701730.html