智能循迹小车 - - - 设计报告

更新时间:2024-04-13 11:40:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

智能循迹小车设计

专 业: 自动化 班 级: 自动化132

姓 名:罗植升 莫柏源 梁桂宾 指导老师:

2014年4月——2010年6月

摘要:

本课题是基于STC89C52单片机的智能小车的设计与实现,小车

完成的主要功能是能够自主识别黑色引导线并根据黑线走向实现快速稳定的寻线行驶。小车系统以 STC89C52单片机为系统控制处理器; 采用红外传感获取赛道的信息,来对小车的方向和速度进行控制。此外,对整个控制软件进行设计和程序的编制以及程序的调试,并最终完成软件和硬件的融合,实现小车的预期功能。

引 言

当今世界,传感器技术和自动控制技术正在飞速发展,机械、电气和电子信息已经不再明显分家,自动控制在工业领域中的地位已经越来越重要,“智能”这个词也已经成为了热门词汇。现在国外的自动控制和传感器技术已经达到了很高的水平,特别是日本,比如日本本田制作的机器人,其仿人双足行走已经做得十分逼真,而且具有一定的学习能力,还据说其智商已达到6岁儿童的水平。

作为机械行业的代表产品—汽车,其与电子信息产业的融合速度也显著提高,呈现出两个明显的特点:一是电子装置占汽车整车(特别是轿车)的价值量比例逐步提高,汽车将由以机械产品为主向高级的机电一体化方向发展,汽车电子产业也很有可能成为依托整车制造业和用车提升配置而快速成为新的增长点;二是汽车开始向电子化、多媒体化和智能化方向发展,使其不仅作为一种代步工具、同时能具有交通、娱乐、办公和通讯等多种功能。

无容置疑,机电一体化人才的培养不论是在国外还是国内,都开始重视起来,主要表现在大学生的各种大型的创新比赛,比如:亚洲广播电视联盟亚太地区机器人大赛(ABU ROBCON)、全国大学生“飞思卡尔”杯智能汽车竞赛等众多重要竞赛都能很好的培养大学生对于机电一体化的兴趣与强化机电一体化的相关知识。但很现实的状况是,国内不论是在机械还是电气领域,与国外的差距还是很明显的,所以作为机电一体化学生,必须加倍努力,为逐步赶上国外先进水平并超过之而努力。

为了适应机电一体化的发展在汽车智能化方向的发展要求,提出简易智能小车的构想,目的在于:通过独立设计并制作一辆具有简单智能化的简易小车,获得项目整体设计的能力,并掌握多通道多样化传感器综合控制的方法。所以立“智能循迹小车”一题作为尝试。

此项设计是在以杨老师提供的小车为基础上,采用AT89C52单片机作为控制核心,实现能够自主识别黑色引导线并根据黑线走向实现快速稳定的寻线行驶。

一、实验目的:

通过设计进一步掌握51单片机的应用,特别是在嵌入式系统中的应用。进一步学习51单片机在系统中的控制功能,能够合理设计单片机的外围电路,并使之与单片机构成整个系统。

二、设计方案:

该智能车采用红外传感器对赛道进行道路检测,单片机根据采集

到的信号的不同状态判断小车当前状态,通过电机驱动芯片L9110发出控制命令,控制电机的工作状态以实现对小车姿态的控制。

三、报告内容安排:

本技术报告主要分为三个部分。第一部分是对整个系统实现方法的一个概要说明,主要内容是对整个技术原理的概述;第二部分是对硬件电路设计的说明,主要介绍系统传感器的设计及其他硬件电路的设计原理等;第三部分是对系统软件设计部分的说明,主要内容是智能模型车设计中主要用到的控制理论、算法说明及代码设计介绍等。

技术方案概要说明

本模型车的电路系统包括电源管理模块、单片机模块、传感

器模块、电机驱动模块。

工作原理:

? 利用红外采集模块中的红外发射接收对管检测路面上的轨迹 ? 将轨迹信息送到单片机

? 单片机采用模糊推理求出转向的角度和行走速度,然后去控制 行走部分

? 最终完成智能小车可以按照路面上的轨迹运行。

硬件电路的设计

1、最小系统:

小车采用STC89C52单片机作为控制芯片,图1是其最小系统电路。主要包括:时钟电路、电源电路、复位电路。其中各个部分的功能如下:

1、时钟电路:给单片机提供一个外接的12MHz的石英晶振。 2、电源电路:给单片机提供5V电源。

3、复位电路:在电压达到正常值时给单片机一个复位信号。

图1 单片机最小系统原理图

2、电源电路设计:

模型车通过自身系统,采集赛道信息,获取自身速度信息,加以处理,由芯片给出指令控制其前进转向等动作,各部分都需要由电路支持,电源管理尤为重要。在本设计中,51单片机使用5V电源,电机及舵机使用6V电源。考虑到电源为充电电池组,额定电压为7.2V,实际充满电后电压则为6.5-6.8V,所以单片机及传感器模块采用7805稳压后的5V电源供电,舵机及电机直接由电池供电。

3、传感器电路:

光电寻线方案一般由多对TCRT5000红外收发管组成,通过检测接收到的反射光强,判断黑白线。原理图由红外对管和电压比较器两部分组成,红外对管输出的模拟电压通过电压比较器转换成数字电平输出到单片机。

图2 赛道检测原理图:

4、电机驱动电路:

电机驱动芯片L9110,内部包含4通道逻辑驱动电路。是一种二相和四

相电机的专用驱动器,即内含二个H桥的高电压大电流双全桥式驱动器,接收标准TTL逻辑电平信号,可驱动46V、2A以下的电机。其引脚排列如图1中U4所示,1脚和15脚可单独引出连接电流采样电阻器,形成电流传感信号。L9110可驱动2个电机,OUT1、OUT2和OUT3、OUT4之间分别接2个电动机。5、7、10、12脚接输入控制电平,控制电机的正反转,ENA,ENB接控制使能端,控制电机的停转。也利用单片机产生PWM信号接到ENA,ENB端子,对电机的转速进行调节。 L9110的逻辑功能:

表1 SHARP GP2D12实物图

外形及封装:

图3 L9110实物图

L9110电路原理图:

由于一片L298N可以直接驱动两个电机,但是为了加大驱动力,我们采用两路并联的方式来驱动电机。

图3.3 L9110电路图

软件系统的实现

小车循迹规则:

若小车偏左的时候,车轮将向右偏转;若小车偏右,车轮将向左偏转;若没有偏移,小车将继续向前;若小车完全偏离黑色轨迹,小车后退以寻找黑色轨迹。小车程序:

#include //调用51单片机的头文件 #include #include

#define uchar unsigned char//宏定义 #define uint unsigned int//宏定义

sbit you1=P1^3;//定义单片机控制右边电机的引脚 sbit you2=P1^4;//定义单片机控制右边电机的引脚 sbit zuo1=P1^5;//定义单片机控制左边电机的引脚 sbit zuo2=P1^6;//定义单片机控制左边电机的引脚 sbit z=P1^1;//定义单片机连接循迹板左边光电管的引脚 sbit y=P1^0;//定义单片机连接循迹板右边光电管的引脚 sbit q=P1^2;//定义单片机连接循迹板前边光电管的引脚

sbit chongshua=P3^6;//定义单片机控制冲刷的引脚 sbit tuodi=P3^7;//定义单片机控制拖地的引脚

//--------------------------------------- //1602液晶相关I/O设置

sbit E=P2^3; //1602液晶的E脚接在P2.3口上 sbit RW=P2^4; //1602液晶的RW脚接在P2.4口上 sbit RS=P2^5; //1602液晶的RS脚接在P2.5口上

//HC-SR04相关I/O设置 sbit TIRG=P3^4; sbit ECHO=P3^2;

bit flag =0;

//定义IO口,具体可以去查看原理图 //定义IO口,具体可以去查看原理图

uchar k;

uchar a=0;//定义一个变量a,用来读取串口的数据

void delay(uint z)//一个带参数的延时程序 { }

void init()//初始化子程序 { }

TMOD=0x20;//设置定时器T1为工作方式2 TH1=0xfd;

TL1=0xfd;//T1定时器装初值 TR1=1;//启动定时器T1 REN=1;//允许串口接收 SM0=0;

SM1=1;//设置串口工作方式1 EA=1;//开总中断 ES=1;//开串口中断 int i,j;//定义两个变量 for(i=10;i>0;i--)

for(j=z;j>0;j--);//将参数z赋值给j

void qian()//左右轮协同前进子函数 { }

void zuo()//左右轮协同左转子函数 {

you1=0; you2=1; zuo1=1; zuo2=0;

delay(9);//pwm调速 此为pwm有效值 you1=1; you2=1; you1=0; you2=1; zuo1=0; zuo2=1;

delay(6);//pwm调速 此为pwm有效值 you1=1; you2=1; zuo1=1; zuo2=1; delay(4);

}

zuo1=1; zuo2=1; delay(1);

void mzuo()//左右轮协同左转子函数 { }

void you()//左右轮协同右转子函数 {

you1=1; you2=0; zuo1=0; you1=0; you2=1; zuo1=1; zuo2=0;

delay(10);//pwm调速 此为pwm有效值 you1=1; you2=1; zuo1=1; zuo2=1; delay(5);

}

zuo2=1;

delay(9);//pwm调速 此为pwm有效值 you1=1; you2=1; zuo1=1; zuo2=1; delay(1);

