1. 项目概述
这个基于STM32的智能台灯项目是我最近完成的一个嵌入式系统设计,它完美融合了硬件设计和软件编程。作为一个经常熬夜工作的程序员,我深知一款好的台灯对眼睛保护的重要性。市面上的普通台灯要么功能单一,要么价格昂贵,于是我决定自己动手打造一款既智能又实惠的台灯。
这款台灯的核心控制器采用了STM32F103C8T6,也就是我们常说的"蓝莓派"最小系统板。选择它的原因很简单:性能足够强大,价格只要十几块钱,而且社区支持非常好。整个系统包含了七大核心功能,从基础的亮度调节到智能的环境光适应,再到贴心的坐姿提醒,可以说考虑到了日常使用的方方面面。
2. 硬件设计详解
2.1 主控电路设计
STM32F103C8T6是这个系统的大脑,我选择它主要基于以下几个考虑:
- 72MHz的主频完全足够处理传感器数据和PWM输出
- 内置的定时器可以方便地生成PWM信号控制LED亮度
- 丰富的GPIO接口可以连接所有外设
- 低功耗特性适合长时间工作
电路设计上,我特别注意了以下几点:
- 电源部分加了100μF的电解电容和0.1μF的陶瓷电容组合,有效滤除电源噪声
- 复位电路采用标准的10k电阻和0.1μF电容组合
- 为每个GPIO都加了保护电阻,防止意外短路损坏芯片
2.2 LED驱动电路
LED驱动是整个系统的关键部分,我采用了PWM调光方式。具体实现如下:
- 使用STM32的TIM3定时器生成PWM信号
- 频率设置为1kHz(这个频率既不会产生可闻噪声,又能避免LED闪烁)
- 通过MOSFET(我用的IRLZ44N)驱动LED灯珠
- 在MOSFET的栅极加了10Ω电阻防止振荡
这里有个小技巧:我在LED回路中串联了一个0.1Ω的采样电阻,通过ADC检测电流,实现了闭环控制,确保亮度稳定。
2.3 传感器模块
2.3.1 光线传感器
选用BH1750数字光照传感器,I2C接口,直接连接到STM32的PB6(SCL)和PB7(SDA)。这个传感器的优点很明显:
- 测量范围广(1-65535 lux)
- 直接数字输出,不需要额外的ADC
- 内置了光学滤光片,测量结果更准确
实际使用中发现,传感器的安装位置很有讲究。我把它放在了灯罩边缘,既不会直接被LED光影响,又能准确感知环境光。
2.3.2 超声波模块
HC-SR04超声波模块用于检测用户与台灯的距离。连接方式:
- Trig引脚接PA0
- Echo引脚接PA1
这里有个重要的注意事项:Echo引脚输出的5V信号需要通过分压电阻降到3.3V再接入STM32,否则可能损坏IO口。
2.4 蓝牙模块
HC-05蓝牙模块通过串口与STM32通信:
- TXD接PA10(UART1_RX)
- RXD接PA9(UART1_TX)
配置蓝牙模块时,我修改了默认波特率为115200,这样数据传输更快。同时设置了固定的配对密码,增强安全性。
2.5 OLED显示
0.96寸OLED显示屏也是通过I2C连接:
- SCL接PB6(与BH1750共用)
- SDA接PB7
为了节省IO口,光线传感器和OLED共用I2C总线,这需要在软件上做好地址管理和时序控制。
3. 软件设计实现
3.1 系统架构设计
整个软件采用模块化设计,主要分为以下几个部分:
- 硬件抽象层:封装底层硬件操作
- 驱动层:各个外设的驱动程序
- 应用层:业务逻辑实现
- 通信协议:蓝牙通信协议处理
使用FreeRTOS实时操作系统来管理各个任务,确保系统响应及时。
3.2 关键功能实现
3.2.1 PWM调光实现
c复制// PWM初始化代码
void PWM_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// GPIO配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 定时器基础配置
TIM_TimeBaseStructure.TIM_Period = 999; // PWM周期=1000
TIM_TimeBaseStructure.TIM_Prescaler = 71; // 72MHz/72=1MHz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// PWM模式配置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 500; // 初始占空比50%
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_Cmd(TIM3, ENABLE);
TIM_CtrlPWMOutputs(TIM3, ENABLE);
}
3.2.2 光线传感器数据处理
为了提高光线检测的稳定性,我采用了滑动平均滤波算法:
c复制#define LIGHT_SAMPLE_SIZE 10
uint16_t light_samples[LIGHT_SAMPLE_SIZE];
uint8_t sample_index = 0;
uint16_t GetFilteredLightValue(void)
{
uint32_t sum = 0;
for(int i=0; i<LIGHT_SAMPLE_SIZE; i++){
sum += light_samples[i];
}
return sum / LIGHT_SAMPLE_SIZE;
}
void LightSensorTask(void *pvParameters)
{
while(1){
light_samples[sample_index] = BH1750_ReadLight();
sample_index = (sample_index + 1) % LIGHT_SAMPLE_SIZE;
vTaskDelay(100 / portTICK_RATE_MS);
}
}
3.2.3 超声波测距
超声波测距的关键是精确计时,我使用了输入捕获功能:
c复制float GetDistance(void)
{
// 发送触发信号
GPIO_SetBits(TRIG_PORT, TRIG_PIN);
delay_us(20);
GPIO_ResetBits(TRIG_PORT, TRIG_PIN);
// 等待回波
while(GPIO_ReadInputDataBit(ECHO_PORT, ECHO_PIN) == 0);
// 开始计时
TIM_SetCounter(TIM2, 0);
while(GPIO_ReadInputDataBit(ECHO_PORT, ECHO_PIN) == 1);
// 计算距离
uint32_t pulse_width = TIM_GetCounter(TIM2);
float distance = (pulse_width * 0.034) / 2; // 单位:cm
return distance;
}
3.3 蓝牙通信协议
为了方便手机APP控制,我设计了一个简单的通信协议:
| 命令头 | 命令类型 | 数据长度 | 数据 | 校验和 |
|---|---|---|---|---|
| 0xAA | 1字节 | 1字节 | N字节 | 1字节 |
典型命令示例:
- 设置亮度:AA 01 01 03 XX (03表示第3档亮度)
- 切换模式:AA 02 01 00 XX (00表示自动模式)
- 读取状态:AA 03 00 XX
4. 系统调试与优化
4.1 硬件调试经验
-
PWM调光时发现LED有轻微闪烁:
- 原因是电源功率不足,更换更大电流的电源适配器后解决
- 在LED两端并联100μF电容也有帮助
-
超声波测距不稳定:
- 发现是电源噪声影响,在VCC和GND之间加了0.1μF电容
- 调整了触发间隔时间,从50ms增加到100ms
-
蓝牙连接经常断开:
- 原来是天线位置不当,调整模块方向后改善
- 在软件上增加了连接状态检测和自动重连机制
4.2 软件优化技巧
-
为了降低功耗,我做了以下优化:
- 在无操作时降低CPU频率
- 关闭不用的外设时钟
- 使用中断代替轮询
-
提高系统响应速度:
- 关键任务设为高优先级
- 使用DMA传输数据
- 优化了中断服务程序
-
增强稳定性:
- 增加了看门狗定时器
- 关键数据做了CRC校验
- 实现了软件复位功能
5. 实际使用效果
经过一个月的实际使用,这款智能台灯表现相当不错:
- 亮度调节非常平滑,五档亮度适应不同环境
- 自动模式下光线适应很自然,眼睛不容��疲劳
- 坐姿提醒功能很实用,特别是长时间工作时
- 蓝牙控制反应迅速,没有明显延迟
- 整体功耗很低,连续工作一周都不用充电
几个还可以改进的地方:
- 增加色温调节功能
- 加入语音控制
- 设计更美观的外壳
- 增加无线充电功能
这个项目从硬件选型到软件开发,再到调试优化,前后花了大约两个月时间。最大的收获不是做出了一个可用的台灯,而是在这个过程中解决的各种实际问题,这些经验对以后的嵌入式开发项目都很有帮助。
