基于51单片机的避障小车设计.docx

上传人:b****8 文档编号:9898122 上传时间:2023-02-07 格式:DOCX 页数:17 大小:160.79KB
下载 相关 举报
基于51单片机的避障小车设计.docx_第1页
第1页 / 共17页
基于51单片机的避障小车设计.docx_第2页
第2页 / 共17页
基于51单片机的避障小车设计.docx_第3页
第3页 / 共17页
基于51单片机的避障小车设计.docx_第4页
第4页 / 共17页
基于51单片机的避障小车设计.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

基于51单片机的避障小车设计.docx

《基于51单片机的避障小车设计.docx》由会员分享,可在线阅读,更多相关《基于51单片机的避障小车设计.docx(17页珍藏版)》请在冰豆网上搜索。

基于51单片机的避障小车设计.docx

基于51单片机的避障小车设计

单片机原理及系统课程设计

评语:

 

考勤10分

守纪10分

过程30分

设计报告30分

答辩10分

总成绩(100分)

专业:

班级:

姓名:

学号:

指导教师:

 

基于单片机的避障小车设计

1引言

本课程设计以AT89C51单片机为核心,完成了一辆利用超声波传感器来实现避障功能的小车,使小车对其运动方向受到的阻碍作出躲避动作。

本次设计主要研究小车的避障功能,当距离障碍物大于30cm时,小车前进;当距离障碍物小于20cm时,小车停止,舵机分别旋转到前、左、右三向,从而使超声波模块进行测距,并且小车采取相应的避障措施。

2整体设计方案及原理

2.1总体设计方案

本系统选用AT89C51单片机为主控机。

通过扩展必要的外围接口电路,实现对避障小车的设计,具体设计如下:

(1)由于小车要进行测距,为了得到较好的避障效果和较精确的距离信息,经综合分析后,决定采用超声波模块进行非接触型测距。

避障小车与障碍物之间的实际距离通过数码管进行显示。

(2)避障小车采用差速方式控制行进方向,通过四个直流电机控制四轮旋转,并采用L298N双H桥直流电机驱动芯片控制直流电机正反转。

(3)超声波模块分别检测前方、左侧及右侧与障碍物之间的距离,因此需要采用舵机进行旋转完成超声波模块三向测距。

2.2系统组成框图

系统模块图如图1所示。

图1系统模块图

3硬件设计

本设计选用AT89C51单片机为主控单元;驱动部分:

采用L298N双H桥直流电机驱动模块;测距避障部分:

采用US100超声波传感器模块;此外,还采用SG90舵机,实现超声波模块方向的变化。

该系统整体电路原理图如附图1所示。

3.1电机驱动模块

本次课程设计采用L298N双H桥直流电机驱动模块,采用SGS公司原装全新的L298N芯片,内部包含4通道逻辑驱动电路,可以直接驱动两路3-16V直流电机,并提供了5V输出接口(输入最低只要6V),可以给5V单片机电路系统供电(低纹波系数),是智能小车电机驱动的必备利器。

L298N芯片是一种二相和四相电机的专用驱动器,即内含二个H桥的高电压大电流双全桥式驱动器,接收标准TTL逻辑电平信号,可驱动46V、2A以下的电机。

该芯片引脚中,1脚和15脚可单独引出连接电流采样电阻器,形成电流传感信号。

L298N可驱动2个电机,OUTl、OUT2和OUT3、OUT4之间分别接2个电动机。

5、7、10、12脚接输入控制电平,控制电机的正反转,ENA,ENB接控制使能端,控制电机的停转。

电机驱动模块电路如图2所示。

图2电机驱动模块电路

3.2测距避障模块

智能车避障系统中的传感器一般分为接触型和非接触型两种,接触型相对比较简单。

本次设计使用了超声波传感器进行测量,也即非接触型传感器。

US-100超声波测距模块可实现0~4.5m的非接触测距功能,拥有2.4~5.5V的宽电压输入范围,静态功耗低于2mA,自带温度传感器对测距结果进行校正,同时具有GPIO,串口等多种通信方式,内带看门狗,工作稳定可靠。

超声波是一种振动频率高于声波的机械波,由换能晶片在电压的激励下发生震动产生的,在碰到杂质获分界面会产生显著反射从而形成反射回波,超声波传感器就是根据超声波在障碍物界面上的反射来判断检测物体的存在及距离。

3.3SG90舵机

SG90舵机是一种位置伺服的驱动器,主要是由外壳、电路板、无核心马达、齿轮与位置检测器所构成。

该舵机旋转的角度范围是0度到180度。

SG90舵机外接三根线,分别用棕、红、橙三种颜色进行区分,棕色为接地线,红色为电源正极线,橙色为信号线。

舵机转动的角度是通过调节PWM信号的占空比来实现的。

工作原理是由接收机或者单片机发出信号给舵机,其内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。

