您现在的位置:数码 >> 数码介绍 >> 单片机实训报告

微型计算机控制系统实训报告

实训题目:智能小车跟随系统

学生姓名:寇景云

学号:

专业:自动化

班级:自19-1

实训任务书

实训题目:智能小车跟随系统

一、实训目的:

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

二、实训内容:

本实训题目为智能小车跟随系统,主要研究小车跟随障碍物行走,小车遇到障碍物时,由于超声波系统能够监测小车距离障碍物的距离,当监测距离在其范围内时,跟随障碍物行走。因为超声波在距离检测方面的较准确定位,所以采用超声波传感器作为探测装置。由于超声波遇到障碍物时发生像光一样的反射和散射,在经过多次发射之后再回到超声波检测端口会产生较严重的路程差,从而影响对距离的检测进而影响对障碍物的较准确定位。通过软件内部校准优化消除外部物理条件造成的误差而达到对障碍物的较准确定位。

障碍物检测是智能小车对周边环境感知技术研究领域中的重要组成部分,以单片机为核心的结构简单、精度较高、测距较长、可靠性较高障碍物检测系统对智能小车的研究有很重要的社会意义。

目录

一、实验方案

1、任务描述

2、任务要求

二、系统组成及工作原理

1、整体组成(包括控制原理介绍)

2、分模块介绍(根据具体模块分别介绍、包括控制原理介绍)

3、控制结构、原理及控制算法

三、功能方案及程序设计

1、功能设计

2、程序设计

四、实训过程

五、实验现象及结果分析

六、实训心得

参考文献

附录(硬件原理图、程序流程图等)

一、实训方案

1、任务描述

(1)、掌握并熟悉单片机的应用方法以及各个模块的功能。

(2)、掌握单片机应用系统一般的设计过程。

(3)、提升动手能力与团队合作能力。

(4)、熟悉超声波、红外检测的原理,通过自行设计程序,实现小车遇到障碍物并且跟随障碍物走。

2、任务要求

(1)、熟悉小车跟随避障基本原理。

(2)、熟悉红外检测功能。

(3)、实现小车避障、跟随功能。

(4)、画出小车用到器件的原理图。

(5)、以组为单位,自拟增加至少一项特色功能(超声波)。

二、系统的组成及工作原理

1、整体组成

小车结构有如下构成:USB供电、步进电机、流水灯、红外发射、LCD、LCD、WIFI、蓝牙模块、CH烧录模块、AD/DA转换模块、DS时钟模块、电可擦存储IC、51最小系统、4*4按键、红外接收、复位按键、供电口、蜂鸣器、DS18B20、8*8数码管、超声波模块等。

2、分模块介绍

(1)超声波模块

超声波传感器是本控制系统的核心模块之一,相当于小车的眼睛,小车启动后,超声波就开始寻找跟随物以确定小车前进方向,进行判断后再进行控制,控制模块是决定系统将要进行什么工作的,如小车应该左转弯、右转弯还是前进,小车行驶过程距离障碍物(跟随物)有多少。超声波传感器原理图如下:

超声波模块与单片机的P30、P31连接,其1脚接电源,2脚连接接收端Echo,3脚连接控制端Trlg,4脚连接VCC。

(2)51最小系统

此模块是小车的最重要部分,它控制着超声测距模块、数码管显示模块、检测提示模块等。单片机通过计时器记录超声波发射和接收的时间差,来计算出小车距离障碍物的距离,如下图原理图:

(3)检测提示模块

检测提示模块原理图如下:

(4)电机模块

电机模块原理图如下:

(5)红外检测模块

红外检测模块原理图如下:

(6)供电模块

供电模块原理图如下:

1、功能设计

实现小车避障功能,要求实现小车跟随同时避障,红外线能够感应到障碍物并跟随着障碍物移动,当左侧传感器检测到障碍物左侧灯会亮,向左拐。当右侧传感器检测到障碍物右侧灯会亮,向右拐。当两个传感器同时检测到障碍物两个灯都会亮,直行。如果两个传感器都没有检测到障碍物两个等都不会亮,停止。

2、程序设计

该方案是先确定主程序,之后再根据各硬件电路功能来设计子程序模块, 再将各模块嵌入主程序中。

