视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
超声波避障小车研究报告
2025-10-04 09:48:13 责编:小OO
文档


超声波避障小车项目研究报告

项目组成员:计科专业0901 

余恒洋
计科专业0901

吴林
生医专业0902

史思总
“智能机器人”创新实践班

2011年5月20日

摘    要

Mega16是AVR系列单片机里应用比较广泛的一款,在自动控制领域里享有很高的价值,以其易用性和多功能性受到了广大电子设计及爱好者的好评。本次设计主要是利用mega16单片机、超声波传感器和L298N完成避障小车的制作,以ATmega16为主控芯片,利用超声波对距离的检测将前方的障碍探测出来并且通过超声波传回的数据进行判断,然后ATmega16发出指令控制电机的转动。

关键词:超声波传感器  避障小车  ATmega16   

绪论

项目研究背景及意义

随着汽车工业的快速发展,关于汽车的研究也越来越受到人们的关注。智能汽车概念的提出给汽车产业带来机遇也带了挑战。汽车的智能化必将是未来汽车产业发展的趋势,在这样的背景下,我们开展了基于超声波的智能小车的避障研究。

超声波作为智能车避障的一种重要手段,以其避障实现方便,计算简单,易于做到实时控制,测量精度也能达到实用的要求,在未来汽车智能化进程中必将得到广泛应用。我国作为一个世界大国,在高科技领域也必须占据一席之地,未来汽车的智能化是汽车产业发展必然的,在这种情况下研究超声波在智能车避障上的应用具有深远意义,这将对我国未来智能汽车的研究在世界高科技领域占据领先地位具有重要作用。

项目主要研究内容

超声波在距离检测方面的较准确定位。超声波传感器主要发射高频超声波,在遇到障碍物时发生像光一样的反射和散射,在经过多次发射之后再回到超声波检测端口会产生较严重的路程差,从而影响对距离的检测进而影响对障碍物的较准确定位。通过软件内部校准优化消除外部物理条件造成的误差从而达到对障碍物的较准确定位。

总体设计方案及论证

总体方案设计

系统采用ATMEL的8位微控制器ATmega8单片机作为核心控制单元用于智能车系统的控制,在超声波检测到障碍物之后,主控芯片根据距离值控制直流电机的转动,在转动的方案上将首先尝试左转,在900ms里面连续转动三次说明前方的障碍不能通过,就控制小车后退,并且向相反的方向转动。系统总体的设计方框图如图2-1所示。

图221 系统总体方案图

  

 图1.2系统总体方框图

硬件设计

电源设计

电源部分的设计主要采用7805芯片,使用7805芯片搭建的电路的优点是简单、实用,并且完全能够满足壁障小车单片机控制系统和L298N芯片的逻辑供电的供电需要。7805芯片有3个引脚,分别为输入IN端、输出OUT端和接地GND端,通常情况下可以提供1.5A的电流,在散热足够的情况下可以提供大于1.5A的电流。7805芯片的输入电压可以为9V、12V、15V不等,输出电压稳定在5V,正负误差不超过0.2V。7805芯片如图2-2。基于这样的情况再结合电机的工作电压,选取了12V电源作为7805的输入电源,搭建的电源部分电路如图2-3

        图 22  7805芯片

电机驱动设计 

电机驱动部分主要采用一片L298N和主控芯片ATmega16单片机直接相连够成驱动电路。L298N芯片直插式的15个引脚,其中有两个使能端ENA和ENB,两个反馈端SA和SB,四个输入端IN1、IN2、IN3和IN4,四个输出端OUT1、OUT2、OUT3和OUT4,一个接地端GND,一个VSS(5V时性能最好)逻辑电源电压输入端和一个VS(最大承载电压46V,鉴于7805和电机电压,选取12V电源供电)功率电源电压输入端。L298N可同时驱动两个电机,最大输出电流为2A,鉴于它的良好性能和价格,选取L298N作为电机驱动芯片,L298N芯片如图2-3。ATmega16的PB4、PB5两个端口直接分别与L298N的两个使能端ENA、ENB相连,控制电机转停的目的。PD0~PD3端口分别与L298N的引脚IN1、IN2、IN3、IN4相连通过电平变化控制电机在持续高速状态下的转向。L298N的四个输出端直接与两个电机相连驱动电机。搭建的电机驱动部分电路如图2-4。

                        图2-3  L298N芯片

图2- 4 电机驱动电路图

超声波测试模块

超声波模块采用现成的HC-SR04超声波模块,该模块可提供 2cm-400cm 的非接触式距离感测功能,测距精度可达高到 3mm。模块包括超声波发射器、接收器与控制电路。