经由电路板上的IC判断转动方向,再驱动无核心马达开始转动,透过减速齿轮将动力传至摆臂,同时由位置检测器送回信号,判断是否已经到达定位。

其适用于那些需要角度不断变化并可以保持的控制系统。

3.4单片机控制模块

单片机是靠程序运行的,并且可以通过修改程序实现不同的功能,尤其是一些特殊复杂的功能。

通过使用单片机编写程序完成控制功能,可以实现高智能,高效率,以及高可靠性。

单片机控制模块电路如图3所示。

图3单片机控制模块电路

4软件设计

4.1流程图

系统总流程图如附录1所示。

4.2程序清单

C语言编辑程序,程序清单如附录2所示。

4.3软件调试

软件的调试主要通过KeiluVision2软件进行操作,对程序编写过程中的错误进行查找,找出错误,进行修改,然后再进行编译直至编译成功,生成HEX文件,才能下载到单片机里,继而实现相应功能。

4.4系统仿真及实际调试

在程序设计方法上,模块化程序设计是单片机应用中最常用的程序设计方法.设计的中心思想是把一个复杂应用程序按整体功能划分成若干相对独立的程序模块,各模块可以单独设计、编程和调试,然后组合起来.这种方法便于设计和调试,容易实现多个程序共存,但各个模块之间的连接有一定的难度.根据需要我们可以采用自上而下的程序设计方法,此方法先从主程序开始设计,然后再编制各从属程序和子程序,层层细化逐步求精,最终完成一个复杂程序的设计.

通过对实际性能的分析,可以得到本次设计满足设计的要求。

4.5出现故障及其原因

(1)外接电源正负极接反,导致小车电机驱动模块损坏。

(2)实践经验不够丰富,解决实际问题需要花费较多的时间。

5总结

本次课程设计是对所学知识的一次综合性运用。

在设计的过程中发现了自身知识的不足,也发现我们必须具备专业基础知识,才能成功的设计出一件合格的东西。

这次课程设计收获很多,也学会了很多新的东西,比如一些仿真软件的应用,最典型的就是PROTEUS软件的应用,以及与KEIL软件的联合使用。

我觉得在这次设计的过程中,很多自己解决不了的问题,只有虚心请教别人才能有效的解决问题,我觉得人与人之间的相互帮助很有必要,这样不仅能帮助大家很快的解决问题,还能提高我们每个人的实际水平,这些能力对于我们今后的学习和工作都很有帮助。

其次就本次设计而言,避障小车应进行更加先进调速控制,如果能够进一步增加测速模块以及速度显示,该避障小车的功能将更加强大。

在本次设计过程中遇到不少问题,在王思明老师和同学的帮助和配合下才顺利的完成了本次课程设计。

王思明老师给予了我们极大的帮助,不仅从知识方面引导了我们的设计思路,同时,在人生观上也给了我们不少的启示。

6参考文献

[1]王思明.单片机原理及应用系统设计[M].北京:

科学出版社,2012

[2]胡辉.单片机原理与应用[M].北京:

中国水利水电出版社,2007:

10-38.

[3]林志琦.单片机原理接口及应用[M].北京:

中国水利水电出版社,2007:

25-54.

[4]赵克林.C语言实例教程[M].北京:

人民邮电出版社,2007:

48-96.

[5]姜承昊.应用与制造新技术新工艺[M].北京:

中国科学技术文献出版社,2008:

37-95.

 

附录1

图2系统总流程图

附录2

//名称:

基于51单片机的避障小车

#include

#include

#defineSevro_moto_pwmP2_7//接舵机信号端输入PWM信号调节速度

#defineECHOP2_4//超声波接口定义

#defineTRIGP2_5//超声波接口定义

#defineLeft_moto_go{P1_0=1,P1_1=0,P1_2=1,P1_3=0;}//左边两电机向前走

#defineLeft_moto_back{P1_0=0,P1_1=1,P1_2=0,P1_3=1;}//左边两电机向后转

#defineLeft_moto_Stop{P1_0=0,P1_1=0,P1_2=0,P1_3=0;}//左边两电机停转

#defineRight_moto_go{P1_4=1,P1_5=0,P1_6=1,P1_7=0;}//右边两电机向前走

#defineRight_moto_back{P1_4=0,P1_5=1,P1_6=0,P1_7=1;}//右边两电机向前走

#defineRight_moto_Stop{P1_4=0,P1_5=0,P1_6=0,P1_7=0;}//右边两电机停转

unsignedcharconstdiscode[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff/*-*/};//定义表

unsignedcharconstpositon[3]={0xfe,0xfd,0xfb};

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

unsignedcharposit=0;//全局变量

unsignedcharpwm_val_left=0;//变量定义

unsignedcharpush_val_left=14;//舵机归中,产生约,1.5MS信号

unsignedlongS=0;

