智能小车

利用LM293D芯片来控制电机:

为什么单片机不能控制直流电动机?

能不能驱动是看功bai率的,而不是只看电压,还i要看电流呢,单片机的IO顶多输20mA左右,远远驱动了一般的电机,所以要加驱动电路。
可以用三极管或者专用驱动IC。
这里用的就是四倍高电流的H桥驱动程序

L293D简介

L293 是提供双向驱动电流高达 1 A,电压
是从 4.5 V 至 36 V 的;L293D 提供双向驱动电流高达 600 毫安,电压是从 4.5 V 至 36 V 的。两个设备是专为驱动等感性
负载继电器,电磁阀,直流双极步进和马达,也可以给其他高电流/高电压提供电源负载。
兼容所有的 TTL 输入。每个输出都是推拉式驱动电路,与达林顿三极管和伪达林源。启用 1,2 EN 驱动器和 3,4 EN 驱动
器。当使能输入为高电平时,相关联的驱动器被启用和他们的
输出处于活动状态,并在其输入端的同相。当使能输入为低,这些驱动器被禁用
其输出关闭,在高阻抗状态。【PS:1,2EN 为 1 和 2 的使能端(高电平使能);3,4EN 同理】用适当的数据输入端,每对
驱动程序的形式一个完整的 H 桥可逆驱动器适用于电磁阀或电机应用。
L293,外部输出为高速钳位二极管,应使用电感的瞬态抑制。VCC1 和 VCC2 分开,提供逻辑输入,以尽量减少设备功
耗。L293 和 L293D 的工作温度是从 0°C 至 70°C

上面简介有些麻烦,看图
在这里插入图片描述
简单来说,VCC2和Vcc1接电源即可,接地的接地,1,2EN是1A,2A,1Y,2Y的使能端,当1,2EN为高电平时,1A,2A,1Y,2Y工作,反之,1A,2A,1Y,2Y不工作,右半部分和左半部分一样,小车制作只用两个电机就可以了,所以对于L293来说只用左半部分即可。

上面说的是L293,其实这次用的是L293D来控制电机,两个驱动其实大同小异,来看下L293D的图:
在这里插入图片描述
还是需要连电源的和连地的电路都连好了,最主要的是input1和input2来控制电机M1,input3和input4来控制电机M2,ENA和ENB是使能端,ENA来控制input1和input2的正常工作,ENB来控制input3和input4的正常工作。通过控制占空比来控制速度。当input1和inut2一个为1,另一个为0时,电机运转,至于正转反转可以通过调试来确定。

再来说说原理图中的蜂鸣器部分:

在这里插入图片描述
蜂鸣器连接一个三级管接地,三级管的基极连通过一个电阻连接io口,当这个io口为低电平时,流过发射极的电流为0,电压也为零,同时流过集电极的电流也为0,电压也为0,所以相当于蜂鸣器下端接地,蜂鸣器发出叫声
当io口为1时,集电极和发射极都有点压,这是蜂鸣器上下端都有电压,蜂鸣器不叫。

智能小车避障:
这个程序利用了超声波模块来进行避障,如果监测到有障碍物就往右转(没有舵机所以只能这样),右转其实就是令左轮转动,右轮不动。
主要是超声波测距:
在这里插入图片描述
超声波的时序图:
在这里插入图片描述
TR引脚是用来触发信号,EC是来输出回响信号,超声波与障碍物会反射回来,根据回响信号的高电平时间就可以算出与障碍物的距离,s=time*速度/2;一来一回所以除以2;如果没有障碍物,也会有输出回响信号为高电平,而且会很长一段时间为高电平;

#include<reg52.h>
sbit x1=P0^0;
sbit y1=P0^1;
sbit x2=P0^2;
sbit y2=P0^3;
sbit ena=P0^4;
sbit enb=P0^5;
sbit fm=P0^6;
sbit tr=P1^3;
sbit ec=P1^2;
sbit led=P2^0;
sbit s4=P3^2;
int flag;
void delayu(int xus)
{
int i,j;
for(i=0;i<xus;i++)
{
for(j=0;j<9;j++)
{

}

}

}
void delaym(int xms)
{
int i,j;
   for(i=0;i<xms;i++)
   {
   for(j=0;j<112;j++)
   {
   }
   }
}
void right()
{
x1=0;
y1=0;
x2=1;
y2=0;
}
void go()
{
x1=1;
y1=0;
x2=1;
y2=0;
}
void stop()
{
x1=x2=y1=y2=0;
}
void main()
{ double time;
double s;
tr=0;
 ena=enb=1;
ec=0;
TMOD=0x01;
TH0=TL0=0;
EA=1;
ET0=1;
while(s4==1);
while(1)
{
	tr=1;
	delayu(10);
	tr=0;
	while(ec==0);
	TR0=1;
	while(ec==1);
	TR0=0;
	time=TH0*256+TL0;
	TH0=TL0=0;
	s=time*0.017;
	if(s<50)
	{	  if(flag==0)
		 stop();
		fm=0;
		led=0;
		 delaym(10); 
		 led=1;
	right();
	 delaym(50);
	 fm=1;
	}
	else 
	{
	go();
	}

}
}