基本工作原理:采用 IO 口 TRIG 触发测距,给至少 10us 的高电平信号;模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。实物如下图2-5。其中VCC 供5V 电源,GND 为地线,TRIG 触发控制信号输入,ECHO 回响信号输出等四支线。

图2- 5 超声波模块实物图

主控系统设计    

主控系统主要采用ATmega16单片机作为处理器,系统主要包含ISP下载端口用于现在单片机程序、超声波连接端口用于和超声波模块的连接输入检测信号和输出指令信号、L298N连接端口用于和驱动电路的连接,输出电机转动信号和各类指示灯用于指示测试信号等。控制系统部分电路如图2-6

图2- 6   主控系统原理图

软件设计

 直流电机控制模块

在单片机的应用领域里面,电机控制的方法比较多,主流的控制方案有以下几种:

方案一:串电阻调速系统。

方案二:静止可控整流器。简称V-M系统。

方案三:脉宽调速系统。

旋转变流系统由交流发电机拖动直流电动机实现变流,由发电机给需要调速的直流电动机供电,调节发电机的励磁电流即可改变其输出电压,从而调节电动机的转速。改变励磁电流的方向则输出电压的极性和电动机的转向都随着改变,所以G-M系统的可逆运行是很容易实现的。该系统需要旋转变流机组,至少包含两台与调速电动机容量相当的旋转电机,还要一台励磁发电机,设备多、体积大、费用高、效率低、维护不方便等缺点。且技术落后,因此搁置不用。

V-M系统是当今直流调速系统的主要形式。它可以是单相、三相或更多相数,半波、全波、半控、全控等类型,可实现平滑调速。V-M系统的缺点是晶闸管的单向导电性,它不允许电流反向,给系统的可逆运行造成困难。它的另一个缺点是运行条件要求高,维护运行麻烦。最后,当系统处于低速运行时,系统的功率因数很低,并产生较大的谐波电流危害附近的用电设备。

采用晶闸管的直流斩波器基本原理与整流电路不同的是,在这里晶闸管不受相位控制,而是工作在开关状态。当晶闸管被触发导通时,电源电压加到电动机上,当晶闸管关断时,直流电源与电动机断开,电动机经二极管续流,两端电压接近于零。脉冲宽度调制(Pulse Width Modulation),简称PWM。脉冲周期不变,只改变晶闸管的导通时间,即通过改变脉冲宽度来进行直流调速。

与V-M系统相比,PWM调速系统有下列优点:

(1)由于PWM调速系统的开关频率较高,仅靠电枢电感的滤波作用就可以获得脉动很小的直流电流,电枢电流容易连续,系统的低速运行平稳,调速范围较宽,可达1:10000左右。由于电流波形比V-M系统好,在相同的平均电流下,电动机的损耗和发热都比较小。

(2)同样由于开关频率高,若与快速响应的电机相配合,系统可以获得很宽的频带,因此快速响应性能好,动态抗扰能力强。

(3)由于电力电子器件只工作在开关状态,主电路损耗较小,装置效率较高。

根据以上综合比较,以及本设计中受控电机的容量和直流电机调速的发展方向,本设计采用了Mega16单片机的PWM输出调速,结合LM298芯片,能够实现比较好的控制效果,在小车避障的过程中,也可以直接控制LM298芯片,改变电机的运转情况,实现简易的转向与后退等功能。

电机控制流程图:

图2- 7 电机控制流程图

    

超声波探测模块

超声波探测模块HC-SR04的使用方法如下:

IO口触发,给Trig口至少10us的高电平,启动测量;

模块自动发送8个40Khz的方波,自动检测是否有信号返回;

有信号返回,通过IO口Echo输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间,测试距离=(高电平时间*340)/ 2,单位为m。

程序中测试功能主要由两个函数完成,即measure()负责启动一次模块的测距,然后由ShouldTurn()确定前方是否有障碍物,根据车体大小及系统的反应,经过测试,取30cm的反应距离效果较为明显。另外,HC-SR04超声波探测模块探测的间隔周期推荐值是ms(图2-8),但经过试验,我们发现在我们的小系统中取125ms较为适宜,使主程序有足够的时间来驱动小车前进,而不至于出现前进不流畅的现象。

图2- 8  超声波探测模块时序图

实现中采用定时器0进行定时测量,8分频,TCNTT0预设值0XCE,当timer0溢出中断发生2500次时为125ms,计算公式为(单位:ms):

T = (定时器0溢出次数 * (0XFF - 0XCE))/ 1000 