unsignedlongS1=0;

unsignedlongS2=0;

unsignedlongS3=0;

unsignedlongS4=0;

unsignedinttime=0;//时间变量

unsignedinttimer=0;//延时基准变量

unsignedchartimer1=0;//扫描时间变量

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

voiddelay(unsignedintk)//延时函数,输入外循环变量k

{

unsignedintx,y;//总延时时间,(若晶振12MHZ)延时时间(t=2*k)ms

for(x=0;x

for(y=0;y<2000;y++);

}

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

voidDisplay(void)//扫描数码管

{

if(posit==0)

{P0=(discode[disbuff[posit]])&0x7f;}//产生点

else

{P0=discode[disbuff[posit]];}

if(posit==0)

{P2_1=0;P2_2=1;P2_3=1;}

if(posit==1)

{P2_1=1;P2_2=0;P2_3=1;}

if(posit==2)

{P2_1=1;P2_2=1;P2_3=0;}

if(++posit>=3)

posit=0;

}

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

voidStartModule()//启动测距信号

{

TRIG=1;

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

TRIG=0;

}

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

voidConut(void)//计算距离

{

while(!

ECHO);//当RX为零时等待

TR0=1;//开启计数

while(ECHO);//当RX为1计数并等待

TR0=0;//关闭计数

time=TH0*256+TL0;//读取脉宽长度

TH0=0;

TL0=0;

S=(time*1.7)/100;//算出来是CM

disbuff[0]=S%1000/100;//更新显示

disbuff[1]=S%1000%100/10;

disbuff[2]=S%1000%10%10;

}

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

voidrun(void)//前速前进

{

Left_moto_go;//左电机往前走

Right_moto_go;//右电机往前走

}

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

voidbackrun(void)//前速后退

{

Left_moto_back;//左电机往前走

Right_moto_back;//右电机往前走

}

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

voidleftrun(void)//左转

{

Left_moto_back;//左电机往前走

Right_moto_go;//右电机往前走

}

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

voidrightrun(void)//右转

{

Left_moto_go;//左电机往前走

Right_moto_back;//右电机往前走

}

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

voidstoprun(void)//停止前进

{

Left_moto_Stop;//左电机停走

Right_moto_Stop;//右电机停走

}

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

voidCOMM(void)

{

push_val_left=5;//舵机向左转90度

timer=0;

while(timer<=4000);//延时400MS让舵机转到其位置

StartModule();//启动超声波测距

Conut();//计算距离

S2=S;

push_val_left=23;//舵机向右转90度

timer=0;

while(timer<=4000);//延时400MS让舵机转到其位置

StartModule();//启动超声波测距

Conut();//计算距离

S4=S;

push_val_left=14;//舵机归中

timer=0;

while(timer<=4000);//延时400MS让舵机转到其位置

StartModule();//启动超声波测距

Conut();//计算距离

S1=S;

if((S2<20)||(S4<20))//只要左右各有距离小于,20CM小车后退

{

backrun();//后退

timer=0;

while(timer<=4000);

}

if(S2>S4)

{

rightrun();//车的左边比车的右边距离小右转

timer=0;

while(timer<=4000);

}

else

{

leftrun();//车的左边比车的右边距离大左转

timer=0;

while(timer<=4000);

}

}

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

/*PWM调制电机转速*/

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

/*左电机调速*/

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

voidpwm_Servomoto(void)

{

if(pwm_val_left<=push_val_left)

Sevro_moto_pwm=1;

else

Sevro_moto_pwm=0;

if(pwm_val_left>=200)

pwm_val_left=0;

}

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

///*TIMER1中断服务子函数产生PWM信号*/

voidtime1()interrupt3using2

{

TH1=(65536-100)/256;//100US定时

TL1=(65536-100)%256;

timer++;//定时器100US为准。

在这个基础上延时

pwm_val_left++;

pwm_Servomoto();

timer1++;//2MS扫一次数码管

if(timer1>=20)

{

timer1=0;

Display();

}

}

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

///*TIMER0中断服务子函数产生PWM信号*/

voidtimer0()interrupt1using0

{

}

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

voidmain(void)//主函数

{

TMOD=0X11;

TH1=(65536-100)/256;//100US定时

TL1=(65536-100)%256;

TH0=0;

TL0=0;

TR1=1;

ET1=1;

ET0=1;

EA=1;

delay(100);//延时时间0.2s

push_val_left=14;//舵机归中

while

(1)/*无限循环*/

{

if(timer>=1000)//100MS检测启动检测一次

{

timer=0;

StartModule();//启动检测

Conut();//计算距离

if(S<20)//距离小于20CM

{

stoprun();//小车停止

COMM();//方向函数

}

else

if(S>30)//距离大于,30CM往前走

run();

}

}

}

 

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

当前位置:首页 > 工程科技 > 城乡园林规划

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

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