写点什么

基于 51 单片机室内灯光控制系统

作者:DS小龙哥
  • 2022 年 2 月 20 日
  • 本文字数:4093 字

    阅读完需:约 13 分钟

1. 功能介绍

这是基于 STC89C52 单片机设计的灯光控制系统,实现对室内灯光的控制,采集光敏传感器,红外线热释电传感器,声音传感器,光照照度传感器等数据进行处理,完成室内灯光的智能控制。


支持的功能与设计要求:


1、室内光控系统的传感部分主要是对环境数据、室内光强、室内噪声、是否有物体接近等进行采集,需要使用单片机模块、人体红外传感器、光敏传感器和噪音传感器;


2、整个室内灯光控制系统的应用主要集中在灯具的控制上,主要是控制灯具的光强、开闭。系统采用智能传感器技术和单片机技术,有利于系统的智能化;


3、系统包括三个主要流程。感应器感应到人体点亮灯,感应器感应到光强改变灯的亮度,感应器感应到一定音量点亮灯。在控制系统中,各传感器设备和控制单元最终以指定方式与主控制器相连,实现各单元之间的通讯和控制;


声音传感器作用是采集当前环境的声音,传递给单片机进行处理,通过预设的阀值进行分析,判断是否有人过来,实现声控开灯的功能;


热释电人体采集传感器可以通过红外功能探测周围是否有发热的物体,正常人体会发出红外光的,当传感器检测到周围指定范围内有人活动时,会通过高点电平的方式通知单片机,单片机根据预先设置的逻辑完成开灯操作。


光敏传感器用于采集周边环境的光强度,通过光强区分白天黑夜,如果光的环境较暗,就需要开灯,如果较亮就需要关灯,单片机得到光强之后通过处理,配合其他传感器的数据,最终判断是否需要开灯关灯


完整项目资料包下载地址: https://download.csdn.net/download/xiaolong1126626497/75319474



2. 硬件介绍

3. 设计思路与相关硬件介绍

3.1 主程序设计

程序的主要功能: STC89C52 单片机作为核心器件,首先初始化 BH1750 光敏传感器,再初始化定时器,开始进行定时器扫描工作。在主函数循环里不断读取光敏、声音传感器、人体感应传感器的数据设置开关灯的状态,以便对采集到的数据作进一步处理。当定时器中断产生后,在定时器中断服务函数里进行处理 LED 的状态。



主程序框架图如下所示:



定时器的运行流程图:


3.2 光敏传感器

光敏传感器采用 BH1750,这是一个 IIC 总线接口的数字光敏传感器,需要封装 IIC 标准的函数接口,完成数据读取。


IIC 总线的通信过程分别由开始信号、结束信号、发送数据、响应信号、接收数据五个部分构成。当 SCL 时钟线为高电平的时候,SDA 数据线不允许变化,当 SCL 时钟线为低电平的时候,SDA 数据线可以在 0 和 1 之间任意变化。 只有当 SCL 时钟线为高电平的时候,IIC 总线电路才能对 SDA 数据线上的电平(0 或 1)进行读取,当 SCL 时钟线为低电平的时候,无论 SDA 数据是高还是低电平,IIC 总线都不对 SDA 数据线进行采样读取。



BH1750 光敏传感器流程图设计:


3.3 声音检测、人体感应传感器

声音检测和人体感应传感器输出的都是 0 和 1,所以代码比较简单,和按键原理一样,读取输入的电平即可,灵敏度可以调整模块上面的电位器。




下面是程序检测的流程图:


4. 项目代码

4.1 BH1750 传感器代码

