单片机实习报告简易智能小车.docx

上传人:b****6 文档编号:3785538 上传时间:2022-11-25 格式:DOCX 页数:23 大小:373.52KB
下载 相关 举报
单片机实习报告简易智能小车.docx_第1页
第1页 / 共23页
单片机实习报告简易智能小车.docx_第2页
第2页 / 共23页
单片机实习报告简易智能小车.docx_第3页
第3页 / 共23页
单片机实习报告简易智能小车.docx_第4页
第4页 / 共23页
单片机实习报告简易智能小车.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

单片机实习报告简易智能小车.docx

《单片机实习报告简易智能小车.docx》由会员分享,可在线阅读,更多相关《单片机实习报告简易智能小车.docx(23页珍藏版)》请在冰豆网上搜索。

单片机实习报告简易智能小车.docx

单片机实习报告简易智能小车

中国地质大学(武汉)

单片机实习报告

指导老师:

李勇波

日期:

2011年7月

班级:

073092-15|姓名:

赵英俊(20091002410)

简易智能小车报告

摘要

本小车以Atmel公司生产的AT89S52为核心,完成寻迹、避障、光源检测和车速测量等功能。

在机械结构上,对普通的小车进行了改造,即用一个万向轮来代替两个前轮,是小车的转向更加灵敏。

采用PWM驱动芯片控制电机,红外传感器检测白线、障碍物以及用来测量速度,光敏器件检测光强。

基于可靠的硬件设计和稳定的软件算法,基本实现题目要求。

关键字:

STC89C52寻迹光源检测避障测速测量

Abstract

ThisdesigniscontrolledwiththeMCU(AT89S52)tocompletethefunctionoffindingtrace,avoidingbarrier,tendingtolightandmeasurespeed.Inthemechanicalstructure,aboutthecar,thereformwhichisauniversalwheelinsteadoftwofront,themoresensitivetothecar.UsingPWMmotordrivechipcontrol,infraredsensordetectionwhiteline,obstaclesandusedtomeasurethespeed,photodetectordetectionlightintensity.Basedonreliablehardwaredesignandstablesoftwarealgorithm,basicallyrealizethetopicrequest.

Keywords:

STC89C52traceavoidingbarriertendingtolightmeasurespeed

1.系统设计

1.1设计要求

1.基本要求

(1)小车从起跑线出发(不得超过起跑线),沿引导线到达B点

在B点有一障碍物需绕过障碍物到达C点

(2)小车到达C点沿一段直到到达D点后进入“弯道区”(中间有一断点),此时有一光源照射,引导小车转弯并通过断点继续进入大弯道区。

(3)小车在光源的引导下通过进入停车区并到达车库

(4)小车在最终在遇到停车标志后停车,并最终显示时间和速度(实时速度)。

1.2方案论证

1.电机驱动方案的选择和论证

由于普通直流电机更易于购买,小车对于精度要求不是特别高,同时电路和控制相对简单,所以本设计采用直流电机作为驱动单元。

方案一:

使用继电器对电机进行开关控制和调制。

但缺点很明显,继电器响应慢而且机械结构容易坏。

方案二:

使用三极管或达林顿管,结合单片机输出PWM信号实现调速的目的,此方案易于实施,但若控制电机转动方向较为困难。

方案三:

使用PWM控制芯片来实现对电机的控制。

方案选择:

采用方案三。

该方案电路简单,性能稳定,可以轻松实现对电机方向的控制。

2.路面寻迹模块

方案一:

采用光敏传感器,根据白色背景和黑色反光程度的不同来判断是否位于黑线上。

方案二:

采用采用反射式红外传感器来进行探测。

只要选择数量和合适的红外传感器,可以准确的判断出黑线的位置。

方案选择:

采用方案二。

方案一受环境光的影响太大,效果不佳而红外光不易受到环境光的干扰。

3.趋光模块

方案一:

采用单一的光敏电阻,利用其在不同的光强下阻值不同,确定小车的转向,保证其朝着光源最强的角度前进。

方案二:

采用多个光敏电阻,在小车车头摆成半圆状结构。

方案选择:

方案二精度较高,实现较为复杂,这里采用方案一,实现效果足以。

4.避障模块

方案一:

采用光电式传感器,根据白色背景和黑色反光程度的不同来判断障碍物。

方案二:

