文章目录
-
- 每日一句正能量
- 导读
- 一、系统总体架构设计
-
- [1.1 功能需求分析](#1.1 功能需求分析)
- 二、PIR人体感应传感器深度解析
-
- [2.1 热释电效应原理](#2.1 热释电效应原理)
- [2.2 双元探测结构的关键设计](#2.2 双元探测结构的关键设计)
- [2.3 菲涅尔透镜的作用](#2.3 菲涅尔透镜的作用)
- [2.4 PIR模块关键参数](#2.4 PIR模块关键参数)
- 三、光敏电阻与光控电路设计
-
- [3.1 光敏电阻工作原理](#3.1 光敏电阻工作原理)
- [3.2 分压采样电路设计](#3.2 分压采样电路设计)
- [3.3 ADC采样与滤波](#3.3 ADC采样与滤波)
- 四、PWM调光技术实现
-
- [4.1 PWM调光原理](#4.1 PWM调光原理)
- [4.2 频率选择的关键考量](#4.2 频率选择的关键考量)
- [4.3 LED驱动电路设计](#4.3 LED驱动电路设计)
- [4.4 Gamma校正](#4.4 Gamma校正)
- 五、自适应亮度控制算法
-
- [5.1 分段线性控制算法](#5.1 分段线性控制算法)
- [5.2 平滑过渡算法](#5.2 平滑过渡算法)
- 六、状态机控制逻辑
-
- [6.1 状态定义与转换](#6.1 状态定义与转换)
- [6.2 状态转换表](#6.2 状态转换表)
- [6.3 完整状态机实现](#6.3 完整状态机实现)
- 七、完整硬件电路设计
-
- [7.1 原理图详解](#7.1 原理图详解)
- [7.2 抗干扰设计要点](#7.2 抗干扰设计要点)
- 八、低功耗优化策略
-
- [8.1 待机功耗分析](#8.1 待机功耗分析)
- [8.2 低功耗代码实现](#8.2 低功耗代码实现)
- 九、调试与常见问题
-
- [9.1 调试技巧](#9.1 调试技巧)
- [9.2 关键参数校准](#9.2 关键参数校准)
- 十、总结与展望

每日一句正能量
不断提升能力,沉淀认知,这才是靠得住的底气。
底气不是来自存款、头衔或他人的承诺,而是来自你确信自己能应对变化的能力。能力让你走路稳,认知让你不迷路。别人拿不走的东西,才是真正的安全垫。
导读
智能家居的普及让台灯不再是简单的照明工具,而是集成了人体感应、环境光自适应、PWM无级调光等功能的智能终端。本文将深入剖析一个基于STM32的智能台灯完整设计方案,从PIR人体感应原理到光敏电阻采样,从PWM调光算法到状态机控制,提供一套可直接落地的工程级解决方案。
一、系统总体架构设计

1.1 功能需求分析
智能台灯的核心需求可归纳为"三感一控":
| 功能模块 | 核心需求 | 技术实现 |
|---|---|---|
| 人体感应 | 人来灯亮、人走灯灭 | PIR热释电传感器 |
| 光控调节 | 环境越暗灯越亮 | 光敏电阻+ADC采样 |
| PWM调光 | 无级平滑亮度调节 | 硬件定时器PWM输出 |
| 延时控制 | 离开后自动关灯 | 软件定时器倒计时 |

系统采用STM32F103C8T6作为主控芯片,其72MHz主频、12位ADC和多路硬件定时器完美满足本项目需求。传感器层包含PIR人体感应模块和光敏电阻,执行层通过PWM驱动LED,并辅以OLED显示当前状态。
二、PIR人体感应传感器深度解析
2.1 热释电效应原理
PIR(Passive Infrared)传感器基于**热释电效应(Pyroelectric Effect)**工作。当特定晶体材料(如锆钛酸铅PZT或锂钽酸锂LiTaO₃)表面温度发生微小变化时,晶体内部偶极矩随之改变,在电极两端产生瞬态电压信号。
人体体温恒定在37℃左右,会持续辐射波长约为9-10μm的红外线。PIR传感器通过以下信号链完成检测:
红外滤光片 → 菲涅尔透镜聚焦 → 双元热释电元件 → JFET阻抗变换 → 两级运放放大 → 窗口比较器 → 施密特触发整形 → TTL电平输出

2.2 双元探测结构的关键设计
商用PIR模块(如HC-SR501)采用**双元(Dual Element)**结构------两个反向串联的PIR单元构成差分检测对。这是整个设计的精髓所在:
- 人体横向移动:红外辐射先后到达A、B两单元,产生相位差信号,差分输出有效
- 静止或纵向移动:两单元同步受热,差分输出趋近于零,有效抑制共模干扰
- 环境温度渐变:两单元同步响应,差分抵消,信噪比提升15dB以上
2.3 菲涅尔透镜的作用
传感器前方的白色蜂窝状塑料罩并非装饰,而是精密的菲涅尔透镜。它将探测区域分割成多个明暗交替的敏感区:
- 光学聚焦:将大范围的红外辐射汇聚到传感器敏感面上
- 空间分区:形成多个独立探测扇区,人体移动时依次触发,产生脉冲式信号
- 探测范围调节:通过更换不同焦距的透镜,可实现3-12米的探测距离和60°-180°的探测角度
2.4 PIR模块关键参数
以HC-SR501为例,其关键参数如下:
| 参数 | 规格 | 说明 |
|---|---|---|
| 工作电压 | DC 4.5V~20V | 宽压输入,兼容3.3V/5V系统 |
| 静态电流 | <50μA | 超低功耗,适合电池供电 |
| 延时时间 | 5s~200s可调 | 通过板载电位器调节 |
| 封锁时间 | 2.5s默认 | 防止连续触发 |
| 感应距离 | 3~7米 | 受透镜和灵敏度调节影响 |
| 感应角度 | <120°锥角 | 水平覆盖范围 |
| 输出电平 | 高3.3V/低0V | TTL电平,可直接接MCU GPIO |
重要提示 :PIR传感器只能检测移动的人体,对静止不动的人无法识别。这是由其热释电原理决定的------只有温度变化才能产生信号输出。
三、光敏电阻与光控电路设计
3.1 光敏电阻工作原理
光敏电阻(LDR, Light Dependent Resistor)基于内光电效应,其阻值随光照强度变化而剧烈变化。以GL5516为例:
| 光照条件 | 阻值范围 | 应用场景 |
|---|---|---|
| 黑暗(<1Lux) | >1MΩ | 夜间卧室 |
| 昏暗(10Lux) | ~100kΩ | 黄昏室内 |
| 室内光(100Lux) | ~10kΩ | 阴天窗边 |
| 明亮(1000Lux) | ~1kΩ | 晴天室内 |

3.2 分压采样电路设计
光敏电阻与固定电阻组成分压电路,将阻值变化转换为电压变化供ADC采样:
VCC(5V) ──┬── 光敏电阻(GL5516) ──┬── GND
│ │
└── 固定电阻(10K) ─────┘
│
ADC输入
当环境变暗时,光敏电阻阻值增大,分压点电压升高,ADC采样值增大。通过软件反向映射,即可实现"环境越暗,台灯越亮"的自适应控制。
3.3 ADC采样与滤波
c
/**
* @brief 光敏电阻ADC采样(带滑动平均滤波)
* @note 使用STM32的12位ADC,采样范围0-4095
*/
#define ADC_SAMPLE_COUNT 16 // 滑动平均窗口大小
#define ADC_CHANNEL_LDR ADC_CHANNEL_1
uint16_t adc_buffer[ADC_SAMPLE_COUNT];
uint8_t adc_index = 0;
/**
* @brief 初始化ADC(单次转换模式)
*/
void LDR_ADC_Init(void)
{
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
// PA1配置为模拟输入
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc1);
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_LDR;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; // 长采样时间提高精度
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
/**
* @brief 读取光敏电阻ADC值(带滑动平均滤波)
* @return 滤波后的ADC值 (0-4095)
*/
uint16_t LDR_ReadFiltered(void)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);
uint16_t raw = HAL_ADC_GetValue(&hadc1);
// 滑动平均滤波
adc_buffer[adc_index] = raw;
adc_index = (adc_index + 1) % ADC_SAMPLE_COUNT;
uint32_t sum = 0;
for (int i = 0; i < ADC_SAMPLE_COUNT; i++) {
sum += adc_buffer[i];
}
return (uint16_t)(sum / ADC_SAMPLE_COUNT);
}
/**
* @brief 将ADC值转换为光照度(近似)
* @note 基于GL5516特性曲线拟合
*/
uint16_t LDR_GetLux(uint16_t adc_value)
{
// 简化模型:Lux ≈ 10000 * (4095 - adc) / adc
// 实际应根据具体光敏电阻校准
if (adc_value == 0) adc_value = 1;
return (uint16_t)(10000UL * (4095 - adc_value) / adc_value);
}
避坑指南:光敏电阻存在暗电流漂移、温度敏感性和响应延迟等问题。实验数据显示,GL5506在连续工作200小时后暗电阻下降15-20%,温度每升高10℃亮电阻下降约8%。建议在灯罩内与LED热源隔离安装,并定期软件校准。
四、PWM调光技术实现
4.1 PWM调光原理
PWM(Pulse Width Modulation)调光通过改变LED的导通占空比来调节平均电流,从而控制亮度。核心优势在于:
- 高效率:LED始终工作在额定电流或零电流状态,无线性损耗
- 无频闪:当PWM频率>100Hz时,人眼无法感知闪烁
- 宽范围 :占空比0%100%可实现0100%亮度调节
4.2 频率选择的关键考量
| PWM频率 | 闪烁感知 | 驱动效率 | 适用场景 |
|---|---|---|---|
| 100Hz | 明显闪烁 | 85% | 不推荐 |
| 500Hz | 轻微闪烁 | 90% | 低端产品 |
| 1kHz | 无可见闪烁 | 92% | 一般应用 |
| 5kHz | 完全无闪烁 | 93% | 护眼台灯 |
| 20kHz | 超声频段 | 93% | 高端产品 |
推荐频率:5kHz~20kHz。频率过低会产生可见闪烁导致视觉疲劳,频率过高则会增加开关损耗降低效率。对于护眼台灯,建议≥5kHz。
4.3 LED驱动电路设计
c
/**
* @brief TIM3 PWM初始化(5kHz,PA2输出)
* @note 系统时钟72MHz,PSC=0,ARR=14399
* PWM频率 = 72MHz / (14399+1) = 5kHz
*/
void LED_PWM_Init(void)
{
__HAL_RCC_TIM3_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
// PA2配置为复用推挽输出
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
htim3.Instance = TIM3;
htim3.Init.Prescaler = 0; // 不分频
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 14399; // 5kHz PWM频率
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_PWM_Init(&htim3);
TIM_OC_InitTypeDef sConfigOC = {0};
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0; // 初始占空比0%
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
}
/**
* @brief 设置LED亮度(0-100%)
* @param brightness 亮度百分比
*/
void LED_SetBrightness(uint8_t brightness)
{
// 限幅保护
if (brightness > 100) brightness = 100;
// 占空比 = brightness% * ARR
uint16_t pulse = (uint16_t)(brightness * 14400UL / 100);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, pulse);
}
4.4 Gamma校正
人眼对亮度的感知并非线性,而是近似对数关系(Gamma≈2.2)。直接线性调节PWM占空比会导致低亮度区间变化过快、高亮度区间变化过慢。
c
/**
* @brief Gamma校正后的亮度设置
* @note 将线性亮度值转换为符合人眼感知的PWM占空比
*/
void LED_SetBrightness_Gamma(uint8_t brightness)
{
if (brightness > 100) brightness = 100;
// Gamma = 2.2,使用查表法或实时计算
// 占空比 = (brightness/100)^2.2 * 100%
float normalized = brightness / 100.0f;
float gamma_corrected = powf(normalized, 2.2f);
uint16_t pulse = (uint16_t)(gamma_corrected * 14400);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, pulse);
}
// 预计算的Gamma校正表(节省实时计算开销)
const uint16_t gamma_table[101] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-9%
1, 1, 1, 2, 2, 3, 3, 4, 4, 5, // 10-19%
6, 7, 8, 9, 10, 11, 12, 14, 15, 17, // 20-29%
19, 21, 23, 25, 28, 30, 33, 36, 39, 42, // 30-39%
46, 50, 54, 58, 62, 67, 72, 77, 82, 88, // 40-49%
94, 100, 107, 114, 121, 128, 136, 144, 152, 161, // 50-59%
170, 180, 190, 200, 211, 222, 233, 245, 257, 270, // 60-69%
283, 297, 311, 326, 341, 357, 373, 390, 407, 425, // 70-79%
443, 462, 482, 502, 523, 544, 566, 588, 611, 635, // 80-89%
659, 684, 710, 736, 763, 790, 818, 847, 876, 906, 937, 968, 1000 // 90-100%
};
void LED_SetBrightness_Fast(uint8_t brightness)
{
if (brightness > 100) brightness = 100;
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, gamma_table[brightness] * 14400 / 1000);
}
五、自适应亮度控制算法

5.1 分段线性控制算法
综合考虑响应速度和人眼舒适度,推荐采用分段线性算法:
c
/**
* @brief 根据环境光照度计算目标亮度
* @param lux 环境光照度 (Lux)
* @return 目标亮度百分比 (0-100%)
*/
uint8_t Calculate_Target_Brightness(uint16_t lux)
{
// 分段线性映射
if (lux < 50) {
// 极暗环境:最大亮度
return 100;
} else if (lux < 200) {
// 昏暗环境:快速衰减
return (uint8_t)(100 - (lux - 50) * 30 / 150);
} else if (lux < 500) {
// 中等亮度:缓慢衰减
return (uint8_t)(70 - (lux - 200) * 20 / 300);
} else {
// 明亮环境:最低亮度(防止完全熄灭造成不适)
return 25;
}
}
5.2 平滑过渡算法
亮度突变会造成视觉不适,需要加入平滑过渡:
c
#define BRIGHTNESS_STEP 2 // 每步调节幅度
#define BRIGHTNESS_INTERVAL 20 // 调节间隔(ms)
uint8_t current_brightness = 0;
uint8_t target_brightness = 0;
/**
* @brief 平滑过渡到目标亮度
* @note 在主循环中周期性调用
*/
void LED_Smooth_Transition(void)
{
static uint32_t last_update = 0;
uint32_t now = HAL_GetTick();
if (now - last_update < BRIGHTNESS_INTERVAL) return;
last_update = now;
if (current_brightness < target_brightness) {
current_brightness += BRIGHTNESS_STEP;
if (current_brightness > target_brightness) {
current_brightness = target_brightness;
}
} else if (current_brightness > target_brightness) {
current_brightness -= BRIGHTNESS_STEP;
if (current_brightness < target_brightness) {
current_brightness = target_brightness;
}
}
LED_SetBrightness_Gamma(current_brightness);
}
六、状态机控制逻辑
6.1 状态定义与转换
智能台灯采用有限状态机(FSM)管理运行状态:
c
typedef enum {
STATE_STANDBY, // 待机:灯灭,低功耗检测
STATE_DETECTING, // 检测中:PIR触发,读取环境光
STATE_ADJUSTING, // 调节中:计算并设置PWM
STATE_ACTIVE, // 运行中:灯亮,持续监测
STATE_DELAY_OFF, // 延时关:倒计时,准备关灯
STATE_COUNT = 5
} LampState_t;
typedef struct {
LampState_t state;
uint32_t entry_time; // 进入当前状态的时间戳
uint32_t delay_duration; // 延时关灯时间(ms)
uint8_t brightness; // 当前亮度
uint8_t pir_detected; // PIR检测标志
} LampContext_t;
LampContext_t lamp_ctx = {
.state = STATE_STANDBY,
.delay_duration = 30000, // 默认30秒延时
};
6.2 状态转换表
| 当前状态 | 触发条件 | 下一状态 | 动作 |
|---|---|---|---|
| 待机 | PIR检测到人体 | 检测中 | 启动ADC采样 |
| 检测中 | ADC采样完成 | 调节中 | 计算目标亮度 |
| 调节中 | PWM设置完成 | 运行中 | 启动延时计数器 |
| 运行中 | PIR再次触发 | 运行中 | 重置延时计数器 |
| 运行中 | PIR无信号+延时到 | 延时关 | 启动倒计时 |
| 延时关 | 倒计时结束 | 待机 | 关闭LED,进入低功耗 |
| 延时关 | PIR再次触发 | 运行中 | 中断倒计时,恢复亮度 |
6.3 完整状态机实现
c
/**
* @brief 状态机主处理函数
* @note 在10ms定时中断或主循环中调用
*/
void Lamp_StateMachine(void)
{
uint32_t now = HAL_GetTick();
switch (lamp_ctx.state) {
case STATE_STANDBY:
// 低功耗模式:仅PIR中断唤醒
if (lamp_ctx.pir_detected) {
lamp_ctx.state = STATE_DETECTING;
lamp_ctx.entry_time = now;
lamp_ctx.pir_detected = 0;
}
break;
case STATE_DETECTING:
// 读取环境光并计算目标亮度
{
uint16_t adc_val = LDR_ReadFiltered();
uint16_t lux = LDR_GetLux(adc_val);
lamp_ctx.brightness = Calculate_Target_Brightness(lux);
lamp_ctx.state = STATE_ADJUSTING;
}
break;
case STATE_ADJUSTING:
// 平滑过渡到目标亮度
LED_Smooth_Transition();
if (current_brightness == lamp_ctx.brightness) {
lamp_ctx.state = STATE_ACTIVE;
lamp_ctx.entry_time = now;
}
break;
case STATE_ACTIVE:
// 持续监测PIR状态
if (lamp_ctx.pir_detected) {
// 有人活动,重置延时
lamp_ctx.entry_time = now;
lamp_ctx.pir_detected = 0;
} else if (now - lamp_ctx.entry_time > lamp_ctx.delay_duration) {
// 超时无活动,进入延时关
lamp_ctx.state = STATE_DELAY_OFF;
lamp_ctx.entry_time = now;
}
break;
case STATE_DELAY_OFF:
// 倒计时期间渐变暗
{
uint32_t elapsed = now - lamp_ctx.entry_time;
if (elapsed < 5000) { // 5秒渐变
uint8_t fade_brightness = lamp_ctx.brightness * (5000 - elapsed) / 5000;
LED_SetBrightness_Gamma(fade_brightness);
} else {
// 完全关闭
LED_SetBrightness_Gamma(0);
lamp_ctx.state = STATE_STANDBY;
}
// 中断倒计时
if (lamp_ctx.pir_detected) {
lamp_ctx.state = STATE_ACTIVE;
lamp_ctx.entry_time = now;
lamp_ctx.pir_detected = 0;
}
}
break;
default:
lamp_ctx.state = STATE_STANDBY;
}
}
/**
* @brief PIR外部中断回调
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == PIR_PIN) {
lamp_ctx.pir_detected = 1;
}
}
七、完整硬件电路设计
7.1 原理图详解

PIR模块接口:
- VCC接5V,GND接地
- OUT信号接PA0(配置为外部中断输入,下降沿触发)
- 模块板载延时和灵敏度电位器,可根据场景调节
光敏电阻分压电路:
- GL5516与10KΩ电阻串联分压
- 分压点接PA1(ADC1通道1)
- 建议并联100nF电容滤波,抑制PWM纹波干扰
LED驱动电路:
- S8050 NPN三极管作为开关
- 基极通过1KΩ电阻接PA2(TIM3_CH3 PWM输出)
- LED串联100Ω限流电阻
- 如需更大功率,可改用MOS管(如AO3400)或专用LED驱动芯片
7.2 抗干扰设计要点
- 电源退耦:PIR模块VCC引脚就近并联100nF陶瓷电容,抑制电源噪声
- 地线隔离:PIR模拟地与数字地单点连接,避免地环路干扰
- 屏蔽走线:PIR信号线远离PWM大电流走线,必要时用地线包络
- 光敏隔离:光敏电阻安装位置远离LED热源,避免温度漂移

八、低功耗优化策略
8.1 待机功耗分析
| 模块 | 工作状态 | 待机状态 | 优化措施 |
|---|---|---|---|
| MCU | 8mA@72MHz | 12μA@STOP模式 | 待机时进入STOP模式 |
| PIR模块 | 1mA | 50μA | 保持供电,中断唤醒 |
| LED | 1000mA(全亮) | 0 | PWM关闭 |
| 光敏电路 | 0.5mA | 0 | 待机时关闭ADC |
| 其他 | 3mA | 0 | 关闭外设时钟 |
待机总功耗可控制在**<1mA**,满足电池供电需求。
8.2 低功耗代码实现
c
/**
* @brief 进入低功耗待机模式
*/
void Enter_Standby_Mode(void)
{
// 关闭不必要的外设
HAL_ADC_DeInit(&hadc1);
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3);
// 配置唤醒源:PIR外部中断
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
// 进入STOP模式,保持SRAM内容
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// 唤醒后重新初始化系统时钟和外设
SystemClock_Config();
LED_PWM_Init();
LDR_ADC_Init();
}
九、调试与常见问题
9.1 调试技巧
| 现象 | 排查方向 | 解决方案 |
|---|---|---|
| PIR不触发 | 灵敏度调节、探测角度、透镜遮挡 | 调节电位器至最大,检查透镜安装 |
| PIR误触发 | 热源干扰、宠物、空调风 | 降低灵敏度,增加延时,调整安装高度 |
| 光控不准 | 光敏老化、温度漂移、PWM干扰 | 更换光敏,隔离热源,增加滤波电容 |
| LED闪烁 | PWM频率过低、电源纹波 | 提高频率至5kHz以上,增加电源退耦 |
| 亮度跳变 | ADC采样噪声、算法突变 | 增加滑动平均窗口,使用平滑过渡 |
9.2 关键参数校准
c
/**
* @brief 系统参数校准结构
*/
typedef struct {
uint16_t pir_sensitivity; // PIR灵敏度阈值
uint16_t lux_dark; // 暗环境ADC阈值
uint16_t lux_bright; // 亮环境ADC阈值
uint8_t min_brightness; // 最低亮度限制
uint8_t max_brightness; // 最高亮度限制
uint32_t delay_time_ms; // 延时关灯时间
} LampConfig_t;
// 默认配置(可根据实际环境调整)
const LampConfig_t default_config = {
.pir_sensitivity = 100,
.lux_dark = 3500, // ADC值>3500视为暗环境
.lux_bright = 1000, // ADC值<1000视为亮环境
.min_brightness = 10, // 最低10%亮度
.max_brightness = 100, // 最高100%亮度
.delay_time_ms = 30000, // 30秒延时
};
十、总结与展望
本文完整实现了一个基于STM32的智能台灯系统,涵盖以下核心技术点:
- PIR人体感应:深入解析热释电效应、双元探测结构和菲涅尔透镜原理,掌握HC-SR501模块的驱动与调参
- 光敏电阻光控:理解内光电效应与阻值特性,设计分压采样电路,实现带滤波的环境光检测
- PWM调光技术:合理选择PWM频率,设计LED驱动电路,引入Gamma校正实现符合人眼感知的平滑调光
- 状态机控制:采用FSM管理台灯运行状态,实现人来灯亮、人走灯灭的智能逻辑
- 低功耗优化:通过STOP模式和外设管理,将待机功耗控制在1mA以下
进阶方向
- 数字光传感器:用BH1750替代光敏电阻,获得精准的Lux值输出,消除温度漂移
- WiFi联网:集成ESP8266模块,实现远程控制和数据统计
- 多档记忆:增加EEPROM存储用户偏好设置
- 恒流驱动:采用PT4115等专用LED恒流驱动芯片,提升光效稳定性
转载自:https://blog.csdn.net/u014727709/article/details/162448168
欢迎 👍点赞✍评论⭐收藏,欢迎指正