STM32F4_光敏传感器

目录

1. 什么是光敏传感器、光敏电阻

2. 硬件分析

3. 实验程序

3.1 main.c

3.2 ADC3.c

3.3 ADC3.h

3.4 Lightsensor.c

3.5 Lightsensor.h


1. 什么是光敏传感器、光敏电阻

光敏传感器也称为光电传感器。是利用光电器件把光信号转换成电信号的一种传感器。它的敏感波长在可见光波长附近,包括红外线波长和紫外线波长。光传感器不只局限于对光的探测,它还可以作为探测元件组成其他传感器,对许多非电量进行检测,只要将这些非电量转换为光信号的变化即可。

光敏传感器是最常见的传感器之一,它的种类繁多,主要有:光电管、光电倍增管、光敏电阻、光敏三极管、太阳能电池、红外线传感器、紫外线传感器、CCD和CMOS图像传感器等。光传感器是目前产量最多、应用最广的传感器之一,它在自动控制和非电量电测技术中占有非常重要的地位。

光敏电阻是一种由半导体材料制成的没有极性的纯电阻,光敏电阻是一种对光敏感的光电器件。

光敏电阻的主要参数:

  • 暗电阻和暗电流:通常把光敏电阻未受到光照射时的电阻称作暗电阻,在没有光照射时流过的电流称作暗电流。
  • 亮电阻和亮电流:亮对应于暗,通常将光敏电阻在受到光照射时的电阻称作亮电阻,在有光照射时通过的电流称作亮电流。

光敏电阻的主要特性:

  • 伏安特性:在一定的光照强度下,光敏电阻两端所加的电压与电流成正比,阻值只和照射的入光强度有关,与加在两端的电流或者电压无关。
  • 光谱特性:我们只要光存在不同的波长,则不同波长的光对光敏电阻的灵敏度是不一样的。
  • 温度特性:光敏电阻受温度的影响较大,当温度升高时,暗电阻和灵敏度都随之下降。

工作原理:

        光敏电阻串联在电流中,在光敏电阻的两端,通常加上合适的电压,在没有光照的条件下,光敏电阻的阻值接近于无穷大,相当于断路,当在一定的光照强度下, 光敏电阻的阻值减少,电流对应增大,足够的光照强度使得光敏电阻所在的支路相当于短路。

实际应用:

        通过STM32F4的ADC去测量电压值

  1.         首先需要确定ADC的位数,也可以说是分辨率,最大数值是多少。比如说一个16位的ADC,最大值就是0xFFFF,对应于2^{16}=65536;
  2.         确定最大值时对应的参考电压值,STM32F4的开发板对应的最大值为3.3V。
  3.         计算电压值,需要把ADC的数值除刚才的确定的最大数值(也就是2^{16})再乘以参考电压值,

        比如说是ADC*(3.3/65536)

2. 硬件分析

        STM32F4板载了一个光敏二极管(光敏电阻),作为开发板的光敏传感器,它对光的变化非常敏感。光敏二极管也叫作光电二极管。光敏二极管和半导体二极管类似,其管芯是一个具有光敏特性的PN结,PN结具有单向导电性,因此工作时需要加反向电压。无光照条件时,有很小的饱和反向漏电流,也就是上面提到的暗电流,此时光敏二极管截止。当受到光照时,饱和反向漏电流大大增加,形成光电流,此时这个值随着入射光的光照强度变化而变化。当光线照射PN结时,可以在PN结中产生电子---空穴对,使得少数的载流子的密度增加。这些载流子在反向电压下产生漂移,使得反向电流增加。因此可以利用光照强度来改变电路中的电流。

        利用PN结中电流的变化,串联一个电阻,就可以转换成电压的变化,通过ADC读取电压值。

STM32F4_光敏传感器_第1张图片

 图中,LSI 就是光敏二极管,R58为其提供反向电压,当环境光线变化时,LSI 两端的电压也会随之变化,通过ADC3_IN5通道,读取LIGHT_SENSOR上面的电压;光线越强,电压越低,光线越暗,电压越高。

3. 实验程序

本实验利用ADC3的通道5(PF7)来读取光敏二极管的电压变化。

STM32F4_光敏传感器_第2张图片

