你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 光敏传感器示例

[复制链接]
STMCU小助手 发布时间:2022-6-15 17:00
01. 光敏传感器简介& z$ o# J1 ^6 \7 K) x
光敏传感器是最常见的传感器之一,它的种类繁多,主要有:光电管、光电倍增管、光敏电阻、光敏三极管、太阳能电池、红外线传感器、紫外线传感器、光纤式光电传感器、色彩传感器、CCD 和 CMOS 图像传感器等。光传感器是目前产量最多、应用最广的传感器之一,它在自动控制和非电量电测技术中占有非常重要的地位。8 Z: p1 J5 J% q+ G* R# ^

! }8 o4 O' S- R- G, X5 s% Y* _光敏传感器是利用光敏元件将光信号转换为电信号的传感器,它的敏感波长在可见光波长附近,包括红外线波长和紫外线波长。光传感器不只局限于对光的探测,它还可以作为探测元件组成其他传感器,对许多非电量进行检测,只要将这些非电量转换为光信号的变化即可。' @0 D+ |4 V! {  \  |: n
: E9 p" ^( c( E$ ~$ [
探索者 STM32F4 开发板板载了一个光敏二极管(光敏电阻),作为光敏传感器,它对光的变化非常敏感。光敏二极管也叫光电二极管。光敏二极管与半导体二极管在结构上是类似的,其管芯是一个具有光敏特征的 PN 结,具有单向导电性,因此工作时需加上反向电压。无光照时,有很小的饱和反向漏电流,即暗电流,此时光敏二极管截止。当受到光照时,饱和反向漏电流大大增加,形成光电流,它随入射光强度的变化而变化。当光线照射 PN 结时,可以使 PN 结中产生电子一空穴对,使少数载流子的密度增加。这些载流子在反向电压下漂移,使反向电流增加。因此可以利用光照强弱来改变电路中的电流。# L& q2 c2 t" [

! X4 c( y3 E" {; G) [利用这个电流变化,我们串接一个电阻,就可以转换成电压的变化,从而通过 ADC 读取电压值,判断外部光线的强弱。/ y; S6 @. i! k- k  W+ I
2 p  |7 T, ]/ T1 X# t
02. 硬件模块
7 o( y6 N2 c7 s( L& X* X用到的硬件资源有:
+ l  \6 ]6 {2 G( K; `( v; o1) 指示灯 DS0
. n: W1 B7 b$ s% F2) TFTLCD 模块- y- M0 F6 ?+ p; c# W
3) ADC  Z4 X$ p, Q) J0 p6 ?
4) 光敏传感器4 ~# `( L4 w5 I

% c3 u5 S2 c" b2 s O[EGGKG5))YC)5L(YW12KXX.png 3 l, ~" V$ ^6 g3 I
) b! P5 e! n1 d) w
LS1 是光敏二极管(实物在开发板摄像头接口右侧),R58 为其提供反向电压,当环境光线变化时,LS1 两端的电压也会随之改变,从而通过 ADC3_IN5 通道,读取LIGHT_SENSOR(PF7)上面的电压,即可得到环境光线的强弱。光线越强,电压越低,光线越暗,电压越高。
7 t6 l% A& h! A: [* g. f9 m0 S
" Z9 y$ M, v! V2 i03. 程序设计+ I4 J0 U( l, B# l( U
adc.h文件
' x9 T5 @* q) ~; D* E* W* p
* R6 `3 h  Q2 Q- h/ o( x
  1. //-----------------------------------+ q4 L- i& W3 ^2 U
  2. //ADC3通道初始化
    * K) ~. v# Y- o! u
  3. void ADC3_Init(void);
    # ~. v; y( Z8 ^6 S. W5 |! h! l
  4. //获取ADC3某个通道的值/ E* A  D) w- X" {* {
  5. u16 Get_Adc3(u8 ch);2 z/ g4 D  W8 o6 L/ j8 V
  6. //获取某个通道给定次数采样的平均值: u, {5 z6 q# @
  7. u16 Get_Adc3_Average(u8 ch, u8 times);
复制代码

; C, l! |, U/ Iadc.c文件  w% Q1 C. H+ i
' C4 N. A2 Y, ?# d0 j
  1. //-------------------------ADC3------------------------3 A7 d) E  q/ u
  2. //ADC3通道初始化0 i2 l( S  w; K/ i$ Z& D8 Z7 m8 F
  3. void ADC3_Init(void)
    ; N/ \8 ]# V# `% F. {
  4. {/ X' |7 l0 s+ H* Q
  5.         GPIO_InitTypeDef GPIO_InitStructure;
    2 o" h, |- \& N8 J6 @9 r
  6.         ADC_CommonInitTypeDef ADC_CommonInitStructure;
    % z% I2 i- V$ k
  7.         ADC_InitTypeDef ADC_InitStructure;
    # e- c, I1 T* l: n: S
  8.         ) T" ^. O8 Q, n  E
  9.         //开启GPIO时钟 PA59 _* i" n( z. J
  10.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); ) x7 j  w0 T' u& d' d* M
  11.         
    ' C% ?: {- A% q
  12.         //开启ADC1时钟( O' D0 ?5 ~' h5 Q  D
  13.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);        " B& \# }4 b% U* @1 d
  14.         " h; i  ]4 m; W$ \, l* s
  15.         //GPIO初始化 初始化为模拟功能# ^- N2 j9 V1 p8 ]* a3 U! c' i2 p
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;# U# B0 Y) ~2 k  e# b" C
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    . q: [* _9 x' t4 i; T6 v- D
  18.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;# i, m; c6 B, p( Z
  19.         GPIO_Init(GPIOF, &GPIO_InitStructure);; I7 P' y! d1 \8 `
  20.         
    " F' u8 X! g' x
  21.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,ENABLE);          //ADC1复位
    / H" g& i$ M7 H, l
  22.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,DISABLE);        //复位结束        
    : p; N1 M* D5 A* a
  23.         
    ) `/ J1 x4 O+ k! E
  24.         
    ; o  N# v( D' \, m. `
  25.         //初始化ADC_CCR寄存器4 p9 M" b$ L0 O. o

  26. % R# O8 j: E0 l! Z5 t& s
  27.         ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
    6 ^: R" Z4 l$ T. \0 L" K. w: v) F
  28.         ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
    " h: v3 z7 [* O
  29.         ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
    6 D  ~! F7 T; ]% N5 P$ ^0 B6 D2 @$ J
  30.         ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;) ~( A: t: G0 ]  X
  31.         ADC_CommonInit(&ADC_CommonInitStructure);
    + a/ p& l% x$ B
  32.         3 R& V+ H- o4 @& Z+ v6 D

  33. 1 U7 a- E9 o& N* j$ A
  34.         //初始化ADC1
    * A) i5 u% s+ n3 @) _  \0 V( J
  35.         ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;. P2 ]$ t2 r6 g9 ~
  36.         ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    . o( ~: b6 y% E& s
  37.         ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;0 R1 H" k- Z$ `1 k
  38.         ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    / G2 p  y2 C# _% v4 A1 m
  39.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;6 r4 ]" O8 V% q: `7 o: V. u" N
  40.         ADC_InitStructure.ADC_NbrOfConversion = 1;
    # U. Y) Y, n, \

  41. 0 _# ?6 g4 d2 J5 z/ n/ y
  42.         ADC_Init(ADC3, &ADC_InitStructure);# {8 m; z9 r! s  E" b+ r) R  A# v
  43. 9 Z% z0 `0 X# K! C
  44. + L6 D6 V, ~; T, g1 r! ?
  45.         //设置ADC规则组通道 一个序列 采样时间  ~+ _, l0 x' x6 v* z% k. k  {
  46.         //ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_480Cycles);3 u5 y- O' M. z" p6 s

  47. ' `5 [# R7 `( _" |
  48. 1 T5 X; H3 f2 H" Z1 b6 s% f
  49.         //使能ADC
    0 S# Z0 ^& f: t6 M( w( I
  50.         ADC_Cmd(ADC3, ENABLE);
    0 r. q/ k' P9 c& R) K0 P
  51.         
    $ n6 X5 c0 w2 X! m" R) p1 C
  52. }. u9 [( n, x' P- {- _
  53. 3 \% q7 C9 {- }9 A
  54. //获取ADC3某个通道的值
    6 i1 [) A# I0 ^4 l* w8 C: b% M
  55. u16 Get_Adc3(u8 ch)' `! f8 k/ H2 }% \& V
  56. {* [% z) y& ^" L  R; k. p) k
  57.         //设置ADC规则组通道 一个序列 采样时间
    # o+ y; P) P' D" A! _' @  y: u
  58.         ADC_RegularChannelConfig(ADC3, ch, 1, ADC_SampleTime_480Cycles);; i  @% c6 d) z: M" V: Y
  59.         7 g* v: N8 t6 U  L# g; F* `, Y
  60.         //开启ADC3的软件转换启动功能
    $ S7 F7 b/ W' @8 ]
  61.         ADC_SoftwareStartConv(ADC3);
    9 G! |! k7 V8 \9 A
  62.         
    + y8 e- a6 U7 W. B3 v5 h
  63.         //等待转换结束: c; x' T' G9 c
  64.         while(ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC) == RESET)1 L- Z  _- y1 `' Y# G. g) u. E5 Z
  65.                 ;
      a9 B9 y- }' [
  66. ' |8 E2 I4 D; I9 `8 }+ U0 K, N1 B
  67.         //读取ADC的值7 K2 T* N& g. Y+ p1 @' q9 N  o
  68.         return  ADC_GetConversionValue(ADC3);9 a+ A2 t3 N) I0 J
  69. - X3 Y$ k% s# G, ]2 ?6 \8 j
  70. }
    3 R4 h$ X8 M6 m4 G3 v
  71. 9 J$ k1 H" l3 X, {/ X# t* b7 d3 _
  72. //获取某个通道给定次数采样的平均值" O, Y2 `( W& K# d0 h
  73. u16 Get_Adc3_Average(u8 ch, u8 times)
    3 ~2 B* K3 K) Z
  74. {
    ) N% H6 W5 V% t; K+ Y. {3 `  J
  75.         u32 tmp = 0;
    " s, B2 o* y( M4 W. G2 l7 t
  76.         u8 i = 0;
    # m8 u4 q( C0 X( T/ n, i, s
  77.         
    # S7 ]9 k8 O. s; G  v* I9 v
  78.         for (i = 0; i < times; i++)9 U4 N7 T' x0 g6 N( }+ Q$ y' y- q
  79.         {$ [- Y9 k) G; q+ R$ F
  80.                 tmp += Get_Adc3(ch);3 C5 Y1 j, e' u, [# r
  81.                 delay_ms(5);- ^* Y/ B' ^9 ?( `% I
  82.         
    - }& z: R# v0 S' ]9 f8 j
  83.         }5 [6 z, d: ~- F9 [# s% L4 z6 M. Y
  84.         8 S$ m% }6 w; R- [
  85.         //得到平均值
    2 V& T! {8 G  l
  86.         tmp /= times;
    6 N" {! k8 u7 o
  87.         # Y7 c' R$ K0 Z  H) y
  88.         if (tmp > 4000)( ^/ i/ i% J& y) y9 d  c1 Y, x
  89.         {7 ^( \; p4 r3 H* T  j* Y" j
  90.                 tmp = 4000;
    " N, ^& y( P) S2 N
  91.         }
    . b& R  n# Z- d5 n6 J. ^7 R
  92.         
    % f$ V$ t! V( f' L7 H
  93.         
      B7 Z7 C! I  ~4 w9 c
  94.         return (u16)(100 - (tmp / 40));6 y4 V( o& K2 t
  95. }
复制代码
5 F* c6 F# k# U% b3 y/ w/ Q
main.c文件2 ^5 o+ y3 m: P- y  V3 y2 m

9 q" @- `- N. T
  1. #include "sys.h"
    * g3 f0 t7 m# O8 g# C- Z1 [
  2. #include "delay.h"
    / w  p0 x1 `$ g0 ~2 l4 v4 |
  3. #include "usart.h"0 c7 L! v% h' n
  4. #include "led.h"
    8 w1 H5 s" b) Y' ?, H+ R" w0 r
  5. #include "beep.h"
    4 d# A$ D& T% d2 i$ ?
  6. #include "key.h"  O2 ?3 H3 }% e7 C( i
  7. #include "usmart.h"/ }( B8 V* L0 K5 O. ?4 e# u, l  x
  8. #include "lcd.h"" N9 Z; `! P* o+ p) m0 n1 h
  9. #include "rtc.h"1 M( L' ^! [- v, k
  10. #include "rng.h"
    ( ]5 Y. J* u  j4 H
  11. #include "key.h"
    6 y5 A8 Q+ F+ P, H/ k3 l; O5 r
  12. #include "wkup.h"+ K! W1 [: |" M! N' f
  13. #include "adc.h"% w/ ]. D4 R# z
  14. ' ?# T; w$ `  l% U  M* e* b+ h0 g
  15. int main(void)/ z1 c+ W7 {! P! @+ H# T2 D4 k
  16. { * ]' l: l4 K/ S) v  \2 ]( F
  17.         //u16 value = 0;7 K' h+ K5 v3 m9 E
  18.         $ b- H: U3 [& N& s
  19.         u16 temp = 0;/ T; g) ]: [5 d- b
  20. 9 U. W$ c8 Q$ E
  21.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组22 l/ p6 B, [) J8 o; M" ~' x
  22.         + v( C% Q, |. r& n( H, S, @
  23.         delay_init(168);
    ( s* y4 G6 f; U: ~$ m6 n- s! ^, C
  24.         " k$ M0 d* R  s/ ?
  25.         uart_init(115200);
    / t0 k3 j' ?1 [, ]. o$ k/ K
  26.         ' _# }2 C% ?9 H8 g4 G. {
  27.         //usmart_dev.init(84);/ I& w0 v4 T" O' \

  28. " R5 c% l3 V5 k  z3 z0 M
  29.         
    + ^$ ?2 x% z. U4 _
  30.         LED_Init();
    7 }$ T4 g6 k9 g8 M% r, ^
  31.         
    ( }. i- n$ E) [- ^8 A3 I
  32.         8 v, ^4 N2 |' V& f6 |; o6 _
  33.         LCD_Init();5 v! D. o' r5 d/ j+ C

  34.   H$ ]3 |. A/ G' L; c% y  t' L: q
  35.         ADC3_Init();, r. t, x0 ]3 o2 s/ v- M4 t2 ~# r! `
  36.         
      g* M2 d4 N2 _' }5 k0 r- ~
  37.                
    + o9 s8 W1 k9 J1 i( A4 N* D/ N& ]$ e4 L
  38.         POINT_COLOR = RED;( q! m# C7 M- C
  39.         
    % k$ A/ b+ l6 i: C
  40.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        
    / A* j7 H5 `) w$ a
  41.         LCD_ShowString(30,70,200,16,16,"LSENS TEST");        5 ^7 H/ b0 r0 p, w: w
  42.         LCD_ShowString(30,90,200,16,16,"ATOM@tom");3 t- r: A! O" X
  43.         LCD_ShowString(30,110,200,16,16,"2020/09/15");           Y+ _; G8 K% d
  44.         1 d; b: [, x7 ]" ?; N7 Z; b
  45.         //设置字体为蓝色' m, f! X: P, D
  46.         POINT_COLOR = BLUE; ' m3 p' l4 r7 w- D, }' W. M. l! }1 Q
  47.         LCD_ShowString(30,140,200,16,16,"LSENS VAL:");         
    : G. Y! d; f6 _5 p
  48.                
    * u) N- d- t! p  @4 a5 I+ t& v0 r
  49.         while(1)( r* ?9 j2 y! ~5 M$ N
  50.         {
      t; y9 {# M3 P2 j2 \$ s
  51.                 //得到温度值
    $ D% N+ R$ n3 I8 O) j7 f
  52.                 temp = Get_Adc3_Average(ADC_Channel_5, 10);( N  B" g5 N: o( y
  53.                
    ) L) s& C( h4 I+ m2 c* V
  54.                 6 \0 Z6 m- a$ N# t- g
  55.                 LCD_ShowxNum(30+10*8,130,temp,3,16,0);//显示ADC的值+ H$ g) e/ B  O; U6 ^; P- i
  56. 9 g1 C  M- T, c( L- O
  57.                 printf("Light: %d\r\n", temp);
    1 y. D1 ~7 c- W7 l1 L. n
  58.                
    ! s. N7 ]) B- z. H: c$ a) Y
  59.                 LED1 = !LED1;
    6 c  k$ u! S0 C, U- q  H- ~
  60.                 % [8 m2 @2 T) Z6 E
  61.                 delay_ms(250);
    7 M6 I: Y3 K. `6 Y# s
  62.         }$ I+ R4 e: s. _8 c  M: K) }( i
  63. }
复制代码

( a6 J9 E8 T" ^$ n5 h, p* h04. 结果验证
- }! f3 ?; U/ C; Z
伴随 DS0 的不停闪烁,提示程序在运行。此时,我们可以通过给 LS1 不同的光照强度,来观察 LSENS_VAL 值的变化,光照越强,该值越大,光照越弱,该值越小。; Z: p- L3 J( K+ I4 |  j  ~  ?

2 k# k/ S  \! a; a- f8 F$ [6 e9 A- h: P* o7 @9 K0 U( o4 W
收藏 评论0 发布时间:2022-6-15 17:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版