小车遇到障碍物有两种情况,第一种是小车正直行遇到障碍物,这时需要stop()让轮子停住,然后再右转50ms,如果不停的话,可能会造成向右前方前行一段距离以至于撞上障碍物(并不知道右前方的情况)
//第二种情况,正右转的时候遇到障碍物,不需要停下来再右转,直接右转即可,否则会浪费一定的时间先暂停再启动,前者可以缩短避障时间。

遥控器控制智能小车: 首先,必须要知道的是红外接收头怎么接收,红外接收头负责接收红外信号,程序进行解码。 https://blog.csdn.net/qq_43743762/article/details/89421704Nec协议进行解码。

代码:
#include<reg52.h>
sbit fm=P0^6;
sbit IR=P3^3;
sbit x1=P0^0;
sbit y1=P0^1;
sbit x2=P0^2;
sbit y2=P0^3;
sbit ena=P0^4;
sbit enb=P0^5;
sbit led=P2^0;
unsigned char code smg[]={0x03,0x9F,0x25,0x0D,0x99,  //定义数码管显示数据
                            0x49,0x41,0x1F,0x01,0x19};
unsigned char  f[5];
unsigned char code dat[]={0x45,0x46,0x47,0x44,0x40,0x43,0x07,0x15,0x09}; 
void delay(int xms)
{
int i,j;
for(i=0;i<xms;i++)
{
for(j=0;j<112;j++)
{
}
}
}
void delayu(int xus)
{
int i=xus,j;
while(i--);
{
for(j=0;j<13;j++)
{
}
}

}
void stop()
{led=1;
x1=x2=y1=y2=0;
}
void ll()
{
led=0;
y1=y2=1;
x1=x2=0;
}
void go()
{
x1=x2=1;
y1=y2=0;
}
void left()
{

  x1=1;
y1=0;
x2=0;
y2=1;
}
void right()
{

x1=0;
y1=1;
x2=1;
y2=0;
}
void car(int x)
{
switch(x)
{
case 1:
{
stop();
delay(30);
go();
break;
}
case 3:
{
  stop();
delay(30);
left();
break;
}
case 4:
{
stop();
break;
}
case 5:
{
stop();
delay(30);
right();
break;
}
case  7:
{
stop();
delay(30);
ll();
break;
}
}
}
void oo() interrupt 2
{
int time=0,i,j;;
	 delay(5);
	 if(IR)
	 {
	 return ;
	 }
	 while(!IR)
	 {
	 delayu(1);
	/* time++;
	  if(time>=70)
	 {
	 return ;
	 }*/
	 }
	 time=0;
	 while(IR)
	 {
	 delayu(1);
	 /*time++;
	  if(time>=70)
	 {
	 return ;
	 }	*/
	 }
	for(i=0;i<4;i++)
	{
	for(j=0;j<8;j++)
	{
	time=0;
	   while(!IR);
	   while(IR)
	   {
	   delayu(1);
	   time++;
	    if(time>=30)
	   {
	   return ;
	   }
	   }
	   f[i]>>=1;
	  	if(time>=8)
		{	 f[i]|=0x80;
		
		}
		time=0;
	}
	}
	if(f[2]!=~f[3])
	{
	return ;
	}
	for(i=0;i<9;i++)
	{
	if(dat[i]==f[2])
	{
	car(i);
	}
	}
}
void main()
{
	  EX1=1;
	  EA=1;
	  IT1=1;
	  ena=enb=1;
	  while(1)
	  {
	  /*P2=smg[f[2]/16];
	  delay(1000);
	  P2=smg[f[2]%16];
	  delay(1000);*/
	  }
}

**这里让我一开始最疑惑的是为什么要不断的检查时序每个阶段的时间大小,过大就直接退出?后来,才知道,红外发射的码有不稳定型,一部分原因是有干扰,另一部分是长按一个键会产生110ms为周期的连续码,而且时序与一般的指令不一样,如果不加一个条件来排除一种不稳定的时序,这两种情况可能会造成程序很长时间卡在一个while(1)里面,造成程序死掉,所以需要加保护措施,来保证程序的正常进行。**

关于连续码看这个页面http://www.taichi-maker.com/homepage/reference-index/arduino-library-index/irremote-library/nec-ir/

蓝牙控制智能车:

