基于51单片机的教室照明灯人数计数系统proteus仿真原理图PCB
功能:
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相关推荐
- 基于51单片机的多路热电偶测温系统proteus仿真原理图PCB
功能: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶实时显示当前检测的温度值 2.循环显示多路热电偶检测值 3.当温度超过设定温度值一定范围以后,蜂鸣器报警,同时启动升温或降温装置 ...
- 基于51单片机的时钟电子秤称重系统proteus仿真原理图PCB
功能介绍: 0.本系统采用STC89C52作为单片机 1.采用LCD1602液晶显示当前时间和检测重量 2.按键可更改时间和设置超重报警阈值 3.采用HEX711和称重支架传感器获取物体重量信息,传入 ...
- 基于51单片机的智能水表水流量计流量报警器proteus仿真原理图PCB
功能: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶显示水流量/累计流量/累计流量阈值 2.按'清零'键清除累计流量,按'加''减'设置累计流量报警阈值,按'启停'启动停止水泵 3 ...
- 基于51单片机声音噪声分贝检测采集显示proteus仿真原理图PCB程序设计
硬件设计 (末尾附文件) 功能说明: 1.基于STC89C51/52(与AT89S51/52.AT89C51/52通用)单片机作为主控制器 2.采用LCD1602液晶显示屏实时显示分贝值: 3.使用小 ...
- T047基于51单片机全自动智能洗衣机烘干脱水浸泡proteus仿真原理图PCB
功能: 0.本项目采用STC89C52作为单片机系统的控制MCU 1.系统支持速洗.标准洗.浸泡洗.脱水和烘干五种模式 2.按下开关键显示"FF",此时按下启动键可进入水位设置,再 ...
- 基于51单片机的模拟心率电子脉搏器proteus仿真原理图PCB
功能介绍: 0.本系统采用STC89C52作为单片机 1.系统可检测心率脉搏值,通过LCD1602液晶实时显示测量值 2.心率脉搏超过设定阈值,蜂鸣器将报警 3.四个功能按键可修改心率脉搏上下限阈值 ...
- 基于51单片机的跑步机心率计速度测量系统proteus仿真原理图PCB
功能介绍: 0.本系统采用STC89C52作为单片机 1.系统实现监测跑步者心率和跑步机速度并显示 2.可以设置跑步速度 3.当心率低于设定下限阈值时跑步机升高速度档位 4.当心率超过设定上限阈值时跑 ...
- 基于51单片机的智能蓝牙路灯街灯控制系统proteus仿真原理图PCB
功能: 0.本系统采用STC89C52作为单片机 1.液晶实时显示时间/环境光强/工作模式 2.每隔5s向蓝牙串口发送一次信息 3.支持路灯故障检测 4.工作时间18~24时,两个路灯同时点亮,24时 ...
- 基于51单片机的水温温度PID算法控制系统proteus仿真原理图PCB
1.本系统采用STC89C52作为单片机 2.采用液晶LCD1602液晶实时显示相关数据 3.采用矩阵键盘可设置PID相关参数 4.采用L298驱动功率电阻模拟加热过程 5.当温度超过设定值的一定范围 ...
最新文章
- python集合属性方法运算_Python基础__字典、集合、运算符
- 差分定位中控软件_【最佳实践】海口美兰国际机场车辆定位管理系统应用
- POJ - 1734 Sightseeing trip(最小环+输出路径)
- 12种提升视频质量的方法
- 将字符串分割为指定长度的子字符串
- P4602 [CTSC2018]混合果汁(主席树)
- 【数字信号处理】基于DFT的滤波系列2(含MATLAB代码)
- 沃尔玛正测试货架扫描机器人,并称不会取代人类员工
- Excel在统计分析中的应用—第五章—统计指数-Part3- 综合指数(现期加权指数(帕氏指数))
- 微型计算机系统的层次关系图,1.2 计算机系统层次结构
- 上班[卒]如何面对复杂工作?
- 震动活塞式柱状取样器的使用
- 简单爬取网易云音乐评论(新手报到)
- 时间序列分析学习笔记:时间序列的预处理(平稳性检验、纯随机性检验)
- 使用QQ邮箱“邮我”组件,给我写信/意见反馈!方便他人快速给你发邮件
- 大三学生HTML个人网页作业作品——电影动漫言叶之庭(4页)带音乐
- Bandit总结3详细版
- 使用STM32CubeMX和TrueSTUDIO开发STM32系列微控制器
- 支付宝被攻击引发备付金监管问题
- 如何选择及管理腾讯云 MySQL 数据库
热门文章
- windows 下 oracle dmp 备份
- 前端使用html2canvas和jspdf生成pdf,以及清晰度问题
- 计算机原理 doc,计算机原理资料.doc
- chatgpt赋能python:如何在Python中取消换行?
- C/C++宏定义连接符“\”
- termux python pandas_Termux-config
- Termux Api
- java语言类间继承关系是,Java语言类间的继承关系是( )。
- 手把手教你微信开发者工具引入Vant
- html小时分钟秒选择器,时间选择器.html