1.光敏传感器介绍:

  • 光敏二极管(光敏电阻),作为光敏传感器;光敏二极管也称光电二极管;
  • 光敏二极管与半导体二极管在结构上类似,其管芯是一个具有光敏特征的PN结,具有单向导电性,因此工作时需要加上反向电压。无光照时,有很小的饱和和反向漏电流,即暗电流,此时光敏二极管截止。当受到光照时,饱和反向漏电流大大增加,形成了光电流,它随入射光强度的变化而变化。
  • 利用这个电流变化,可以串接一个电阻,就可以转换成电压的变化,从而通过ADC读取电压值,判断外部光线的强弱;
  • 光敏传感器是利用光敏元件,将光信号转换为电信号的一种传感器;
  • 2.光敏传感器实验:

    功能实现:通过ADC3通道6采集光敏传感器的AD值,并将该值转换为光照强度值0-100,0对应最暗。100对应最亮,并通过串口1输出光照强度值,LED0指示灯闪烁提示系统正常运行。

    (1)原理图:

      

    (2)主函数:

    #include "delay.h"
    #include "led.h"
    #include "usart1.h"
    #include "ldr.h"
    
    
    
    int main(){
        
        u8 i=0;    
        int LIGHT_VALUE=0;
       
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);      //设置分组
        delay_init();                                        //延时初始化
        LED_Init();  
        usart1_Init(9600);                                   //串口通信初始化
        LDR_Init();                                          //光敏传感器初始化
       
        while(1)
           {
              i++;
              if(i%20==0)
              {
                 LED0=!LED0;
              }
    
               delay_ms(10);
              
               if(i%100==0)
               {
                  LIGHT_VALUE+=Get_LDR_Value();           //获取光照强度值
                  printf("当前光照强度值:%d \r\n",LIGHT_VALUE);
                  printf("\r\n");
                  
               }
           
          }       
    }
    

    (3)头文件:
     

    #ifndef __LDR_H
    #define __LDR_H
    
    
    typedef unsigned char u8;
    typedef unsigned short u16;
    typedef unsigned int u32;
    
    void LDR_Init(void);                         //光敏传感器初始化
    u16 Get_ADC3_Value(u8 ch,u8 times);          //获取ADC3的值
    u8 Get_LDR_Value(void);                      //获取光照强度值
    
    
    #endif
    

    (4)光敏传感器功能函数:

    #include "stm32f10x.h"
    #include "delay.h"
    #include "ldr.h"
    
    
    
    /*
       功能:光敏传感器初始化
       变量:无
       返回值:无
    */
    void LDR_Init(void)
    {
       GPIO_InitTypeDef GPIO_InitStruct;
       ADC_InitTypeDef ADC_InitStruct;
       
       //1.使能端口时钟和ADC时钟,设置引脚模式
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF|RCC_APB2Periph_ADC3,ENABLE);
       
       GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;                    //模拟输入
       GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;                        //PF8
       GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
       GPIO_Init(GPIOF,&GPIO_InitStruct);
       
       //2.设置ADC的分频因子
       RCC_ADCCLKConfig(RCC_PCLK2_Div6);
       
       //3.初始化ADC参数
       ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;                                      //不连续转换
       ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;                                   //右对齐
       ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;                      //不使用外部触发,使用软件触发
       ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;                                       //独立模式
       ADC_InitStruct.ADC_NbrOfChannel=1;                                                  //通道数量
       ADC_InitStruct.ADC_ScanConvMode=DISABLE;                                            //不扫描
       ADC_Init(ADC3,&ADC_InitStruct);
       
       //4.使用ADC校准
       ADC_Cmd(ADC3,ENABLE);                                          //使能ADC3
       
       ADC_ResetCalibration(ADC3);                                    //复位校准
       while(ADC_GetResetCalibrationStatus(ADC3));                    //判断复位校准是否完成
       
       ADC_StartCalibration(ADC3);                                    //开启校准
       while(ADC_GetCalibrationStatus(ADC3));                         //判断开启校准是否完成
       
       //5.开启软件触发
       ADC_SoftwareStartConvCmd(ADC3,ENABLE);
       
    }
    
    
    
    /*
       功能:获取ADC3的值
       变量:ch:通道       times:获取次数
       返回值:ADC滤波后的值
    
    */
    u16 Get_ADC3_Value(u8 ch,u8 times)
    {
       u8 i=0;
       u32 LDR_Val=0;             //存储获取到的ADC值
        
       ADC_RegularChannelConfig(ADC3,ch,1,ADC_SampleTime_239Cycles5);    //配置ADC规则通道
       
       for(i=0;i<times;i++)
       {
          ADC_SoftwareStartConvCmd(ADC3,ENABLE);                         //开启软件触发
          while(!ADC_GetFlagStatus(ADC3,ADC_FLAG_EOC));                  //判断规则组转换是否完成
          LDR_Val+=ADC_GetConversionValue(ADC3);                         //获取ADC3的值
          delay_ms(10);
          
       }
       
       return LDR_Val/times;                                             //将所获得的ADC值进行滤波
       
    }
    
    
    
    /*
       功能:获取光照强度值
       变量:无
       返回值:光照强度值
    
    
    */
    
    #define LIGHT_READ_TIMES      20             //采集ADC3的次数
    u8 Get_LDR_Value()
    {
       u8 i=0;
       u32 light_val=0;                          //存储关照强度值
       
       for(i=0;i<LIGHT_READ_TIMES;i++)
       {
          light_val+=Get_ADC3_Value(ADC_Channel_6,LIGHT_READ_TIMES);        //获取ADC3采集的值
          delay_ms(10);
          
       }
       
       light_val/=LIGHT_READ_TIMES;        //将获取的ADC值进行滤波
       
       if(light_val>4000)
       {
          light_val=4000;                  //将大于4000的值都设置为4000
       }
       
       return (100-light_val/40);          //返回光照强度值(0~4000,设置笑死范围[0,100]中)
       
    }
    
    
    

    (5)实验结果:

     

    作者:jhan&

    物联沃分享整理
    物联沃-IOTWORD物联网 » 探讨20型光敏传感器

    发表回复