STM32學習心得二十五:光敏傳感器原理及實驗

記錄一下,方便以後翻閱~
主要內容:
1) 光敏傳感器概述;
2) 相關實驗代碼解讀。
實驗功能:通過ADC3_CH6來檢測光敏二極管一端的電壓變化來達到檢測光強的目的(可通過檢測環境光,調節LCD的背光大小)。
官方資料:《STM32中文參考手冊V10》第11章——模擬/數字轉換ADC
1. 光敏傳感器概述
光敏傳感器是最常見的傳感器之一,它的種類繁多,主要有:光電管、光電倍增管、光敏電阻、光敏三極管、太陽能電池、紅外線傳感器、紫外線傳感器、光纖式光電傳感器、色彩傳感器、CCD和CMOS圖像傳感器等。光傳感器是目前產量最多、應用最廣的傳感器之一,它在自動控制和非電量電測技術中佔有非常重要的地位。

光敏傳感器是利用光敏元件將光信號轉換爲電信號的傳感器,它的敏感波長在可見光波長附近,包括紅外線波長和紫外線波長。光傳感器不只侷限於對光的探測,它還可以作爲探測元件組成其他傳感器,對許多非電量進行檢測,只要將這些非電量轉換爲光信號的變化即可。
光敏二極管也叫光電二極管。光敏二極管與半導體二極管在結構上是類似的,其管芯是一個具有光敏特徵的PN結,具有單向導電性,因此工作時需加上反向電壓。無光照時,有很小的飽和反向漏電流,即暗電流,此時光敏二極管截止。當受到光照時,飽和反向漏電流大大增加,形成光電流,它隨入射光強度的變化而變化。當光線照射PN結時,可以使PN結中產生電子一空穴對,使少數載流子的密度增加。這些載流子在反向電壓下漂移,使反向電流增加。因此可以利用光照強弱來改變電路中的電流。

簡而言之:照射光敏二極管的光強不同,通過光敏二極管的電流大小就不同,所以可以通過檢測電流大小,達到檢測光強的目的。利用這個電流變化,我們串接一個電阻,就可以轉換成電壓的變化,從而通過ADC讀取電壓值,判斷外部光線的強弱。
2. 硬件連接圖
在這裏插入圖片描述
3.相關代碼解讀
3.1 adc.h頭文件代碼解讀

#ifndef __TSENSOR_H
#define __TSENSOR_H 
#include "stm32f10x.h"
void Adc3_Init(void);     //ADC3初始化//
u16  Get_Adc3(u8 ch);     //獲得ADC3某個通道值//  
#endif 

3.2 adc.c文件代碼解讀

#include "delay.h"
#include "sys.h"
#include "adc.h"
//編寫Adc3_Init初始化函數//                  
void  Adc3_Init(void)
{      
 ADC_InitTypeDef ADC_InitStructure; 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3 , ENABLE );    //使能ADC3通道時鐘//   
 RCC_ADCCLKConfig(RCC_PCLK2_Div6);                         //設置ADC時鐘//
 ADC_DeInit(ADC3);                                         //復位ADC3,將外設ADC3的全部寄存器重設爲缺省值// 
 //ADC3_InitStructure參數設置//
 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                   //獨立模式//
 ADC_InitStructure.ADC_ScanConvMode = DISABLE;                        //關閉掃描模式//
 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                  //單次轉換模式//
 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  //軟件觸發啓動//
 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;               //數據右對齊//
 ADC_InitStructure.ADC_NbrOfChannel = 1;                              //順序進行規則轉換的ADC通道的數目//
 ADC_Init(ADC3, &ADC_InitStructure);   
 ADC_Cmd(ADC3, ENABLE);                                               //使能指定的ADC3//
 //下面四個函數用於校準//
 ADC_ResetCalibration(ADC3);                                          //使能復位校準//   
 while(ADC_GetResetCalibrationStatus(ADC3));                          //等待復位校準結束//
 ADC_StartCalibration(ADC3);                                          //開啓AD校準//
 while(ADC_GetCalibrationStatus(ADC3));                               //等待校準結束//
}   
//編寫Get_Adc3函數//
u16 Get_Adc3(u8 ch)   
{
 //設置指定ADC的規則組通道,四個入口參數//
 ADC_RegularChannelConfig(ADC3, ch, 1, ADC_SampleTime_239Cycles5 );          
 ADC_SoftwareStartConvCmd(ADC3, ENABLE);         //使能指定的ADC3的軟件轉換啓動功能//   
 while(!ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC )); //等待轉換結束//
 return ADC_GetConversionValue(ADC3);            //返回最近一次ADC3規則組的轉換結果//
} 

