其他分享
首页 > 其他分享> > 炒冷饭系列-STM32F103之光敏传感器

炒冷饭系列-STM32F103之光敏传感器

作者:互联网

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"


void myLseorInit(void);
u16 myLseorHandler(u8 ch);
u16 LseorcArc(u8 ch,u8 time);
 int main(void)
 {	
	 
	u8 lightval=0;
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 	//串口初始化为115200
 	LED_Init();			     //LED端口初始化
	KEY_Init();
	LCD_Init();
	 myLseorInit();
	 LCD_ShowString(30,130,200,16,16,"LSENS_VAL:");
  while(1) 
	{		
		 lightval=LseorcArc(6,20);
		LCD_ShowxNum(30+10*8,130,lightval,3,16,0);//显示 ADC 的值
		LED0=!LED0;
		delay_ms(250);
	} 
}
 

//利用 ADC3 的通道 6(PF8)来读取光敏二极管电压的变化
void myLseorInit(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStruct;
	
	//1) 开启 PF 口时钟和 ADC3 时钟,设置 PF8 为模拟输入。
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);//使能ADC时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);//使能GPIO时钟

	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //PA8 为模拟输入。
 	GPIO_Init(GPIOF, &GPIO_InitStructure);//

	//2) 复位 ADC1,同时设置 ADC1 分频因子
	ADC_DeInit(ADC3);
	//ADC最大转换频率为1MHz,对应的最大转换时间就是1us
	// ADC 的转换时间公式=Tcovn=采样时间+12.5个周期
	// ADCCLK=14Mhz 的时候,设置 1.5 个周期的采样时间,则得到: Tcovn=1.5+12.5=14 个周
	//期=1us。
	//APB2对应的时钟频率是72MHz,分频因子要确保 ADC1 的时钟(ADCCLK)不超过14Mhz。
	//6分频之后72/6=12Mhz,所以ADC的频率是12Mhz
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	//3) 初始化 ADC1 参数, 设置 ADC1 的工作模式以及规则序列的相关信息。
	ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;//ADC 工作模式:独立模式
	ADC_InitStruct.ADC_ScanConvMode=DISABLE;//AD 单通道模式
	ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;//AD 单次转换模式
	ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//转换由软件而不是外部触发启动
	ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//ADC 数据右对齐ADC_DataAlign_Right,左对齐会咋样?ADC_DataAlign_Left
	ADC_InitStruct.ADC_NbrOfChannel=1;//顺序进行规则转换的 ADC 通道的数目 1
	ADC_Init(ADC3, &ADC_InitStruct);
	
	//4) 使能 ADC 并校准。
	//执行复位校准和 AD 校准,注意这两步是必须的!不校准将导致结果很不准确。
	ADC_Cmd(ADC3,ENABLE);//使能 ADC
	ADC_ResetCalibration(ADC3);//复位校准
	ADC_StartCalibration(ADC3);//AD 校准
	
	//记住,每次进行校准之后要等待校准结束。 这里是通过获取校准状态来判断是否校准是否结束
	//一旦校准结束, CAL位被硬件复位   校准状态复位完成的返回值是0,
	while(ADC_GetResetCalibrationStatus(ADC3));//等待复位校准完成	为0时退出while
	while(ADC_GetCalibrationStatus(ADC3));//等待AD 校准完成
	
	
}

//返回 ADC 值
//ch:通道值6
u16 myLseorHandler(u8 ch)
{
	//5) 设置规则通道6的参数
	//ADC3的通道6,Rank:规则顺序中的第一个转换1,ADC_SampleTime:采样周期要大于17.1us
	ADC_RegularChannelConfig(ADC3, ch, 1,ADC_SampleTime_239Cycles5);
	ADC_SoftwareStartConvCmd(ADC3,ENABLE);//使能指定的 ADC3 的软件转换启动功能
	
	while(!ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC ));//等待转换结束
	return ADC_GetConversionValue(ADC3);//获取转换 ADC 转换结果数据,16位里面含有12位,右对齐,高位对齐
}


//读取 Light Sens 的值
//0~100:0,最暗;100,最亮
u16 LseorcArc(u8 ch,u8 time)
{
	u8 i=0;
	u32 adc_value=0;
	for(i=0;i<time;i++)
	{
		adc_value+=myLseorHandler(ch);
		delay_ms(10);
	}
	
	adc_value/=time;//取平均值
	if(adc_value>4000)
	{
		adc_value=4000;//12位最大值是4096,去掉96,有点小误差,
	}
	
	adc_value=(100-(adc_value/40));//(adc_value/40)为了让取值范围在0-100,100-(adc_value/40)光线越强,电压值越低
	
	return (u8)adc_value;
}


标签:STM32F103,校准,炒冷饭,value,ADC3,光敏,GPIO,adc,ADC
来源: https://blog.csdn.net/chenyouledashen/article/details/120683365