首先,蓝牙模块,TX口接单片机的RX口,RX口接单片机的TX口;其余接好即可,在这里插入图片描述
蓝牙模块上电之后,一直闪烁,这时处于自动连接状态,然后用手机的蓝牙串口助手进行连接,(直接用蓝牙连连不上,可能是蓝牙模块比较老),连接上之后,不再闪烁,这时可以将蓝牙模块接一跟usb转ttl线插到电脑上,与电脑上的串口助手进行串口通信,这时就可以对蓝牙模块进行设置,比如更改波特率和名字之类的,具体看
https://blog.csdn.net/zy_like_study/article/details/89076506

如何控制小车?

将蓝牙模块插在单片机上,用手机的蓝牙串口助手对蓝牙模块发送信息,信息会从TX端输出,这时RX接收数据会触发中断,在中断函数里可以判断接收到的控制小车。注意:
一:蓝牙模块连接上之后可能会发送什么字符,具体不清楚,所以在代码里面需要设置没有一连接上发送的字符。
二:还有就是,单片机和蓝牙模块的波特率必须一致,也可以使用波特率倍增位置一使波特率倍增。
三:蓝牙插入后,串口被占用,没办法下载程序,程序下载也是用的串口。
四:SBUF只能存一个字节,字母也是一个字节,所以,发字符串只能一位一位发送,且字母是以字符的形式存储在SBUF而不是以字符串的形式存储。
比如传入’A’,存储的时候也是‘A’。串行发送就是发送的字符,接收到的也是字符,比如发送5,接收到的就是’5’。

代码:`#include<reg52.h>
sbit x1=P0^0;
sbit y1=P0^1;
sbit x2=P0^2;
sbit y2=P0^3;
sbit ena=P0^4;
sbit enb=P0^5;
void delay(int xms)
{
int i,j;
for(i=0;i<xms;i++)
{
for(j=0;j<112;j++)
{
}
}
}
void stop()
{
x1=x2=y1=y2=0;
}
void back()
{
y1=y2=1;
x1=x2=0;
}
void go()
{
x1=x2=1;
y1=y2=0;
}
void left()
{

x1=1;
y1=0;
x2=0;
y2=1;
}
void right()
{

x1=0;
y1=1;
x2=1;
y2=0;
}
void ll() interrupt 4
{
RI=0;
switch(SBUF)
{
case ‘5’:
go();
break;
case ‘l’:
back();
break;
case ‘p’:
right();
break;
case ‘e’:
left();
break;
case ‘f’:
stop();
break;
}
}
void main()
{EA=1;
ES=1;
ET1=1;
TMOD=0X20;
TH1=TL1=0xfa; //产生4800的波特率
TR1=1;
SCON=0x50;
PCON=0x80; //倍增一下成9600
while(1);

}`

寻光程序:
在这里插入图片描述这一部分就是寻光程序的主要结构图
LM393左右两边原理一样,先看左边,VCC与地之间有两个电阻分压,光敏电阻的阻值随着光线的变强阻值减少,分压减少,可以通过调节W1来调整灵敏度,使的光敏电阻在没有光线的时候分压比上面大,这时LM393的OUT处输出高电平,当一有光线的时候,上面的分压就比下面光敏电阻的大,这时OUTA输出低电平。左右两边原理一样,来检测通过输出的电平来检测有没有光。

关于LM393芯片:

程序设计:
观察检测光的两个电平,如果哪边有光就往哪边走,如果都有光就直着走,如果没光就暂停;
代码:

*事先调试:
**本程序主要是通过主板左右两个光敏传感器感应光照 ,当右边光敏传感器检测到光照
而左边没有检测到,小车则向右转弯,当两个光敏传感器同时检测到光照时,小车则
前进,当关照源移动时,当左边光敏传感器检测到光照,右边没有检测,则小车左转
,当左右两个传感器同时检测到光照,则小车前进,周而复始。

	程序测试方法:打开您的智能手机的手电筒功能,首先确保在没有开手电筒功能时候,
	主板左侧LED  D1和右侧LED D2 没有亮,如果亮了就用一字起把对应的电位器细致调
	节下,直到LED熄灭,然后打开手机的手电筒功能,照一下左右两个光敏传感器看是否
	会亮,如果不亮说明之前那一步调过头,那么你就要再细微调节下,直到亮为止,这样***
	系统测试完毕,就可以正常寻光了;祝你成功!
#include<reg52.h>
sbit x1=P0^0;
sbit y1=P0^1;
sbit x2=P0^2;
sbit y2=P0^3;
sbit ena=P0^4;
sbit enb=P0^5;
sbit lightl=P1^1;
sbit lightr=P1^0;
void delay(int xms)
{
int i,j;
for(i=0;i<xms;i++)
{
for(j=0;j<112;j++)
{
}
}
}
void go()
{
x1=x2=1;
y1=y2=0;
}
void stop()
{
x1=x2=y1=y2=0;
}
void left()
{
x1=y1=0;
x2=1;
y2=0;
}
void right()
{
x1=1;
y1=0;
x2=0;
y2=0;
}
void main()
{
ena=enb=1;

while(1)
{
if(lightl==0&&lightr==0)
{
go();
}
else if(lightl==0&&lightr==1)
{
left();
}
else if(lightl==1&&lightr==0)
{
right();
}
else 
{
stop();
} 
}
}

智能小车红外避障:
在这里插入图片描述
**划红线的就是红外避障也是利用LM393芯片来控制,v7是红外发射管,v4是红外接收管,红外发射后遇到障碍物会发射回来红外线,如果接收到红外线,v4的电阻就会减少,相应的电压也会减少,再根据设计好的电路图,一旦有近距离障碍物i,INA+的电压就会小于INA-的电压,障碍物越近,反射回来的红外线越强,V4的电阻越小,电压越小。如果检测到障碍物,就后退且左转来避开。注意一点,对于黑色障碍物无法检测,黑色会吸收红外光,这一点可以结合超声波避障来消除。
代码:
`#include<reg52.h>
sbit x1=P0^0;
sbit y1=P0^1;
sbit x2=P0^2;
sbit y2=P0^3;
sbit ena=P0^4;
sbit enb=P0^5;
sbit out=P3^7;
void go()
{
x1=x2=1;
y1=y2=0;
}
void stop()
{
x1=x2=0;
y1=y2=0;
}
void back()
{
x1=x2=0;
y1=y2=1;
}
void right()
{
x1=1;
y1=0;
x2=0;
y2=1;
}
void delay(int xms)
{
int i,j;
for(i=0;i<xms;i++)
{
for(j=0;j<112;j++)
{
}
}
}
void main()
{
ena=enb=1;
while(1)
{
if(out==1) //没有障碍物
{
go();
}
else
{
stop(); // 防止电机反相电压冲击 导致系统复位
delay(300);
back();
delay(300);
stop();
delay(50);
right();
delay(500);
stop();
delay(300);
}
}

}`**

循迹程序:

**循迹也是利用红外二极管发出红外线,红外接收管进行接收,如果接收到说明在地面上,如果接收不到就是不在地面上或者下面是黑色物体。
电路图:
画红线的就是循迹模块的电路图
**
左右两边原理一样,V5发射红外线,V2如果接收到反射电阻下降,进而导致电平为低电平,D5发光,P35为低电平,如果是下面是黑色,就会吸收反射光,V2阻值不变,进而P3^5为高电平。
循迹模块:
在这里插入图片描述
那一块黑色的就是一组发送和接收。
判断左右两边的电平进而控制电机,控制小车的运动一直在黑线上。
代码:`#include<reg52.h>
sbit x1=P0^0;
sbit y1=P0^1;
sbit x2=P0^2;
sbit y2=P0^3;
sbit ena=P0^4;
sbit enb=P0^5;
sbit lc=P3^5;
sbit lr=P3^6;
void go()
{
x1=x2=1;
y1=y2=0;
}
void stop()
{
x1=x2=0;
y1=y2=0;
}
void back()
{
x1=x2=0;
y1=y2=1;
}
void right()
{
x1=0;
y1=1;
x2=1;
y2=0;
}
void delay(int xms)
{
int i,j;
for(i=0;i<xms;i++)
{
for(j=0;j<112;j++)
{
}
}
}
void left()
{
x1=1;
y1=0;
x2=0;
y2=1;
}
void main()
{
ena=enb=1;
while(1)
{
if(lc0&&lr0)
{
go();
delay(10);
stop();
delay(5);
}
else if(lc1&r0)
{

left();
delay(10);
stop();
delay(5);
}
else if(lc0&&lr1)
{
right();
delay(10);
stop();
delay(5);
}
}
}`
一直检测有没有检测到黑线,如果有就说明走歪了再调整一下即可,调整角度还不能过大。整个运行速度也不能过快,所以go()完10ms之后stop()5ms来达到减速。

风扇驱动:
原理图:
在这里插入图片描述
由图可知,只要OA和OB一正一负就可以让风扇转起来。
LG9110芯片:
在这里插入图片描述
根据真值表来驱动风扇即可。
代码:

#include<reg52.h>
sbit f1=P1^4;
sbit f2=P1^5;
void delay(int xms)
{
int i,j;
for(i=0;i<xms;i++)
{
for(j=0;j<112;j++)
{
}
}
}
void main()
{
	   f1=0;
	   f2=1;
	   delay(1500);
	   f1=0;
	   f2=0;
	   delay(10);
	   f2=1;
	   f1=0;
	   while(1);
}

实物图:;;在这里插入图片描述

撒花完结

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值