基于51单片机的智能蓝牙路灯街灯控制系统proteus仿真原理图PCB

news2024/11/27 5:38:16

功能:
0.本系统采用STC89C52作为单片机
1.液晶实时显示时间/环境光强/工作模式
2.每隔5s向蓝牙串口发送一次信息
3.支持路灯故障检测
4.工作时间18~24时,两个路灯同时点亮,24时以后,B路灯关闭,若检测到由物体通过,路灯B点亮10s后关闭
5.非工作时间,光照强度低于设定光照阈值,两个路灯点亮
6.可蓝牙控制两个路灯状态
7.按键更改时间/工作时间/光照阈值/工作模式/路灯亮度
8.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:
在这里插入图片描述
在这里插入图片描述

PCB :
在这里插入图片描述

主程序:

#define __MAIN_C
#include <reg52.h>
#include "main.h"

bit dispFlag = 1;
bit setFlag = 0;
bit sendFlag = 0;
unsigned char setIndex = 0;
unsigned char lightValue;
unsigned char lightValueA;
unsigned char lightValueB;
unsigned char lightLimit = 70;
unsigned char timeLimit[4] = {18, 0, 5, 0};
char dispMode = DISP_NORMAL;
bit autoFlag = 0;
bit lampBDelay = 0;
bit lampAError = 0;
bit lampBError = 0;
bit lampASwitch;
bit lampBSwitch;
unsigned char lampAPWM = 3;
unsigned char lampBPWM = 3;
int cnt = 0;
unsigned int time500us = 0;
unsigned char i = 0;
unsigned char R_buf[4];

void main()
{
    //初始化
    lampASwitch = LAMP_OFF;
    lampBSwitch = LAMP_OFF;
    LCD_Init();
    DS1302_Init();
    EEPROM52_Read();
    if (isNew == 1)
    {
        DS1302_WriteTime();
    }
    DS1302_ReadTime();
    EEPROM52_Init();
    Timer0_Init();

    UART0_Init();
    
    DelayMs(20);
    //开机显示
    LCD_DispStr(0, 0, "    Welcome!    ");
    DelayS(2);
    LCD_Clear();
    DS1302_ReadTime();
    DispNormal(setIndex);

    while(1)
    {
        // LCD1602液晶显示
        if (dispFlag == 1 && setFlag == 0)
        {
            dispFlag = 0;
            LampCtr();
            CheckLamp();
            DS1302_ReadTime();

            if (dispMode == DISP_NORMAL)
            {
                DispNormal(setIndex);
            }
            else if (dispMode == SET_TIME_LIMIT)
            {
                DispSetLimit(setIndex);
            }
            else if (dispMode == SET_LIGHT)
            {
                DispSetLight(setIndex);
            }
            else if (dispMode == CHECK_LIGHT)
            {
                DispCheckLight(setIndex);
            }
        }

        //发送一次串口信息
        if (sendFlag == 1)
        {
            sendFlag = 0;

            if (lampAError == 1)
            {
                sprintf(dispRow0, "A:%d Er  ", (int)lampAPWM);
            }
            else
            {
                sprintf(dispRow0, "A:%d Ok  ", (int)lampAPWM);
            }

            if (lampBError == 1)
            {
                sprintf(dispRow1, "B:%d Er", (int)lampBPWM);
            }
            else
            {
                sprintf(dispRow1, "B:%d Ok", (int)lampBPWM);
            }

            if (lampASwitch == LAMP_OFF)
            {
                UART0_SendStr("C",1);
            }
            else
            {
                UART0_SendStr("O",1);
            }
            UART0_SendStr(dispRow0, 8);

            if (lampBSwitch == LAMP_OFF)
            {
                UART0_SendStr("C",1);
            }
            else
            {
                UART0_SendStr("O",1);
            }

            UART0_SendStr(dispRow1,6);
            UART0_SendStr("\r\n", 2);
            
            if (autoFlag == 1)
            {
                sprintf(dispRow1, "%02d:%02d:%02d L:%02d A ", (int)timeBufDec[4], (int)timeBufDec[5], (int)timeBufDec[6], (int)lightValue);
            }
            else
            {
                sprintf(dispRow1, "%02d:%02d:%02d L:%02d M ", (int)timeBufDec[4], (int)timeBufDec[5], (int)timeBufDec[6], (int)lightValue);
            }
            UART0_SendStr(dispRow1, 16);
            UART0_SendStr("\r\n", 2);
            UART0_SendStr("\r\n", 2);
        }
        KeyProcess();
    }
}

