目录
一、主要功能
1、LCD1602显示日期、时间、光照强度;
 2、采用DS1302运行系统时间;
 3、采用光敏电阻+PCF8591检测光照;
 4、按键可修改系统时间、工作开始/结束时间、光照阈值;
 5、工作时间:路灯点亮,
 6、非工作时间:光照强度低于光照阈值,路灯点亮;
二、使用步骤
基于51单片机的智能路灯系统设计结合光控、时控、等多种功能,以实现节能和智能化管理,通过按键来切换模式和时间以及光敏阈值设置。
三、硬件资源
1、51单片机核心模块
 2、按键模块
 3、时钟模块
 4、蜂鸣器模块
 5、PCF8591模块
 6、LCD1602显示模块
四、软件设计
#include<reg52.h>
 #include <string.h>
 #include <intrins.h>
 #define uint unsigned int
 #define uchar unsigned char
//液晶屏的与C51之间的引脚连接定义(显示数据线接C51的P0口)
 sbit en=P2^7;
 sbit rw=P2^6;   //如果硬件上rw接地,就不用写这句和后面的rw=0了
 sbit rs=P2^5;
 sbit I2C_SCL = P1^3;//I2C通信的两个引脚
 sbit I2C_SDA = P1^4;
 //DS1302时钟芯片与C51之间的引脚连接定义
 sbit SCLK = P1^0;
 sbit IO   = P1^1;
 sbit RST  = P1^2;
sbit ACC0=ACC^0;
 sbit ACC7=ACC^7;
 
 sbit led_1 = P3^7;
uchar code tab1[]= {"20  -  -        "};     //年显示的固定字符
 uchar code tab2[]= {"  :  :          "};        //时间显示的固定字符
 uchar count=0;                    
 uchar Led_count=0;                         
 uchar light;                           
 uchar light_limit=100;                        
 uchar Mode_flag = 0;
 void Timer0Init(void);       
 void uart_init(); 
 void delay(uint xms);//延时函数,有参函数
 void write_1602com(uchar com);
 void write_1602dat(uchar dat);
 void write_ShouNum(uchar x,uchar y,uchar dat);
 void lcd_init();//***液晶初始化函数****
 uchar read_byte();//读一个字节
 void write_byte(uchar dat);//写一个字节
 void I2C_delay()//I2C延时函数
 {
     _nop_();
     _nop_();
     _nop_();
     _nop_();
 }
void I2C_start()//I2C起始信号
 {
     I2C_SDA = 1;
     I2C_SCL = 1;
     I2C_delay();
     I2C_SDA = 0;
     I2C_delay();
     I2C_SCL = 0;
     I2C_delay();
 }
void I2C_stop()//I2C停止信号
 {
     I2C_SDA = 0;
     I2C_SCL = 0;
     I2C_delay();
     I2C_SCL = 1;
     I2C_delay();
     I2C_SDA = 1;
     I2C_delay();
 }
bit I2C_write(uint dat)//I2C写一个字节
 {
     bit ack = 0;
     uint mask = 0;
     for(mask=0x80;mask!=0;mask>>=1)
     {
         if((mask&dat) == 0)
             I2C_SDA = 0;
         else
             I2C_SDA = 1;
         I2C_delay();
         I2C_SCL = 1;
         I2C_delay();
         I2C_SCL = 0;
         I2C_delay();
     }
     I2C_SDA = 1;
     I2C_delay();
     I2C_SCL = 1;
     I2C_delay();
     ack = I2C_SDA;
     I2C_delay();
     I2C_SCL = 0;
     I2C_delay();
     
     return (~ack);    
 }
uint I2C_read_ACK()//I2C读一个字节,并发送应答位
 {
     uint dat = 0;
     uint mask = 0;
     I2C_SDA = 1;
     for(mask=0x80;mask!=0;mask>>=1)
     {
         if(I2C_SDA == 0)
             dat = dat & (~mask);
         else
             dat = dat | mask;
         I2C_delay();
         I2C_SCL = 1;
         I2C_delay();
         I2C_SCL = 0;
         I2C_delay();
     }
     I2C_SDA = 0;
     I2C_delay();
     I2C_SCL = 1;
     I2C_delay();
     I2C_SCL = 0;
     I2C_delay();
    return dat;
 }
uint I2C_read_NACK()//I2C读一个字节,并发送非应答位
 {
     uint dat = 0;
     uint mask = 0;
     I2C_SDA = 1;
     for(mask=0x80;mask!=0;mask>>=1)
     {
         if(I2C_SDA == 0)
             dat = dat & (~mask);
         else
             dat = dat | mask;
         I2C_delay();
         I2C_SCL = 1;
         I2C_delay();
         I2C_SCL = 0;
         I2C_delay();
     }
     I2C_SDA = 1;
     I2C_delay();
     I2C_SCL = 1;
     I2C_delay();
     I2C_SCL = 0;
     I2C_delay();
    return dat;
 }
uint get_ADC_vaule(uint chn)//获取AD值
 {
     uint value = 0;
     I2C_start();//I2C起始信号
     if(!I2C_write(0X90))//写入PCF8591地址及读写选择位为写
     {
         I2C_stop();
         return 0;
     }
 //    I2C_write(0X40 | chn);//写入PCF8591通道0
     I2C_write(0x00 | chn);//写入PCF8591通道0
     I2C_start();//I2C起始信号
     I2C_write(0x48<<1 | 0x01);
     I2C_read_ACK();//提供转换所需的时钟信号
     value = I2C_read_NACK();//读取上一次转换的结果
     I2C_stop();//I2C结束信号
    return value;
 }
 //*******************主函数**************************
 void main()
 {
    lcd_init();      //调用液晶屏初始化子函数
     Timer0Init();   //定时器0初始化
 //    ds1302_init();   //调用DS1302时钟的初始化子函数
     while(1)  //无限循环下面的语句:
     {        
         qiehaun();//模式切换
         keyscan();//时间设置
         set_work_time();                //设定工作时间
         set_limit_light();                //设定光照阈值
         light = 255-get_ADC_vaule(0);                    //读取ADC数值     
     }
 }
五、实验现象
演示视频:

