STM32学习心得二十五:光敏传感器原理及实验

2023-11-03

记录一下,方便以后翻阅~
主要内容:
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学习心得二十四:内部温度传感器原理及实验

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32学习心得二十五:光敏传感器原理及实验 的相关文章

  • ARM NEON:如何实现 256 字节查找表

    我正在使用内联汇编将我编写的一些代码移植到 NEON 我需要的一件事是将范围 0 128 的字节值转换为表中采用完整范围 0 255 的其他字节值 该表很短 但其背后的数学并不容易 因此我认为不值得每次 即时 计算它 所以我想尝试查找表 我
  • 通用 ELF 中的重定位(EM:40)

    我尝试从 Ubuntu 交叉编译到Friendly arm 但出现了奇怪的错误 root kevin VirtualBox home kevin Desktop makef make ARCH arm CROSS COMPILE arm n
  • 如何创建具有自定义外设和内存映射的 QEMU ARM 机器?

    我正在为 Cortex M3 cpu 编写代码 并且正在使用以下命令执行单元测试qemu arm二进制 现在一切都很好 但我想知道我是否能够使用测试整个系统qemu system arm 我的意思是 我想为 qemu 编写自定义 机器 我将
  • ARM 汇编不能同时使用立即值和 ADDS/ADCS

    我目前正在尝试使用汇编来加速 Cortex M0 Freescale KL25Z 上的一些 C 函数 我遇到这个最小测试程序的问题 syntax unified cpu cortex m0 text global test code 16
  • ARM 9处理器的opencv交叉编译

    我需要为 ARM 9 处理器交叉编译 opencv 我有处理器的工具链 但不知道如何交叉编译 请告诉我为arm板交叉编译的过程 谢谢大家 看这个参考 http www airs com ian configure configure 5 h
  • 将ELF文件加载到内存中

    我正在尝试将 elf 文件放入内存然后执行它 步骤如下 1 要放入内存的文件 int main printf Hello world n return 0 2 编译它gcc o hello hello c static ELF Header
  • arm64 汇编:LDP 与 LD4 执行时间

    假设我想用连续内存位置的值加载四个连续的 aarch64 向量寄存器 一种方法是 ldp q0 q1 x0 ldp q2 q3 x0 32 根据ARM优化指南 https static docs arm com uan0016 a cort
  • 如何在 ARM 架构上从 RAM 运行代码

    我正在对 ARM Cortex R4 进行编程 并且有一些二进制文件 我想从 TCRAM 执行它们 只是为了看看性能的提升是否足够好 我知道我必须编写一个函数来将二进制文件复制到 RAM 这可以通过链接器脚本来完成 并且知道二进制文件的大小
  • 警告:可加载部分“my_section”位于 ELF 段之外

    我使用 Cortex R4 的 Arm Compiler v6 9 构建了一个 axf elf 文件 但是 当我使用 Arm MCU Eclipse J link GDB 插件将其加载到目标时 它无法加载我的段的初始化数据 如果我使用 Se
  • ARM Linux 如何模拟 PTE 的脏位、访问位和文件位?

    As per pgtable 2 level h https git kernel org cgit linux kernel git torvalds linux git tree arch arm include asm pgtable
  • 使用 STM32F0 ADC 单独读取不同的输入

    STM32F072CBU 微控制器 我有多个 ADC 输入 并且希望单独读取它们 STMcubeMX 生成样板代码 假设我希望按顺序读取所有输入 但我无法弄清楚如何纠正这个问题 这篇博文 http blog koepi info 2015
  • 源和目标具有不同的 EABI 版本

    我正在尝试使用 ARM 工具链编译 so 文件 但是我不断收到这个错误 错误 源对象的 EABI 版本为 0 但目标对象的 EABI 版本为 5 我无法更改工具链中的任何内容 因为我必须使用给定的工具链 我以前从未见过这个错误 我使用了这个
  • M1 MacBook Pro 上的 Android Studio 无法使用 ABI armeabi-v7a 模拟系统映像

    我的 M1 Macbook Pro 上的 Android Studio 可以很好地模拟 ABI arm64 v8a 的所有系统映像 API 24 29 30 31 但是 它无法使用 ABI armeabi v7a 运行所有映像 例如 API
  • ARM 调用约定是否允许函数不将 LR 存储到堆栈中?

    正如标题所示 我在理解 ARM 架构的调用约定时遇到问题 特别是 我仍然很难知道当你调用子程序时 LR 寄存器会发生什么 我认为 当您进入子程序时 处理 LR 寄存器的最明显 最安全的方法是将其存储到堆栈中 但该行为没有出现在文档中 因此我
  • 为什么 i2c_smbus 函数不可用? (I2C——嵌入式Linux)

    有很多参考使用i2c smbus 开发嵌入式 Linux 软件时在 I2C 总线上进行通信的函数 什么时候i2c smbus函数如i2c smbus read word data在软件项目中引用了 ARM8 处理器错误 例如 i2c smb
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能
  • 基于 Windows 8 ARM 的平板电脑上的 VB6

    随着 Windows 8 将支持 VB6 我的问题是 Microsoft 是否在任何地方表示 是或否 VB6 应用程序将在基于 ARM 的平板电脑上运行 如果没有 是否有任何 ARM 模拟器 以便我们可以在 Windows 8 ARM 平板
  • arm-linux-gnueabi 编译器选项

    我在用 ARM Linux gnueabi gcc在 Linux 中为 ARM 处理器编译 C 程序 但是 我不确定它编译的默认 ARM 模式是什么 例如 对于 C 代码 test c unsigned int main return 0x
  • 如何模拟ARM处理器运行环境并加载Linux内核模块?

    我尝试加载我的vmlinux into gdb并使用 ARM 内核模拟器 但我不明白为什么我会得到Undefined target command sim 这是外壳输出 arm eabi gdb vmlinux GNU gdb GDB 7
  • ARM Chromebook 上的 Android 开发环境?

    我尝试了多次安装和使用安卓工作室 https developer android com studio index html on an ARM Chromebook C100P https archlinuxarm org platfor

