功能:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时显示当前时间/温度/教室人数
2.自动模式下,在工作时间内(1824时),当环境黑暗时,根据进入教室的人数开启14盏灯,其余时候灯光关闭
3.手动模式下,可通过按键开启灯光
4.按键可设置当前时间/工作模式/工作时间
5.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:

PCB :

主程序:

#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned intuchar time_data[7];
uchar code write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};       //数据的地址
uchar code read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};uchar code table1[]="C: 00|2000/00/00";
uchar code table2[]="T: 00|00:00:00 0";
uchar code table3[]="                ";           //清屏内容
uchar code table4[]="  Set Real Time ";
uchar code table5[]="  Set Open Time ";
uchar code table6[]="   Start Time:  ";
uchar code table7[]="    00:00:00    ";
uchar code table8[]="    End Time:   ";
uchar code table9[]="Date: 2000/00/00";
uchar code table0[]="Time: 00:00:00 0";bit Adjust;             //调节标志位,=1表示进入调节模式,=0是正常模式
bit Auto_flg;         //自动模式标志位,=1表示手动模式,=0是自动模式
sbit rs=P2^7;        //LCD1602
// sbit rw=P1^1;         //LCD1602
sbit e=P2^6;         //LCD1602
sbit sck=P2^0;       //时钟端口
sbit io=P2^1;        //时钟端口
sbit rst=P2^2;       //时钟端口
sbit SELT =P1^6;     //选择键
sbit ENTER=P1^7;     //确认键
sbit UP   =P3^0;     //加键
sbit DOWN =P3^1;     //减键
sbit MODE =P3^2;     //切换按键接口
sbit SWITCH=P3^3;    //手动开关
sbit AUTO_LED=P2^4;      //自动模式灯接口
sbit HAND_LED=P2^3;      //手动灯接口
sbit LAMP1=P3^4;     //灯接口
sbit LAMP2=P3^5;     //灯接口
sbit LAMP3=P3^6;     //灯接口
sbit LAMP4=P3^7;     //灯接口
sbit LIGHT1=P1^0;    //光线检测端口
sbit IN1=P1^1;
sbit OUT1=P1^2;
sbit DQ=P1^5;        //温度数据口
uchar Select_num;     //选择按键按下次数
uchar Enter_num;      //确认按键按下次数
uchar Switch_num;     //手动开关按键按下次数
float Year,Month,Day,Hour,Minute,Second;            //时间设置值
uchar Week;
float Hour_H,Minute_H,Second_H;                     //设置开始时间
float Hour_L,Minute_L,Second_L;                     //设置结束时间
int Value1;                                         //人数
uchar IN1_flag=0;
uchar OUT1_flag=0;
uint Count;           //T0定时器中断计数次数
uchar Miao;int temperature;                                 //全局变量 温度void read_rtc();/**************************************************LCD1602显示*******************************************************************/
void delay1(uint z)           //延时函数
{uint x,y;for(x=z;x>0;x--)for(y=10;y>0;y--);
}void write_com(uchar com)           //写指令函数
{//rw=0;delay1(5);rs=0;delay1(5);e=1;delay1(5);P0=com;delay1(5);e=0;delay1(5);
}void write_date(uchar date)            //写数据函数
{                                   //rw=0;delay1(5);rs=1;delay1(5);e=1;delay1(5);P0=date;delay1(5);e=0;delay1(5);
}void init()                            //初始化函数
{   uchar num;Year=17;Month=1;Day=1;Hour=15;Minute=30;Second=50;Week=1;Hour_H=22;Minute_H=0;Second_H=0;Hour_L=18;Minute_L=0;Second_L=0;e=0;                           // 时序表e初始为0write_com(0x38);             //设置16*2显示,5*7点阵,8位数据接口write_com(0x0c);               //设置光标write_com(0x06);              //光标自动加1,光标输入方式write_com(0x01);             //清屏write_com(0x80);                //设置初始显示位置for(num=0;num<16;num++){write_date(table1[num]);delay1(5);}write_com(0x80+0x40);for(num=0;num<16;num++){write_date(table2[num]);delay1(5);}
}void SetTime_dispaly(uchar add,uchar dat)   //第一个:参数的地址,第二个:参数的内容
{uchar shi,ge;shi=dat/10;                          //把十位提取出来ge=dat%10;                            //把个位提取出来write_com(add);                        //要写的地址write_date(0x30+shi);               //十位的内容   1602字符库write_date(0x30+ge);              //个位的内容   1602字符库
}void Week_dispaly(uchar add,uchar dat) //第一个:参数的地址,第二个:参数的内容
{write_com(add);                        //要写的地址if (dat == 0){write_date(0x30+7);             //十位的内容   1602字符库}else{write_date(0x30+dat);               //十位的内容   1602字符库}}
void Date_dispaly(uchar add,uchar dat)   //第一个:参数的地址,第二个:参数的内容
{uchar shi,ge;shi=dat/16;                          //把十位提取出来ge=dat%16;                            //把个位提取出来write_com(add+3);                 //要写的地址write_date(0x30+shi);               //十位的内容   1602字符库write_date(0x30+ge);              //个位的内容   1602字符库
}void LCD_Clean(uchar i)                    //液晶屏清除显示
{uchar num;if(i==1){write_com(0x80);              //设置初始显示位置for(num=0;num<16;num++)         //显示第一行内容{write_date(table3[num]);delay1(1);}}if(i==2){write_com(0x80+0x40);for(num=0;num<16;num++)            //显示第二行内容{write_date(table3[num]);delay1(1);}}
}void LCD_Display_String(unsigned char line,unsigned char *string)
{                                       //液晶屏显示内容,把要显示的内容写到对应的位置unsigned char i;unsigned char address=0;if(line==1){address=0x80;                    //0X80是第1行的第1个位置  ,0x81第2位}else if(line==2){address=0x80+0x40;              //0X80+0x40是第2行的第1个位置  ,0X80+0x40+1是第2行第2位}for(i=0;i<16;i++){write_com(address);write_date(string[i]);address++;}
}
/**********************************DS1302时钟***************************************/
void Time_Display(void)
{read_rtc();Date_dispaly(0x80+0x40+9,time_data[6]);  //显示秒Date_dispaly(0x80+0x40+6,time_data[5]);    //显示分Date_dispaly(0x80+0x40+3,time_data[4]);  //显示时Date_dispaly(0x80+11,time_data[3]);       //显示日Date_dispaly(0x80+8,time_data[2]);        //显示月Week_dispaly(0x80+0x40+15,time_data[1]-1); //显示周Date_dispaly(0x80+5,time_data[0]);      //显示年//    Year/10*16+Year%10Hour=time_data[4]/16*10+time_data[4]%16;;Minute=time_data[5]/16*10+time_data[5]%16;;Second=time_data[6]/16*10+time_data[6]%16;;
}void write_ds1302_byte(uchar dat)
{uchar i;for(i=0;i<8;i++){sck=0;io=dat&0x01;                       //准备数据,从最低位开始dat=dat>>1;sck=1;}
}void write_ds1302(uchar add,uchar dat)
{rst=0;_nop_();                        //CPU原地踏步sck=0;_nop_();rst=1;_nop_();write_ds1302_byte(add);          //传地址write_ds1302_byte(dat);            //传数据rst=0;                            //不受其他影响_nop_();io=1;                         //释放sck=1;
}uchar read_ds1302(uchar add)
{uchar i,value;rst=0;_nop_();  //CPU原地踏步sck=0;_nop_();rst=1;_nop_();write_ds1302_byte(add);for(i=0;i<8;i++){value=value>>1;sck=0;if(io)value=value|0x80;sck=1;}rst=0;_nop_();sck=0;_nop_();sck=1;io=1;return value;
}void set_rtc()                   //设置时间
{uchar i,j;for(i=0;i<7;i++)            //转换BCD码{j=time_data[i]/10;time_data[i]=time_data[i]%10;time_data[i]=time_data[i]+j*16;}write_ds1302(0x8e,0x00);     //去除写保护for(i=0;i<7;i++){write_ds1302(write_add[i],time_data[i]);}write_ds1302(0x8e,0x80);      //加写保护
}void read_rtc()
{uchar i;for(i=0;i<7;i++){time_data[i]=read_ds1302(read_add[i]); //最终读出来的数 16进制}Year=time_data[0]/16*10+time_data[0]%16;Month=time_data[2]/16*10+time_data[2]%16;Day=time_data[3]/16*10+time_data[3]%16;Hour=time_data[4]/16*10+time_data[4]%16;Minute=time_data[5]/16*10+time_data[5]%16;Second=time_data[6]/16*10+time_data[6]%16;Week=time_data[1]/16*10+time_data[1]%16-1;if (Week == 0){Week = 7;}
}/*************************************************按键****************************************************************/
void Keyscan(void)
{if(SELT==0){delay1(2);if(SELT==0){while(!SELT);Select_num++;                 //选择键按下一次Adjust=1;                     //进入调节模式            }if(Select_num==1){LCD_Clean(1);LCD_Clean(2);LCD_Display_String(1,table4);LCD_Display_String(2,table5);write_com(0x80+0);                //写 >>write_date(0x3e);write_com(0x80+1);                //写 >>write_date(0x3e);Enter_num=0;}if(Select_num==2){LCD_Clean(1);LCD_Clean(2);LCD_Display_String(1,table4);LCD_Display_String(2,table5);write_com(0x80+0x40+0);                //写 >>write_date(0x3e);write_com(0x80+0x40+1);              //写 >>write_date(0x3e);Enter_num=0;}if(Select_num==3){LCD_Clean(1);LCD_Clean(2);LCD_Display_String(1,table1);LCD_Display_String(2,table2);Select_num=0;Enter_num=0;                  Adjust=0;}write_com(0x0c);                                 //光标不再闪烁Enter_num=0;}if(ENTER==0){delay1(2);if(ENTER==0){while(!ENTER);Enter_num++;}if(Select_num==1)                  //设置实时时间{if(Enter_num==1){LCD_Clean(1);LCD_Clean(2);LCD_Display_String(1,table9);LCD_Display_String(2,table0);SetTime_dispaly(0x80+8,Year);SetTime_dispaly(0x80+11,Month);SetTime_dispaly(0x80+14,Day);SetTime_dispaly(0x80+0x40+6,Hour);SetTime_dispaly(0x80+0x40+9,Minute);SetTime_dispaly(0x80+0x40+12,Second);Week_dispaly(0x80+0x40+15,Week);write_com(0x80+8);          //光标闪烁地址,停留在年的位置上                    write_com(0x0f);            //光标闪烁}if(Enter_num==2){write_com(0x80+11);          //光标闪烁地址,停留在月的位置上                    write_com(0x0f);            //光标闪烁}if(Enter_num==3){write_com(0x80+14);          //光标闪烁地址,停留在日的位置上                    write_com(0x0f);            //光标闪烁}if(Enter_num==4){write_com(0x80+0x40+6);     //光标闪烁地址,停留在时的位置上                    write_com(0x0f);            //光标闪烁}if(Enter_num==5){write_com(0x80+0x40+9);     //光标闪烁地址,停留在分的位置上                    write_com(0x0f);            //光标闪烁}if(Enter_num==6){write_com(0x80+0x40+12);    //光标闪烁地址,停留在秒的位置上                    write_com(0x0f);            //光标闪烁}if(Enter_num==7){write_com(0x80+0x40+15);    //光标闪烁地址,停留在星期的位置上                   write_com(0x0f);            //光标闪烁}if(Enter_num==8){Enter_num=0;write_com(0x0c);         //光标不再闪烁LCD_Clean(1);LCD_Clean(2);LCD_Display_String(1,table1);LCD_Display_String(2,table2);time_data[0]=Year;///10*16+Year%10;time_data[1]=Week+1;///10*16+Week%10;time_data[2]=Month;///10*16+Month%10;time_data[3]=Day;///10*16+Day%10;time_data[4]=Hour;///10*16+Hour%10;time_data[5]=Minute;///10*16+Minute%10;time_data[6]=Second;///10*16+Second%10;set_rtc();                     //设置时间Select_num=0;Adjust=0;}}if(Select_num==2)                    //设置开关锁时间{if(Enter_num==1){LCD_Clean(1);LCD_Clean(2);LCD_Display_String(1,table6);LCD_Display_String(2,table7);SetTime_dispaly(0x80+0x40+4,Hour_L);SetTime_dispaly(0x80+0x40+7,Minute_L);SetTime_dispaly(0x80+0x40+10,Second_L);write_com(0x80+0x40+4);       //光标闪烁地址,停留在时的位置上                    write_com(0x0f);            //光标闪烁}if(Enter_num==2){write_com(0x80+0x40+7);     //光标闪烁地址,停留在分的位置上                    write_com(0x0f);            //光标闪烁}if(Enter_num==3){write_com(0x80+0x40+10);    //光标闪烁地址,停留在秒的位置上                    write_com(0x0f);            //光标闪烁}if(Enter_num==4){write_com(0x0c);          //光标不再闪烁LCD_Clean(1);LCD_Clean(2);LCD_Display_String(1,table8);LCD_Display_String(2,table7);    SetTime_dispaly(0x80+0x40+4,Hour_H);SetTime_dispaly(0x80+0x40+7,Minute_H);SetTime_dispaly(0x80+0x40+10,Second_H);write_com(0x80+0x40+4);        //光标闪烁地址,停留在时的位置上                    write_com(0x0f);            //光标闪烁}if(Enter_num==5){write_com(0x80+0x40+7);     //光标闪烁地址,停留在分的位置上                    write_com(0x0f);            //光标闪烁}if(Enter_num==6){write_com(0x80+0x40+10);    //光标闪烁地址,停留在秒的位置上                    write_com(0x0f);            //光标闪烁}     if(Enter_num==7){Enter_num=0;write_com(0x0c);            //光标不再闪烁LCD_Clean(1);LCD_Clean(2);LCD_Display_String(1,table1);LCD_Display_String(2,table2);Select_num=0;Adjust=0;}}}

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

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

基于51单片机的教室照明灯人数计数系统proteus仿真原理图PCB相关推荐

  1. 基于51单片机的多路热电偶测温系统proteus仿真原理图PCB

    功能: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶实时显示当前检测的温度值 2.循环显示多路热电偶检测值 3.当温度超过设定温度值一定范围以后,蜂鸣器报警,同时启动升温或降温装置 ...

  2. 基于51单片机的时钟电子秤称重系统proteus仿真原理图PCB

    功能介绍: 0.本系统采用STC89C52作为单片机 1.采用LCD1602液晶显示当前时间和检测重量 2.按键可更改时间和设置超重报警阈值 3.采用HEX711和称重支架传感器获取物体重量信息,传入 ...

  3. 基于51单片机的智能水表水流量计流量报警器proteus仿真原理图PCB

    功能: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶显示水流量/累计流量/累计流量阈值 2.按'清零'键清除累计流量,按'加''减'设置累计流量报警阈值,按'启停'启动停止水泵 3 ...

  4. 基于51单片机声音噪声分贝检测采集显示proteus仿真原理图PCB程序设计

    硬件设计 (末尾附文件) 功能说明: 1.基于STC89C51/52(与AT89S51/52.AT89C51/52通用)单片机作为主控制器 2.采用LCD1602液晶显示屏实时显示分贝值: 3.使用小 ...

  5. T047基于51单片机全自动智能洗衣机烘干脱水浸泡proteus仿真原理图PCB

    功能: 0.本项目采用STC89C52作为单片机系统的控制MCU 1.系统支持速洗.标准洗.浸泡洗.脱水和烘干五种模式 2.按下开关键显示"FF",此时按下启动键可进入水位设置,再 ...

  6. 基于51单片机的模拟心率电子脉搏器proteus仿真原理图PCB

    功能介绍: 0.本系统采用STC89C52作为单片机 1.系统可检测心率脉搏值,通过LCD1602液晶实时显示测量值 2.心率脉搏超过设定阈值,蜂鸣器将报警 3.四个功能按键可修改心率脉搏上下限阈值 ...

  7. 基于51单片机的跑步机心率计速度测量系统proteus仿真原理图PCB

    功能介绍: 0.本系统采用STC89C52作为单片机 1.系统实现监测跑步者心率和跑步机速度并显示 2.可以设置跑步速度 3.当心率低于设定下限阈值时跑步机升高速度档位 4.当心率超过设定上限阈值时跑 ...

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

    功能: 0.本系统采用STC89C52作为单片机 1.液晶实时显示时间/环境光强/工作模式 2.每隔5s向蓝牙串口发送一次信息 3.支持路灯故障检测 4.工作时间18~24时,两个路灯同时点亮,24时 ...

  9. 基于51单片机的水温温度PID算法控制系统proteus仿真原理图PCB

    1.本系统采用STC89C52作为单片机 2.采用液晶LCD1602液晶实时显示相关数据 3.采用矩阵键盘可设置PID相关参数 4.采用L298驱动功率电阻模拟加热过程 5.当温度超过设定值的一定范围 ...

最新文章

  1. python集合属性方法运算_Python基础__字典、集合、运算符
  2. 差分定位中控软件_【最佳实践】海口美兰国际机场车辆定位管理系统应用
  3. POJ - 1734 Sightseeing trip(最小环+输出路径)
  4. 12种提升视频质量的方法
  5. 将字符串分割为指定长度的子字符串
  6. P4602 [CTSC2018]混合果汁(主席树)
  7. 【数字信号处理】基于DFT的滤波系列2(含MATLAB代码)
  8. 沃尔玛正测试货架扫描机器人,并称不会取代人类员工
  9. Excel在统计分析中的应用—第五章—统计指数-Part3- 综合指数(现期加权指数(帕氏指数))
  10. 微型计算机系统的层次关系图,1.2 计算机系统层次结构
  11. 上班[卒]如何面对复杂工作?
  12. 震动活塞式柱状取样器的使用
  13. 简单爬取网易云音乐评论(新手报到)
  14. 时间序列分析学习笔记:时间序列的预处理(平稳性检验、纯随机性检验)
  15. 使用QQ邮箱“邮我”组件,给我写信/意见反馈!方便他人快速给你发邮件
  16. 大三学生HTML个人网页作业作品——电影动漫言叶之庭(4页)带音乐
  17. Bandit总结3详细版
  18. 使用STM32CubeMX和TrueSTUDIO开发STM32系列微控制器
  19. 支付宝被攻击引发备付金监管问题
  20. 如何选择及管理腾讯云 MySQL 数据库

热门文章

  1. windows 下 oracle dmp 备份
  2. 前端使用html2canvas和jspdf生成pdf,以及清晰度问题
  3. 计算机原理 doc,计算机原理资料.doc
  4. chatgpt赋能python:如何在Python中取消换行?
  5. C/C++宏定义连接符“\”
  6. termux python pandas_Termux-config
  7. Termux Api
  8. java语言类间继承关系是,Java语言类间的继承关系是(    )。
  9. 手把手教你微信开发者工具引入Vant
  10. html小时分钟秒选择器,时间选择器.html