小车设计程序如下:

#includereg52.h//包含52系统头文件

#include"bst_car.h"//包含bst_car.h智能小车头文件

#includeintrins.h

#defineLCM_DataP0//

#defineBusy0x80//用于检测LCM状态字中的Busy标识

sbitDU=P2^6;//74hc53le低电平有效引脚

sbitWE=P2^7;//另一片74hc53驱动le脚

sbitRX=P2^0;//Echo接收端超声波模块

sbitTX=P2^1;//Trig发送端

sbitLCM_RW=P1^1;//定义LCD引脚,读写选择端,高电平读,低电平写

sbitLCM_RS=P1^0;//数据命令选择端,高电平选择数据存储器,低电平选择指令存储器

sbitLCM_E=P2^5;//E脚

voidLCMInit(void);//LCD初始化函数

voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData);//LCD显示一个字符函数

voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData);//LCD显示一个字符串函数

voidDelay5Ms(void);//延时5毫秒函数

voidDelayMs(void);//延时毫秒函数

voidDecode(unsignedcharScanCode);

voidWriteDataLCM(unsignedcharWDLCM);//LCD写数据函数

voidWriteCommandLCM(unsignedcharWCLCM,BuysC);//LCD写命令函数

//unsignedcharReadDataLCM(void);

unsignedcharReadStatusLCM(void);//

unsignedcharcodeRange[]="==RangeFinder==";//LCD显示格式

unsignedcharcodeASCII[13]=".-M";//

unsignedcharcodetable[]="Distance:.0cm";//

unsignedcharcodetable1[]="!!!Outofrange";//

//staticunsignedcharDisNum=0;//显示用指针

unsignedinttime=0;//测距来回的时间

unsignedlongS=0;//测距长度z

bitfla=0;//标志位

unsignedchardisbuff[4]={0,0,0,0,};//

unsignedcharpwm_val_left=0;//占空比有关变量定义

unsignedcharpwm_val_right=0;//

unsignedcharpush_val_left=6;//左电机占空比N/20//速度调节变量0-20。。。0最小,20

unsignedcharpush_val_right=6;//右电机占空比N/20

bitRight_PWM_ON=1;//右电机PWM开关

bitLeft_PWM_ON=1;//左电机PWM开关

//延时函数

voiddelay(unsignedintxms)//

{

unsignedinti,j;

for(i=xms;i0;i--)//i=xms即延时约xms毫秒

for(j=;j0;j--);

}

//前进

voidrun(void)

{

Left_moto_go;//左电机往前走

Right_moto_go;//右电机往前走

}

//左转

voidleftrun(void)

{

右电机往前走

Left_moto_Stop;//左电机停止

}

//右转

voidrightrun(void)

{

Left_moto_go;//左电机往前走

Right_moto_Stop;//右电机往前走

}

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

//PWM调制电机转速

//左电机调速

/*调节push_val_left的值改变电机转速,占空比*/

voidpwm_out_left_moto(void)

{

if(Left_PWM_ON)//

{

if(pwm_val_left=push_val_left)//

{

EN1=1;//左边

}

else

{

EN1=0;

}

if(pwm_val_left=20)

pwm_val_left=0;//清零

}

else

{

EN1=0;//若未开启PWM则EN1=0左电机停止

}

}

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

/*右电机调速*/

voidpwm_out_right_moto(void)

{

if(Right_PWM_ON)

{

if(pwm_val_right=push_val_right)//20ms内电平信号11111

{

EN2=1;//占空比6:20

}

else

{

EN2=0;

}

if(pwm_val_right=20)

pwm_val_right=0;

}

else

{

EN2=0;//若未开启PWM则EN2=0右电机停止

}

}

voidcmg88()//关数码管

{

DU=1;//2.6给高电平灭LED使能

P0=0X00;//八位双向数据线给低电平共阴极灭灯

DU=0;//另一片

}

voidWriteDataLCM(unsignedcharWDLCM)

{

ReadStatusLCM();//检测忙

LCM_Data=WDLCM;//

LCM_RS=1;//10RS1RW0E0写数据

LCM_RW=0;//

LCM_E=0;//若晶振速度太高可以在这后加小的延时

LCM_E=0;//延时断使能再开

LCM_E=1;//

}

