[Proteus仿真]基于51单片机的智能车位锁系统(电流检测、电压检测、红外检测、灯光报警)

本文详细描述了一个使用STC89C51单片机控制的智能车位锁系统,涉及按键操作、红外传感器检测、电机驱动、升降杆控制、电流电压监测以及实时中断处理。系统通过ADC0832进行模拟信号转换,并利用LCD1602显示屏显示状态。
摘要由CSDN通过智能技术生成

目录

一、主要功能

二、硬件资源

三、程序编程

四、实现现象


一、主要功能

基于STC89C51单片机,具有复位电路和晶振电路;
1.按下升起的按键后,然后用GP2D12红外传感器判断车辆是否在位,若不在位,升降杆高度为0,L298N驱动电机顺时针运转,升降杆起升,高度慢慢提高;假设提高到10,电机停止;高度通过LCD1602显示屏显示;
2.按下下降的按键后,用GP2D12红外传感器判断车辆是否在位,若不在位,还得判断高度,高度为10的话,L298N驱动电机逆时针转动,升降杆下降,检测高度为0,电机停止;5S后再判断GP2D12红外传感器判断车辆是否在位,若不在位,L298N驱动电机顺时针转动,升杆,升到最高处停止;高度通过LCD1602显示屏显示;
3.滑动变阻器连接ADC0832数模转换器,体现电流,电流过大,电机停止,蜂鸣器报警,灯光亮起,5S后没有任何信号,全部不显示;滑动变阻器连接ADC0832数模转换器,体现电压,若电压过低,则蜂鸣器发出警告,但不影响其他工作;电流和电压通过LCD1602显示屏显示;
在这此中,将电压和电流测量加入外部中断,周期每隔50ms检测,1S内检测20次,保证随时生效;

仿真图 :

二、硬件资源

基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。

单片机STC895C1
电机是L298N驱动器,驱动直流电机
红外传感器:GP2D12型号
数模转换器:ADC0832
显示屏:LCD1602显示屏

全部资源包括:

三、程序编程

/*全部代码看页尾*/

#include <REGX52.H>
#include<intrins.h>
#include<stdio.h>
#include "Delay.h"
#include "LCD1602.h"
#define uchar unsigned char
#define uint unsigned  int
typedef unsigned char u8;
typedef unsigned int  u16;
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
sbit CS  = P1^0;        //红外传感器
sbit CLK = P1^1;
sbit DIO = P1^2;
sbit CS1  = P3^5;        //电流
sbit CLK1 = P3^6;
sbit DIO1 = P3^7;
sbit CS2  = P3^2;        //电压
sbit CLK2 = P3^3;
sbit DIO2 = P3^4;
sbit motor1_EN  = P1^7;
sbit motor1_IN1 = P1^5;
sbit motor1_IN2 = P1^6;
sbit key1 = P1^3;
sbit key2 = P1^4;
sbit LED  = P2^4;
sbit BEEP = P2^3;

/*变量定义*/
static int flag = 0 , flag2 = 0,flag3 = 0;
int gaodu= 0;					
static 	char u,DL,DY;
unsigned char count;

/*函数定义*/
void anjianpd();//按键函数定义
void MOTORRIGHT_MOVE();
void MOTORLEFT_MOVE();
void MOTOR_STOP();
void gdpdss();
void gdpdxj();
void dianpd();
void dianpd1();
void pdsq();

uchar get_AD_Res()          //ADC0832启动读取红外的值
{
	uchar i, data1=0, data2=0;
	CS=0;
	
	CLK=0;DIO=1;_nop_();
	CLK=1;_nop_();
	
	CLK=0;DIO=1;_nop_(); 
	CLK=1;_nop_();
	
	CLK=0;DIO=0;_nop_();
	CLK=1;_nop_();
	
	CLK=0;DIO=1;_nop_(); 
	
	for(i=0; i<8; i++)
	{
		CLK=1;_nop_();
		CLK=0;_nop_();
		data1=(data1<<1)|(uchar)DIO; 
	}
	
	for(i=0; i<8; i++)
	{
		data2=data2|(uchar)DIO<<i;
		CLK=1;_nop_();
		CLK=0;_nop_();
	}
	CS=1;
	
	return(data1 == data2)?data1:0;
}

uchar get_AD_Res1()          //ADC0832启动读取电流值
{
	uchar i, data1=0, data2=0;
	CS1=0;
	
	CLK1=0;DIO1=1;_nop_();
	CLK1=1;_nop_();
	
	CLK1=0;DIO1=1;_nop_(); 
	CLK1=1;_nop_();
	
	CLK1=0;DIO1=0;_nop_();
	CLK1=1;_nop_();
	
	CLK1=0;DIO1=1;_nop_(); 
	
	for(i=0; i<8; i++)
	{
		CLK1=1;_nop_();
		CLK1=0;_nop_();
		data1=(data1<<1)|(uchar)DIO1; 
	}
	
	for(i=0; i<8; i++)
	{
		data2=data2|(uchar)DIO1<<i;
		CLK1=1;_nop_();
		CLK1=0;_nop_();
	}
	CS1=1;
	
	return(data1 == data2)?data1:0;
}