其中定时器0初值计算依据分频不同而有差异。

超声波探测程序流程图:

图2- 9超声波探测程序流程图

软件与硬件的整合

在本次设计过程中,考虑到各个模块之间的控制复杂性,我们将电机控制,超声波测距分开调试,当两个模块都可以正常工作之后,再将它们结合起来调试,采取了“分而治之”的思想。

调试超声波模块

在调试超声波的时候,主要思想是用定时器检测超声波会送信号维持高电平的时间,用串口示波器将测得的数据显示在串口示波器上,根据返回的结果,确定达到转弯距离以内所需要的时间,然后利用时间控制电机

电机调试

在点击调试的过程中,我们首先将Mega16的PWM输出在示波器上反映出来,确保PWM波的输出正常,并且能够根据用户设定的比较值产生不同形式的输出,在比较匹配发生之后,调节其占空比,实现电机的速度控制,在控制电机转动的时候,采用直接控制LM298芯片的方式,实现左转,右转,后退等功能。

测试

由于HR-S04对于障碍物的反射面有一定要求,即不能凹凸不平,应尽量平滑,否则测量不会很准确。针对障碍物表面的平整与不平整,我们分别测试了小车的运行情况。当障碍物表面叫平整时,除非是极端的拐角处小车无法退出外(考虑到编程的复杂度以及仅仅是示意模型小车,程序中未记录小车转弯路径),小车能很好的避障;当障碍物表面不是很平整时,结果不能预测,有时小车能较好的转弯,而有时不能,这主要取决于探测模块的探测灵敏度,因为超声波和普通声波一样,有可能经过多次反射后回来的信号已出现偏差,而这程序很难实现辨别。总的说来,小车的运行结果基本达到了预期的效果,实现了演示性的避障功能。

针对以上测试结果我们对控制程序进行了细微的改进,这样考虑:由于小车只有前方一个导向源,当遇到障碍物时而不能通过时会卡死,所以我们想到在程序中设立一个计数器,记录小车探测到障碍物的次数,同时也记下记录到相应次数时所用的总的探测时间,当在短时间内测量次数达到一定数量时说明周围障碍物较多或已堵死在前方,此时让小车后退一段距离然后随机的转一个方向,再继续前进,实践中我们取得探测次数为3次,时间为6000us,即3次探测到障碍物的总时间小于6000us时就执行后退功能。经过实际测试,改进后小车避障效果表现的较为出色(当然是在只有前方一个探测器的前提下),与之前相比有很大的提高,基本不会出现小车不能继续前进的情况,达到了我们预期的效果。

结果分析

小车经过测试,运行结果良好。硬件上没有错误,主要瓶颈在于探测模块的灵敏度,因为软件完全靠探测模块返回的信号作为依据进行下一步控制的操作,无法确认该信号是否准确。为使小车转弯更加准确与智能,可以有以下改进:

(1)增加对小车转弯次数和每次转弯时前面所经过的时间的记录,这样可以进行回退,使小车显得更智能一些,不过这会增加开发难度,也会要求更多的存储空间及数据处理时间,如果处理器速度不是很快,效果可能不会太明显;

(2)增加探测模块的个数,如左右各增加一个探测器,这样同时检测多个方向,明显改进避障的效果,特别是针对墙角、三面均有障碍物的情况。

总结

本超声波避障小车的设计基于单片机原理和传感器原理,以ATmega16单片机为主控芯片,采用L298N和12V直流电机为驱动元件,通过软件编程制作了一整套结构完整,功能模块化,反应较为灵敏的超声波避障小车。经过对该避障小车的避障测试实验,实验结果证明该避障小车能够很好的按照预期完成避障动作,并且能够快速运动灵敏避障,效果良好,运行稳定性较好。

但是该超声波避障小车还存在着许多的不足,比如说只能对正前方一定角度内进行探测,使用的是一路超声波而不是多路超声波探测,并且为了简化,默认的只是向同一个方向转弯等,这些都是有待进一步发展和提高的,这与制作者自身的对与障碍检测距离分析、自动控制信号处理、图像处理等诸多技术的有限性分不开的,还需要研究制作者的学习和探索。

本次项目共历时两个月,有充分的时间来准备,但由于我们对所需器件的不熟悉导致花在器件采购上的时间较多,以后需要详细规划好项目预计使用的器材,这样可方便一次购买到位。此外项目的进度控制不是很准确,小组的执行力不够,以致有几次都没能按预计进度完成规定任务,当然技术上本身也有一定难度,但我们认为这不是主要原因,以后我们会强调时间概念,按时并且争取有效率的完成规定阶段的任务。

超声波避障小车的实物主体框架由史思总负责完成,包括硬件电路的设计与焊接和最胡的组装,吴林和余恒洋负责软件上的编写。我们分工比较明确,使得小组各成员能专注于自己的那部分任务,工作完成质量更有保证,并且查错与改错也更容易一些。

我们遇到的困难主要在于对超声波模块的使用方法不了解,实验室的模块并没有配套的资料,而网上也比较难找到它的手册资料,最后我们选择参考模板程序,然后对其进行改进使之适于自己的需求,这样也减少了从头到尾重复编写代码的时间。最初我们考虑到会使用pwm波来控制电机,但后来测试发现我们的小车速度并不快,无需pwm调速都能正常运行,故我们在项目结束时没有考虑pwm的使用,这也使我们的工作大大简化,我们总结得出:能用简单方法解决的问题便不用复杂的技术。

参考文献

[1] 邵贝贝. 嵌入式实时操作系统[LC/OS-Ⅱ(第2版)[M]. 北京.清华大学出版社.2004

[2] 邵贝贝. 单片机嵌入式应用的在线开发方法[M].北京.清华大学出社.2004

[3] 王晓明. 电动机的单片机控制[M].北京. 北京航空航天大学出版社.2002 

[4] 臧杰,阎岩. 汽车构造[M]. 北京. 机械工业出版社.2005 

[5] 安鹏,马伟.S12单片机模块应用及程序调试[J]. 电子产品世界. 2006.第211期. 162-163

[7] 童诗白,华成英.模拟电子技术基础[M].北京. 高等教育出版社.2000 

[8] 沈长生.常用电子元器件使用一读通[M].北京. 人民邮电出版社.2004 

[9] 宗光华.机器人的创意设计与实践[M].北京. 北京航空航天大学出社.2004 

[10] 张伟等.Protel DXP高级应用[M].北京. 人民邮电出版社.2002 

[11] 张文春. 汽车理论[M].北京.机械工业出版社.2005 

[12] 江海波,王卓然,耿德根编著.深入浅出AVR单片机.中国电力出版社,2008.

[13] 袁新娜,与红英编著.超声波传感器在智能小车避障系统中的应用.[A]中北大学 (2009)08-0085-04

附 录

附录一:超声波避障小车原理图

附录二:超声波避障小车PCB图

附录三:小车运行图片

附录四:超声波避障小车程序源代码

附录一:超声波避障小车原理图

附录二:超声波避障小车PCB图

附录三:小车运行图片

附录四:超声波避障小车程序源代码

///////////////////////////////

//   Motor.h

///////////////////////////////

#ifndef  _MOTOR_H_

#define  _MOTOR_H_

#include

#include

//宏定义

#define STOP_LEFT PORTC &= ~((1<#define FORWARD_R PORTC |= (1<#define BACKWARD_R PORTC &= ~(1<#define STOP_RIGHT PORTC &= ~((1<#define FORWARD_L PORTC &= ~(1<#define BACKWARD_L PORTC &= ~(1<//自定义类型

typedef unsigned char uchar;

typedef unsigned int  uint;

typedef unsigned long ulong;

typedef enum {FALSE=0,TRUE=1,LEFT,RIGHT,FORWARD,BACKWARD,STOP}BOOL;

//函数声明

void Backward(void);

void Forward(void);

void Stop(void);

void Turn(int flag);

#endif

///////////////////////////////

//   Motor.c

///////////////////////////////

#include "motor.h"

#include "delay.h"

////////////////////////////////////////////////////

void Forward(void)

{

           FORWARD_R;

         FORWARD_L;

}

///////////////////////////////////////////////////

void Backward(void)

{

     BACKWARD_R;

     BACKWARD_L;

     

}

///////////////////////////////////////////////////

void Turn(int flag)

{

      Stop();

     Delay_ms(10);

      if(flag == RIGHT)

     {

          STOP_RIGHT;

        FORWARD_L;

     }

     else if(flag == LEFT)

     {

          STOP_LEFT;

        FORWARD_R;

     }

     else if(flag == FORWARD)

     {

            Forward();

     }

     else 

     {

            Backward();

     }

     Delay_ms(500);    

}

///////////////////////////////////////////////////

void Stop(void)

{

      STOP_LEFT;

     STOP_RIGHT;

}

///////////////////////////////

//   Measure.h

///////////////////////////////

#ifndef _MEASURE_H

#define _MEASURE_H

//触发端口:PB0

//回应端口:PD3

#define ECHO PD3

#define START_TRIG PORTB |= 0X01

#define STOP_TRIG  PORTB &= 0XFE

#define CLEAR_TRIG STOP_TRIG

#define CLEAR_ECHO PORTD &= ~(1<// 0b00001000 = 1<#define ECHO_IS_LOW (!(PIND & (0b00001000))) 

#define ECHO_IS_HIGH (PIND & (0b00001000))

//函数声明

void measure(void);

int ShouldTurn(void);

#endif

///////////////////////////////

//   Measure.c

///////////////////////////////

#include "measure.h"

#include "delay.h"

#include

#include

///////////////////////////////////////////////////

void measure(void)

{    

    CLEAR_TRIG;    

    START_TRIG;     //触发探测        

    Delay_us(20);    //产生20us的触发信号    

    STOP_TRIG;         

    CLEAR_ECHO;        //将 ECHO 口置为低

}

///////////////////////////////////////////////////

int ShouldTurn(void)

{    

     unsigned long tmp = 0;

     TCCR1B = 0X00; //关闭定时器 1

     TCNT1H = 0x00; 

      TCNT1L = 0x00;     

     //若检测为低电平则等待,高电平说明有障碍物  

      while( ECHO_IS_LOW )            

 {          

      }      

     TCCR1B = 0X02;    //8分频,启动定时器 1     

     while( ECHO_IS_HIGH )

     {

          tmp = TCNT1H;

        tmp <<= 8;

        tmp += TCNT1L;

          if( tmp > 2000 )  //大于半米的距离, 半米的距离需 1470 = 0x05BE(us)

        {

             TCCR1B = 0X00;

            return 0;

        }

     }     

     TCCR1B = 0X00; //关闭定时器 1

     return 1;

}

////////////////////////////////

//   Delay.h

///////////////////////////////

#ifndef _DELAY_H_

#define _DELAY_H_

void Delay_us(unsigned int);

void Delay_ms(unsigned int);

#endif

///////////////////////////////

//   Delay.c

///////////////////////////////

#include

#include "delay.h"

///////////////////////////////////////////////////

void Delay_us(unsigned int time)

{

      while(time--)

     {

          NOP();NOP();

     }     

}

///////////////////////////////////////////////////

void Delay_ms(unsigned int time)

{

      while(time--)

           Delay_us(1000);

}

///////////////////////////////

//   main.c

///////////////////////////////

#include "Motor.h"

#include "delay.h"

#include "measure.h"

uint count = 0;                    //计数定时器 0 的溢出次数

BOOL MEASURE_FLAG = FALSE;

//******** port_init *********

//初始时所有端口均为低,但控制电机的两个引脚PD4、PD5为高

void port_init(void)    

{

 PORTA = 0x00;

 DDRA  = 0xFF;

 PORTB = 0x00;

 DDRB  = 0xFF;

 PORTD = 0X00;

 PORTD |= (1 << PD4)|(1 << PD5);    //启动电机,ENA,ENB分别对应PD4、PD5

 DDRD  = 0xFF;

 DDRD &= ~(1 << PD3);    //将 PD3 设为输入

 PORTC = 0x00;        

 DDRC = 0xFF;

}

//************** timer0_init **************

void timer0_init(void)

{

 TCCR0 = 0x00; //stop

 TCNT0 = 0xCE; //set count

 TCCR0 = 0x02; //start timer

}

//************** timer0_ovf_isr ***************

#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF

void timer0_ovf_isr(void)

{

 TCNT0 = 0xCE;         //reload counter value

 if(++count >= 2500)    //125毫秒测量一次

 {

      count = 0;    

    measure();               //开始测量    

    MEASURE_FLAG = TRUE;

 }

}

//*************** init_devices ***************

void init_devices(void)

{

 CLI();            //disable all interrupts

 port_init();

 timer0_init(); 

 MCUCR = 0x00;       

 GICR  = 0x00;   //未开外部中断1

 TIMSK = 0x01;   //timer0溢出中断允许

 SEI();             //re-enable interrupts

}

//************************** main *********************************

int main( )

{

   init_devices();     

   while(1)

   {     

       Forward();                       

           if( MEASURE_FLAG == TRUE )

        {

             MEASURE_FLAG = FALSE;

            if( ShouldTurn() )          //判断是否该转弯,是返回 1,否返回 0

            {

                 TCCR0 = 0x00;          //stop         

                Turn( LEFT );

                TCNT0 = 0XCE;      //将定时器 0重置初值

                TCCR0 = 0x02;          //start timer

            } 

        }        

   }

   return 0;

}下载本文

显示全文
专题