目录
一、主要功能
基于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站演示视频:
全部资料(源程序、仿真文件、安装包、演示视频):
链接:https://pan.baidu.com/s/1X7RqBHxeeJ00zkdAV_Ysdw
提取码:diw9
–来自百度网盘超级会员V4的分享