功能介绍:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时显示当前时间/工作模式/灯光亮度
2.具备闹钟功能,到达闹钟时间,蜂鸣器报警
3.自动模式下,有人灯亮,人离开后15s,灯光熄灭,并且可根据环境光亮度,自动调整灯光亮度
4.手动模式下,可手动调试灯光亮度
5.可通过蓝牙发送命令分别控制台灯状态
发送命令格式:*Ax#,x表示灯光等级,1~3有效,C表示关闭
*MM# 切换为手动模式 *MA#切换为自动模式
6.可通过按键更改当前时间/工作模式/闹钟开关/闹钟时间
7.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB:
主程序:
#define __MAIN_C
#include <reg52.h>
#include "main.h"
bit dispFlag = 1;
bit setFlag = 0;
unsigned char setIndex = 0;
unsigned char lightValue;
unsigned char timeLimit[2] = {22, 11};
char dispMode = NORMAL;
bit autoFlag = 0;
bit lampASwitch = 0;
unsigned char lampAPWM = 0;
int cnt = 0;
unsigned int time500us = 0;
unsigned char i = 0;
unsigned char R_buf[4];
unsigned char timeDelay = 0;
unsigned char alarmDelay = 0;
bit alarmSwitch = 0;
void main()
{
//初始化
lampASwitch = LAMP_OFF;
Timer0_Init();
UART0_Init();
LCD_Init();
DS1302_Init();
DelayMs(20);
//开机显示
LCD_DispStr(0, 0, " Welcome! ");
DelayS(2);
LCD_Clear();
while(1)
{
// LCD1602液晶显示
if (dispFlag == 1 && setFlag == 0)
{
dispFlag = 0;
Alarm(); //闹钟控制
LampCtr(); //灯光自动控制
DS1302_ReadTime(); //读取时间
if (dispMode == NORMAL) //正常显示模式
{
DispNormal(setIndex);
}
else if (dispMode == SET_ALARM_CLOCK) //设定闹钟模式
{
DispSetLimit(setIndex);
}
}
KeyProcess(); //按键处理
}
}
//灯光自动控制
void LampCtr()
{
if (autoFlag) //自动模式下
{
lightValue = 99 - 99 * ReadADC1(AIN0_GND) / 255; //读取当前光照强度
if (IRFLAG == 0) //有人
{
timeDelay = 50;
}
if (timeDelay > 0)
{
timeDelay--;
lampASwitch = LAMP_ON; //有人灯亮
}
else
{
lampASwitch = LAMP_OFF;
}
if (lampASwitch == LAMP_ON) //灯光打开时根据光强控制亮度
{
if (lightValue <= 30)
{
lampAPWM = 3;
}
else if (lightValue > 30 && lightValue <= 60)
{
lampAPWM = 2;
}
else if (lightValue > 60)
{
lampAPWM = 1;
}
}
}
}
//闹钟控制
void Alarm(void)
{
if (alarmSwitch == 1) //闹钟打开
{
if (timeBufDec[4] == timeLimit[0] && timeBufDec[5] == timeLimit[1] && timeBufDec[6] == 0) //闹钟时间到
{
alarmDelay = 50;
}
if (alarmDelay > 0) //蜂鸣器响
{
alarmDelay--;
BUZZER = 0;
}
else
{
BUZZER = 1;
}
}
}
//定时器0初始化
void Timer0_Init(void)
{
TMOD &= 0xF0;
TMOD |= 0x01;
TL0 = 0x33; //设置定时初值
TH0 = 0xFE; //设置定时初值 500us
TR0 = 1; //启动T0计时
ET0 = 1; //打开T0中断
EA = 1; //打开总中断
}
//定时器0中断
void Timer0_Intterupt(void) interrupt 1
{
static unsigned char ACount = 0;
TL0 = 0x33; //设置定时初值
TH0 = 0xFE; //设置定时初值 500us
cnt++;
if (cnt >= 500) //250ms刷新一次状态
{
cnt = 0;
dispFlag = 1;
}
if (lampASwitch == LAMP_ON)
{
ACount++;
if (ACount <= lampAPWM) //占空比调节
{
LAMPA = LAMP_ON;
}
else if ((ACount > lampAPWM) && (ACount <= 3))
{
LAMPA = LAMP_OFF;
}
else
{
ACount = 0;
}
}
else
{
LAMPA = LAMP_OFF;
}
}
//串口初始化
void UART0_Init()
{
SCON = 0x50;
TMOD &= 0x0F;
TMOD |= 0x20; //8位自动重装
TH1 = RH_UART;
TL1 = TH1;
ET1 = 0; //禁止T1中断
TR1 = 1; //启动T1计时
ES = 1; //打开串口中断
EA = 1; //打开总中断
}
void UART0_SendByte(unsigned char dat) //串口发送单字节数据
{
unsigned char time_out;
time_out = 0x00;
SBUF = dat; //将数据放入SBUF中
while ((!TI) && (time_out < 100)) //检测是否发送出去
{
time_out++;
DelayUs10x(2);
} //未发送出去 进行短暂延时
TI = 0; //清除ti标志
}
void UART0_SendStr(unsigned char *str, unsigned char length) //发送定长度字符串
{
// unsigned char *tmp;
unsigned char cnt = 0;
// unsigned char length = 0;
// tmp = str;
// while (*(tmp++) != '\0')
// {
// length++;
// }
while (cnt < length) //发送长度对比
{
UART0_SendByte(*str); //发送单字节数据
str++; //指针++
cnt++; //下一个++
}
}
//串口中断
void UART0_Interrupt() interrupt 4
{
if (TI)
{
TI = 0;
}
if (RI)
{
RI = 0;
if (SBUF == '*')
{
i = 0;
}
R_buf[i] = SBUF;
SBUF = SBUF;
i++;
if (i == 4)
{
i = 0;
if (R_buf[0] == '*' && R_buf[3] == '#')
{
if (R_buf[1] == 'A')
{
if (R_buf[2] == 'C')
{
lampASwitch = LAMP_OFF;
lampAPWM = 0;
}
else if (R_buf[2] == '1')
{
lampASwitch = LAMP_ON;
lampAPWM = 1;
}
else if (R_buf[2] == '2')
{
lampASwitch = LAMP_ON;
lampAPWM = 2;
}
else if (R_buf[2] == '3')
{
lampASwitch = LAMP_ON;
lampAPWM = 3;
}
autoFlag = 0;
}
else if (R_buf[1] == 'M')
{
if (R_buf[2] == 'A')
{
autoFlag = 1;
}
else if (R_buf[2] == 'M')
{
autoFlag = 0;
}
}
}
}
}
}