采用超声波测距的方法,利用超声波传感器,监视测量发射脉冲和接受脉冲的时间差,计算超声波和物体之间的距离。

可以将避障和寻光模块一起排列为环状结构。

方案选择:

虽然超声波测距有其性能上的优势,但价格过高,且通过算法上的优化光电式传感器测距完全可以满足设计要求,故采用方案一。

5.测距模块

方案一:

采用断电式光电开关测距。

方案二:

采用光电传感器,结合轮子外围自身所带白条,通过光电传感器红外检测单位时间内扫描到白条的个数。

方案选择:

考虑到小车的实际机械结构,如果采用方案一必然会对小车的结构有较大的改变。

方案二结构简单易于在小车上很好的固定安装,而且在软件上也易于实现。

2.硬件电路设计

智能小车总体构成:

本系统以STC89C52为控制核心,最小系统如下:

2.1主控制模块

STC89C52是一种带8K字节闪烁可编程擦出只读存储器的低电压,高性能COMMOS8的微处理器。

该器件采用ATMEL高密度非易失真存储器制造技术制造,和工业标准的MCS-51指令集和输出管脚相兼容。

STC89C52主要完成液晶显示、寻迹、避障、光源检测和车速测量等功能。

2.2电机驱动模块

电机的驱动芯片选用L298N作为驱动芯片。

工作稳定电机驱动信号由单片机提供,信号经过光耦隔离后传至PWM控制芯片L298N,通过L298N的输出引脚和两个电机相连。

L198N的连接方法如下图所示

本设计中采用脉宽调制技术(PWM)控制使能端(En),然后改变IN1和IN2的状态实现电机的正转和反转。

同时可改变脉宽的占空比来调节电机的转速。

PWM波形为周期不变的周期性高低电平信号,占空比为高电平时间除以周期,改变占空比实质上是改变了电动机的驱动电压。

下图为10%和50%占空比的PWM信号。

EnA

IN1

IN2

运转状态

0

X

X

停止

1

1

0

正转

1

0

1

反转

1

1

1

刹停

1

0

0

停止

2.2寻迹模块

当小车在白色地面行驶时,装在小车下的红外发射管发射红外线信号,经白色反射后,被接收管接受,一旦接收管接收到信号,输输出端将输出低电平,从而实现了通过红外线检测信号的功能。

将检测到的信号传到单片机的I/O口,当I/O口检测到的信号为高电平时,表明红外光被地上的黑线吸收了,表明小车正处在黑色的引线上;同理,当I/O口检测到的信号为低电平时,表明小车行驶在白色地面线上。

反射式红外传感器ST188采用高发射功率红外广电二极管和高灵敏度光电晶体管组成。

检测距离可调整范围为4—15mm;采用非接触式检测方式。

当ST188前方为白色时,ST188接收管导通,电阻值减少,输出电压降低,此时比较器同相输入端(3脚)输入电压小,比较器输出为低电平,发光二极管点亮。

如下图所示

2.3趋光避障模块

本设计采用光敏电阻检测光源从而达到趋光效果,光敏电阻阻值随光照强度增大而减小,首先在自然光条件下调节R18改变基准电压,使发光二极管点亮。

当光照强度增大,光敏电阻阻值减少,输出电压增加,此时比较器同相输入端(3脚)输入电压大,比较器输出为高电平,发光二极管熄灭,如下图所示

在进行避障时采用了反射式红外传感器ST188,放于小车前部,三个ST188,左右中间各一个,且左右两个各向各自的两边倾斜45度角。

具体算法如下:

继续执行,当再次遇到障碍物时再次执行上程序,直到绕出障碍物为止。

2.4测距和显示模块

测距采用反射式红外传感器ST188结合小车轮子外围白条,进行扫描,由单片机计算其一秒钟所扫描白条的个数乘以两白条间的距离即可。

显示部分:

控制端口如下:

RS

RW

E

D0~D7

读状态

L

H

H

状态字

写状态

L

L

高脉冲

指令码

读数据

H

H

H

数据

写数据

H

L

高脉冲

数据

2.5电源模块

小车采用单电源供电,12VDC给电机驱动芯片L298N供电,并经一降压模块输出5V给主控制芯片以及其他芯片供电,电路如图所示:

3.结论

按照要求,小车已经较好的完成了题目要求的任务。

涉及包括机械结构,硬件,软件。

