当前位置: 首页 > news >正文

外设模块学习(11)——火焰传感器、光敏电阻传感器(STM32)

目录

引言

一、火焰传感器介绍

1.1 概述

1.2 特性

1.3 检测原理

1.4 应用场景

二、光敏电阻传感器介绍

2.1 概述

2.2 特性

2.3 检测原理

2.4 应用场景

三、类似特性

四、参考代码

4.1 火焰传感器参考代码

4.1.1 flame.h

4.1.2 flame.c

4.1.3 adc.h

4.1.4 adc.c

4.1.4 main.c

4.2 光敏电阻传感器参考代码

4.2.1 light.h

4.2.2 light.c

4.2.3 adc,h

4.2.4 adc.c

4.2.5 main.c

五、总结


引言

       本次,我们继续学习两种传感器,分别是火焰传感器、光敏电阻传感器,之所以放一块讲,主要原因是这俩传感器都非常类似,控制起来也是非常简单,他们都是使用一个均采用LM393比较器加上电位器控制输出开关量(是否达到一定阈值)和模拟量(具体强度)实现对火焰和光强的检测。这俩传感器外观如下图所示。

       对于本次传感器学习,需要大家具有一定的C语言基础,同时STM32需要熟悉GPIO外设以及ADC外设的应用逻辑。


一、火焰传感器介绍

1.1 概述

       火焰传感器主要用于探测火焰及 760nm~1100nm 波长光源,搭载 LM393 比较器,工作电压 3.3V-5V;支持 DO 数字(0/1)、AO 模拟输出,可调灵敏度,体型小(3.2cm×1.4cm)且带安装孔,易对接单片机。

1.2 特性

(1)对火焰光谱敏感,打火机探测距 80cm(火焰越大距越远),探测角约 60°;

(2)电位器可调灵敏度,LM393 输出信号干净,驱动能力超 15mA;

(3)供电电压3.3V-5V 宽压适配,双输出模式,小巧易安装。

1.3 检测原理

       通过黑色光敏元件捕捉火焰的红外光谱(760nm~1100nm),蓝色电位器可调节灵敏度。模块输出 DO 数字信号(0/1)和 AO 模拟信号,工作电压 3.3V-5V,能直接对接单片机。主要用于火焰报警、火源探测,探测角度约 60 度,打火机火焰探测距离达 80cm,火焰越大探测距离越远,还设有固定孔方便安装。

1.4 应用场景

(1)家庭 / 工厂火灾预警;

(2)工业明火安全监控;

(3)火焰追踪机器人、互动玩具感应;

(4)实验室 / 户外设备火焰状态判断。

二、光敏电阻传感器介绍

2.1 概述

       该光敏电阻传感器基于光敏电阻的光电特性,用于检测环境光线强度,搭载信号调理电路,工作电压 3.3V-5V;支持 DO 数字(0/1)、AO 模拟输出,可调灵敏度,体型小巧且带安装孔,易对接单片机。

2.2 特性

(1)对光线强度敏感,可检测可见光范围内的光线变化,探测范围随光敏电阻特性而定;

       其它特性与火焰传感器介绍的基本一致。

2.3 检测原理

       通过红色光敏电阻感知光线强度,光线越强,光敏电阻阻值越小;蓝色电位器调节灵敏度,将光敏电阻的阻值变化转化为电压信号,经处理后输出 DO 数字信号(0/1,用于判断光线是否超过阈值)和 AO 模拟信号(用于反映光线强度的连续变化),工作电压 3.3V-5V,可直接对接单片机,用于光线检测、自动光控等场景,设有固定孔方便安装。

2.4 应用场景

(1)智能照明系统,根据光线强度自动开关灯;

(2)智能玩具,通过光线变化触发互动效果;

(3)环境监测设备,检测光照强度变化;

(4)自动控制设备,如光线感应的自动窗帘、遮阳棚等。

三、类似特性

       通过前面对俩模块的介绍,大家应该能够明显感觉到:无论是外观还是检测原理上都非常相似,只是检测内容不同导致模块有稍微的差异。因此接下来,我们再说一下这俩基本类似的特性。

(1)作控制开关:由于这俩传感器的数字量 DO 输出端输出的是开关量(数字量),因此都可直接驱动继电器模块,由此能组成光控或火警开关。