void LampCtr()
{
    lightValue = 99 - 99 * ReadADC1(AIN0_GND) / 255; //读取当前光照强度
    if (autoFlag)
    {
        if ((timeBufDec[4] == timeLimit[0] && timeBufDec[5] >= timeLimit[1]) || (timeBufDec[4] > timeLimit[0]) \
            || (timeBufDec[4] == timeLimit[2] && timeBufDec[5] < timeLimit[3]) || (timeBufDec[4] < timeLimit[2])) //工作时间内路灯操作
        {
            lampASwitch = LAMP_ON;
            if ((timeBufDec[4] >= 0 && timeBufDec[4] < timeLimit[2]) || (timeBufDec[4] == timeLimit[2] && timeBufDec[5] < timeLimit[3]))
            {
                if (!lampBDelay)
                {
                    lampBSwitch = LAMP_OFF;
                    if (IRFLAG == 0) //检测到有人或车经过 启动10s定时
                    {
                        lampBDelay = 1; 
                    }
                }
                
            }
            else
            {
                lampBSwitch = LAMP_ON;
                lampBDelay = 0;
            }
        }
        else //工作时间外路灯操作
        {
            if (lightValue < lightLimit) //光照强度低于设定阈值
            {
                lampASwitch = LAMP_ON;
                lampBSwitch = LAMP_ON;
            }
            else
            {
                lampASwitch = LAMP_OFF;
                lampBSwitch = LAMP_OFF;
            }
            
        }
    }
}

void CheckLamp()
{
    if (lampASwitch == LAMP_ON) //路灯A打开时,检测对应光强
    {
        lightValueA = 99 - 99 * ReadADC2(AIN1_GND) / 255; //读取当前光照强度
        if (lightValueA < 50) //路灯A故障声光报警 阈值可根据实际情况调整
        {
            lampAError = 1;
            BUZZER = 0; //打开蜂鸣器
        }
        else
        {
            lampAError = 0;
        }
    }

    if (lampBSwitch == LAMP_ON) //路灯B打开时,检测对应光强
    {
        lightValueB = 99 - 99 * ReadADC2(AIN0_GND) / 255; //读取当前光照强度
        if (lightValueB < 50) //路灯B故障声光报警 阈值可根据实际情况调整
        {
            lampBError = 1;
            BUZZER = 0; //打开蜂鸣器
        }
        else
        {
            lampBError = 0;
        }
    }

    if (lampAError == 0 && lampBError == 0) //灯都没有故障
    {
        BUZZER = 1; //关闭蜂鸣器
    }

    if (lampASwitch == LAMP_OFF && lampBSwitch == LAMP_OFF) //灯全部关闭
    {
        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 char BCount = 0;

    TL0 = 0x33;		//设置定时初值
	TH0 = 0xFE;		//设置定时初值 500us

    if (cnt > 10000) //5s发送一次串口信息
    {
        sendFlag = 1;
        cnt = 0;
    }
    else
    {
        cnt++;
    }
    
    if (autoFlag)
    {
        if (lampBDelay == 1)
        {
            time500us++;
            lampBSwitch = LAMP_ON;
            if (time500us >= 20000) //定时10s关闭路灯B
            {
                lampBDelay = 0;
                lampBSwitch = LAMP_OFF;
                time500us = 0;
            }
        }
    }

    if (cnt % 500 == 0) //250ms刷新一次状态
    {
        dispFlag = 1;
        if (setFlag == 1)
        {
            LCD_WriteCommand(0x0F, 0);
            LCD_WriteCommand(0x0F, 0);
        }
        else
        {
            LCD_WriteCommand(0x0C, 0);
            LCD_WriteCommand(0x0C, 0);
        }
    }
    
    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;
    }   
    
    if (lampBSwitch == LAMP_ON)
    {
        BCount++;
        if (BCount <= lampBPWM) //占空比调节
        {
            LAMPB = LAMP_ON;
        }
        else if ((BCount > lampBPWM) && (BCount <= 3))
        {
            LAMPB = LAMP_OFF;
        }
        else
        {
            BCount = 0;
        }
    }
    else
    {
        LAMPB = 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 (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] == '0')
                    {
                        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;
                    }
                }
                else if (R_buf[1] == 'B')
                {
                    if (R_buf[2] == '0')
                    {
                        lampBSwitch = LAMP_OFF;
                        lampBPWM = 0;
                    }
                    else if (R_buf[2] == '1')
                    {
                        lampBSwitch = LAMP_ON;
                        lampBPWM = 1;
                    }
                    else if (R_buf[2] == '2')
                    {
                        lampBSwitch = LAMP_ON;
                        lampBPWM = 2;
                    }
                    else if (R_buf[2] == '3')
                    {
                        lampBSwitch = LAMP_ON;
                        lampBPWM = 3;
                    }
                }
                else if (R_buf[1] == 'M')
                {
                    if (R_buf[2] == 'A')
                    {
                        autoFlag = 1;
                    }
                    else if (R_buf[2] == 'M')
                    {
                        autoFlag = 0;
                    }
                }

            }
        }
    }
    
    if (TI)
    {
        TI = 0;
    }
}

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/47976.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Kafka】Kafka的重复消费和消息丢失问题