其中机械结构是小车能否稳定运行的基础,硬件电路决定了小车实现的功能,而软件部分则是控制的灵魂,算法的好坏直接决定了完成任务的质量。

整个设计无疑是一个充满辛苦的过程,期间也遇到了很多的困难,不过在全组组员的共同努力下,在整个实验室同仁的无私帮助下,以及老师的指导下,最终完成任务,在此对指导老师以及各位同学一并表示感谢!

程序源代码:

/***************************************

后来修改部分:

趋光由P1.6改为P3.0

四传感器将传感器INT去掉,接上P0.3

/***************************************/

#include

#include

#defineuintunsignedint

#defineucharunsignedchar

#include"motor.h"

#include"1602.h"

#include"xunji.h"

#defineWHITE0

#defineBLACK1

sbitBUZZER=P1^7;

sbitOPT=P3^0;

sbitzhang_left=P3^3;

sbitzhang_middle=P3^4;

sbitzhang_right=P3^5;

sbitcesu=P0^4;

ucharflag=0;//全白标志位

charroad_status=0;

/******蜂鸣器发声xMs,低电平发声*****************/

voidBuzzer(ucharx)

{

BUZZER=0;

DelayMs(x);

BUZZER=1;

}

/***********趋光*******************************

函数名称:

Park

函数输入:

函数输出:

函数功能:

**********************************************/

voidPark(void)//灯亮(OPT1导通OPT=0,左拐)

{

Stop(100,100);

GoHead(0,0);

DelayMs(100);

//if(OPT==1)//这种情况下只能用do{}...while光照一下即可

//do

//{

//{GoHead(52,5);DelayMs(5);}//右转

//}while(RIGHT_ST188&MID1_ST188&MID2_ST188&LEFT_ST188);//任何一个检测到白线停止

do

{

TurnLeft(20,20);DelayMs(1000);

GoHead(20,15);

}while(OPT);

}

/***********蔽障*****************************

函数名称:

Bizhang

函数输入:

函数输出:

函数功能:

**********************************************/

voidBiZhang(void)//倒退右转90度前进_左转90度

{

GoBack(20,20);

DelayMs(200);

TurnRight(25,25);//右转90度

DelayMs(1000);

GoHead(21,21);

DelayMs(1000);

TurnLeft(25,25);//左转90度

road_status=(P0&0x0f);

while(!

zhang_left||!

zhang_middle||!

zhang_right);

road_status=(P0&0x0f);

}

/********************主函数******************/

voidmain()

