目录
一、主要功能
基于AT89C51单片机,LCD1602显示前进,L298N驱动两个电机前行,然后超声波检测距离,并通过LCD1602显示屏实时显示距离,如果距离小于50cm,则电机发生变化,实现转向,同时红外传感器检测果实,如果检测到果实,LCD1602显示屏显示YES,代表检测到果实,舵机转动,表示抓取果实动作,然后红外要是检测不到果实,LCD1602显示屏显示NO,舵机不转。
仿真图:
编辑
二、硬件资源
基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。
本系统包含51单片机最小系统、超声波传感器、GP2D12红外检测模块、ADC0832数模转换器、L298N电机模块、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; //51单片机引脚设置
sbit CLK=P1^1;
sbit DIO=P1^2;
sbit Motor1_IN1 = P3^3; //电机IN1口
sbit Motor1_IN2 = P3^4;
sbit Motor1_EN = P3^2; //电机使能端1
sbit Motor2_IN1 = P2^4; //电机IN2口
sbit Motor2_IN2 = P2^5;
sbit Motor2_EN = P2^7; //电机使能端2
sbit motor = P1^3;
sbit motor1 = P1^4;
sbit Tr=P3^0;//触发信号
sbit Ec=P3^1;//回响信号
uchar Recv_Buffer\[4\];
uint Voltage\[\]={'0','0','0','0'};
bit bdata IIC_ERROR;
unsigned char count;
unsigned int distance;
static uint temp;
uint temp;
static unsigned char num;
unsigned int Read_value(void);//读值函数
void Delay10us(void);//10us延时函数
void Time0_Init() //定时器初始化
{
TMOD = 0x01;
TH0 = 0x00;
TL0 = 0x00;
TR0 = 0;//先关闭定时器0
}
void Time0_Int() interrupt 1 //中断程序
{
TH0 = 0xfe; //重新赋值
TL0 = 0x33;
}
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;
}
unsigned int Read_value()
{
uint result;
Tr=1;//触发引脚发出11us的触发信号(至少10us)
Delay10us();
Tr=0;
while(!Ec);//度过回响信号的低电平
TR0=1;//开启定时器0
while(Ec);//度过回响信号高电平
TR0=0;//关闭定时器0
result=((TH0\*256+TL0)\*0.034)/2; // 距离cm=(时间us * 速度cm/us)/2
return result + 2; //+2修正补偿
}
void main() //主函数
{
uchar u;
Tr=0;//出发引脚首先拉低
LCD_Init(); //显示屏初始化
Time0_Init(); //定时初始化
motor=0; //关掉风扇
while(1)
{
Motor1_EN = 1;
Motor1_IN1 = 1; //电机IN口
Motor1_IN2 = 0;
Motor2_EN = 1;
Motor2_IN1 = 1; //电机IN口
Motor2_IN2 = 0;
u=get\_AD\_Res(); //读取红外传感器的值
if(u>100)
{
u=0; //舵机转动标志位
}
else
{
u=1;
}
if( u == 0 ) //舵机停止
{
motor = 0;
motor1 = 0;
LCD_ShowString(1,1,"guoshi:NO! ");
}
else //舵机转动
{
motor = 1;
motor1 = 1;
LCD_ShowString(1,1,"guoshi:YES!");
}
distance = Read_value();//读值
distance-=1;
if(distance<50)
{
Motor2_EN = 0;
}
else
{
Motor1_EN = 1;
Motor1_IN1 = 1; //电机IN口
Motor1_IN2 = 0;
Motor2_EN = 1;
Motor2_IN1 = 1; //电机IN口
Motor2_IN2 = 0;
}
LCD_ShowString(2,1,"distance:");
LCD_ShowNum(2,10,distance,3); //第二行显示距离
}
}
void Delay10us()
{
TL0=0xF5;
TH0=0xFF;
TR0=1;
while (TF0==0);
TR0=0;
TF0=0;
}
四、实现现象
具体动态效果看B站演示视频:
基于51单片机的小车避障采摘果实_哔哩哔哩_bilibili
全部资料(源程序、仿真文件、安装包、演示视频):
链接:https://pan.baidu.com/s/1rjA2o0jT_74CbwUwFqAc2A
提取码:006s
–来自百度网盘超级会员V4的分享