基于51单片机汽车智能灯光控制系统设计

本文详细介绍了使用51单片机实现的汽车智能灯光控制系统,包括光敏传感器、超声波测距、LCD1602显示和按键控制等功能。设计过程涉及程序编写、硬件选型及原理图设计。
摘要由CSDN通过智能技术生成

基于51单片机汽车智能灯光控制系统

(仿真+程序+原理图+PCB+设计报告)

功能介绍

具体功能:

1.光敏传感器测光线,低于设定值开启灯光;

2.使用超声波测距,低于设定距离开近光,高于设定距离转换成远光;

3.LCD1602实时显示监控到的光亮度和距离;

4.按键可以设置光亮和距离阈值;

5.可以切换成手动模式,手动控制灯光;

​演示视频:

基于51单片机汽车智能灯光控制系统设计 

#include <reg52.h>
#include "LCD1602.H"
#include "eeprom52.H"
#include "adc0832.H"			

uint time=0;

int S=0;	  //测量距离
sbit  echo=P2^3;				   //超声波接口定义
sbit  trig=P2^4;	
bit ir_ok=0;		//定时测量标志位
sbit led1=P1^4;
sbit led2=P1^6;	  //手动自动LED指示灯灯接口定义
sbit LED_1=P2^0;
sbit LED_2=P2^1; //远近光灯接口定义
sbit key1=P3^2;	 //设置
sbit key2=P3^3;	 //增加
sbit key3=P3^4;	 //减小
sbit key4=P3^5;	 //手动/自动
sbit key5=P3^6;	 //远光	 //近光
sbit key6=P3^7;	 //手动关灯

bit key1_flag=0;
bit key2_flag=0;
bit key3_flag=0;
bit key4_flag=0;
bit key5_flag=0;
bit key6_flag=0;	//按键标志位

uchar sec1=0,sec2=0,ms=0; //sec1、sec2按键长按标志位,ms定时自加变量
uchar light_set=50,S_set=30,state;	//光照设置值,距离设置值,设置变量
bit s0;	 //液晶闪烁效果标志位
bit memory_flag=0; //存储标志位
uchar light=0,ad_count;	  //光照值,滤波用累加变量
uint ad_dat=0;	  //ad数据
uchar beam;//0关闭 1近光 2远光
bit A_M=0;//0手动

uchar count; //中断累加变量
long int distance; //测量所得距离

void memory()  //存储函数
 {
   SectorErase(0x2000);	 //清扇区
   byte_write(0x2000,S_set/256);
   byte_write(0x2001,S_set%256);  //往扇区存设置距离
   byte_write(0x2002,light_set);  //往扇区存设置光强
 } 
void read_memory()	//读存储函数
 {
  S_set=byte_read(0x2000)*256+byte_read(0x2001);  //将存的数据读出来
  light_set=byte_read(0x2002); 		//
  if(S_set>400||light_set>100)	//判断数据不正常,重新赋值
   {
     S_set=30;
	 light_set=50;
   }
 }
void trigger()	   //测量启动函数
{
	trig=0;
	_nop_();   //空语句,用来占用时间
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	trig=1; 
}
void delayt(uint x)	//延时函数
{
	uchar j;
	while(x-- > 0)
	{
		for(j = 0;j < 125;j++)
		{
			;
		}
	}
}
void init_measuring()
{
	trig=1;
	echo=1;
	count=0;
}
void measuring() 		      //启动测距信号
{
	uchar l;
	uint h,y;
	TR0 = 1;
	while(echo==1)
	{
	;
	} 
	TR0 = 0;
	l = TL0;
	h = TH0;
	y = (h << 8) + l;
	y = y - 0xfc66;//us部分
	distance = y + 1000 * count;//计算总时间,单位是微秒
	TL0 = 0x66;
	TH0 = 0xfc;
	delayt(30);
	S = 3453* distance / 200000;//原始为:(0.34毫米/us)*时间/2// 
}

void interrupt_int()  //定时器初始化
 {
   TMOD=0x11;		//定时器0,定时器1都用模式1
   TH0=0x00;
   TL0=0x00;	  //定时器0赋初值0
   ET0=1;		   //使能定时器0
   TR0=0;		  //先不打开定时器0

   TH1=0x3c;
   TL1=0xb0;	//定时器1赋值50ms
   ET1=1;
   TR1=1;	   //打开定时器1
  
   EA=1;	 //打开总中断
 }

void display()	//显示函数
 {
   if(state==0)	   //如果是非设置状态
   {
	   LCD1602_write(0,0x80); //第一行
	   LCD1602_writebyte("distance:"); //显示距离
	   if(S>99) LCD1602_write(1,0x30+S/100%10);
	   else LCD1602_writebyte(" ");
	   if(S>9) LCD1602_write(1,0x30+S/10%10);
	   else LCD1602_writebyte(" ");
	   LCD1602_write(1,0x30+S%10);
	   LCD1602_writebyte("cm   ");
	
	   LCD1602_write(0,0xC0);		//第二行
	   LCD1602_writebyte("light:");	 //显示光照强度
	   if(light>99) LCD1602_write(1,0x30+light/100%10);
	   else LCD1602_writebyte(" ");
	   if(light>9) LCD1602_write(1,0x30+light/10%10);
	   else LCD1602_writebyte(" ");
	   LCD1602_write(1,0x30+light%10);
	   LCD1602_writebyte("%        ");
   }
   else	  //设置状态
   {
   	   LCD1602_write(0,0x80);  //第一行
	   LCD1602_writebyte("dis_set:");  //设置距离
	   if(state==1&&s0)	LCD1602_writebyte("   ");	//闪烁效果
	   else
	   {
		   if(S_set>99) LCD1602_write(1,0x30+S_set/100%10);
		   else LCD1602_writebyte(" ");
		   if(S_set>9) LCD1602_write(1,0x30+S_set/10%10);
		   else LCD1602_writebyte(" ");
		   LCD1602_write(1,0x30+S_set%10);
	   }
	   LCD1602_writebyte("cm   ");
	
	   LCD1602_write(0,0xC0);	
	   LCD1602_writebyte("lig_set:"); //设置光照
	   if(state==2&&s0)	LCD1602_writebyte("   ");
	   else
	   {
		   if(light_set>99) LCD1602_write(1,0x30+light_set/100%10);
		   else LCD1602_writebyte(" ");
		   if(light_set>9) LCD1602_write(1,0x30+light_set/10%10);
		   else LCD1602_writebyte(" ");
		   LCD1602_write(1,0x30+light_set%10);
	   }
	   LCD1602_writebyte("%        ");
   }
 }