//------------------------------------void Delay5us();void Delay5ms();void BH1750_Start();                    //起始信号void BH1750_Stop();                     //停止信号void BH1750_SendACK(bit ack);           //应答ACKbit  BH1750_RecvACK();                  //读ackvoid BH1750_SendByte(BYTE dat);         //IIC单个字节写BYTE BH1750_RecvByte();                 //IIC单个字节读      
/**************************************延时5微秒(STC90C52RC@12M)不同的工作环境,需要调整此函数,注意时钟过快时需要修改当改用1T的MCU时,请调整此延时函数**************************************/void Delay5us(){ _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();}
/**************************************延时5毫秒(STC90C52RC@12M)不同的工作环境,需要调整此函数当改用1T的MCU时,请调整此延时函数**************************************/void Delay5ms(){ WORD n = 560;
while (n--);}
/**************************************起始信号**************************************/void BH1750_Start(){ SDA = 1; //拉高数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 0; //产生下降沿 Delay5us(); //延时 SCL = 0; //拉低时钟线}
/**************************************停止信号**************************************/void BH1750_Stop(){ SDA = 0; //拉低数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 1; //产生上升沿 Delay5us(); //延时}
/************************************** 发送应答信号入口参数:ack (0:ACK 1:NAK)**************************************/void BH1750_SendACK(bit ack){ SDA = ack; //写应答信号 SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时}
/**************************************接收应答信号**************************************/bit BH1750_RecvACK(){ SCL = 1; //拉高时钟线 Delay5us(); //延时 CY = SDA; //读应答信号 SCL = 0; //拉低时钟线 Delay5us(); //延时
return CY;}
/**************************************向IIC总线发送一个字节数据**************************************/void BH1750_SendByte(BYTE dat){ BYTE i;
for (i=0; i<8; i++) //8位计数器 { dat <<= 1; //移出数据的最高位 SDA = CY; //送数据口 SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时 } BH1750_RecvACK();}
/**************************************从IIC总线接收一个字节数据**************************************/BYTE BH1750_RecvByte(){ BYTE i; BYTE dat = 0;
SDA = 1; //使能内部上拉,准备读取数据, for (i=0; i<8; i++) //8位计数器 { dat <<= 1; SCL = 1; //拉高时钟线 Delay5us(); //延时 dat |= SDA; //读数据 SCL = 0; //拉低时钟线 Delay5us(); //延时 } return dat;}
//*********************************
void Single_Write_BH1750(uchar REG_Address){ BH1750_Start(); //起始信号 BH1750_SendByte(SlaveAddress); //发送设备地址+写信号 BH1750_SendByte(REG_Address); //内部寄存器地址, // BH1750_SendByte(REG_data); //内部寄存器数据, BH1750_Stop(); //发送停止信号}

//*********************************************************////连续读出BH1750内部数据////*********************************************************void Multiple_read_BH1750(void){ uchar i; BH1750_Start(); //起始信号 BH1750_SendByte(SlaveAddress+1); //发送设备地址+读信号 for (i=0; i<3; i++) //连续读取2个地址数据,存储中BUF { BUF[i] = BH1750_RecvByte(); //BUF[0]存储0x32地址中的数据 if (i == 3) {
BH1750_SendACK(1); //最后一个数据需要回NOACK } else { BH1750_SendACK(0); //回应ACK } }
BH1750_Stop(); //停止信号 Delay5ms();}

//初始化BH1750,根据需要请参考pdf进行修改****void Init_BH1750(){ Single_Write_BH1750(0x01);
}
复制代码

4.2 定时器代码

void Timer0Interrupt(void) interrupt 1{    TL0 = 0xAE;    //设置定时初始值  TH0 = 0xFB;    //设置定时初始值    count++;  timecount++;  if(timecount>20000)timecount=20000;  

if(timecount<12000) { if(count<out) { LED = 0; } else if(count<100) { LED = 1; } else count=0; } else { LED = 1; }}
复制代码

4.3 main 函数代码

void main(){  delay300ms();      //延时300ms    Init_BH1750();       //初始化BH1750    TL0 = 0xAE;    //设置定时初始值  TH0 = 0xFB;    //设置定时初始值  EA = 1;  ET0 = 1;  TR0 = 1;
ADDR = 0; LED = 1; while(1) { unsigned char disbuff[9]={0}; if(RT == 1 || SY == 0) { timecount = 0; Single_Write_BH1750(0x01); // power on Single_Write_BH1750(0x10); // H- resolution mode
delay_nms(180); //延时180ms
Multiple_Read_BH1750(); //连续读出数据,存储在BUF中
dis_data=BUF[0]; dis_data=(dis_data<<8)+BUF[1];//合成数据,即光照数据 out = dis_data/80; if(out>100)out=100; if(out<10)out=10; delay_nms(100); } }}
复制代码


发布于: 刚刚阅读数: 2
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022.01.06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
基于51单片机室内灯光控制系统