文章目录前言一、重复消费1.1 重复消费出现的场景1.1.1 Consumer消费过程中&#xff0c;进程挂掉/异常退出1.1.2 消费者消费时间过长1.2 重复消费解决方案1.2.1 针对于消费端挂掉等原因造成的重复消费问题1.2.2 针对于Consumer消费时间过长带来的重复消费问题二、消息丢失2.1 生…

Multipass,多平台本地轻量级Linux体验!

Multipass 是由Ubuntu官方提供&#xff0c;在Linux&#xff0c;MacOS和Windows上快速生成 Ubuntu虚拟机 的工具。它提供了一个简单但功能强大的CLI&#xff0c;可让我们在本地快速进入Ubuntu系统环境并使用Linux命令&#xff0c;亦可以在本地计算机创建自己的迷你型云服务器。总…

zabbix监控网络连接状态

目录 一、环境准备 二、网络连接状态介绍 三、自定义监控key 四、给主机添加监控项 一、环境准备 1、搭建zabbix基础环境 zabbix基础环境部署参照&#xff1a;zabbix基础环境部署_桂安俊kylinOS的博客-CSDN博客 2、给web1安装nginx环境&#xff0c;并加载status模块 以…

SpringCloud学习笔记 - 链路监控 - SpringCloud Sleuth

1. Sleuth简介 在微服务框架中&#xff0c;一个由客户端发起的请求&#xff0c;在后端系统中会调用多个不同的的服务节点&#xff0c;来协同产生最后的响应结果&#xff0c;因此每一个前端请求都会形成一条复杂的分布式服务调用链路&#xff0c;链路中的任何一环出现高延时或错…

信号量Semaphore详解

前言 大家应该都用过synchronized 关键字加锁&#xff0c;用来保证某个时刻只允许一个线程运行。那么如果控制某个时刻允许指定数量的线程执行&#xff0c;有什么好的办法呢? 答案就是JUC提供的信号量Semaphore。 介绍和使用 Semaphore&#xff08;信号量&#xff09;可以用…

iwebsec靶场 SQL注入漏洞通关笔记10- 双重url编码绕过

系列文章目录 iwebsec靶场 SQL注入漏洞通关笔记1- 数字型注入_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记2- 字符型注入&#xff08;宽字节注入&#xff09;_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记3- bool注入&#xff08;布尔型盲注&#…

VF01销售开票发票金额控制增强

实施隐式增强 全部代码如下&#xff1a; method IF_EX_BADI_SD_BILLING~INVOICE_DOCUMENT_CHECK. CALL FUNCTION ‘SIPT_DOC_CHECK_SD’ EXPORTING it_xvbrk fxvbrk it_xvbrp fxvbrp it_xkomv fxkomv it_xvbpa fxvbpa IMPORTING ev_bad_data fbad_data. “”“”“”“…

【LeetCode每日一题】——171.Excel 表列序号

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【题目提示】八【时间频度】九【代码实现】十【提交结果】一【题目类别】 字符串 二【题目难度】 简单 三【题目编号】 171.Excel 表列序号 四【题目描述】 给你一个字…

SecXOps 技术发展趋势

