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

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

[复制链接]
STMCU小助手 发布时间:2022-3-28 10:42
01. 光敏传感器简介& R, R0 f' f6 j
光敏传感器是最常见的传感器之一,它的种类繁多,主要有:光电管、光电倍增管、光敏电阻、光敏三极管、太阳能电池、红外线传感器、紫外线传感器、光纤式光电传感器、色彩传感器、CCD 和 CMOS 图像传感器等。光传感器是目前产量最多、应用最广的传感器之一,它在自动控制和非电量电测技术中占有非常重要的地位。
; F4 D( V2 |5 b+ F
5 {6 `) {& x  H# H8 K" _光敏传感器是利用光敏元件将光信号转换为电信号的传感器,它的敏感波长在可见光波长附近,包括红外线波长和紫外线波长。光传感器不只局限于对光的探测,它还可以作为探测元件组成其他传感器,对许多非电量进行检测,只要将这些非电量转换为光信号的变化即可。0 d6 E( Y# ^* o. `# }9 s
  @7 H( w, V/ o  p
探索者 STM32F4 开发板板载了一个光敏二极管(光敏电阻),作为光敏传感器,它对光的变化非常敏感。光敏二极管也叫光电二极管。光敏二极管与半导体二极管在结构上是类似的,其管芯是一个具有光敏特征的 PN 结,具有单向导电性,因此工作时需加上反向电压。无光照时,有很小的饱和反向漏电流,即暗电流,此时光敏二极管截止。当受到光照时,饱和反向漏电流大大增加,形成光电流,它随入射光强度的变化而变化。当光线照射 PN 结时,可以使 PN 结中产生电子一空穴对,使少数载流子的密度增加。这些载流子在反向电压下漂移,使反向电流增加。因此可以利用光照强弱来改变电路中的电流。
6 E! X4 c& e9 M" i3 @( z+ K& ^6 S
: t1 D7 x" `- w% q) T1 g  ^利用这个电流变化,我们串接一个电阻,就可以转换成电压的变化,从而通过 ADC 读取电压值,判断外部光线的强弱。
) S4 w! T. m. b" p0 P7 N" K0 s# w" s; I+ D1 Q! e) i' w1 {
02. 硬件模块# q" h4 o& Z# `; I( z% S  T
用到的硬件资源有:2 z3 ~3 l- I/ b. _5 H* J
1) 指示灯 DS0
9 P. b1 M- y: H4 B' x. Y6 i4 \2) TFTLCD 模块
3 _  l5 L0 ]& r# _) U3 d8 |+ c  S3) ADC! I5 r! B/ r' J6 b8 H" |5 d
4) 光敏传感器: f7 M, v& _% U# H, `' f3 x2 g+ [
# x" ~6 o* y, g1 Z# B6 r0 S7 K
5FSQRTDF(13TY~XI3YW(EFC.png & q3 g( @) M# \+ s

6 A' B0 @; H# \) E* V9 j' mLS1 是光敏二极管(实物在开发板摄像头接口右侧),R58 为其提供反向电压,当环境光线变化时,LS1 两端的电压也会随之改变,从而通过 ADC3_IN5 通道,读取LIGHT_SENSOR(PF7)上面的电压,即可得到环境光线的强弱。光线越强,电压越低,光线越暗,电压越高。
! X: a$ i; W% v/ e+ m9 N+ G  a3 K% y8 C9 W
03. 程序设计
3 V' S5 R/ j" ~9 O. e% {$ s& z- I0 Oadc.h文件7 D9 P" e# @7 x6 d! B6 \
  1. //-----------------------------------5 T$ M# b1 q4 n5 a$ h& u5 p
  2. //ADC3通道初始化
    2 [0 \# N4 E$ V7 d
  3. void ADC3_Init(void);
    # s- N" N1 S9 R4 c. Y
  4. //获取ADC3某个通道的值
    : f% _# C! G. o" O$ P# f
  5. u16 Get_Adc3(u8 ch);% M8 l2 b# E" V) W. N  a
  6. //获取某个通道给定次数采样的平均值
    $ p/ [9 T0 x2 @6 p
  7. u16 Get_Adc3_Average(u8 ch, u8 times);
复制代码

3 b! H2 m/ ~0 h3 M8 aadc.c文件
% ^- L* U% A: L- ~' a& m( A( G/ M0 {/ |3 X
  1. //-------------------------ADC3------------------------6 R6 @6 a) o9 E1 h: V6 H* D4 F2 p
  2. //ADC3通道初始化0 R% |* N' d9 |
  3. void ADC3_Init(void)
    $ e6 }9 q* a5 q; P: n
  4. {/ k/ H8 K$ K- e7 l+ ?. |: d$ ]
  5.         GPIO_InitTypeDef GPIO_InitStructure;
    . P. H, i4 y& n5 f' X0 C- Z  t( t9 a/ Y' z$ F
  6.         ADC_CommonInitTypeDef ADC_CommonInitStructure;+ J! X. Z; H' F
  7.         ADC_InitTypeDef ADC_InitStructure;& ?* C, l% P6 X; z* g1 R
  8.         
    # m9 G% Z# q& X
  9.         //开启GPIO时钟 PA5
    ' X! Q' q% S, H2 y' R+ {, e
  10.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); ) }& U1 U7 R/ Z9 L' r4 q7 i9 T
  11.         
    3 }! R, W" R. q$ L! G3 |' R! v* x- m
  12.         //开启ADC1时钟
    + s4 c2 Q& i6 m3 |2 L; M% R# r8 k
  13.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);        
    5 L- z; a4 ~2 {
  14.         ) [6 A! Q7 Q: G/ G& ?* C4 ^' u
  15.         //GPIO初始化 初始化为模拟功能
    4 h9 }9 i/ {0 P* d9 Q: h3 k
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    ( ]7 Z) n% v" r7 r: b: ^
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    ( Z4 K3 }" i# H; Y7 B# q
  18.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    5 I2 g) {5 Y& p
  19.         GPIO_Init(GPIOF, &GPIO_InitStructure);. m; V. k1 B) B
  20.         8 }7 I5 f! G/ b$ n8 n* p
  21.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,ENABLE);          //ADC1复位
    " @2 i  n/ O4 [5 S
  22.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,DISABLE);        //复位结束        
    8 @( s1 d/ n8 c5 P
  23.         
    * b' d. ], m) \! a% K% _
  24.         ; k5 y) D  P9 B) ~0 w
  25.         //初始化ADC_CCR寄存器. V! h( J4 l. t) x, v' g0 d3 X

  26. & Y% D$ F  |, @" |
  27.         ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
    ) a9 q+ K" L8 z' n* x
  28.         ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;# C7 J( g/ D3 G5 R$ T2 A
  29.         ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
    9 P4 J$ F0 j; u/ w: S) x
  30.         ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;2 D; R$ V/ a* P1 E6 g# X; ^( Z
  31.         ADC_CommonInit(&ADC_CommonInitStructure);
    / ~5 I9 ~9 z( w& r, H7 P4 V* l
  32.         * t- B) b6 E6 t3 f/ a* z* A
  33. " ^" i+ }, S$ P, a4 ~7 r- n
  34.         //初始化ADC15 p0 e& i- H5 U4 r2 e) S( _  Z6 A/ k; [
  35.         ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;. N3 S# y; s2 N1 |+ B
  36.         ADC_InitStructure.ADC_ScanConvMode = DISABLE;# e$ t" P& U3 p5 K( c
  37.         ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    " A9 Y9 h3 @* f1 g* @2 l
  38.         ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    / U2 c1 e# G+ Y9 ?8 g9 b( x
  39.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    9 k# T# d! ]9 f6 f. U4 m, ^2 t% N
  40.         ADC_InitStructure.ADC_NbrOfConversion = 1;
    8 }' U) q; v3 V' u. l
  41. : L6 d; r5 e& c) ?6 i) G- L
  42.         ADC_Init(ADC3, &ADC_InitStructure);
    0 X$ c" W" e8 V% Q) J  X+ b7 o

  43. 3 m8 V; W9 X4 y6 x$ b
  44. ( j' E5 X7 M$ A3 R& a3 e
  45.         //设置ADC规则组通道 一个序列 采样时间
    + Y# B1 I3 `1 w# c9 K% H# N5 A
  46.         //ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_480Cycles);( V# P# X) G" p8 S7 r7 H- u
  47. : @4 j$ X; T9 Y* u: P# H5 g

  48. 5 H3 \7 {5 I. Y2 y
  49.         //使能ADC0 u9 S. S, D9 R# T
  50.         ADC_Cmd(ADC3, ENABLE);. g6 t& j& c7 E1 l* A. u
  51.         
    # F6 c1 e8 W$ t; ]5 D
  52. }
    % c! v2 z. e! I( g

  53. % v* t5 g4 x8 S0 O5 X; F
  54. //获取ADC3某个通道的值
    / T$ w3 p  N; ]( k. q% Y
  55. u16 Get_Adc3(u8 ch). j5 }6 @0 }4 l0 L1 O
  56. {
    : R0 n( m& o  _6 a: I
  57.         //设置ADC规则组通道 一个序列 采样时间* O# K' R) n! B
  58.         ADC_RegularChannelConfig(ADC3, ch, 1, ADC_SampleTime_480Cycles);
    3 h' }, p* ~% I: {( p& s% ]; m4 l
  59.         4 Q+ D# b1 U2 [% `7 M
  60.         //开启ADC3的软件转换启动功能
    / n3 |: X1 N1 `9 d* l
  61.         ADC_SoftwareStartConv(ADC3);
    ) G8 X+ R0 i! F% l0 j
  62.         : T1 j7 P: K% o" F' C6 J
  63.         //等待转换结束
    : Q& q# R- ^5 C0 r* F
  64.         while(ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC) == RESET)
    $ w# q) d  a; s9 I. d4 m4 \$ Z) j
  65.                 ;" Z* r5 K  [/ v* A) w
  66. 3 w+ p' p; q& r4 q& c; }7 Z
  67.         //读取ADC的值
    7 h. a8 ^5 a* R+ {, b
  68.         return  ADC_GetConversionValue(ADC3);
    9 w3 N$ V8 I) p" o/ g( m; _

  69. $ l7 ?& B2 Y% s  Z! [
  70. }+ P$ j0 b; A- N; M! A2 C
  71. 4 N/ }7 l. G3 W1 T6 T, n% n- k
  72. //获取某个通道给定次数采样的平均值- I5 s+ i$ \% @; d- G% c1 u: {
  73. u16 Get_Adc3_Average(u8 ch, u8 times)' B, @: ~* ^9 E* K) o; e) Y
  74. {
    , v8 q  y: z( z% P
  75.         u32 tmp = 0;
    3 ~7 q* A+ f; o5 ?+ X' G# p; _! [
  76.         u8 i = 0;
    * q2 C0 ]) a2 H9 t, Z8 F! R' }. f! y
  77.         . b  t" @. D7 o/ {; c
  78.         for (i = 0; i < times; i++)
    5 r: H. Z* P% g4 _, o, @
  79.         {
    0 a2 s& L0 G# E6 |5 x
  80.                 tmp += Get_Adc3(ch);& ^; @+ D9 C( \4 E) J. J
  81.                 delay_ms(5);' Y8 [5 V6 Z& D# m
  82.         7 K+ C8 ^( l* }6 F" M8 ~* |$ m( w
  83.         }
    ) B1 d- I( h" j$ X4 a5 \
  84.         
    7 f, l& y' g) R- y" @/ r( }
  85.         //得到平均值
    : @4 o! \7 H. T1 ?4 n4 g! F7 U
  86.         tmp /= times;: D2 q' t0 {. v, q. ]
  87.         ; o( D7 v3 ?5 R9 t9 B
  88.         if (tmp > 4000)
    $ t( c: e  |* ]1 V/ R) d
  89.         {  e9 m# y5 W% m; M  ^7 c7 ?
  90.                 tmp = 4000;& n3 r. N* y8 W. A6 D/ ?1 C) P
  91.         }
    $ R9 h9 D( _7 }) c" q. i
  92.         8 `' `7 L5 ~0 Y2 }1 T, M
  93.         
    7 N1 B7 t8 p' q; x7 y1 O0 ]
  94.         return (u16)(100 - (tmp / 40));9 l% m6 o0 q! R0 H  S, M
  95. }
复制代码

6 T  B3 ]1 q7 Y& U; Nmain.c文件
% V: _' I7 K5 i/ U/ j( G" U6 D. s; j; ^' Y
  1. #include "sys.h"7 s- V+ P1 q& {+ o
  2. #include "delay.h", r8 m9 K. g5 k% F
  3. #include "usart.h"0 ]+ r9 J" y6 C
  4. #include "led.h"
    - K/ L- e- R1 V3 g
  5. #include "beep.h"
    0 L+ }3 {& Q: c
  6. #include "key.h"
    2 l( V5 b0 N+ e* N8 Q0 }9 a
  7. #include "usmart.h"
    1 U+ u/ }. J5 V4 B( [2 v, G: x( j
  8. #include "lcd.h"
    , o3 f. E, D& C5 a* c
  9. #include "rtc.h"
    - L+ G! a4 {* D
  10. #include "rng.h"- A# N6 J! F; p+ x0 y
  11. #include "key.h"- }1 `/ i. V6 L  P
  12. #include "wkup.h"
    7 a7 ]" Q* A9 o9 ]& `$ ?( h3 j
  13. #include "adc.h"9 K) b: G& t" a  C
  14. 7 {8 q2 f: I6 U$ ]# N: `. Q: k3 J
  15. int main(void)
    - S: G7 d5 Q% A
  16. {
    1 x$ p; \0 h) j' m
  17.         //u16 value = 0;
    9 n& m) U1 y/ {0 Q4 \3 I: u8 c8 o
  18.         
    4 P* O: H* l4 v$ @5 T/ ^
  19.         u16 temp = 0;
    0 |2 `1 H5 t4 M9 c  z. r# D! _
  20. ; K" i" x& Z- F6 X& B, i0 z
  21.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2# K6 q$ B% N/ H% ]0 B; j* S6 g
  22.         
    , B' k. F- N9 ?1 t
  23.         delay_init(168);
    + \- v7 I5 p+ N" w
  24.         + X* j3 E7 S! t% ?% L+ F
  25.         uart_init(115200);. D3 G) B& ]4 O
  26.         
    8 k4 I8 f) c' S# F$ \. V( R
  27.         //usmart_dev.init(84);4 m6 P8 C' e$ _6 z+ R! j
  28. . ~8 V$ ~+ I9 G
  29.         
      p# o% Y- [( P) ^0 h: L, l6 ]
  30.         LED_Init();0 M7 X8 |: F2 V/ P4 g
  31.         ; w* D- z0 \; Q5 ]  p5 H
  32.         3 w: n: G5 ]  n4 U$ K* M! j
  33.         LCD_Init();$ p4 M4 O6 X6 x8 Q. ~. c& `) o- A, M
  34. ! P& F8 c7 [3 d+ S. p% _
  35.         ADC3_Init();
    0 `( Y+ N0 \9 ^" ]& Y7 Q8 s  [
  36.         ( N+ H. [4 \2 p+ Y
  37.                 , Q* J# W/ l0 P: O$ |
  38.         POINT_COLOR = RED;
    / ~; v! R0 q! p2 O, D7 W( b- X
  39.         : B6 W  J+ O& y1 q
  40.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        / o$ Y) N  Q- ^( i
  41.         LCD_ShowString(30,70,200,16,16,"LSENS TEST");        ) J! r* y* P5 P. G7 H
  42.         LCD_ShowString(30,90,200,16,16,"ATOM@tom");6 Z3 ?" L, ]2 n2 V( Q4 O) j0 @
  43.         LCD_ShowString(30,110,200,16,16,"2020/09/15");         
    , u7 ]  O) w0 ], u* ?+ D
  44.         
    ) U3 |9 L. Q6 O2 K/ P2 E9 g
  45.         //设置字体为蓝色  v( F5 `7 g2 |+ _
  46.         POINT_COLOR = BLUE; : |: _0 b7 g$ n  M: m4 J3 J2 ]
  47.         LCD_ShowString(30,140,200,16,16,"LSENS VAL:");         
    0 V9 Z  @* B9 _6 L' |1 L
  48.                
    " d- P7 Y6 r1 E
  49.         while(1)4 e  t4 }, D; p4 b
  50.         {
    7 [, y) S6 P" e' k3 [8 p- v
  51.                 //得到温度值
    , N: E" i/ a# I+ H& M. V; Q* _
  52.                 temp = Get_Adc3_Average(ADC_Channel_5, 10);
    - T: L) V- ]3 r+ I
  53.                
    2 e) d# M0 g( e6 h: z- H' S
  54.                 ) Z) V: i  Q) \0 F# M0 ~. T& d
  55.                 LCD_ShowxNum(30+10*8,130,temp,3,16,0);//显示ADC的值* D8 h6 A/ ^3 E3 E& _9 _) r3 {% y

  56. 1 ?2 B* M6 a- \6 y. t
  57.                 printf("Light: %d\r\n", temp);
    6 h" f0 c" Z. V/ |
  58.                
    # m' _+ X2 a2 o" F  n9 {/ I6 q
  59.                 LED1 = !LED1;% B6 c. N" g! Q$ ^* P" z5 C
  60.                   w; ~1 [  F  s( ?4 f9 K, G9 w& s- n
  61.                 delay_ms(250);. n7 O4 W  C6 d1 _/ {
  62.         }* T* W+ G! i5 w
  63. }) o1 W8 a; S0 I8 X& [0 J1 x
复制代码

! o0 X' |& `- e  {) R9 S0 j; [04. 结果验证
) M) Q. ~" h0 y伴随 DS0 的不停闪烁,提示程序在运行。此时,我们可以通过给 LS1 不同的光照强度,来观察 LSENS_VAL 值的变化,光照越强,该值越大,光照越弱,该值越小。
. i) H' x0 [! @& Q4 X  ~% e0 x7 z% |( Z# o  c; y
8 l. Z+ w8 }% M6 v8 {. P. t& H# j2 A- @
赞 收藏 评论0 发布时间:2022-3-28 10:42

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版