3.3 lsens.h頭文件代碼解讀

#ifndef __LSENS_H
#define __LSENS_H 
#include "sys.h" 
#include "adc.h" 
//定義兩個常量//
#define LSENS_READ_TIMES 10              //定義光敏傳感器讀取次數,讀10次,然後取平均值//
#define LSENS_ADC_CHX    ADC_Channel_6   //定義光敏傳感器所在的ADC通道編號,即0x06//
//申明兩個函數//    
void Lsens_Init(void);                   //初始化光敏傳感器函數//
u8 Lsens_Get_Val(void);                  //讀取光敏傳感器值的函數//
#endif 

3.4 lsens.c文件代碼解讀

#include "lsens.h"
#include "delay.h"
//初始化光敏傳感器函數,即對GPIO,PF8初始化參數配置//
void Lsens_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);    //使能GPIOF時鐘 
 //配置GPIOF參數,引腳8,模擬輸入//
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;     
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;  
 GPIO_Init(GPIOF, &GPIO_InitStructure); 
 Adc3_Init();
}
//讀取Light Sens的值,範圍0-100,0最暗;100最亮// 
u8 Lsens_Get_Val(void)
{
 u32 temp_val=0;
 u8 t;
 for(t=0;t<LSENS_READ_TIMES;t++)       //LSENS_READ_TIMES在lsens.h文件中設好,默認10//
 {
  temp_val+=Get_Adc3(LSENS_ADC_CHX);   //讀取ADC值,LSENS_ADC_CHX在lsens.h文件中設好,默認ADC_Channel_6,即0x06//
  delay_ms(5);
 }
 temp_val/=LSENS_READ_TIMES;           //計算平均值// 
 if(temp_val>4000)temp_val=4000;       //當計算後的值大於4000時,強制轉換爲4000//
 return (u8)(100-(temp_val/40));       //將temp_val值歸一化到0-100之間//
}

3.5 main.c文件代碼解讀

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"  
#include "adc.h"
#include "lsens.h" 
 int main(void)
 {  
 u8 adcx; 
 delay_init();        //延時函數初始化   
 uart_init(115200);   //串口初始化爲115200
 LED_Init();          //初始化與LED連接的硬件接口
 Lsens_Init();        //初始化光敏傳感器             
 while(1)
 {
  adcx=Lsens_Get_Val();
  printf("光線強度:%d\n",adcx); 
  LED0=!LED0;
  delay_ms(500); 
 }
}

4. 實驗結果
在這裏插入圖片描述
舊知識點
1)複習如何新建工程模板,可參考STM32學習心得二:新建工程模板
2)複習基於庫函數的初始化函數的一般格式,可參考STM32學習心得三:GPIO實驗-基於庫函數
3)複習寄存器地址,可參考STM32學習心得四:GPIO實驗-基於寄存器
4)複習位操作,可參考STM32學習心得五:GPIO實驗-基於位操作
5)複習寄存器地址名稱映射,可參考STM32學習心得六:相關C語言學習及寄存器地址名稱映射解讀
6)複習時鐘系統框圖,可參考STM32學習心得七:STM32時鐘系統框圖解讀及相關函數
7)複習延遲函數,可參考STM32學習心得九:Systick滴答定時器和延時函數解讀
8)複習ST-LINK仿真器的參數配置,可參考STM32學習心得十:在Keil MDK軟件中配置ST-LINK仿真器
9)複習ST-LINK調試方法,可參考STM32學習心得十一:ST-LINK調試原理+軟硬件仿真調試方法
10)複習如何對GPIO進行復用,可參考STM32學習心得十二:端口複用和重映射
11)複習串口通信相關知識,可參考STM32學習心得十四:串口通信相關知識及配置方法
12)複習ADC原理及一般配置步驟,可參考STM32學習心得二十三:ADC轉換原理及模數轉換實驗STM32學習心得二十四:內部溫度傳感器原理及實驗

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章