功能介绍:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时显示当前时间/灯光亮度/姿势检测
2.姿势不正确时,蜂鸣器报警,同时语音提醒
3.具备久坐提醒功能,到达提醒时间,蜂鸣器报警,同时语音提醒
4.有人时根据环境光强调整台灯亮度,人离开后,灯光调到最暗,当回到座位自动变亮,以节约用电
5.可通过按键更改当前时间
6.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
#define __MAIN_C
#include <reg52.h>
#include "main.h"
#define ALARM_TIME 1 //定时提醒时间,最大59分钟
bit dispFlag = 1;
bit setFlag = 0;
unsigned char setIndex = 0;
unsigned char lightValue;
char dispMode = NORMAL;
bit bodyFlag = 0;
bit postureRightFlag = 0;
unsigned char lampAPWM = 1;
unsigned int time500us = 0;
unsigned char timeMinuteBuf = 0;
unsigned char timeSecondBuf = 0;
unsigned char alarmDelay = 0;
void main()
{
//初始化
UART_Init(); //初始化串口
Timer0_Init(); //初始化定时器
LCD_Init();
DS1302_Init();
DelayMs(20);
//开机显示
LCD_DispStr(0, 0, " Welcome! ");
DelayS(2);
LCD_Clear();
DS1302_ReadTime();
timeMinuteBuf = timeBufDec[5]; //重置计时
timeSecondBuf = timeBufDec[6]; //重置计时
while(1)
{
// LCD1602液晶显示
if (dispFlag == 1 && setFlag == 0)
{
dispFlag = 0;
DS1302_ReadTime();
if (BODY_PIN == 0) //有人
{
bodyFlag = 1; //有人标志
LampCtr();
if (POSTURE_PIN == 0) //姿势正确
{
postureRightFlag = 1; //姿势正确标志
}
else
{
postureRightFlag = 0; //姿势不正确标志
UART_SendStr("请注意坐姿\r\n", 12); //发送数据
DelayS(3);
}
if (timeMinuteBuf >= (60 - ALARM_TIME)) //分钟大于(60 - ALARM_TIME)的处理
{
if (timeBufDec[5] == (timeMinuteBuf + ALARM_TIME - 60)) //ALARM_TIME分钟到
{
if (timeBufDec[6] == timeSecondBuf)
{
alarmDelay = 10; //蜂鸣器报警
UART_SendStr("请注意休息\r\n", 12); //发送数据
timeMinuteBuf = timeBufDec[5]; //重置计时
timeSecondBuf = timeBufDec[6]; //重置计时
}
}
}
else
{
if (timeBufDec[5] == timeMinuteBuf + ALARM_TIME) //ALARM_TIME分钟到
{
if (timeBufDec[6] == timeSecondBuf)
{
alarmDelay = 10; //蜂鸣器报警
UART_SendStr("请注意休息\r\n", 12); //发送数据
timeMinuteBuf = timeBufDec[5]; //重置计时
timeSecondBuf = timeBufDec[6]; //重置计时
}
}
}
}
else
{
bodyFlag = 0; //没人
lampAPWM = 1; //将台灯亮度调到最暗
timeMinuteBuf = timeBufDec[5]; //重置计时
timeSecondBuf = timeBufDec[6]; //重置计时
}
if (dispMode == NORMAL)
{
DispNormal(setIndex);
}
Alarm();
}
KeyProcess();
}
}
void LampCtr()
{
lightValue = 99 - 99 * ReadADC1(AIN0_GND) / 255; //读取当前光照强度
if (lightValue <= 30)
{
lampAPWM = 3;
}
else if (lightValue > 30 && lightValue <= 60)
{
lampAPWM = 2;
}
else if (lightValue > 60)
{
lampAPWM = 1;
}
}
void Alarm(void)
{
if (alarmDelay > 0) //蜂鸣器响
{
alarmDelay--;
BUZZER = 0;
}
else
{
BUZZER = 1;
}
}
void Timer0_Init(void)
{
TMOD &= 0xF0;
TMOD |= 0x01;
TL0 = 0x33; //设置定时初值
TH0 = 0xFE; //设置定时初值 500us
TR0 = 1; //启动T0计时
ET0 = 1; //打开T0中断
EA = 1; //打开总中断
}
void Timer0_Intterupt(void) interrupt 1
{
static unsigned char ACount = 0;
static unsigned int cnt;
TL0 = 0x33; //设置定时初值
TH0 = 0xFE; //设置定时初值 500us
cnt++;
if (cnt >= 500) //250ms刷新一次状态
{
cnt = 0;
dispFlag = 1;
}
ACount++;
if (ACount <= lampAPWM) //占空比调节
{
LAMPA = LAMP_ON;
}
else if ((ACount > lampAPWM) && (ACount <= 3))
{
LAMPA = LAMP_OFF;
}
else
{
ACount = 0;
}
}
/************************* 串口配置 *************************/
void UART_Init(void)
{
SCON = 0x50;
TH2 = 0xFF;
TL2 = 0xDB;
RCAP2H = 0xFF; //(65536-(FOSC/32/BAUD)) BAUD = 9600 FOSC = 11059200
RCAP2L = 0xDB;
/*****************/
TCLK = 1;
RCLK = 1;
C_T2 = 0;
EXEN2 = 0;
/*****************/
TR2 = 1;
ES = 0; //打开串口中断
EA = 1; //打开总中断
}
/************************* 串口发送字节 *************************/
void UART_SendByte(unsigned char dat) //串口发送单字节数据
{
unsigned char time_out;
time_out = 0;
SBUF = dat; //将数据放入SBUF中
while ((!TI) && (time_out < 100)) //检测是否发送出去
{
time_out++;
DelayUs10x(2);
} //未发送出去 进行短暂延时
TI = 0; //清除ti标志
}
/************************* 串口发送字符串 *************************/
void UART_SendStr(unsigned char *s, unsigned char length)
{
unsigned char num;
num = 0x00;
while (num < length) //发送长度对比
{
UART_SendByte(*s); //放松单字节数据
s++; //指针++
num++; //下一个++
}
}