{

Init();//内部资源初始化

LcdReset();//液晶初始化

DisplayListChar(0,0,"Time",4);

DispOneChar(7,0,':

');

DisplayListChar(0,1,"Speed",5);

DisplayListChar(8,1,"cm/s",4);

//DisplayListChar(8,0,"Time",4);

road_status=(P0&0x0f);//取低四位00001111

while

(1)

{

road_status=(P0&0x0f);

if((road_status==0))//一次全白

{

Buzzer(1000);//1000ms

flag++;

if(flag==1)//第一次全白,开始趋光

{

Park();//趋光

}

elseif(!

zhang_left||!

zhang_middle||!

zhang_right)

{

BiZhang();

}

elseif(flag==2)//第二次全白,终点停车

{

Stop(0,0);

EA=0;//关总中断

while

(1)

{

DispOneChar(5,0,MinuteH+0x30);//显示时间00110000x,y,*DLata,L

DispOneChar(6,0,MinuteL+0x30);//+48

DispOneChar(8,0,SecondH+0x30);

DispOneChar(9,0,SecondL+0x30);

}

}

}

DispOneChar(5,0,MinuteH+0x30);//显示时间00110000x,y,*DLata,L

DispOneChar(6,0,MinuteL+0x30);//+48

DispOneChar(8,0,SecondH+0x30);

DispOneChar(9,0,SecondL+0x30);

RoadTrack(road_status);//循迹

DispOneChar(6,1,(b/10)+0x30);//显示速度

DispOneChar(7,1,(b%10)+0x30);

Delay_10Us(5);

}

}

#definedataportP2//8位数据口#definedataportP0

#definebusy0x80//忙检测DB7DB7=1忙,DB7=0允许读写

sbitrs=P0^7;//寄存器选择输入端(硬件)

sbitrw=P0^6;//读写控制输入端(硬件)

sbite=P0^5;//使能信号输入端(硬件)

/*****************************液晶显示头文件*******************************/

/*--------简易延时函数---------*/

voiddelay(unsignedinti)

{

for(i;i>0;i--);

}

voidDelay5Ms(void)

{

uintTemp=4552;

while(Temp--);

}

/*--------------延时--------*/

voidLcddelay(unsignedcharMS)

{

unsignedchari,j;

while(MS!

=0)

{

j=4;

while(j!

=0)

{

i=0xf0;

while(i!

=0)

{

i--;

}

j--;

}

MS--;

}

}

/*---------------检测lcd状态--------------------*/

voidWaitForEnable(void)//等待使能

{

dataport=0xff;//dataport=P2;P2=0xff;

rs=0;

rw=1;

Lcddelay(5);

_nop_();

e=1;

_nop_();

_nop_();//DB7=1忙,DB7=0允许读写

while(dataport&busy);//busy=0x8010000000

e=0;

}

/*--------------------写命令--------------*/

voidLcdWriteCommand(unsignedcharCMD,unsignedcharAttribC)

{

if(AttribC)//en需要一个高脉冲读出/写入

WaitForEnable();

rs=0;

rw=0;

_nop_();

dataport=CMD;

Lcddelay(5);

_nop_();

e=1;

_nop_();

_nop_();

e=0;

}

/*----------显示光标定位------------*/

voidLocateXY(charpolx,charpoly)

{

unsignedchartemp;

temp=polx&0x0f;//0xf=0x0f

poly&=0x01;

if(poly)

temp|=0x40;

temp|=0x80;

LcdWriteCommand(temp,0);

}

/*------------写字符---------------*/

voidLcdWriteLata(charlataW)

{

WaitForEnable();//检测忙否且en需要一个高脉冲读出/写入

rs=1;

rw=0;

_nop_();

dataport=lataW;

Lcddelay(5);

_nop_();

e=1;

_nop_();

_nop_();

e=0;

}

/*-------------在指定位置显示单个字符-----------------*/

voidDispOneChar(unsignedcharx,unsignedchary,unsignedcharWlata)

{

LocateXY(x,y);

LcdWriteLata(Wlata);

}

/*---------初始化----------*/

voidLcdReset(void)

{

LcdWriteCommand(0x38,0);//显示模块设置00111000;

Lcddelay(5);

LcdWriteCommand(0x38,0);

Lcddelay(5);

LcdWriteCommand(0x38,0);

Lcddelay(5);

LcdWriteCommand(0x38,1);//清屏

LcdWriteCommand(0x08,1);//00001000关显示,不显示光标,光标不闪烁;

LcdWriteCommand(0x01,1);

LcdWriteCommand(0x06,1);

LcdWriteCommand(0x0c,1);

}

/*---在指定位置显示字符串---*///

voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DLata,unsignedcharL)

{

unsignedchari;

for(i=0;i

DispOneChar(X++,Y,DLata[i]);

}

//扫到白线输出为低

/***********道路检测循迹**********************

函数名称:

RoadTrack

函数输入:

函数输出:

函数功能:

**********************************************/

voidRoadTrack(road_status)

{

switch(road_status)

{

case1:

GoHead(64,30);break;//小小右转00010x01

case3:

GoHead(65,13);break;//小右转00110x03//

case7:

GoHead(65,6);break;//大右转01110x07//

case11:

GoHead(80,81);break;//直线前进10110x0b//

case13:

GoHead(80,81);break;//直线前进11010x0d//

case9:

GoHead(80,81);break;//直线前进10010x09//

case8:

GoHead(30,64);break;//小小左转10000x08

case12:

GoHead(13,65);break;//小左转11000x0c//

case14:

GoHead(6,64);break;//大左转11100x0e//

case15:

GoBack(20,21);DelayMs

(2);break;//倒退1111//0x0f

//case0x00:

GoBack(50,50);break;//直线后退

default:

break;

}

}

/*

//***********直道循迹**********************

voidRoadTrackZ()

{

road_status=P0&0x0f;

switch(road_status)

{

case0x09:

GoHead(50,50);DelayMs

(2);break;//1001前进

//一下:

P0.0-P0.3

case0x0d:

GoHead(40,55);break;//1011一级左转

case0x0c:

GoHea

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1