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\r\n",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\r\n",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\r\n",result);
return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM