基于51单片机光电对管智能小车从入门到精通全教程分解Word下载.docx
《基于51单片机光电对管智能小车从入门到精通全教程分解Word下载.docx》由会员分享,可在线阅读,更多相关《基于51单片机光电对管智能小车从入门到精通全教程分解Word下载.docx(20页珍藏版)》请在冰豆网上搜索。
3、制作方案(硬件方面)
3.1系统概述
智能循迹小车主要由单片机模块、红外检测模块、电机驱动模块组成。
单片机为主控模块,接受并判断各种信号,控制电机驱动。
在智能循迹小车系统设计过程中,用L293驱动两个电机,产生信号驱动小车前进时,是通过循迹模块里的红外对管ST188是否检测到黑线产生的电平信号通过LM339在返回到单片机,单片机再根据程序设计的要求作出相应的判断送给电机驱动模块,以实现小车自动循迹的功能(可对应附录里的系统原理图)。
图9-3-1小车工作图
3.2单片机模块
单片机模块为此次小车系统的核心,是作为系统信号采集和输出控制的重要部分。
51单片机的种类繁多,通常使用的是AT51单片机和STC51单片机,其中STC12单片机自带PWM,可以直接使用。
单片机模块为核心模块,其它由时钟、电源、串口MAX232与程序烧录、I/O接口等组成。
通过各结构的工作加上丰富的I/O接口,实现数据处理,进而对外部模块进行控制。
我们队设计方案主要分为两种:
设计一个包含电源、串口与程序烧录、外接I/O口组成,实现现场的小车调试程序烧录。
本次制作智能循迹小车所需提供9V电源,一方面9V电源直接供给电机驱动,驱动电机直接转停,另一方面9V经过稳压芯片,将9V电压稳压到5V直接给单片机模块、红外、指示灯工作,才能使小车正常工作。
稳压芯片7805输出为+5V稳定电压,最高输入极限电压36,最低输入电压7V,集成稳压块的最佳工作状态是输入电压与输出电压间的压差在3~4V左右。
压差太大可在输入前端串联几个二极管降压,这样稳压块就不会很烫了。
图9-3-2电源供应
图9-3-3程序下载口
图9-3-4单片机最小模块
单片机系统作为循迹小车的核心控制器,起着控制小车所有运行状态的作用。
控制方法有许多,大部分采用单片机来控制。
单片机将红外对管采集的道路信息进行处理。
小车进入循迹模式后,即不停的扫描与循迹模块相连接的I/O口,一旦检测到某个I/O口有信号变化,程序进入判断程序,把相应的信号传给减速电机控制器L293从而纠正小车的状态。
单片机最小系统调试步骤:
方法一:
1.用万用表确定是否正常供电。
2.用示波器确定晶振是否起振。
3.单片机是否工作。
比如,单片机一上电,它的有些管脚ALE引脚会输出脉冲,可以通过示波器查看。
方法二:
1.查看是否可以烧录程序。
2.可以结合图上的指示灯电路点亮一个发光二级管。
参考程序在右边。
3.3指示灯原理图
本模块是用4个发光二极管作为指示灯显示模块,通过红外对管对道路进行检测后传输信号给单片机,由单片机处理信号后,控制P2口的LED1、LED2、LED3、LED4(小车总原理图上)的输出高、低电平,控制NPN三极管的通断,来控制指示灯的亮、灭。
即以此来显示小车对道路的检测情况。
图9-3-5指示灯电路
3.4红外对管原理图
能够用来采集赛道数据的传感器有很多种,比如红外传感器、黑白线检测传感器、光电传感器和摄像头等;
但综合价格、性能、使用三方面来看,红外传感器是较为理想的。
黑白线传感器如tk-20虽然性能优秀,但价格较高;
光电传感器则受环境的影响太大,摄像头能很好的采集赛道数据,但使用起来不如前面几种传感器简单,且价格较贵;
因此这次的小车采用的是ST188红外传感器,其检测距离可调整的范围大,4-10mm均可使用。
如图所示为st188红外传感器。
图9-3-6红外对管外型
图9-3-7红外对管电路图
在焊接st188时应该注意其引脚的位置,不要弄错了;
同时在使用时也要小心,因为st188很容易烧掉,其价格在2-3元不等。
焊接完成后,检测st188是否正常工作可以使用手机的照相功能,若通过手机的照相功能能够观察到红光,则说明st188已经可以正常工作了。
接下来要调整可调电阻以达到一个合适的比较电压,可以使用示波器进行调整。
如图9-3-7所示,当有电流经过R4时,红外发射管发射红外线到轨道上,光线经过道路反射,红外接收管接收到红外线C和E引脚就有电流通过,此时C引脚的电压近似为0V。
若发射管发射的红外被黑线吸收,接收管接收不到,此时C和E之间可视为断开,此时C脚的电压为5V。
红外对管的道路的检测越清楚,传输给单片机的信息越稳定,小车就能更好地循迹。
而红外循迹模块的调试首先要判定自己的红外对管用没有用,而红外对管的检测方案有:
1):
通过测量红外发光二极管的正反向电阻,还可以在很大程度上推测其性能的优劣。
把万用表拨在R×
100或R×
1K挡,黑表笔接红外发光二极管正极,红表笔接负极,测得正向电阻应在20≈40K;
黑表笔接红外发光二极管负极,红表笔接正极,测得反向电阻应大于500K以上。
2):
先给红外对管通电,采用手机摄像功能查看红外发射管是否是好的。
图9-3-8LM339内部结构图
LM339电压比较器芯片内部装有四个独立的电压比较器,如图7所示当同相输入端的电压大于反相输入端时,输出正最大,此时7脚输出为5v;
若反相输入端的电压大于同相输入端。
3.5电机驱动模块
本次循迹小车的制作采用直流减速电机,直流减速电机转动力矩大,体积小、重量轻、装配简单、使用方便。
其内部由高速电机提供原动力,带动变速(减速)此轮组,产生较大扭力。
驱动模块采用芯片L293为电机驱动芯片,L293是一个具有高电压高电流的全桥驱动芯片,响应频率很高。
可以直流带动两个12V的直流电机。
L293内部的原理图如下:
图9-3-9L293内部原理图
OUT1与OUT2与小车的一个电机的正负极相连,OUT3与OUT4与小车的另一个电机的正负极相连,单片机通过控制IN1与IN2,IN3与IN4分别控制电机的正反转。
ENA与ENB分别控制两个电机的使能(控制电机停转)。
表9-3-1L293控制表
IN1
IN2
ENA
电机状态
x
停止
1
顺时针
逆时针
图9-3-10L293N引脚图
图9-3-11电机驱动电路
L293有两路电源分别为逻辑电源和动力电源,上图中6V为逻辑电源,12V为动力电源。
J4接入逻辑电源,J6接入动力电源,J1与J2分别为单片机控制两个电机的输入端,J3与J5分别与两个电极的正负极相连。
ENA与ENB直接接入6V逻辑电源也就是说两个电机时刻都工作在使能状态,控制电机的运行状态只有通过J1与J2两个接口。
由于我们使用的电机是线圈式的,在从运行状态突然转换到停止状态和从顺时针状态突然转换到逆时针状态时会形成很大的反向电流,在电路中加入二极管的作用就是在产生反向电流的时候进行泄流,保护芯片的安全。
4、制作方案(软件方面)
本次小车制作系统主控芯片为AT89S52,程序主要分为以下几个模块:
1、主函数;
作为整个程序的开始,与结束。
Check_Load()、Deal_Message_of_Load()作为子程序可在后调用。
例:
voidmain(void)
{
Timer_Init();
while
(1)
{
Check_Load();
Deal_Message_of_Load();
}
}
2、赛道信息采集函数;
对地面信号进行一个采集后,具体地对Load_Size进行赋值,以便赛道处理按函数,对信号进行处理。
voidDeal_Message_of_Load(void)
switch(Load&
0X0F)
{
case0X01:
Load_Size=0X01;
break;
//0001
case0x02:
Load_Size=0X02;
//0010
case0X03:
Load_Size=0X03;
//0011
case0x04:
Load_Size=0X04;
//0100
case0X06:
Load_Size=0X05;
//0110
case0x08:
Load_Size=0X06;
//1000
case0X0C:
Load_Size=0X07;
//1100
case0X00:
Load_Size=0X08;
//0000
case0x0f:
Load_Size=0X09;
//1111
default:
P2=Load&
0X0F;
//点亮指示灯
3、赛道处理函数;
通过对赛道信息采集后,进行判断,并做出相应的指令控制电机转动。
voidControl_Wheels(void)
{
if(Load_Size==0x01)
IN1=!
IN1;
Time_Count1++;
if(Time_Count1/20==0)
{
IN3=1;
}
else
IN3=0;
if(Time_Count1==255)
Time_Count1=0;
4、定时器初始化函数;
顾名思义就是对时间进行计数,以方便中断的执行。
voidTimer_Init(void)
TMOD=0x11;
//设定定时器T0和T1为工作方式1,为16位定时器/计数器
TH0=(65536-60000)/256;
TL0=(65536-60000)%256;
TR0=1;
IE=0X8A;
IN1=1;
IN2=0;
IN3=1;
IN4=0;
ENA=1;
ENB=1;
5、延时函数;
对时间进行控制,使在一定时间后执行需要执行的指令。
voidDelay(ucharTime)
uchari=0,j=0;
for(i=Time;
i>
0;
i--)
for(j=100;
j>
j--);
6、定时器中断T0服务函数;
暂停当前程序的执行,优先执行中断函数里的程序。
voidTimer0()interrupt1
Time_Count2++;
ENA=0;
ENB=0;
if(Time_Count2==2)
ENA=1;
ENB=1;
TH0=(65536-60000)/256;
TL0=(65536-60000)%256;
Control_Wheels();
Time_Count2=0;
}
4、附录
5.1实物和效果展示
图9-5-1实物图
图9-5-2效果图
5.2参考程序:
这里为
主程序:
#include<
reg52.h>
Check_Load.h>
change_direction.h>
#defineucharunsignedchar
#defineuintunsignedint
//定时器初始化配置
//获取当前赛道信息
//小车只能转弯
下面为程序中的<
头文件函数,作为子程序起到解释作用。
#ifndef_CHECK_LOAD_H_
#define_CHECK_LOAD_H_
/*************全局变量声明*********************/
ucharLoad=0;
//赛道信息存储变量
ucharLoad_Size=0;
//赛道类型存储变量
/***********************************************/
/****************************************
函数功能:
提取赛道信息
入口参数:
无
出口参数:
****************************************/
voidCheck_Load(void)
P1=0XFF;
//释放P1端口,此语句可以省略
Load=P1;
//读取P1端口,初步提取赛道信息
处理赛道信息
Load
备注:
誰誰2012217
*****************************************/
#endif
下面为<
chang_direction.h>
头文件也和上面的<
头文件一样,作为子程序。
#ifndef_CHANGE_DERECTION_H_
#define_CHANGE_DERECTION_H_
sbitIN1=P0^0;
//位定义
sbitIN2=P0^1;
sbitIN3=P0^2;
sbitIN4=P0^3;
sbitENA=P0^4;
sbitENB=P0^5;
ucharTime_Count1=0;
ucharTime_Count2=0;
voidDelay(ucharTime);
/*******************************************
控制左右车轮的转动,实现小车的智能循迹
控制思想:
当Load_Size=0x01时,说明小车最右边的光电对管采到黑线,故小车应该往右边转,应使得小车的左轮转得比右轮多,依此类推
*******************************************/
/*按照赛道处理的结果(Load_Size)对应的处理左右轮子的转速实现转弯*/
if(Time_Count1/20==0)//20
elseif(Load_Size==0x02)
if(Time_Count1/10==0)//10
elseif(Load_Size==0x03)
if(Time_Count1/15==0)//15
elseif(Load_Size==0x04)
IN3=!
IN3;
if(Time_Count1/10==0)
IN1=1;
IN1=0;
elseif(Load_Size==0x06)
elseif(Load_Size==0x07)
if(Time_Count1/15==0)
}
elseif((Load_Size==0x05)||(Load_Size==0x08))
else
{;
定时器初始化
********************************************/
//初始化定时器高8位
//初始化定时器低8位
//启动定时器T0
//开定时器T0中断,开总中断
//初始化L293的IN1~IN4引脚。
//使能OUT1、OUT2
//使能OUT3、OUT4
/*********************************************
延时
Time
备注:
誰誰2012218
*********************************************/
定时器T0中断服务函数(已验证)
/*设定时器初始值为60000*/
//重新载入定时器TH0初始值
TL0=(65536-60000)%256