//写指令

voidWriteCommandLCM(unsignedcharWCLCM,BuysC)//BuysC为0时忽略忙检测

{

if(BuysC)ReadStatusLCM();//根据需要检测忙

LCM_Data=WCLCM;//

LCM_RS=0;//00写命令

LCM_RW=0;//

LCM_E=0;//

LCM_E=0;//同理延时

LCM_E=1;//

}

//读状态

unsignedcharReadStatusLCM(void)

{

LCM_Data=0xFF;//P0给高电平LCD数据输入端

LCM_RS=0;//01读状态

LCM_RW=1;//

LCM_E=0;//

LCM_E=0;//

LCM_E=1;//

while(LCM_DataBusy);//检测忙信号

return(LCM_Data);//

}

voidLCMInit(void)//LCM初始化

{

LCM_Data=0;//P0给低电平LCD数据输入端

WriteCommandLCM(0x38,0);//三次显示模式设置,不检测忙信号0x38为显示模式设置

Delay5Ms();

WriteCommandLCM(0x38,0);

WriteCommandLCM(0x38,1);//显示模式设置,开始要求每次检测忙信号

WriteCommandLCM(0x08,1);//关闭显示

WriteCommandLCM(0x01,1);//显示清屏

WriteCommandLCM(0x06,1);//显示光标移动设置

WriteCommandLCM(0x0c,1);//显示开及光标设置

}

//按指定位置显示一个字符

voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData)

{

Y=0x1;//位与指令操作

X=0xF;//限制X不能大于15,Y不能大于1

if(Y)X

=0x40;//当要显示第二行时地址码+0x40;或

X

=0x80;//算出指令码

WriteCommandLCM(X,1);//发命令字

WriteDataLCM(DData);//发数据

}

//按指定位置显示一串字符

voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData)

{

unsignedcharListLength;//

ListLength=0;//定义开始长度为0

Y=0x1;

限制X不能大于15,Y不能大于1

while(DData[ListLength]0x19)//若到达字串尾则退出

{

if(X=0xF)//X坐标应小于0xF

{

DisplayOneChar(X,Y,DData[ListLength]);//显示单个字符

ListLength++;//

X++;//

}

}

}

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

voidConut(void)//超声波距离计算函数

{

time=TH1*+TL1;//

TH1=0;//

TL1=0;//

S=(time*1.7)/10+10;//算出来是MM距离测算1.7除二再劈成份cm再除以十就是毫米级

if((S=7)

fla==1)//超出测量范围或运算

{

fla=0;//

DisplayListChar(0,1,table1);//

}

else

{

disbuff[0]=S%10;

disbuff[1]=S/10%10;

disbuff[2]=S/%10;

disbuff[3]=S/1;

DisplayListChar(0,1,table);

DisplayOneChar(9,1,ASCII[disbuff[3]]);

DisplayOneChar(10,1,ASCII[disbuff[2]]);

DisplayOneChar(11,1,ASCII[disbuff[1]]);

DisplayOneChar(12,1,ASCII[10]);

DisplayOneChar(13,1,ASCII[disbuff[0]]);

}

}

voidzd0()interrupt3//T0中断用来计数器溢出,超过测距范围

{

fla=1;//中断溢出标志

RX=0;//关闭接收口2.0

}

voidStartModule()//启动模块

{

TX=1;//启动一次模块发送端2.1口置1使能

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

TX=0;

}

voidTimer_Count(void)//超声波高电平脉冲宽度计算函数

{

TR1=1;//开启计数

while(RX);//当接收口RX为1计数并等待等待接收

TR1=0;//关闭计数

Conut();//计算

}

//5ms延时

voidDelay5Ms(void)

{

unsignedintTempCyc=;//

while(TempCyc--);//

}

//ms延时

voidDelayMs(void)

{

unsignedcharTempCycA=5;//

unsignedintTempCycB;//

while(TempCycA--)//

{

TempCycB=;//

while(TempCycB--);

};

}

//TIMER0(函数名,定时/计数器0的意思)中断服务子函数产生PWM信号

voidtimer0()interrupt1using2//1:BH定时器0中断入口地址2:寄存器10H-17H组