(2)模拟量获取强度值:这俩传感器都含有AO口,即Analog Output模拟输出引脚。模拟量 AO 可与单片机的AD外设或外置AD模块相连,通过 AD 转换,能获得环境光强/火焰强度的数值。

(3)开关量输出电平:这俩传感器都通过DO口输出一个高低电平来判断检测内容强度是否达到一定程度。当环境火焰强度/光线亮度达不到设定阈值时,DO 端输出高电平;当外界环境火焰强度/光线亮度超过设定阈值时,DO 端输出低电平。

(4)阈值调节:检测亮度/火焰强度的阈值均可通过蓝色电位器进行调节,顺时针调电位器,检测亮度/火焰强度的阈值增加;逆时针调电位器,检测亮度/火焰阈值减少

四、参考代码

       根据前面描述,我们可以发现驱动这俩传感器的逻辑就很简单了,实际与前面介绍的几个传感器都非常类似,即使用单片机接收传感器通过DO输出的电平(低电平--达到光强/火焰强度阈值、高电平--未达到阈值),只不过还多了个AO口的输出,所以还需要涉及到ADC转换的逻辑。

       因此,接下来我们就直接给出参考代码,该代码是基于STM32F103系列单片机、寄存器方式编写的代码。

4.1 火焰传感器参考代码

4.1.1 flame.h

#ifndef __FLAME_H
#define __FLAME_H#include "stm32f10x.h"/*** 引脚接线* * VCC  --->  3.3/5V* GND  --->  GND* DO   --->  PA0* AO   --->  PA1* 
*/void Flame_Init(void);
uint8_t Flame_Detect(void);#endif 
/*** (C) COPYRIGHT 2025 END OF FILE ***/

4.1.2 flame.c

/** @Descripttion: 火焰传感器驱动文件(.c)* @Author: JaRyon* @version: * @Date: 2025-10-28 12:19:43*/
#include "flame.h"/*** @brief      火焰传感器初始化* @param      void 无* @return     void* @example    Flame_Init();* @attention  */
void Flame_Init(void)
{// 1. 开启时钟 PARCC->APB2ENR |= RCC_APB2ENR_IOPAEN;// 2. DO-PA0 浮空输入 mode-00 cnf-01GPIOA->CRL &= ~GPIO_CRL_MODE0;GPIOA->CRL |= GPIO_CRL_CNF0_0;GPIOA->CRL &= ~GPIO_CRL_CNF0_1;
}/*** @brief      检测火焰,获取状态* @param      void 无* @return     uint8_t* @example    uint8_t flameState = Flame_Detect();* @attention  */
uint8_t Flame_Detect(void)
{uint8_t flameState = 0;if (GPIOA->IDR & GPIO_IDR_IDR0){flameState = 1;}return flameState;
}

4.1.3 adc.h

#ifndef __ADC_H
#define __ADC_H#include "stm32f10x.h"void ADC1_Init(void);
void ADC1_StartConvert(void);
double ADC1_GetVol(void);#endif

4.1.4 adc.c

/** @Descripttion: ADC单通道采集驱动* @Author: JaRyon* @version: * @Date: 2025-10-28 21:16:11*/
#include "adc.h"// 初始化
void ADC1_Init(void)
{// 1. 开启时钟RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;// 分频:6分频 12MHzRCC->CFGR |= RCC_CFGR_ADCPRE_1;RCC->CFGR &= ~RCC_CFGR_ADCPRE_0;// 2. GPIO工作模式:模拟输入 MODE-00 CNF-00GPIOA->CRL &= ~(GPIO_CRL_MODE1 | GPIO_CRL_CNF1);// 3. ADC配置ADC1->CR1 &= ~ADC_CR1_SCAN;ADC1->CR2 |= ADC_CR2_CONT;ADC1->CR2 &= ~ADC_CR2_ALIGN;ADC1->SMPR1 |= ADC_SMPR2_SMP1_0;ADC1->SMPR1 &= ~(ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP1_1);ADC1->SQR1 &= ~ADC_SQR1_L;ADC1->SQR3 &= ~ADC_SQR3_SQ1;ADC1->SQR3 |= (1 << 0);ADC1->CR2 |= ADC_CR2_EXTTRIG;ADC1->CR2 |= ADC_CR2_EXTSEL;    
}// 开启转换
void ADC1_StartConvert(void)
{// 1. 上电唤醒ADC1->CR2 |= ADC_CR2_ADON;// 2. AD校准ADC1->CR2 |= ADC_CR2_CAL;// 轮询判断校准是否完毕,完成则清除while (ADC1->CR2 & ADC_CR2_CAL){}// 3. 启动转换ADC1->CR2 |= ADC_CR2_SWSTART;// 4. 判断是否转换完成 EOC置位while (ADC1->SR & ADC_SR_EOC == 0){}
}// 输出转换后的模拟电压
double ADC1_GetVol(void)
{return ADC1->DR * 3.3 / (4096 - 1);
}