uchar get_AD_Res2()          //ADC0832启动读取电压值
{
	uchar i, data1=0, data2=0;
	CS2=0;
	
	CLK2=0;DIO2=1;_nop_();
	CLK2=1;_nop_();
	
	CLK2=0;DIO2=1;_nop_(); 
	CLK2=1;_nop_();
	
	CLK2=0;DIO2=0;_nop_();
	CLK2=1;_nop_();
	
	CLK2=0;DIO2=1;_nop_(); 
	
	for(i=0; i<8; i++)
	{
		CLK2=1;_nop_();
		CLK2=0;_nop_();
		data1=(data1<<1)|(uchar)DIO2; 
	}
	
	for(i=0; i<8; i++)
	{
		data2=data2|(uchar)DIO2<<i;
		CLK2=1;_nop_();
		CLK2=0;_nop_();
	}
	CS2=1;
	
	return(data1 == data2)?data1:0;
}

void Time1Init()
{
	TMOD |= 0x10;
	TH1   = (65536-57567)/256;
	TL1   = (65536-57567)%256;
	EA    = 1;
	ET1   = 1;
	TR1   = 1;
}

void Time1Start() interrupt 3
{
    static	u16 count = 0;      //定义计数变量
	TH1   = (65536-57567)/256;
	TL1   = (65536-57567)%256;
	count++;
	if(count == 10)//达到1s
	{
		count = 0; 
	    dianpd();              //电流电压检测
		u=get_AD_Res();	
	
		if(flag2 == 1)
		{
		 dianpd1();
		}

		if(flag3 == 1)
		{
		  pdsq();
		}

	}
}

void main()					  //主函数
{	
	Time1Init();        //定时器1初始化
	LCD_Init();         //显示屏初始化
	LCD_ShowString(1,1,"HIGH:");
	LCD_ShowString(2,1,"DL:");
	LCD_ShowString(2,10,"DY:");

	while(1)
	{
	    if(flag == 0)
		{
	    anjianpd();         //按键判断
		}
	}
	
}

void anjianpd()
{
 if(key1 == 0)	   //升起按键
 {
  Delay(150);
  if(key1 == 0)
  {
   	u=get_AD_Res();	   //判断车位是否在位
	if(u <= 100 && gaodu == 0)	   //车辆不在位并且高度为0
	{
	  MOTORRIGHT_MOVE(); //顺时针转动
	  gdpdss(); //高度上升
	  if(gaodu>=10)
	  {
	   MOTOR_STOP();  //电机停止
	  }
	}
  }
 }

 if(key2 == 0)	 //下降按键
 {
  Delay(150);
  if(key2 == 0)
  {
    u=get_AD_Res();
   	if(u <= 100 && gaodu == 10)	   //车辆不在位并且高度为0
	{
	  MOTORLEFT_MOVE(); //逆时针转动
	  gdpdxj(); //高度判断下降
	  if(gaodu==0)
	  {
	   MOTOR_STOP();  //电机停止
	   Delay(5000);  //延时
	   flag3 = 1; 
	  }
	}
  }
 }
}

void gdpdss()
{
 while(gaodu<=9)
 {
  ++gaodu;
  LCD_ShowNum(1,6,gaodu,3);
  Delay(500);
 }
}

void gdpdxj()
{
  while(gaodu > 0)
  {
  --gaodu;
  LCD_ShowNum(1,6,gaodu,3);
  Delay(500);
  }
}
void MOTORRIGHT_MOVE()	  //顺时针转动
{
   	  motor1_EN = 1;
	  motor1_IN1 = 1;
	  motor1_IN2 = 0;
}

void MOTORLEFT_MOVE()	  //逆时针转动
{
   	  motor1_EN = 1;
	  motor1_IN1 = 0;
	  motor1_IN2 = 1;
}

void MOTOR_STOP()	    //停止转动
{
   	  motor1_EN = 0;
	  motor1_IN1 = 0;
	  motor1_IN2 = 0;
}

void dianpd() //电流电压检测
{
  	    DL = get_AD_Res1();	//读取电流
		DY = get_AD_Res2(); //读取电压
		LCD_ShowNum(2,4,DL,3);
		LCD_ShowNum(2,14,DY,3);
		

		if(DL > 80)  //电流过大
		{
		  MOTOR_STOP(); //所有电机停止
		  BEEP = 1   ;  //蜂鸣器报警
		  LED  = 1   ;  //LED灯亮起
		  Delay(5000);  //延时
		  flag2 = 1;
		}
		else 
		{
		  BEEP = 0   ; 
		  LED  = 0   ;  
		}

		if(DY < 50 ) //电压过低
		{
		  BEEP = 1   ;  //蜂鸣器报价
		  LED  = 1   ;  //LED灯亮起
		}
		else 
		{
		 BEEP = 0   ;  
		 LED  = 0  ;   
		}
}

void dianpd1()
{
        DL = get_AD_Res1();	//读取电流
	   	LCD_ShowNum(2,4,DL,3);
 	    if(DL>80)
		  {
		  EA = 0;
		  BEEP = 0   ;  
		  LED  = 0   ;  
		  LCD_ShowString(1,1,"                "); //清屏
		  LCD_ShowString(2,1,"                "); //清屏
		  flag = 1;
		  }
		  else 
		  {
		   flag2 = 0;
		  }
}

void pdsq()
{
    if(u <= 100)   //如果车辆不在位
	  {
	    MOTORRIGHT_MOVE(); //顺时针转动
	    gdpdss(); //高度上升
	    if(gaodu>=10)
	    {
	     MOTOR_STOP();  //电机停止
	    }
	  }
}

四、实现现象

具体动态效果看B站演示视频:

基于51单片机的智能车位锁系统_哔哩哔哩_bilibili

全部资料(源程序、仿真文件、安装包、演示视频):

链接:https://pan.baidu.com/s/1X7RqBHxeeJ00zkdAV_Ysdw 
提取码:diw9 
--来自百度网盘超级会员V4的分享

  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜间去看海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值