可以预见&#xff0c;安全智能分析技术的发展&#xff0c;将全面提升网络安全 关键应用场景下威胁检测的效果&#xff0c;推动安全分析从基础级、领先级&#xff0c;向卓越级演进。根据 Gartner 2021 年十大数据和分 析技术趋势&#xff0c;XOps 的目标是利用 DevOps 最佳实践实…

计算机网络性能指标——时延,时延带宽积,RTT和利用率

时延 时延&#xff1a;数据&#xff08;报文、分组、比特流&#xff09;从网络的一端传送到另一端所需要的时间。也叫延迟或迟延&#xff0c;单位是s。 时延包括&#xff1a;发送时延&#xff08;传输时延&#xff09;,传播时延&#xff0c;排队时延&#xff0c;处理时延。 高…

2022年最新安徽食品安全管理员模拟试题及答案

百分百题库提供食品安全管理员考试试题、食品安全管理员考试预测题、食品安全管理员考试真题、食品安全管理员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 1.引起副溶血弧菌食物中毒的主要食品是&#xff1a; A.罐头食品…

公司新来一个同事,把网关系统设计的炉火纯青,万能通用,稳的一批。。

本文准备围绕七个点来讲网关&#xff0c;分别是网关的基本概念、网关设计思路、网关设计重点、流量网关、业务网关、常见网关对比&#xff0c;对基础概念熟悉的朋友可以根据目录查看自己感兴趣的部分。 什么是网关 网关&#xff0c;很多地方将网关比如成门&#xff0c; 没什么…

操作系统学习(九)死锁

目录 学习建议&#xff1a; 基本内容&#xff1a; 一、死锁的形成&#xff1a; 二、死锁的必要条件&#xff1a; 三、资源分配图&#xff1a; 四、解决死锁问题的几个策略&#xff1a; 五、死锁的防止&#xff1a; 1.互斥条件&#xff1a; 2.占有并等待资源&#xff1a…

[NCTF2019]SQLi

进来就有个弹窗 甚至给了sql语句 sqlquery : select * from users where username and passwd 先扫一下目录&#xff0c;发现有个robots.txt 提示有个hint.txt $black_list "/limit|by|substr|mid|,|admin|benchmark|like|or|char|union|substring|select|greatest|%00…

特种品种权限开通和豁免

目前国内期货市场&#xff0c;许多商品期货品种需要特殊开户流程。主要有7个&#xff08;未包含期权以及金融期货&#xff09;&#xff1a;铁矿石、PTA、20号胶、低硫燃料油、棕榈油、原油、国际铜。 想要交易铁矿石&#xff0c;首先需要拥有一个期货账户&#xff0c;其次再向…

TCL 基于 StarRocks 构建统一的数据分析平台

作者&#xff1a;陈树煌&#xff0c;TCL 实业数据管理部副总监&#xff08;本文为作者在 StarRocks Summit Asia 2022 上的分享&#xff09; 作为伴随改革开放浪潮成长起来的中国领先电子企业&#xff0c;TCL 拥有 13 万员工&#xff0c;业务遍及 160 多个国家和地区&#xff…

[附源码]计算机毕业设计springboot公共台账管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【重温C++ Primer】第一章、初识C++

目录前言一、编写一个简单的c程序二、编译、运行程序三、初识输入输出四、注释类型五、控制流5.1、循环语句&#xff1a;while for5.2、读取数量不定的输入数据5.2、if 语句六、类Reference前言 上次学C还是在大一的时候&#xff0c;一直都想好好的温习一下C。刚好最后被隔离…

CS5263数据手册|CS5263替代PS176|DP转HDMI2.0芯片设计资料

CS5263替代PS176用于DP转HDMI2.0转换器芯片&#xff0c;DP转HDMI 4K60HZ转换方案芯片&#xff0c;CS5263芯片管脚分布及定义&#xff1a; CS5263芯片DEMO功能演示板如下&#xff1a; CS5263替代PS176支持HDCP 1.4和HDCP2.3&#xff0c;带有支持HDCP中继器的片上键。用于Typec扩…

电脑怎么提取图片中的文字?

图片记录着我们生活的点点滴滴&#xff0c;比如各种办公截图、查快递单号、布置的课堂作业等等&#xff0c;都离不开这种便捷的方法。而我们有时难免需要从图片中提取想要的文字&#xff0c;总不能就靠打字打到手软吧&#xff0c;那么电脑怎么提取图片中的文字呢?有需要的朋友…