4.1.4 main.c

       主程序测试逻辑比较简单,就是每10ms查询一次传感器检测情况:外界环境火焰强度达到设定阈值时点亮某个LED,同时在OLED 屏幕上显示“Fire!!”,否则熄灭某个LED且OLED显示“Normal”,然后同时显示获取的火焰强度。(其中,显示的火焰强度由0-100的数值展示)

/** @Descripttion: 火焰传感器测试* @Author: JaRyon* @version: * @Date: 2025-10-28 12:19:43*/
#include "stm32f10x.h"
#include "Systick.h"
#include "oled.h"
#include "flame.h"
#include "LED.h"
#include "adc.h"int main(void)
{uint32_t waitTimes = 0;char *str = "Normal";double FlameIntensity = 0, flameRes = 0.0;uint8_t count = 0;// 初始化Systick_Init();LED_Init();OLED_Init();OLED_ClearAll();ADC1_Init();Flame_Init();ADC1_StartConvert();waitTimes = Systick_GetTick();while(1){	if (Systick_GetTick() - waitTimes >= 10000){if (Flame_Detect() == 0){str = "Fire!!";LED_On(LED1);}else{str = "Normal";LED_Off(LED1);}// 提高精度 算10次均值FlameIntensity += (3.3 - ADC1_GetVol()) * 100 / 3.3;count++;if (count >= 10){flameRes = FlameIntensity / count;count = 0;FlameIntensity = 0;}waitTimes = Systick_GetTick();}OLED_ShowString(39, 27, str, 8);OLED_ShowString(25, 45, "FI:", 8);OLED_ShowFloat(53, 45, flameRes, 3, 1, 8);OLED_Update();}
}

4.2 光敏电阻传感器参考代码

4.2.1 light.h

#ifndef __LIGHT_H
#define __LIGHT_H#include "stm32f10x.h"/*** 引脚接线* * VCC  --->  3.3/5V* GND  --->  GND* DO   --->  PA0* AO   --->  PA1* 
*/void Light_Init(void);
uint8_t Light_Detect(void);#endif 
/*** (C) COPYRIGHT 2025 END OF FILE ***/

4.2.2 light.c

/** @Descripttion: 光敏传感器驱动文件(.c)* @Author: JaRyon* @version: * @Date: 2025-10-29 11:59:07*/
#include "light.h"/*** @brief      光敏传感器初始化* @param      void 无* @return     void* @example    Light_Init();* @attention  */
void Light_Init(void)
{// 1. 开启时钟 PARCC->APB2ENR |= RCC_APB2ENR_IOPAEN;// 2. DO-PA0 浮空输入 mode-00 cnf-01GPIOA->CRL &= ~GPIO_CRL_MODE0;GPIOA->CRL |= GPIO_CRL_CNF0_0;GPIOA->CRL &= ~GPIO_CRL_CNF0_1;
}/*** @brief      检测光照,获取状态* @param      void 无* @return     uint8_t* @example    uint8_t lightState = Light_Detect();* @attention  */
uint8_t Light_Detect(void)
{uint8_t lightState = 0;if (GPIOA->IDR & GPIO_IDR_IDR0){lightState = 1;}return lightState;
}

4.2.3 adc,h

4.2.4 adc.c

       这里的ADC驱动可直接移植前面给出的ADC代码,因为使用的引脚相同,所以没有问题,因此这里不再赘述。

4.2.5 main.c

       主程序测试逻辑与火焰传感器逻辑基本相同,就是每10ms查询一次传感器检测情况:外界环境光照强度达到设定阈值时点亮某个LED,同时在OLED 屏幕上显示“HLight”,否则熄灭某个LED且OLED显示“Normal”,然后同时显示获取的光照强度。(其中,显示的光照强度由0-100的数值展示)