随机推荐

  • 小理解

    一 数组指针 数组名本身就是一个指针 指向数组的首地址 如int p 10 表示一个指向10个int元素的数组的一个指针 注意这是声明定长数组时 其数组名指向的数组首地址是常量 而声明数组并使某个指针指向其值指向某个数组的地址 不一定是首地
  • 堆栈详解

    堆区 1 存储的全部是对象 每个对象都包含一个与之对应的class的信息 class的目的是得到操作指令 2 jvm只有一个堆区 heap 被所有线程共享 堆中不存放基本类型和对象引用 只存放对象本身 栈区 1 每个线程包含一个栈区 栈中只
  • 程序设计的基本概念

    程序设计的基本概念 1 程序 2 结构化程序设计 1 程序 由高级语言编写的程序称为 源程序 由C语言编写的程序扩展名为 C 经过 编译 目标程序 后生成文件的扩展名为 obj 经过 链接 可执行程序 后生成文件的扩展名为 exe C语言源
  • System.Net.HttpListenerException (0x80004005): 拒绝访问。

    C 生成的exe突然报错了 原来是被人改了权限配置 我也没改回来 只需要将生成的exe设置成管理员身份运行 往后就不会再报错了
  • 15个免费学习JavaScript的最佳网站

    JavaScript是Web最流行的语言 对于任何Web开发人员来说 JavaScript现在是必须学习的语言 像追踪树这样的创新已经大大提高了JavaScript的性能 并且它在所有开发人员中越来越受欢迎 如果您想要事业得到进一步的发展
  • Python 基础——range() 与 np.arange()

    range 返回的是range object 而np arange 返回的是numpy ndarray type np arange 10 np ndarray 两者都是均匀地 evenly 等分区间 range尽可用于迭代 而np ara
  • Images之Dockerfile中的命令2

    COPY COPY has two forms COPY chown
  • cocos2dx中毒冰冻shader

    中毒效果 ifdef GL ES precision mediump float endif uniform sampler2D u texture varying vec2 v texCoord varying vec4 v fragme
  • 《深入理解Java函数式编程》系列文章

    Introduction 本系列文将帮助你理解Java函数式编程的用法 原理 本文受启发于JavaOne 2016关于Lambda表达式的相关主题演讲Lambdas and Functional Programming和Refactorin
  • 在Python环境下使用pgmpy构建动态贝叶斯网络并进行参数学习(附详细代码)

    首先列举当前主要构建贝叶斯网络的一些工具 1 软件 Netica SMILE 2 MATLAB包 BNT 3 Python包 pgmpy libpgm pomegranate 4 R包 dbnlearn 如果是单纯的进行贝叶斯网络的学习与推
  • html弹窗代码只弹窗一次,信息弹窗提示一天只弹出一次js代码

    信息弹窗提示一天只弹出一次js代码 通过jquery cookie js实现功能 避免重复弹出 弹窗提示 margin 0 padding 0 alert windows display none position absolute z i
  • 计算机网络第八版详细思维导图复习(可复制修改)

    按照我们学校的教学课本 计算机网络第八版 谢希仁 计算机网络自顶向下第七版 老师习题讲解课件 B站 计算机网络微课堂 有字幕无背景音乐版 王道计算机考研 计算机网络 湖科大深入浅出计算机网络 示范教学包等途径整合而成 有个人总结和自己的思考
  • 使用SVG+React实现飞行仪表仿真

    SVG React实现 演示地址 https liujialun github io i
  • 深入理解Mysql底层数据结构

    一 索引的本质 索引是帮助MySQL高效获取数据的排好序的数据结构 二 索引的数据结构 二叉树 红黑树 Hash表 BTree B Tree mysql的索引采用的是B 树的结构 mysql为什么不用二叉树 因为对于单边增长的数据列 二叉树
  • SSE2介绍及其简单用法举例

    SSE2 全名为Streaming SIMD Extensions 2 是一种IA 32架构的SIMD指令集 SSE2是在2001年随着Intel发表第一代Pentium 4处理器也一并推出的指令集 它延伸较早的SSE指令集 而且可以完全取
  • 腾讯开启薪酬改革,晋升不调薪,需要结合业绩评估

    六月的第一天有媒体爆出 腾讯全员收到邮件 公司开启新一轮的薪酬改革 邮件中的重点内容是 公司认可晋升代表能力提升以及更高的职责要求 同时也要求将能力转化为业绩贡献 所以年度薪资回顾时会结合业绩贡献 能力提升 薪酬竞争力等因素综合评估 腾讯公
  • stable diffusion--二次元福利

    继上次用stable diffusion生成谪仙男子外貌翻车后 痛定思痛 发现用stable diffusion webui这个神器 效果出乎意料的好 01 安装教程 1 pytorch安装 具体安装可查看我之前的图文libtorch导入模
  • Object.defineProperty()方法的使用

    在我们学习到Vue响应式原理的时候 必然要了解到JS里Object defineProperty 方法 底层就是用这个方法来实现的 可以实现对象的简单代理 Object defineProperty 方法会直接在一个对象上定义一个新属性 或
  • SQL中如何使用EXISTS替代IN

    我们在程序中一般在做SQL优化的时候讲究使用EXISTS带替代IN的做法 理由是EXISTS执行效率要比IN高 之前我一直挺懵懂的一件事情是如何使用EXISTS来替换IN呢 二者表示的意义又是什么呢 今天就我个人理解记录一下 IN表示范围
  • STM32学习心得二十五:光敏传感器原理及实验

    记录一下 方便以后翻阅 主要内容 1 光敏传感器概述 2 相关实验代码解读 实验功能 通过ADC3 CH6来检测光敏二极管一端的电压变化来达到检测光强的目的 可通过检测环境光 调节LCD的背光大小 官方资料 STM32中文参考手册V10 第