功能介绍:
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
#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; //设置定时初值 500usTR0 = 1; //启动T0计时ET0 = 1; //打开T0中断EA = 1; //打开总中断
}//定时器0中断
void Timer0_Intterupt(void) interrupt 1
{static unsigned char ACount = 0;TL0 = 0x33; //设置定时初值TH0 = 0xFE; //设置定时初值 500uscnt++;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;}}}}}
}
仿真演示视频:
https://www.bilibili.com/video/BV1ug411o7k4/
实物演示视频:
https://www.bilibili.com/video/BV1aG411g7yG/