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

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

[复制链接]
STMCU小助手 发布时间:2022-6-15 17:00
01. 光敏传感器简介% A  ?- X3 n. x( Q& L* Y
光敏传感器是最常见的传感器之一,它的种类繁多,主要有:光电管、光电倍增管、光敏电阻、光敏三极管、太阳能电池、红外线传感器、紫外线传感器、光纤式光电传感器、色彩传感器、CCD 和 CMOS 图像传感器等。光传感器是目前产量最多、应用最广的传感器之一,它在自动控制和非电量电测技术中占有非常重要的地位。
( G% |% S% j: u' s+ b0 I9 `5 P8 h. B2 s0 n$ l, C; E
光敏传感器是利用光敏元件将光信号转换为电信号的传感器,它的敏感波长在可见光波长附近,包括红外线波长和紫外线波长。光传感器不只局限于对光的探测,它还可以作为探测元件组成其他传感器,对许多非电量进行检测,只要将这些非电量转换为光信号的变化即可。
- z# S4 z( i% k& K9 m% M
0 @- E7 P: O/ d# q) `探索者 STM32F4 开发板板载了一个光敏二极管(光敏电阻),作为光敏传感器,它对光的变化非常敏感。光敏二极管也叫光电二极管。光敏二极管与半导体二极管在结构上是类似的,其管芯是一个具有光敏特征的 PN 结,具有单向导电性,因此工作时需加上反向电压。无光照时,有很小的饱和反向漏电流,即暗电流,此时光敏二极管截止。当受到光照时,饱和反向漏电流大大增加,形成光电流,它随入射光强度的变化而变化。当光线照射 PN 结时,可以使 PN 结中产生电子一空穴对,使少数载流子的密度增加。这些载流子在反向电压下漂移,使反向电流增加。因此可以利用光照强弱来改变电路中的电流。
" A. w/ B6 ~7 P2 \$ O
. `+ n% i/ o% t% a' f6 B- K9 R利用这个电流变化,我们串接一个电阻,就可以转换成电压的变化,从而通过 ADC 读取电压值,判断外部光线的强弱。
$ F8 z( n$ n5 ^) M2 ^6 ]; X1 p3 h" H* n% Z
02. 硬件模块
/ B& U' k, C( ^9 J* d! v用到的硬件资源有:. S! o4 }$ ]3 ?" e8 u# C
1) 指示灯 DS0
5 d( S$ @9 Z, k- r; K' y2) TFTLCD 模块: `! V, C$ `- b' Q& h4 p5 ?
3) ADC1 F+ ^! X3 I. Y4 A
4) 光敏传感器6 w; o. k0 m% _9 n8 t& x( W

" G+ D! t+ r$ ?. {, {0 `# ~ O[EGGKG5))YC)5L(YW12KXX.png 7 c& ]' v( u, V+ C& M" g2 X1 |
: ?/ n8 ]( q+ e. C% b; D( \
LS1 是光敏二极管(实物在开发板摄像头接口右侧),R58 为其提供反向电压,当环境光线变化时,LS1 两端的电压也会随之改变,从而通过 ADC3_IN5 通道,读取LIGHT_SENSOR(PF7)上面的电压,即可得到环境光线的强弱。光线越强,电压越低,光线越暗,电压越高。. T% j( _2 `( B5 x8 \, y8 f, z
% `+ A  c8 k# o& ^
03. 程序设计) ~) x2 l/ W2 C
adc.h文件$ L* L/ y2 |& _7 N
: T% D" s1 t5 Y
  1. //-----------------------------------
    6 Y( J9 K. ^' T: Q9 p
  2. //ADC3通道初始化- s9 }% w; @3 k6 a- s. M8 S" Q' @
  3. void ADC3_Init(void);
    ! I, F# F; w3 _, Q
  4. //获取ADC3某个通道的值
    ) ^0 `0 x7 K5 d" j  ^7 h
  5. u16 Get_Adc3(u8 ch);
    ! J$ M! F( q' a( a7 M! d& j
  6. //获取某个通道给定次数采样的平均值# ~9 ?. Y# n4 [1 J# w
  7. u16 Get_Adc3_Average(u8 ch, u8 times);
复制代码
; j0 F+ I* I  o3 f
adc.c文件
2 `4 c: S' s8 e0 f1 q2 o/ `: W7 R, Y9 S
  1. //-------------------------ADC3------------------------
    9 U2 G: T9 ?6 \( g. o' I+ _8 u
  2. //ADC3通道初始化
      M/ b; c2 n2 l. [2 }0 `
  3. void ADC3_Init(void)
    3 M6 T' S5 Z' r7 n- ?9 b) j
  4. {8 A' j% S4 ]3 s( @* }
  5.         GPIO_InitTypeDef GPIO_InitStructure;( L4 Z4 Z5 W3 [" y, ]( O8 l
  6.         ADC_CommonInitTypeDef ADC_CommonInitStructure;
    $ N- P. G& ?, e" Q
  7.         ADC_InitTypeDef ADC_InitStructure;  |; N" N4 j& ?9 `3 i
  8.         + K' @2 i1 x( a: f7 O( M4 B
  9.         //开启GPIO时钟 PA5
    ( x7 S+ _% X1 o# \
  10.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); 0 d1 ]  X' k4 ^# z8 y
  11.         
    : D+ d0 y6 t! V5 b) w" A4 t
  12.         //开启ADC1时钟( I/ f" M& s. j" Q4 F
  13.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);        
    9 O" \/ {/ ^' `* a) x" W
  14.         " C2 C1 J5 g: j* U' u5 z- I
  15.         //GPIO初始化 初始化为模拟功能7 u& h" [) n' i
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;  g& _& [3 V5 O% ~
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    9 A2 s/ m4 l1 m1 e4 O0 u7 I. g6 g9 m
  18.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;- Y; @/ o1 v* ]! l
  19.         GPIO_Init(GPIOF, &GPIO_InitStructure);' P4 O0 o) F3 x; z
  20.         5 `. O6 r- T8 g3 G/ g  N
  21.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,ENABLE);          //ADC1复位4 t, |( m8 T: I$ r! z5 K6 X
  22.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,DISABLE);        //复位结束        
    $ ^1 l* p& d9 F9 O# ]5 |, a. P
  23.         ; D+ i  J" {) n- f& K5 h
  24.         
    ' k- Y# j- P/ k2 b. d% V  ~6 W
  25.         //初始化ADC_CCR寄存器$ R: `6 H5 o: b7 h

  26. ; P! o7 ~# s4 A' S+ X; d/ z
  27.         ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;- y4 j9 e# R3 S/ V
  28.         ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;& w/ s6 i8 B& b. u! U
  29.         ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;5 X( V0 E3 E2 q5 |, A8 \
  30.         ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;+ H. p3 k, r9 H- ?) \( U
  31.         ADC_CommonInit(&ADC_CommonInitStructure);
    - V& s! u; P6 q
  32.         , K( M9 F: i# d+ R

  33. ( V' c6 s( f7 \0 n" l6 l+ h, A
  34.         //初始化ADC1
    ! C9 ?' u: H  ]
  35.         ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;4 r: y8 O$ y3 a2 t* j
  36.         ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    9 ]5 n2 g" v" T8 t) O# C% p
  37.         ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;& W9 m3 K% z* J, @; i
  38.         ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;: T" k+ d+ O" E1 U8 ]$ N" I  B1 z
  39.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    : T) `8 `, ]0 k. M3 A) s( \; V& L
  40.         ADC_InitStructure.ADC_NbrOfConversion = 1;- H: H: d' m& ^

  41. % t* T3 ?$ H; G4 [9 x" I
  42.         ADC_Init(ADC3, &ADC_InitStructure);
    $ h& j3 P3 G& }, j) [  ^7 P/ _! C
  43. ' p1 G* m, x* W) r

  44. 4 B( ~0 J% o6 h, T
  45.         //设置ADC规则组通道 一个序列 采样时间
    ' K# N$ I7 C! t- @+ [+ Z, m; ^4 q, f
  46.         //ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_480Cycles);. K! G# b  |5 |2 R1 }0 A

  47. , A3 ^. O4 F: w! T

  48. " D2 K  s2 c4 b% L! h2 v
  49.         //使能ADC5 @1 n2 @$ T. f, ~
  50.         ADC_Cmd(ADC3, ENABLE);
    1 v6 v+ k3 U3 d" `& C1 s
  51.         # `% |6 ?& g6 B$ }7 m: W
  52. }  T2 I# u# Z5 i% ], z" }

  53. 3 n' Y& c3 e; V+ {7 ]; c6 p3 s0 [
  54. //获取ADC3某个通道的值8 N1 ^* p8 j# P) e
  55. u16 Get_Adc3(u8 ch)
    : L/ `0 E) C; S2 w: M* u
  56. {
    % W/ g7 X0 g: m/ N+ {- W. e3 o
  57.         //设置ADC规则组通道 一个序列 采样时间  R6 W' A2 _0 F) S3 z! U' t
  58.         ADC_RegularChannelConfig(ADC3, ch, 1, ADC_SampleTime_480Cycles);
    , D- ^5 Q2 a, D, r
  59.         
    8 N% L7 h* O" h- a: z6 u
  60.         //开启ADC3的软件转换启动功能
    5 s  u. B1 ]% U7 S
  61.         ADC_SoftwareStartConv(ADC3);: K  i  m# m- G* R
  62.         ' k, H+ `$ u; Y2 ~
  63.         //等待转换结束
    1 D- F% X* J, y9 `: u7 m  C
  64.         while(ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC) == RESET)2 k" N& q* P2 o" c9 h5 s
  65.                 ;
    $ Y% t* J& S6 W/ W& t0 p

  66. 2 l" `3 b3 c" n& u' i2 t
  67.         //读取ADC的值
    " g2 o! c/ b9 r, }
  68.         return  ADC_GetConversionValue(ADC3);
    2 }7 V! o# R; v) S. G2 h

  69. 5 t; n: g8 \1 a0 s( ], R- J- E9 J
  70. }
    ; V9 Y& M8 |7 l+ e
  71. ! L! ^# ]( r+ {% ~4 \8 ]+ |5 [
  72. //获取某个通道给定次数采样的平均值' X& I7 z: N4 a$ l) B5 E
  73. u16 Get_Adc3_Average(u8 ch, u8 times)9 j5 q( ]; P- t/ X8 `' C  x: n2 r
  74. {2 _8 Z" |0 X! b8 T+ R  N, A
  75.         u32 tmp = 0;- n; ]8 }" P2 \! @3 f
  76.         u8 i = 0;
    ) }+ d7 L& N" N) c
  77.         
    3 v' s  c  H( H" Z3 y" @
  78.         for (i = 0; i < times; i++)) b  _5 i( s6 e4 W
  79.         {
    6 @; t! Y# D' ^0 m0 m# `7 E
  80.                 tmp += Get_Adc3(ch);4 `. {/ A5 u' W  V) p
  81.                 delay_ms(5);
    - \3 J: x  o5 B3 ~' R* q+ g
  82.         
    8 f: E8 ?" f. E; E# G5 I4 a
  83.         }
    1 o; o: @) u1 j1 ?
  84.         
    * n. Y6 r1 A$ w; k1 I; _
  85.         //得到平均值0 h6 S. x/ Z' w( M
  86.         tmp /= times;3 Y* s; C# P" @) {; {% u
  87.         
      e) a% X. d& C8 f' I
  88.         if (tmp > 4000)# ]9 ]+ M/ |$ ~, g1 J- _* R1 a
  89.         {
    ' l( ?3 v) |/ L- {" b
  90.                 tmp = 4000;
    6 U5 Y. H' O% ]' T5 m/ A% s/ e- ^
  91.         }
    " j+ f6 v0 l4 }4 t; l
  92.         
    5 K1 t9 Q4 q# h- \
  93.         
    & q( ~" [: M6 b: A$ w8 k$ X
  94.         return (u16)(100 - (tmp / 40));
    0 L8 S# t; Q* B5 d
  95. }
复制代码
% N% I+ ]9 U2 L7 a1 L- f+ s
main.c文件
2 N1 y6 {3 e6 H) J" _. ~5 U8 z9 {* R$ j. f) W8 k( P7 X& X
  1. #include "sys.h"
    2 q/ R% o8 `6 n3 _# }' i
  2. #include "delay.h"4 I& T2 e- Y, G9 s
  3. #include "usart.h"
    / K! Q& P% d. Y2 Z# x. ]! p; {8 P1 a( J
  4. #include "led.h"
    4 a# J/ y8 }+ {! T% v
  5. #include "beep.h"" p" Z" t$ c" W" p+ o/ S
  6. #include "key.h"
    . s, H# @' h2 w, e
  7. #include "usmart.h"
    ) E. \! Q/ m! A# v- y
  8. #include "lcd.h"' d6 P  |& g9 U' }8 t
  9. #include "rtc.h", f$ z+ N" I+ |! {
  10. #include "rng.h"
    , O0 q1 n( [9 S1 f/ ]: H+ C4 h
  11. #include "key.h"- Q( z' ^, h1 s: \
  12. #include "wkup.h"
    * I/ a& Y7 h( i& f
  13. #include "adc.h"
    9 {" R7 X- I3 b/ t; g- |

  14. 3 F1 n- S1 {3 S( c
  15. int main(void)
      q$ @+ R: n5 _# B& M4 ~4 D
  16. { % y0 y3 F0 A/ h5 Q* l% Y4 P
  17.         //u16 value = 0;
    , [- L  K: [. `/ h5 Y
  18.         
    ! u& Q; Z9 \! q+ |. ]4 M. i
  19.         u16 temp = 0;, _: ~) k$ _* L

  20. 5 ~5 c" C, B7 C1 [: l. b$ B
  21.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
    0 D. a( }/ Y( \6 F
  22.         
    6 S' n) N. p6 b( u
  23.         delay_init(168);
    ' N2 f" |5 {3 o! A4 \) _
  24.         
    ; Z9 }$ C5 S' B6 W
  25.         uart_init(115200);
      E) I" w3 n, `# z; M, i7 ]4 O
  26.         
    ! S" y7 M( D$ [( |, ]/ J, V
  27.         //usmart_dev.init(84);7 p/ F2 }2 W7 k
  28. 6 q1 o3 C0 m6 U7 S
  29.         6 k2 [3 ~- G$ \" [- J1 a
  30.         LED_Init();
    . y  i9 ?8 o4 y+ v9 ?% f: \
  31.         
    & s% P4 z& V& l! n, \
  32.         + M9 q) n  m, D1 f$ ?( ^9 q8 ]3 R
  33.         LCD_Init();
    + Z& g8 L6 L' g% i" H

  34. / @. |( ^) [$ B2 @/ C7 G% @
  35.         ADC3_Init();
    1 `9 o; s7 O/ ~1 q- I' P
  36.         0 R( S4 ^" L2 W& c5 l- n
  37.                
    6 z& E5 ]  ?( V( J$ A# C
  38.         POINT_COLOR = RED;
    ( k! l, U! L4 j- B$ Y  X
  39.           T' n" A) C4 c( a% O
  40.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        
    1 z& E" Z* u5 T; [5 W; j5 l
  41.         LCD_ShowString(30,70,200,16,16,"LSENS TEST");        . s3 U* G6 I) v2 ^6 w- A
  42.         LCD_ShowString(30,90,200,16,16,"ATOM@tom");# q/ C7 [- y$ z: D; N8 `
  43.         LCD_ShowString(30,110,200,16,16,"2020/09/15");         * X8 ?! z  z0 x0 Y' y  H" l$ m
  44.         
    # r3 p9 Q6 Z* K1 Y4 K" o. n
  45.         //设置字体为蓝色
    6 _- u8 r( e1 L7 M; J( _# Z
  46.         POINT_COLOR = BLUE;
    9 ]( R$ j3 V/ f, \" I
  47.         LCD_ShowString(30,140,200,16,16,"LSENS VAL:");         
    6 F) ^) P5 z. e5 h% _1 E3 q
  48.                
    ' ~% n, [& v/ M4 B  f- o
  49.         while(1)
    - @3 q% W9 g* G9 c& b/ L  m2 E" y
  50.         {2 f- T. J- T: O& U. y0 t4 X: \; ~
  51.                 //得到温度值
    : U0 p3 Y  U! E' c! p% B' e3 A% m
  52.                 temp = Get_Adc3_Average(ADC_Channel_5, 10);
    6 a, n3 d% o- U" t
  53.                 ( i) c; k9 e- A( K4 f3 f
  54.                 - \- ?9 w1 J) |
  55.                 LCD_ShowxNum(30+10*8,130,temp,3,16,0);//显示ADC的值
    ! K' ^: A8 t0 o: v4 Z
  56. ' t0 W$ M% V2 D9 p  F$ Q
  57.                 printf("Light: %d\r\n", temp);- W0 o" B6 a: _
  58.                 ' U3 \( a5 d/ y1 k0 L
  59.                 LED1 = !LED1;
    + L& p- T4 k4 a: Y
  60.                 * Z. Q/ S! K. }! ]
  61.                 delay_ms(250);
    6 ]/ R8 N7 O2 J: |$ z
  62.         }
    4 x: U" V- I' p, B1 o+ k8 r6 s9 e
  63. }
复制代码

1 V6 r; `: r' a) ^1 s04. 结果验证
7 u  U9 O5 ^& P
伴随 DS0 的不停闪烁,提示程序在运行。此时,我们可以通过给 LS1 不同的光照强度,来观察 LSENS_VAL 值的变化,光照越强,该值越大,光照越弱,该值越小。
; |6 n7 J( c; u" h9 A' [7 ^, t) h& |& L& z6 i/ \
5 Q# Q& X( M7 W
收藏 评论0 发布时间:2022-6-15 17:00

举报

0个回答

所属标签

相似分享

官网相关资源

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