一. 系统概述
这款智能台灯系统具备多种功能,能够自动调节亮度、监测人体活动、感知环境光照,此外还有定时和报警功能,极大地提升了用户体验和功能的扩展性。具体功能包括:
-
亮度调节:
- 台灯有自动和手动两种模式可调节亮度。自动模式根据环境光强自动调整,手动模式通过按键调节亮度。
-
坐姿提醒:
- 利用红外光电开关监测人体与台灯的距离,若距离过近则发出报警提醒。
-
学习定时:
- 时钟模块进行学习时间的定时提醒,OLED显示屏显示当前时间,定时结束时蜂鸣器发出提醒。
-
光照检测:
- 通过光敏电阻模块检测光强,OLED显示屏实时显示数据。
二. 电路设计
电路设计采用Altium Designer进行绘制:
- 系统的核心控制由STM32F103C8T6单片机最小系统实现。
- DS1302模块用于时钟定时功能,通过SDA、SCK、DAT引脚连接单片机。
- 光电开关用于人体检测,模块数据输出直接连接单片机的GPIO口。
- 独立按键用于灯光控制和模式切换,一端接地,另一端连至单片机的GPIO口。
- 数据显示采用0.96寸OLED12864,使用IIC总线与单片机通信。
- 光敏电阻模块用于光强检测,传感器模拟端连接单片机的模拟输入端。
三.程序设计
#include "stm32f10x.h"
#include "OLED_I2C.h"
#include "ds1302.h"
#include "timer.h"
#include "gpio.h"
#include "delay.h"
#include "key.h"
#include "adc.h"
#include "stdio.h"
#include "string.h"
unsigned char setn=0;
unsigned char txshi=12,txfen=0,txmiao=0;
u8 tixing=0;//0:时间提醒关,1:时间提醒开
u8 mode=0;//0:自动模式,1手动模式
unsigned char miao = 0;//没有人的计时时间
unsigned char PWM_Val = 0xFF;//用于PWM调节
unsigned char GearTemp = 0;//0~3档
u8 RemindFlag=0;//提醒时间到了标志
u8 PostureFlag=0;//坐姿提醒
int main(void)
{
char i=0;
DelayInit();
I2C_Configuration(); //IIC初始化
OLED_Init(); //OLED初始化
KEY_Init(); //按键初始化
BEEP_AND_GD_RTHW_GPIO_Config();
OLED_CLS();//清屏
DS1302_Init(&SysDate);
DelayMs(100);
DS1302_DateRead(&SysDate);//读时间
OLED_CLS();//清屏
for(i=0;i<4;i++)OLED_ShowCN(i*16,2,i+8,0);//测试显示中文:亮度等级
OLED_ShowStr(62,2,": ",2);//显示冒号
for(i=0;i<4;i++)OLED_ShowCN(i*16,4,i,0);//测试显示中文:提醒时间
DisplayMode();
TIM2_Init(49,71); //定时器初始化,定时50us
TIM3_Init(499,7199); //定时器初始化,定时50ms
//Tout = ((arr+1)*(psc+1))/Tclk ;
//Tclk:定时器输入频率(单位MHZ)
//Tout:定时器溢出时间(单位us)
while(1)
{
KeySettings();
DisplayTime();
DisplayTiXingTime();
AutoHandle();
LedGearHandle(GearTemp);
if(GD == 0)//检测坐姿不正确
{
if(PostureFlag==0)
{
PostureFlag=1;
BEEP=1;//蜂鸣器提醒
OLED_CLS();//清屏
for(i=0;i<6;i++)OLED_ShowCN(i*16+16,2,i+16,0);//测试显示中文:请注意坐姿!
DelayMs(1000);
OLED_CLS();//清屏
for(i=0;i<4;i++)OLED_ShowCN(i*16,2,i+8,0);//测试显示中文:亮度等级
OLED_ShowStr(62,2,": ",2);//显示冒号
for(i=0;i<4;i++)OLED_ShowCN(i*16,4,i,0);//测试显示中文:提醒时间
DisplayMode();
}
}
else
{
PostureFlag=0;
}
}
}
void TIM2_IRQHandler(void)//定时器2中断服务程序
{
static u8 time_count = 0;
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除中断标志位
time_count++;
if(time_count > 200)time_count = 0;//10ms一个周期
if(time_count >= PWM_Val)LED = 1;//占空比调节
else LED = 0;
}
}
void TIM3_IRQHandler(void) //TIM3中断
{
static u8 count=0,count2=0;
if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
if(count2++>=2)
{
count2 = 0;
if(GD == 1)
{
if(RemindFlag==1 && txshi==SysDate.hour && txfen==SysDate.min)
{
BuzzerSound();
}
else
{
BEEP=0;
}
}
}
if(count++ >= 20)//1秒时间到
{
count = 0;
if(RTHW==1)miao=30;//检测到有人,时间赋值30秒
else
{
if(miao>0)miao--;//没有人,30秒倒计时
}
}
}
}
四.资料内容
24-32-04