光敏二极管位于开发板的左下角,如上图PCB图所示;可以用强光照射该处,观察光敏电阻的变化;

3.1 main.c

#include "stm32f4xx.h"
#include "delay.h"
#include "usart.h"
#include "LED.h"
#include "lcd.h"
#include "usmart.h"
#include "ADC3.h"
#include "Lightsensor.h"


//LCD状态设置函数
void led_set(u8 sta)//只要工程目录下有usmart调试函数,主函数就必须调用这两个函数
{
	LED1=sta;
}
//函数参数调用测试函数
void test_fun(void(*ledset)(u8),u8 sta)
{
	led_set(sta);
}
int main(void)
{
	u8 adcx;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	delay_init(168);
	uart_init(115200);
	LED_Init();
	LCD_Init();
	LightSensor_Init();
	POINT_COLOR=RED;
	LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
	LCD_ShowString(30,70,200,16,16,"Lightsensor Test");
	LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
	LCD_ShowString(30,110,200,16,16,"2023/20/23");
	POINT_COLOR=BLUE;
	LCD_ShowString(30,130,200,16,16,"Lightsensor:");
	while(1)
	{
		adcx=LightSensor_Get_Val();
		LCD_ShowxNum(30+12*8,130,adcx,3,16,0);
		LED0=!LED0;
		delay_ms(250);
	}
}


3.2 ADC3.c

#include "stm32f4xx.h"                 
#include "ADC3.h"

void Adc3_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3,ENABLE); //使能ADC3时钟
	
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,ENABLE);  //ADC3复位
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,DISABLE);   //复位结束
	
	//初始化CCR寄存器
	ADC_CommonInitTypeDef ADC_CommonInitStructure;
	ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled; //DMA不使能,DMA通常用于多通道的转移
	ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;  //独立模式
	ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;  //预分频4分频
	ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;  //两个采样阶段之间延迟5个时钟
	ADC_CommonInit(&ADC_CommonInitStructure);
	
	//初始化ADC
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;  //关闭连续转换
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;  //右对齐
	ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
	ADC_InitStructure.ADC_NbrOfConversion=1; //1个转换在规则序列中
	ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;  //12位模式分辨率
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;  //非扫描模式
	ADC_Init(ADC3,&ADC_InitStructure);
	
	ADC_Cmd(ADC3,ENABLE);  //开启AD转换器
}
//获得ADC的值
//ch:通道值0~16  ADC_Channel_0~ADC_Channel_16 
//返回值:转换的结果
u16 Get_Adc3(u8 ch)
{
	ADC_RegularChannelConfig(ADC3,ch,1,ADC_SampleTime_480Cycles); //设置ADC规则组通道,1个序列 采样时间
	ADC_SoftwareStartConv(ADC3);//使能指定的ADC3的软件转换启动功能
	while(!ADC_GetFlagStatus(ADC3,ADC_FLAG_EOC));//等待状态寄存器转换标志位结束
	return ADC_GetConversionValue(ADC3);   //返回转换的结果
}

3.3 ADC3.h

#ifndef _ADC3__H_
#define _ADC3__H_

u16 Get_Adc3(u8 ch);
void Adc3_Init(void);
#endif

3.4 Lightsensor.c

#include "stm32f4xx.h"                
#include "Lightsensor.h"
#include "ADC3.h"
#include "delay.h"

void LightSensor_Init(void)    //初始化光敏传感器
{
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);  //初始化GPIOF时钟
	
	//初始化GPIOF PF7通道
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;  //模式为模拟输入
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;  //不带上下拉
	GPIO_Init(GPIOF,&GPIO_InitStructure);
	
	Adc3_Init(); //初始化ADC3
}
//读取光敏电阻Light Sensor的值
//0~100 0最暗,100最亮
u8 LightSensor_Get_Val(void)
{
	u32 temp_val=0;
	u8 t;
	for(t=0;t4000)
		temp_val=4000;
	return (u8)(100-(temp_val/40));
	
}

3.5 Lightsensor.h

#ifndef _LIGHTSENSOR__H_
#define _LIGHTSENSOR__H_

#define LSENS_READ_TIMES	10

u8 LightSensor_Get_Val(void);
void LightSensor_Init(void);
#endif


你可能感兴趣的:(STM32,stm32,单片机)