/** @Descripttion: 光敏电阻传感器测试* @Author: JaRyon* @version: * @Date: 2025-10-29 11:59:07*/
#include "stm32f10x.h"
#include "Systick.h"
#include "oled.h"
#include "light.h"
#include "LED.h"
#include "adc.h"int main(void)
{uint32_t waitTimes = 0;char *str = "Normal";double LightIntensity = 0, LightRes = 0.0;uint8_t count = 0;// 初始化Systick_Init();LED_Init();OLED_Init();OLED_ClearAll();Light_Init();ADC1_Init();ADC1_StartConvert();waitTimes = Systick_GetTick();while(1){	if (Systick_GetTick() - waitTimes >= 5000){if (Light_Detect() == 0){str = "HLight";LED_On(LED1);}else{str = "Normal";LED_Off(LED1);}// 提高光强精度 算10次均值LightIntensity += (3.3 - ADC1_GetVol()) * 100 / 3.3;count++;if (count >= 10){LightRes = LightIntensity / count;count = 0;LightIntensity = 0;}waitTimes = Systick_GetTick();}OLED_ShowString(39, 27, str, 8);OLED_ShowString(25, 45, "LI:", 8);OLED_ShowFloat(53, 45, LightRes, 3, 1, 8);OLED_Update();}
}

       需要说明的是:主程序中会涉及到OLED 屏幕显示、LED驱动以及延时等代码逻辑,由于本次主要介绍传感器相关内容,因此这些内容就不再赘述,大家可缺少相关器件可使用串口输出,没有什么影响。当然若需要相关代码可私聊。


五、总结

       本次我们介绍了火焰传感器和光敏电阻传感器的原理与应用。两种传感器结构相似,均采用LM393比较器,提供数字(DO)和模拟(AO)双输出,可通过电位器调节灵敏度。

       同时提供了基于STM32的驱动代码实现方案,包括初始化配置、状态检测和ADC数据采集。两种传感器均可通过GPIO读取开关量状态,并通过ADC获取强度模拟量,具有相似的硬件接口和应用方式。


以上便是本次文章的所有内容,欢迎各位朋友在评论区讨论,本人也是一名初学小白,愿大家共同努力,一起进步吧!

鉴于笔者能力有限,难免出现一些纰漏和不足,望大家在评论区批评指正,谢谢!

http://www.dtcms.com/a/553450.html

相关文章:

  • 笨鸟网站开发江苏seo平台
  • WPF检测网络状态切换
  • ✨WPF编程进阶【6.1】:图形原则(附源码)
  • 网站建设企业建站哪家好?来这里看看网站建设时间进度表模板
  • 无锡地区做网站赣州快车微信公众号
  • Vue3的异步DOM更新:nextTick的正确使用方法
  • Vue 项目中全局样式的正确写法:不要把字体和主题写在 #app 上
  • 网站推广策划的策略凡科做的网站百度能收录吗
  • 如何用SQL进行多表联查(JOIN)?
  • 笔试强训:Week-3
  • 网站建设公司的前景怎么建立和设计公司网站
  • 【项目实战1 -瑞吉外卖|day21 】
  • 变分自编码器(VAE):用概率解锁生成式AI的“基因密码”
  • C++ 容器入门:从初始化到常用操作全解析
  • 飞致云开源社区月度动态报告(2025年10月)
  • 企业网站建设的步骤网站维护包括哪些
  • 网站建设缺乏个性网站如何优化关键词
  • GNN变体
  • SpringMVC基础入门
  • XiangJsonCraft v1.1.0发布:JSON配置网页的终极进化,支持所有CSS选择器!
  • UVa 12670 Counting Ones
  • C++17(新特性)
  • 韩国风网站什么网站有做册子版
  • day58-Shell编程(第四部分)
  • 用AI写了一个文档拼音标注工具 中文+拼音一键生成
  • 做网站还有意义同样是div 怎么有些网站收录少 有些多
  • 企必搜做网站做国际物流在哪些网站找客户
  • 移动端适配完全指南:从基础到最佳实践
  • 使用JMeter进行API性能压测(执行篇)
  • IntelliJ IDEA 远程调试(Remote Debugging)教程