void myou()//左右轮协同右转子函数 { }

you1=1; you2=0; zuo1=0; zuo2=1;

delay(10);//pwm调速 此为pwm有效值 you1=1; you2=1; zuo1=1; zuo2=1; delay(5);

void hou()//左右轮协同前进子函数 { }

void ting()//左右轮都停止转动 { }

you1=1; you2=1; zuo1=1; zuo2=1; you1=1; you2=0; zuo1=1; zuo2=0;

delay(9);//pwm调速 此为pwm有效值 you1=1; you2=1; zuo1=1; zuo2=1; delay(1);

void Delay1602(unsigned int t) {

unsigned int k; //定义一个16位寄存器用来做延时用 for(k=0;k

void LCD1602_busy(void) {

P0_7=1; // RS=0; //RS=0读入

RW=1; //RS=0读入

E=1; //RS=0读入

while(P0_7==1); // E=0; //}

延时 将P0.7置1,为读状态做准备

、RW=1、E=1时,忙信号输出到DB7,由P0.7、RW=1、E=1时,忙信号输出到DB7,由P0.7、RW=1、E=1时,忙信号输出到DB7,由P0.7由P0.7读入1,表示1602液晶忙,需要等待 读完以后,恢复E的电平 void LCD1602_Write_com(unsigned char combuf) {

RS=0; //选择指令寄存器 RW=0; //选择写状态

P0=combuf; //将命令字通过P0口送至DB E=1; //E高电平将命令字写入1602液晶 E=0; //写完以后,恢复E的电平 }

void LCD1602_Write_com_busy(unsigned char combuf) {

LCD1602_busy(); //调用忙检测函数 LCD1602_Write_com(combuf); //调用忙检测函数 }

void LCD1602_Write_data_busy(unsigned char databuf) {

LCD1602_busy(); //调用忙检测函数 RS=1; //选择数据寄存器 RW=0; //选择写状态

P0=databuf; //将命令字通过P0口送至DB

E=1; //E高电平将命令字写入1602液晶 E=0; //写完以后,恢复E的电平 }

void LCD1602_Write_address(unsigned char x,unsigned char y) {

x&=0x0f; //列地址限制在0-15间 y&=0x01; //行地址限制在0-1间 if(y==0) //如果是第一行

LCD1602_Write_com_busy(x|0x80); //将列地址写入 else //如果是第二行

LCD1602_Write_com_busy((x+0x40)|0x80); //将列地址写入 }

void LCD1602_init(void) {

Delay1602(1500); //调用延时函数

LCD1602_Write_com(0x38); //8位数据总线,两行显示模式,5*7点阵显示

Delay1602(500); //调用延时函数

LCD1602_Write_com(0x38); //8位数据总线,两行显示模式,5*7点阵显示

Delay1602(500); //调用延时函数

LCD1602_Write_com(0x38); //8位数据总线,两行显示模式,5*7点阵显示

LCD1602_Write_com_busy(0x38); //8位数据总线,两行显示模式,5*7点阵显示

LCD1602_Write_com_busy(0x08); //显示功能关,无光标 LCD1602_Write_com_busy(0x01); //清屏

LCD1602_Write_com_busy(0x06); //写入新的数据后,光标右移,显示屏不移动

LCD1602_Write_com_busy(0x0C); //显示功能开,无光标 }

void LCD1602_Disp(unsigned char x,unsigned char y,unsigned char buf) {

LCD1602_Write_address(x,y); //先将地址信息写入 LCD1602_Write_data_busy(buf); //再写入要显示的数据 }

void Timer0(void) interrupt 1 {

}

flag=0;

void xunji() {

qian();//调用前进子函数,使小车光电管不满足以下几个条件时都处

于前进状态

while((z==0)&&(y==1)&&(q==1))//判断当左边光电管遇到黑线, { }

while((z==1)&&(y==0)&&(q==1))//判断当右边光电管遇到黑线, { }

while((z==0)&&(y==0)&&(q==1))//判断当左边光电管遇到黑线,右边

//左边和前边的光电管遇到白线时右转

//右边和前边的光电管遇到白线时左转

zuo();//调用左转函数 zd=1;

you();//调用右转函数 yd=1;

光电管也遇到黑线

{

//前边的光电管遇到白线时停止

ting();//调用停止函数

}

hd=1;

while((z==0)&&(y==0)&&(q==0))//判断当左边、右边、前边光电管同

时遇到黑线 }

void csb() {

long S; unsigned int i; unsigned int Timeout;

{ }

//即遇到十字路口,小车前进

qian();//调用前进函数

LCD1602_init(); //调用1602液晶初始化函数

//***定时器Timer0初始化***

TMOD&=0xF0; //将TMOD的低4位定时器0控制部分清零 TMOD|=0x01; //设置定时器0为方式1

TMOD=0x01;

TL0=0; //设置定时器0初值低8位 TH0=0;

//设置定时器0初值高8位

TR0=0; //停止定时器0 ET0=1; //Timer0中断允许

//***开全局中断设置****

//定时器Timer0设置了中断允许,此处要开全局中断 EA=1; //开全局中断

TIRG=1;

//发一个脉冲触发信号

//维持约17US,符合不低于10US的要求

//维持约17US,符合不低于10US的要求

i=4;

while(i>0) i--;

TIRG=0;

TR0=0;

//维持约17US,符合不低于10US的要求

//撤销触发信号

//关闭定时器

//设置定时器0初值低8位为0

TL0=0;

TH0=0;

//设置定时器0初值高8位为0

//清除溢出标志

k=0; flag=0; Timeout=0;

while((ECHO==0)&&((Timeout++)<50000));

//等待回响高

电平

TR0=1; //回响高电平来后启动定时器

Timeout=0;

while((ECHO==1)&&((Timeout++)<50000)); //等待回响高

电平结束后

TR0=0;

//关闭定时器

S=((TH0*256+TL0)*1)/58;

if(flag==1||S>400) {

//超出测量范围显示“-”

//显示百位-

//显示十位-

}

LCD1602_Disp(0, 0, '-'); LCD1602_Disp(1, 0, '-'); LCD1602_Disp(2, 0, '-'); LCD1602_Disp(3, 0, 'C'); LCD1602_Disp(4, 0, 'M');

//显示个位- //显示C //显示M

else {

LCD1602_Disp(0, 0, S00/100+'0'); //显示百位

}

LCD1602_Disp(1, 0, S000/10+'0'); //显示十位 LCD1602_Disp(2, 0, S000+'0'); //显示个位 LCD1602_Disp(3, 0, 'C'); LCD1602_Disp(4, 0, 'M');

//显示C //显示M

i=18000;

//维持约77400US,符合不低于60MS的要求 //维持约77400US,符合不低于60MS的要求

while(i>0)

i--; }

void main()//主程序 {

//维持约77400US,符合不低于60MS的要求

init();//调用初始化子程序 while(1)//死循环 {

switch(a)//判断a从串口读取到的数据 {

case 0x00://如果是0x1f就前进 xunji(); break;

case 0x01://如果是0x2f就后退 qian(); break;

case 0x02://如果是0x3f就左转

csb(); break;

case 0x03://如果是0x4f就右转 mzuo(); zd=1; break;

case 0x04://如果是0x00就停止 hou(); break;

case 0x05://如果是0xa0车灯打开 myou(); yd=1; break;

case 0x06://如果是0xb0车灯关闭 chongshua=1; break;

case 0x07://如果是0xc0蜂鸣器鸣响

}

ting(); hd=1; break;

case 0x08://如果是0xc0蜂鸣器鸣响

tuodi=1; break;

}

}

void chuan() interrupt 4//串口中断服务程序 { }

RI=0;//软件清除串口响应

a=SBUF;//读取单片机串口接受的蓝牙模块发送的数据

结论

根据本次设计要求,我们小组系统地阅读了大量的资料,并认真分析了设计课题的需求,还系统学习了51系列单片机的工作原理及其使用方法,并独自设计智能小车的整个项目。

虽然条件艰苦,但经过不懈钻研和努力,购买到了所有所需的元器件,并系统的进行了多项试验,最终做出了整个小车的硬件系统,然后结合课题任务和小车硬件进行了程序的编制,本系统能够基本满足设计要求,能够较快较平稳的是小车沿引导线行驶,但由于经验能力有限,该系统还存在着许多不尽人意的地方有待于进一步的完善与改进。

通过本次课题设计,不仅是对我们课本所学知识的考查,更是对我的自学能力和收集资料能力以及动手能力的考验。本次毕业设计使我们对一个项目的整体设计有了初步认识,还认识了几种传感器,并能独立设计出其接口电路,再有对电路板的制作有了一定的了解,并学会了使用Protel设计电路。本次毕业设计使我们意识到了实验的重要性,在硬件制作和软件调试的过程中,出现了很多问题,最终都是通过实验的方法来解决的。还有以前对程序只是一个很模糊的概念,通过这次的课题设计使我对程序完全有了一个新的认识,并能使用C熟练的进行编程了。通过本次课题设计,极大的锻炼了我们的思考和分析问题的能力,并对单片机有了一个更深的认识。

总之,在课题设计的过程中,无论是对于学习方法还是理论知识,我们都有了新的认识,受益匪浅,这将激励我们在今后再接再厉,不断完善自己的理论知识,提高实践运作能力。

本文来源:https://www.bwwdw.com/article/w2sp.html

Top