void AD_dispose()	 //光照处理
{
	if(ad_count<10)		//读十次光照数据,取平均值,起到滤波的作用
	{
		ad_dat+=A_D(1);
		ad_count++;
	}
	else
	{
	   light=ad_dat/10;
	   light=(light*100)/255; //最大是255,所以这里扩大100倍除以255,可以得到百分比数据
	   ad_count=0;
	   ad_dat=0;
	}
}

void key_scan()	  //按键扫描
{

	if(!key1)	  //按键1按下
	{		
		if(key1_flag)  //如果标志位是1
		{
			key1_flag=0;	//清0
			state=(state+1)%3;	   //设置变量自加,%3限制了最大只能是2
		}
	}
	else
	{
		key1_flag=1; 	   //按键松开,才会给标志位置1,这样的话,按键按下只执行一次按键内容,起到了松手检测的作用
	}
	
	if(!key2)
	{		
		if(key2_flag)
		{
			key2_flag=0;
			if(state==1)	//设置距离状态
			{
				if(S_set<400) S_set++;	 //小于400,就自加
			}
			else if(state==2)//设置光照状态
			{
				if(light_set<100) light_set++;	//小于100就自加
			}
		}
		if(sec2==0)	//sec2==0,按键长按
		{
			if(state==1)  //实现连加效果
			{
				if(S_set<400) S_set++;
			}
			else if(state==2)
			{
				if(light_set<100) light_set++;
			}
		} 
		memory_flag=1;	//按键每次按下,存储标志位置1一次,这样只有设置的时候才会存储一次,一直执行存储函数会拖慢程序执行速度
	}
	else
	{
		key2_flag=1; sec2=2; //按键松开,按键标志位置1,按键长按变量赋0,当按键按下时,sec2不会再次赋值2,定时器有他的自减,当减到0,即为按键长按
	}
	
	if(!key3)  //同上
	{		
		if(key3_flag)
		{
			key3_flag=0;
			if(state==1)
			{
				if(S_set>0) S_set--;
			}
			else if(state==2)
			{
				if(light_set>0) light_set--;
			}
		}
		if(sec1==0)
		{
			if(state==1)
			{
				if(S_set>0) S_set--;
			}
			else if(state==2)
			{
				if(light_set>0) light_set--;
			}
		} 
		memory_flag=1;
	}
	else
	{
		key3_flag=1; sec1=2;
	}

	if(!key4)
	{		
		if(key4_flag)
		{
			key4_flag=0;
			A_M=!A_M;	   //手动自动切换
			if(A_M==0) beam=0;	  //如果切换到手动,就把灯关了
		}
	}
	else
	{
		key4_flag=1; 
	}

	if(!key5)
	{		
		if(key5_flag)
		{
			key5_flag=0;
			if(A_M==0)	 //手动状态
			{
				if(beam==1) beam=2;	 //远近光灯切换
				else beam=1;
			} 
			
		}
	}
	else
	{
		key5_flag=1; 
	}
	if(!key6)
	{		
		if(key6_flag)
		{
			key6_flag=0;
			if(A_M==0)		 //手动状态
			{
				beam=0;		//可关闭远近光灯
			} 
			
		}
	}
	else
	{
		key6_flag=1; 
	}
}

void police()  //自动模式处理函数
{
	if(light<light_set)	  //如果光照小于设置值,即天黑
	{
		if(S>S_set) beam=2;	  //如果距离大于设置距离,远光打开
		else beam=1;	 //否则近光打开
	}
	else beam=0;	 //否则光照强,就关闭远近光灯
}




硬件设计

使用元器件:

单片机:STC89C51;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

10uF电解电容;30p瓷片电容;

5228光敏电阻;电源接口;

轻触按键;草帽LED;

3mm红色LED灯;超声波模块;

LCD1602液晶屏+16P排座;

4P排针;8位103排阻;

8550三极管;3K电阻;

10K电阻;1K电阻;

330欧电阻;自锁开关;

DIP40管座;12M晶振;

ADC0832芯片+DIP8底座;

导线:若干;

流程图:

设计资料

01 仿真图

本设计使用proteus7.8版本设计,资料里有安装包和安装视频教程,无需担心!具体如图!

02 原理图

本系统原理图采用Altium Designer19设计,具体如图!

03 程序

本设计使用软件keil4和keil5两个版本编程设计,无需担心!具体如图!

04 设计报告

六千字设计报告,具体如下!

05 设计资料

        资料获取请关注同名公众号,全部资料包括仿真源文件 、程序(含注释)、AD原理图、pcb电路图、开题报告、参考论文、流程图、任务书、仿真视频等。具体内容如下,全网最全! !

资料获取请观看前面演示视频!

点赞分享一起学习成长。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值