基于51单片机的带坐姿检测语音提醒智能护眼台灯proteus仿真原理图PCB

功能介绍:
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++;			  //下一个++
	}
}

仿真演示视频:
https://www.bilibili.com/video/BV1gZ4y1h7Yx/

实物演示视频:
https://www.bilibili.com/video/BV13Y4y167WM/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值