{

TH0=0XFC;//1Ms定时说明定时器工作在方式1

TL0=0X66;//11.脉冲个数位其/12=个TH0=(-)/=0xfc%=0x66

pwm_val_left++;//变量的标志位增加

pwm_val_right++;//

pwm_out_left_moto();//电机调速调用

pwm_out_right_moto();//

}

voidkeyscan(void)//按键扫描函数

{

A:if(K4==0)//判断是否有按下信号

{

delay(10);//延时10ms消抖

if(K4==0)//再次判断是否按下

{

FM=0;//蜂鸣器响

while(K4==0);//判断是否松开按键

FM=1;//蜂鸣器停止

}

else

{

gotoA;//跳转到A重新检测

}

}

else

{

gotoA;//跳转到A重新检测

}

}

voidmaichongjisuan()

{

unsignedintvalA;//

for(valA=;valA0;valA--)//循环

{

//有信号为0没有信号为1

if(Left_2_led==0Right_2_led==0)

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

if(Left_2_led==0Right_2_led==1)//左边检测到障碍物

{

leftrun();//调用小车左转函数

}

if(Right_2_led==0Left_2_led==1)//右边检测到障碍物

{

rightrun();//调用小车右转函数

}

if(RX==1)

{

Timer_Count();//超声波高电平脉冲宽度计算函数

}

}

}

//主函数

voidmain(void)

{

P1=0X00;//关电机电机用P1口控制

keyscan();//按键启动检测

delay(1);//1s后启动

TMOD

=0X01;//采用或的方式T0方式1,门控0与外部无关定时

TMOD

=0x10;//T0方式1门控1受外控定时

TH0=0XFC;//1ms定时定时器0的高八位

TL0=0X66;//

TR0=1;//定时器0的启动位

ET0=1;//定时器0溢出中断控制位

TH1=0;//

TL1=0;

ET1=1;//允许T0中断

EA=1;//开总中断

cmg88();//关数码管

LCMInit();//LCM初始化

Delay5Ms();//延时片刻

DisplayListChar(0,0,Range);//

DisplayListChar(0,1,table);//

while(1)//无限循环

{

RX=1;//接收端给高电平2.0

StartModule();//启动模块

maichongjisuan();//用计算函数算脉冲宽度

}

}

四、实训过程

三人一组为单位进行智能小车的程序的设计以及运行,前期一人负责小车组装以及小车零件的检验测试,两人负责程序的编程以及文献的查阅,后期三人负责调试以及程序的修改。对原理图进行分析,熟悉并掌握原理图功能以及实物的运行。对程序反复钻研,反复揣摩,以达到掌握的程度。

五、实验现象及结果分析

(1)首先把小车放到空旷的地板上,启动小车后自动开始寻找跟随物体。

(2)找到跟随物体后,小车调整方向,向着跟随物体前进。

(3)小车在跟随的过程中,数码管会显示物体的距离。

(4)红外线能够感应到障碍物并跟随着障碍物移动,当左侧传感器检测到障碍物左侧灯会亮,向左拐。当右侧传感器检测到障碍物右侧灯会亮,向右拐。当两个传感器同时检测到障碍物两个灯都会亮,直行。如果两个传感器都没有检测到障碍物两个等都不会亮,停止。

(5)对避障控制模拟运行的验收。

(6)实物小车如下图:

六、实训心得

本次智能小车在硬件上采用了超声波传感器和红外传感器跟随障碍物行走。在软件上充分利用了STC89C51的系统资源,使智能小车完美的实现了障碍物检测、障碍物测距并跟随障碍物行走等功能。本次小车结构简单,调试方便,系统反应灵活等。

通过这次实训,让自己很清楚的认清自己对于单片机哪一部分不怎么熟悉熟练,锻炼了自己的动手能力和团队的合作能力,这次实训让自己学到了很多的新知识,再一次了解到单片机是个什么样的概念而不是仅仅只局限于课本知识,通过操作让自己更加熟悉单片机,熟悉最小的51系统,通过拓展自己添加新的内容超声波模块,更加锻炼了自己的能力,也非常感谢能有一次这样的实训机会。

附智能小车红外避障接线图:



转载请注明地址:http://www.abmjc.com/zcmbzl/1873.html