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

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

[复制链接]
STMCU小助手 发布时间:2022-3-28 10:42
01. 光敏传感器简介
2 {# U! m( s9 K, r- N- B3 ]. k光敏传感器是最常见的传感器之一,它的种类繁多,主要有:光电管、光电倍增管、光敏电阻、光敏三极管、太阳能电池、红外线传感器、紫外线传感器、光纤式光电传感器、色彩传感器、CCD 和 CMOS 图像传感器等。光传感器是目前产量最多、应用最广的传感器之一,它在自动控制和非电量电测技术中占有非常重要的地位。
. ^) g9 W# P$ I$ F  ~
& G. A3 P( V: N0 L7 F光敏传感器是利用光敏元件将光信号转换为电信号的传感器,它的敏感波长在可见光波长附近,包括红外线波长和紫外线波长。光传感器不只局限于对光的探测,它还可以作为探测元件组成其他传感器,对许多非电量进行检测,只要将这些非电量转换为光信号的变化即可。
. b- E7 l1 S# @1 P/ j7 ]" k! p; Z; {1 ^/ N5 r/ i; T
探索者 STM32F4 开发板板载了一个光敏二极管(光敏电阻),作为光敏传感器,它对光的变化非常敏感。光敏二极管也叫光电二极管。光敏二极管与半导体二极管在结构上是类似的,其管芯是一个具有光敏特征的 PN 结,具有单向导电性,因此工作时需加上反向电压。无光照时,有很小的饱和反向漏电流,即暗电流,此时光敏二极管截止。当受到光照时,饱和反向漏电流大大增加,形成光电流,它随入射光强度的变化而变化。当光线照射 PN 结时,可以使 PN 结中产生电子一空穴对,使少数载流子的密度增加。这些载流子在反向电压下漂移,使反向电流增加。因此可以利用光照强弱来改变电路中的电流。) _% v& V( s. m: ?7 s
5 H/ R, }5 T4 U5 }& ?
利用这个电流变化,我们串接一个电阻,就可以转换成电压的变化,从而通过 ADC 读取电压值,判断外部光线的强弱。
; n2 ^  H2 ?& c5 T$ ~# A
8 K: S; u  s8 S/ z6 u8 a02. 硬件模块
8 P% w" W" S3 u# p- y  m0 x* U用到的硬件资源有:
! K. p: ~# |* [9 D- d* _1) 指示灯 DS0
8 n3 G2 E) Y  ^/ {3 a1 b2) TFTLCD 模块/ u+ E1 w; Z6 M# ]
3) ADC
7 a/ C) Z* D/ [, G. @4) 光敏传感器0 }3 {$ q  t+ U8 h- M1 r+ Z% D* c
7 G* T, {( ^* j0 k
5FSQRTDF(13TY~XI3YW(EFC.png $ b$ ?% l5 {& e% s' _' m, f9 R

$ N7 N3 N4 j! \, {  F) C4 m) h  p3 WLS1 是光敏二极管(实物在开发板摄像头接口右侧),R58 为其提供反向电压,当环境光线变化时,LS1 两端的电压也会随之改变,从而通过 ADC3_IN5 通道,读取LIGHT_SENSOR(PF7)上面的电压,即可得到环境光线的强弱。光线越强,电压越低,光线越暗,电压越高。! L' G+ U! s7 Z7 J; V
/ T3 c! M+ p6 _
03. 程序设计) D3 j1 y4 ^3 D; W
adc.h文件
9 p0 u" \+ b" Y! d- l3 N5 U
  1. //-----------------------------------1 T% X2 m; }* \2 ?
  2. //ADC3通道初始化
    - J& C- c5 T% d4 a: S
  3. void ADC3_Init(void);
    % L) }6 [% {8 f
  4. //获取ADC3某个通道的值
    2 P* ~* H0 C5 G: Z
  5. u16 Get_Adc3(u8 ch);- |8 f9 B  A& x  A4 j
  6. //获取某个通道给定次数采样的平均值1 q6 z  g8 R5 G& ^6 `
  7. u16 Get_Adc3_Average(u8 ch, u8 times);
复制代码

$ g% N  H! [% B' Y) v( Ladc.c文件& ~/ Z% A2 S; z' L& E. j! F$ s
& z5 c' n/ D2 B5 m( b! T
  1. //-------------------------ADC3------------------------
    3 R, V, c7 f6 \' R( V  H
  2. //ADC3通道初始化
    6 P; W1 B) x/ e% S! s* q: J$ u3 a9 [
  3. void ADC3_Init(void)
    0 q4 Y/ Z6 {; [+ `' X
  4. {& K! f! h- {. F, L" X- U, i
  5.         GPIO_InitTypeDef GPIO_InitStructure;' q: z5 r, T4 v& m* y
  6.         ADC_CommonInitTypeDef ADC_CommonInitStructure;
    * {; B  I! x: E6 E9 L
  7.         ADC_InitTypeDef ADC_InitStructure;$ a9 Q  h1 @' U$ z2 K
  8.         
    ( w& T, e5 {4 a' N: m
  9.         //开启GPIO时钟 PA5
    ( Q; m( ?8 I% J6 N# l3 w
  10.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
    3 j' t1 {# {, a3 Q* P# d
  11.         2 y3 c* P" P( u" u. ^# d+ W, b4 O% M
  12.         //开启ADC1时钟$ h) N" e0 ]: j" ?% T
  13.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);        0 A, B. }: i( H
  14.         
    9 f- W$ u) R: K+ {2 P
  15.         //GPIO初始化 初始化为模拟功能0 d3 k- L5 _& |' C
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    + Q6 b: y$ f: K. H9 z2 u
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    6 ], i+ N) `( M! _
  18.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  I0 Q8 o& w5 z6 c* o* Y
  19.         GPIO_Init(GPIOF, &GPIO_InitStructure);' @& \7 H$ z9 u/ `1 x3 o& A
  20.         
    ' _0 z8 |8 I. z+ {  ^% Y
  21.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,ENABLE);          //ADC1复位
    ( z0 W& o2 C& J$ L2 P5 S% Q
  22.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,DISABLE);        //复位结束        
    ' y+ f: l: a. Y, [1 O+ _( P! x
  23.         ; h/ c; A! c2 s- k. o+ u
  24.         
    9 z0 n3 R5 b$ t
  25.         //初始化ADC_CCR寄存器8 u8 Z2 {. K% _$ b* x" y+ S; Q4 ^

  26. : L# r  s7 o( j, P: o; }
  27.         ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;1 z+ a) _" D( g" ^% ^
  28.         ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
    ) K% A+ S% N, p7 i4 ?( T# Q
  29.         ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
    ( w+ b% o" H& x
  30.         ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
    6 q; I# J; r4 q) x+ X3 m
  31.         ADC_CommonInit(&ADC_CommonInitStructure);
    & C! _' ~, f# I5 r) X0 h; |: x8 m% T
  32.         
    5 w6 T5 M5 I8 |, w5 O8 {* X7 F
  33. 2 @9 r3 l5 H& p1 q0 k+ s1 @2 F5 n1 T( h
  34.         //初始化ADC1- |5 Z: T' V. D. T
  35.         ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;7 [. g7 G$ C. e  ?
  36.         ADC_InitStructure.ADC_ScanConvMode = DISABLE;6 v2 B4 [+ Q* a, e% }
  37.         ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    " L% J2 v+ Y7 h0 [6 {, R. B3 r
  38.         ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ! k9 M4 I, d3 \5 w# F5 C$ p! P
  39.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ; g9 C! N: F! P" Y; O8 Z
  40.         ADC_InitStructure.ADC_NbrOfConversion = 1;9 ]0 i5 J: X5 ]9 C+ |4 E
  41. , Y  c+ N* e& K
  42.         ADC_Init(ADC3, &ADC_InitStructure);% ]) j1 W9 o* T9 h5 W
  43. 7 t* C* q) f' n4 l& u3 ^) M+ D

  44. - |; S) n+ c! O( b. Q9 f( \
  45.         //设置ADC规则组通道 一个序列 采样时间
    - V- Q/ q0 I: ?+ B
  46.         //ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_480Cycles);
    5 _( j5 h# [( e) Y& M
  47. . P! T0 {) j# r3 R; \' s$ v

  48. ! i; d& r* y9 B; U" r$ c* _4 u
  49.         //使能ADC
    2 S- H6 g- N/ {
  50.         ADC_Cmd(ADC3, ENABLE);! k# [8 s; n  I0 ^
  51.         
    ' \/ E/ c  g  w2 B9 [& `" D
  52. }
    & ~, C; o3 Q" M& a/ W, f

  53. - u1 z! \, `' X+ ?. l
  54. //获取ADC3某个通道的值8 }+ b: W' C: p* T+ j5 c
  55. u16 Get_Adc3(u8 ch)# e. d8 n, [5 i* R5 \( ?
  56. {
    ! U. I3 R& ~5 a7 M+ j
  57.         //设置ADC规则组通道 一个序列 采样时间
    # X" I/ J! q% ~( i
  58.         ADC_RegularChannelConfig(ADC3, ch, 1, ADC_SampleTime_480Cycles);
    % e# ~# Q. x* z" r
  59.         
    6 ?- X5 h5 j1 F4 B& s) [0 r
  60.         //开启ADC3的软件转换启动功能
    . s0 g9 Y8 J' }' F( L* P
  61.         ADC_SoftwareStartConv(ADC3);
    : J3 Q; }2 J: m
  62.         
    : T  }% V* @/ ~0 C
  63.         //等待转换结束
    * k- n$ A1 X5 I0 k1 w6 G
  64.         while(ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC) == RESET)
    , C3 A0 x  J# @1 `7 }
  65.                 ;2 ^5 x0 U" P( k1 |

  66. , R* n0 ]2 l/ @% N- L9 K
  67.         //读取ADC的值# V1 y$ q) O- ~: b
  68.         return  ADC_GetConversionValue(ADC3);& H5 L6 X$ X! g0 w' U7 t$ p
  69. " U# L, K) \* Q9 m. k
  70. }( @, i  @% g- L
  71. 4 U+ w% }/ r1 y* J- S9 {! V
  72. //获取某个通道给定次数采样的平均值
    1 V2 ]0 n% U) N+ Y
  73. u16 Get_Adc3_Average(u8 ch, u8 times)
    3 G2 f! K) M* Q1 ~3 K8 z
  74. {
    8 Q  ]) C5 Z( Y8 L5 |
  75.         u32 tmp = 0;
    3 h8 u4 m, S8 N. g& i# W
  76.         u8 i = 0;( X. K" `! ~; h+ c% l; s0 H9 G/ M
  77.         
    " l/ w# {1 }! Y; ], ]9 _; ], r9 z
  78.         for (i = 0; i < times; i++)" x1 e; A" ?  _# c- X* q* p  J
  79.         {4 ~1 [7 c8 n' g" d( s5 e
  80.                 tmp += Get_Adc3(ch);
    ! q) E, a7 ^( h* l$ j1 `& E# h
  81.                 delay_ms(5);
    3 W' }5 `; r/ U4 J7 ~
  82.         
    % [0 T$ D2 p! K2 S  r; y8 H
  83.         }6 \  l( x4 m4 E
  84.           b7 y& j6 w! ~- W" U% Y8 P# x
  85.         //得到平均值2 Y% q0 Z0 }3 w' e  N1 a& s0 L9 W" i
  86.         tmp /= times;
    + `9 r, A2 C3 C: o
  87.         . }( ?' A4 m1 Q6 k- p* b, R
  88.         if (tmp > 4000)  G4 B, l% ], {3 j) \% N1 h+ u
  89.         {
    ( U$ M, k, v# z1 w7 `
  90.                 tmp = 4000;
    0 A: f. ^7 @0 V  n3 k
  91.         }
    2 g  t6 C5 B* `9 U# h# ^
  92.         
    * y. B" q4 b2 C
  93.         
    % D+ h0 U% g8 k/ J9 K$ Z6 l
  94.         return (u16)(100 - (tmp / 40));" j+ H6 C$ J, r( Z$ g3 E) w
  95. }
复制代码
% V2 F$ g; o" U  S* l
main.c文件* G% g0 k1 x! u. e/ A

$ _% W; ~: g* N# J) F  b9 w% K1 J
  1. #include "sys.h"1 A% ^/ |* g* V$ M+ b; Q2 \) X- n# b
  2. #include "delay.h", q, B5 u7 ^; i$ H
  3. #include "usart.h"
    6 z+ C3 Y: S1 e0 G
  4. #include "led.h"
    7 r/ i5 |' k6 L$ r3 B2 t3 j
  5. #include "beep.h"
    . b' ?; W, ?7 D# \8 j6 o; w
  6. #include "key.h"
    9 F/ e% F$ E+ A% L: |
  7. #include "usmart.h"8 p/ x! i% D# l% U
  8. #include "lcd.h"3 A) h& S& w* N2 t3 M8 I+ u9 v; o# D) \5 s
  9. #include "rtc.h"# E% ]5 y3 [4 u$ }' M2 [
  10. #include "rng.h"  t+ E( G+ |0 E4 M" G
  11. #include "key.h"
    9 u7 V: G% n0 ~* ~; a
  12. #include "wkup.h"8 v; _3 f) {0 m2 |) X6 I
  13. #include "adc.h": T0 F% {* D6 x* G

  14. " i/ q  b# X. N! t" v
  15. int main(void)  m$ C5 e5 O) P0 P
  16. { 9 s) T; r/ W3 f5 R5 Y7 \, X
  17.         //u16 value = 0;
    + x& g" t; [2 h$ q2 P5 f6 U/ M% c
  18.         
    2 O0 W9 l8 B' M9 v; U
  19.         u16 temp = 0;
    . c3 I4 Q$ _7 W; V8 m
  20. / L; P$ [$ _4 ?( m" Z0 B
  21.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2' S) o; t$ \" i
  22.         1 q8 T# d- M. ?7 o2 ~+ X8 v
  23.         delay_init(168);
    0 H# t: G/ D: f4 y" x( p6 |
  24.         
    ) z2 l  m. x/ D: s' w
  25.         uart_init(115200);1 x3 S$ k5 V" j
  26.         % }8 Y/ a  ?' k5 y5 Y- Q& |7 e3 K
  27.         //usmart_dev.init(84);
    ) m4 c5 b& [$ D" |& @
  28. - S9 y2 {$ P0 J: d: T$ A$ `1 R
  29.         
    6 {! v- [6 R, k+ P: v) u( b! m
  30.         LED_Init();- r! ?; p9 ^/ C: z+ a5 x
  31.         
    " Y3 j$ \0 ~- `5 }
  32.         
      e$ T! @9 A6 `3 v
  33.         LCD_Init();, @2 l) o, G# g# ~6 g  H4 _
  34. " t: U& Z1 r7 c9 Q+ n
  35.         ADC3_Init();
    4 ~( y4 ?7 j# m) w. ]
  36.         - {- E7 s8 Q" V8 f: }1 X5 ?( M2 m
  37.                
    # M4 H( T# u" ?! u
  38.         POINT_COLOR = RED;7 x1 X. \6 S# s! H7 H' x
  39.         * A7 K- j( ^/ S
  40.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        
    ! Z9 j7 B4 g% S2 T
  41.         LCD_ShowString(30,70,200,16,16,"LSENS TEST");        
    # l$ x$ e1 e% B& C0 e: ?0 d
  42.         LCD_ShowString(30,90,200,16,16,"ATOM@tom");% L8 r  c' I1 Y, n$ U) S- ~
  43.         LCD_ShowString(30,110,200,16,16,"2020/09/15");         
    - {2 B7 Z) V$ D$ _
  44.         % `, Z6 ]+ m- s% r* C/ ?/ p
  45.         //设置字体为蓝色; H- z1 M7 y3 N5 G
  46.         POINT_COLOR = BLUE; * L/ Z5 M! x/ d9 _: V
  47.         LCD_ShowString(30,140,200,16,16,"LSENS VAL:");         * ]# x! _0 a  @, E% J. f- c* i" y
  48.                 " s) A# o) b+ k8 J' f5 D8 _
  49.         while(1)& e5 Y) C: |4 t
  50.         {
    4 t! J4 m9 u( A6 ^& }& f! ]
  51.                 //得到温度值
    " z" o' u! S+ G0 p
  52.                 temp = Get_Adc3_Average(ADC_Channel_5, 10);, H- G% O) Y+ `8 A
  53.                
    ' @  Q/ ?( _0 v/ v
  54.                 " `/ v& T2 Q& U' t' }( T. y
  55.                 LCD_ShowxNum(30+10*8,130,temp,3,16,0);//显示ADC的值! W, |) f2 {/ f5 ?! l/ W7 L
  56. + k2 ~8 ?4 n, @9 {: B/ \3 S4 i1 ~
  57.                 printf("Light: %d\r\n", temp);
    $ G! V4 b( ^/ M& X8 ]. Z: L. ^
  58.                
    # l: V0 o* l( m, ~, c
  59.                 LED1 = !LED1;9 ]' d8 V! D+ z! Y- I) C8 z/ D- u
  60.                 5 h# h* r3 \. a5 G: I, O' V' @+ m
  61.                 delay_ms(250);
    ) Z( r+ Y( C  i; Y
  62.         }( v: t8 t4 b( e7 G
  63. }, \2 P4 h' T2 X2 C, M- `
复制代码

, o* r1 q6 X( v3 |( M* {04. 结果验证
: M) I2 j- m$ D伴随 DS0 的不停闪烁,提示程序在运行。此时,我们可以通过给 LS1 不同的光照强度,来观察 LSENS_VAL 值的变化,光照越强,该值越大,光照越弱,该值越小。
. {2 G, {6 e; W7 V) r  E% N' W! t: J
5 E' c8 v2 u7 M' n3 y3 D
收藏 评论0 发布时间:2022-3-28 10:42

举报

0个回答

所属标签

相似分享

官网相关资源

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