本科毕业论文
基于单片机智能小车设计 Design based on microcomputer smart car
学院名称: 电子信息与电气工程学院 专业班级:自动化2013级2班 学生姓名:鲁顺 学 号: 13020610225 指导教师姓名:杨欣 指导教师职称:讲师
2017 年 5 月 毕业设计(论文)原创性声明和使用授权说明 原创性声明 本人郑重承诺:所呈交的毕业设计(论文),是我个人在指导教师的指导下进行的研究工作及取得的成果。尽我所知,除文中特别加以标注和致谢的地方外,不包含其他人或组织已经发表或公布过的研究成果,也不包含我为获得安阳工学院及其它教育机构的学位或学历而使用过的材料。对本研究提供过帮助和做出过贡献的个人或集体,均已在文中作了明确的说明并表示了谢意。 作 者 签 名: 日 期: 指导教师签名: 日 期: 使用授权说明 本人完全了解安阳工学院关于收集、保存、使用毕业设计(论文)的规定,即:按照学校要求提交毕业设计(论文)的印刷本和电子版本;学校有权保存毕业设计(论文)的印刷本和电子版,并提供目录检索与阅览服务;学校可以采用影印、缩印、数字化或其它复制手段保存论文;在不以赢利为目的前提下,学校可以公布论文的部分或全部内容。
作者签名: 日 期: 目录 摘要。 5 Abstract. 6 引 言 7 第一章 方案设计与论证 9 1.1 设计任务及要求 9 1.2 设计方案论证 9 1.2.1 单片机选择 9 1.2.2 电机驱动芯片的选择 11 1.2.3 路况检测模块 12 2 系统硬件电路与实现 14 2.1 主控模块电路设计 14 2.1.1 STC89C52单片机的简介 14 2.1.2时钟电路 16 2.1.3复位电路 18 2.2红外遥控模块的电路设计 19 2.2.1红外遥控的实现原理 20 2.2.2红外发射器 21 2.2.3红外接收器 22 2.3电机驱动模块的设计 23 2.3.1 L293D芯片简介 24 2.4路况检测模块 26 2.4.1 HC-SR04超声波模块 26 2.4.2 循迹模块 29 2.4.3传感器的选择: 30 2.5蓝牙无线传输模块 31 2.5.1蓝牙模块的选择 31 2.5.2显示模块的电路显示 35 2.6智能防撞报警模块 36 2.6.1智能防撞报警模块原理 36 3系统软件设计与实现 38 3.1整体程序的构架 39 3.2红外遥控解码的实现 39 3.3电机驱动 42 3.4 小车寻迹 42 3.5 小车防撞报警 44 4 小车系统原理图 46 总结 48 参考文献 50 附录 52 元件清单 52 系统程序 53
基于单片机智能小车设计 摘要:随着科学技术的不断进步,关于汽车的研究也成为人们关注的焦点,智能车辆将成为未来的必然产物,本设计产品就是根据这一大背景下提出来的,本设计是基于STC89C52单片机控制及传感器技术的,来实现小车自动自动寻线寻迹,利用超声波模块来完成避障功能,小车前轮由两个电机驱动左右两个轮,通过两个电机的转速及转动时间的差别,达到小车正常行驶和转向的目的。安装蓝牙模块,通过手机app来实现无线通信,来控制小车的行驶。 关键词:智能小车;STC89S52单片机;寻线;避障;超声波传感器;蓝牙
Design based on microcomputer smart car Abstract:Along with the advance of science and technology, the research on vehicle has become the focus of attention, intelligent vehicle will become the inevitable outcome of the future, the design of products is based on this background, this design is based on the STC89C52 single-chip microcomputer control and sensor technology, to realize the automatic automatic car line tracing, the use of ultrasonic module to complete obstacle avoidance function, the car front wheel driven by two motor around two rounds, through two motor rotation speed and the difference of time, achieve the goal of the car moving and steering.Install bluetooth module, realize the wireless communication through mobile phone app, to control the motion of the car.Key words:Smart car;STC89S52 ;microcontroller; Line; Obstacle avoidance; Ultrasonic sensor; bluetooth.
引言 随着科学技术的飞速发展,关于智能汽车的研究也就备受人们的关注。每年举行的全国电子大赛中,各种功能的智能小车项目都占很大的比例,全国的各个高校也都非常重视智能小车课题的研究。可见其研究意义很大。智能小车是现代科学技术的新产品,将会是以后的发展方向和必然产物,他可以在没有人直接参与的情况下,利用外加的设备或装备,使小车的某个工作状态或者参数自动的按照预定的规定运行。可用于科学探索侦察等的用途。智能小车的控制器模块主要接收传感器部分发送过来的实时信号,并且根据之前烧录到单片机中的软件程序,来命令智能小车做出相应的动作,就像是人的大脑部分。而执行器模块和传感器模块则像是人体的四肢和眼睛耳朵一样。单片机具备构造简单、可靠性高、多功能、适合在恶劣环境中工作、抗干扰能力高及小型化等优势,他渗透到生活的各个领域,可以说哪一个范畴都能找到单片机的踪影,首先应用最广泛的就是生产自动化领域的应用,能降低劳动程度,提高生产效率,还可以应用实时测量方面、智能化仪表、智能化产品、家用电器、国防现代化、信息通信领域等。这些年来,单片机技术突飞猛进,一些高功能的单片机如雨后春笋大量涌现,技术日新月异,是我们做智能小车的首选。
第一章 方案设计与论证 1.1 设计任务及要求本智能小车的设计要求如下: ●具有单片机控制核心模块; ●具有电机驱动模块; ●具有超声波避障模块; ●具有光电感应模块; ●具有七段数码管显示模块; ●具有无线蓝牙传输模块; ●具有防撞报警模块;
1.2 设计方案论证1.2.1 单片机选择方案一:采用MSP430单片机 MSP430系列单片机他具有处理能力强、超低功耗、片内资源丰富等优点。但是也有很多不足之处,比如价格较高,比较适用于复杂的应用系统,当用户设计需要更多考虑成本时,MSP430单片机并不一定合适。 方案二:采用STC89C52单片机 ●全静态工作,工作范围:0Hz~24MHz;
●三级程序存储器加密;
●128×8位内部RAM;
●32位双向输入输出线;
●两个十六位定时器/计数器
●五个中断源,两级中断优先级;
●一个全双工的异步串行口;
●间歇和掉电两种工作方式; 方案选择: 综上所述:通过以上两种方案的比较,在本系统中的单片机选 第二个方案,MSP430对系统的控制比较麻烦并且价位较高,所以选择使用STC89S52作为控制器芯片。 1.2.2 电机驱动芯片的选择方案一:使用L298N芯片来驱动普通直流电机,用该芯片作为电机驱动,操纵便利,比较平稳,直流电机具有能耗低、性能优越、振动小、噪声低、维护成本低、调整范围广等优点,普通直流电机结构紧凑,体积小,造型美观,通用性强,采用新型密封装置的直流电机保护性能好,对环境适应性强,可在恶劣的环境中连续工作。 方案二:采用步进电机,步进电动机最主要的功能就是能够控制位置,你要它在什么地方停止,它就在什么地方停止,并且可以实现开环控制无需反馈信号,优点是中低输出力矩大、性价比高,只有伺服的四分之一左右,缺点是振动大、发热大高速性能差、有丢步的可能,需要专门的驱动器。 方案选择: 本智能小车设计采用方案一更好,购买方便,价钱合理。 1.2.3 路况检测模块方案一:使用超声波传感器,超声波是一种机械波,依靠介质才能传播,从发射信号开始到接收到信号结束来计算往返的时间差,并且将信号放大后放到主控制芯片当中从而判定距离,这就是它工作的原理。现在应用比较广泛的还有一种方法也是利用同样的原理实现的,比如红外光探头,同样可以在高精度下完成测量,并且简化了电路,它的使用成本低、易于操作,在智能机器人发挥着很大的作用。 方案二:使用视觉传感器,它主要是由摄像头及处理图像的控制器组成,广泛的应用于生产现场,用于检测零部件的优良,从而避免次品外流,可以同时测量多个目标,具有高精度的特点,其优点是尺寸小,价格合理,但是算法复杂,运行速度慢。 方案选择:
综合以上方案,采用方案一较为合理,因为本设计的智能小车实现避障功能即可,无需太复杂,并不需要经过传输回来的图像来分析前方障碍物。
2 系统硬件电路与实现本智能小车采用了STC89C52单片机作为主要控制芯片来处理各个模块的运行,系统整体硬件总框图如图2.1 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB2E.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB2F.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB30.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB31.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB32.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB33.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB34.tmp.png 图2.1 系统硬件总体框图
2.1 主控模块电路设计 2.1.1 STC89C52单片机的简介 STC89C52是STC公司生产的一种低功耗、高性能CMOS8位微控制器,其主要特点是: ●全静态工作,工作范围:0Hz~24MHz;
●三级程序存储器加密;
●128×8位内部RAM;
●32位双向输入输出线;
●两个十六位定时器/计数器
●五个中断源,两级中断优先级;
●一个全双工的异步串行口;
●间歇和掉电两种工作方式;
图2.1 STC89C52的管脚图 (1)主要特性: file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB35.tmp.jpg 图2.1.1 ●用户应用程序空间为8K字节 ●片上集成512字节RAM ●具有EEPROM功能 ●共3个16位定时器/计数器。即定时器T0、T1、T2 ●PDIP封装
2.2红外遥控模块的电路设计 2.2.1红外遥控的实现原理 怎么样才能让烧录的程序去分析0位和1位是红外遥控能够实现的至关重要步骤,高电平脉冲后的低电平的脉宽的不一样也就定义了是位0还是位1,位0代表的是脉冲宽度为0.565ms、时间间隔为0.56ms、周期为1.125ms;而位1代表的脉冲脉宽为0.565ms、时间间隔为1.685ms、周期为2.25ms。
解码和上诉红外遥控实现原理类似,也是如何让程序去识别分析0位和1位。位0和位1的相同点是都是从低电平0.565ms开始的,不同点在于它们的高电平宽度不同,所以高电平宽度就是区分位0还是位1的关键。红外遥控的流程图如图2.2.1所示。 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB36.tmp.png file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB37.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB47.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB48.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB49.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB4A.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB4B.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB4C.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB4D.tmp.png 充电放大 解调 解码 图2.2.1
2.2.2红外发射器 该电路的主要控制器件是采用PPM进行编码遥控器芯片HT6221,红外遥控发射器电路图如图2.2.2所示。各个开关的功能分别为:K1停止;K2右转;K3左转;K4启动;K5加速;K6循迹;K7制动;K8后退。 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB4E.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB4F.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB50.tmp.png file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB51.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB52.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB63.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB64.tmp.png 键盘 编码调制 LED
图2.2.2 2.2.3红外接收器 红外线接收器的主要特点: ●小型设计 ●内置专用IC ●宽角度及长距离接收 ●抗干扰能力强 ●能抵挡环境干扰光纤 ●低电压工作 ●红外线接收器的结构 ●脉冲信号输出端,直接接单片机的IO口 ●GND接系统的地线(0V) ●VCC接系统的电源正极(+5V) 该模块的电路如图2.2.3所示。 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB65.tmp.jpg
图2.2.3
2.3电机驱动模块的设计 2.3.1 L293D芯片简介 L293D驱动芯片主要特点是: ●工作电压高,最高工作电压可达36V ●该芯片可以驱动两台直流电机
一、直流电机驱动模块的参数
输入逻辑电压:5.0V
输入电机电压:5.0V-36.0V
输出驱动电流:1000mA
尺寸:(长)34mm * (宽)18mm * (高)8mm
连接方式:
P1:控制M1电机PWM1输入引脚。
D1:控制M1电机转向输入引脚。
P2:控制M2电机PWM2输入引脚。
D2:控制M2电机转向输入引脚。
GND:电源地接口。
5V:逻辑电源+5V接口。
VC:输入电机驱动电压接口。
GND: 电源地接口。
M1+:M1电机驱动输出引脚正极。
M1-:M1电机驱动输出引脚负极。
M2+:M2电机驱动输出引脚正极。
M2-:M2电机驱动输出引脚负极。 电机驱动模块的硬件电路图如图2.3.1。 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB66.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB67.tmp.jpg 图2.3.1
2.4路况检测模块2.4.1 HC-SR04超声波模块 1、此模块性能稳定,测度距离精确,模块高精度,盲区小,图2.4.1为HC-SR04超声波模块实物图。
2、 主要技术参数:
●使用电压:DC---5V
●静态电流:小于2mA
●电平输出:高5V
●电平输出:底0V
●感应角度:不大于15度
●探测距离:2cm-450cm
●高精度 可达0.2cm file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB68.tmp.jpg 图2.4.1 3、电气参数
电气参数 | | | | | | | | | | | | | | | | | | | [size=12.0000pt] 45*20*15mm |
2.4.2 循迹模块 小车循迹的原理:使用红外探测法使小车延黑线行驶,其主要特点是红外线在不同颜色的物体上反射性质不同,在小车行驶过程中不断地向地面发射红外光,当红外光遇到白色纸质地板时发生漫反射,反射光被装在小车上的接收管接收;如果遇到黑线则红外光被吸收,小车上的接收管接收不到红外光,小车前方探头实物如图2.4.2所示。 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB69.tmp.jpg 图2.4.2
2.4.3传感器的选择: ST系列集成红外探头价格便宜、体积小、使用方便、性能可靠、用途广泛,所以该系统中最终选择了LM324反射传感器作为红外光的发射和接收器件,其内部结构和外接电路均较为简单,其硬件原理图如图2.4.3所示,LM324引脚图(管脚图)如图2.4.3-2所示。 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB6A.tmp.jpg 图 2.4.3-1
LM324的特点: ●短跑保护输出 ●真差动输入级 ●可单电源工作:3V-32V ●每封装含四个运算放大器。 ●具有内部补偿的功能。 ●共模范围扩展到负电源 ●行业标准的引脚排列 ●输入端具有静电保护功能
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB6B.tmp.jpg 图2.4.3-2
2.5蓝牙无线传输模块 2.5.1蓝牙模块的选择 ZS-040是比较早的产品,AT指令集很少,包括修改蓝牙名(限于从机),修改密码,修改波特率,询问版本号等几个基本功能,在本次设计中我们只需实现简单的通信,因此选用ZS-040模块,产品实物图如图2.5.1所示。 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB7C.tmp.jpg 图2.5.1-1 蓝牙模块ZS-040的主要特征: ●无线收发 1、灵敏度(误码率)达到 -80dBm 2、-4 -> 6dBm 功率可调输出 ●性能概要 完整的蓝牙解决方案 1、蓝牙 2.0 带 EDR, 2Mbps-3Mbps 调制度 2、外置 8Mbit FLASH 3、可选 PIO 控制 4、 标准 HCI 端口(UART or USB) 5、 USB 协议: Full Speed USB1.1, Compliant With 2.0 6、模块可以作为 SMD 贴片工艺 7、RoHS 制程 8、引脚半孔工艺 ● 低功耗 ● 高性能无线收发系统 ● 低成本 ● 应用领域 1、蓝牙车载免提 2、蓝牙 GPS 3、蓝牙 PCMCIA , USB Dongle 4、蓝牙数据传送 ● 软件 CSR 二、 蓝牙通信模块的分析处理,引脚定义如图2.5.1-2所示。 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB7D.tmp.jpg 图2.5.1-2 (1) ZS-040蓝牙转串口模块的作用是将从手机蓝牙发送过来的指令接收到后转换成串口的形式通过单片机的串口传给单片机。只需将该模块的RXD接上51单片机的TXD引脚,TXD接51的RXD,然后接单片机的VCC供电,因为我们只用它接收手机蓝牙信号,不发送数据,参考原理图如图2.5.1-3所示。 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB7E.tmp.jpg 图2.5.1-3 2.5.2显示模块的电路显示 本系统采用一个七段数码管显示器,其电路原理图如图2.6.2所示。 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB7F.tmp.jpg 图2.6.2 当手机app控制智能小车前进、后退、左转、右转时,一位七段数码管分别显示1、2、3、4。
2.6智能防撞报警模块
2.6.1智能防撞报警模块原理 智能防撞报警系统是现代智能小车必装的一个系统模块,有很大的研究价值,有十分重要的现实意义。使智能小车能够自动的判别前方是否有障碍物,如果前方遇到有障碍物则会自动的调节状态以避开障碍物所带来的严重损失,同时在即将遇到障碍物之前,能够触发报警系统,以警告主人避免危险。
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB80.tmp.png将智能小车放在空旷无人的地面上,位于小车前端的两个探头能够感应前方是否有阻碍行驶的障碍物,与此同时,朝下的探头也会同时接收到来自路面路况的实时信息状况,当小车运行到障碍物旁边时,装置在小车上面的主控芯片STC89C52单片机就会接收到此时的路况信息,进而去改变小车的运行方向,使小车赶紧掉头行驶,同时发出报警信号。报警模块硬件图如图2.6.1所示。
图2.6.1 当智能小车前面遇到障碍物时,主控芯片单片机分析之后会送给P0.6一个高电平信号,使得三极管V1导通,从而引起SB1蜂鸣器导通,发出报警信号。
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB81.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB82.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB83.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB84.tmp.png3系统软件设计与实现 在进行智能小车的系统软件设计时,我们将所有涉及到的模块程序全部都放入到到遥控器中,这种方法主要是为了方便控制,并且不占用CPU,因为遥控模块、寻迹模块、以及避障模块等都同时用到了实时检测扫描,这样不仅占用CPU,而且几个程序同时运行还会产生矛盾冲突使小车无法正常工作。各个模块的整体控制如图3.1所示。 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB85.tmp.png
图3.1
当遥控器发送红外信号时,会开启STC89C52单片机外部中断0,使主程序立刻进入中断函数,并且进行解码。完成解码任务以后,主程序再接收遥控的反馈信息,主程序对比遥控器输入值之后进入相应模块执行相关操作,由电机驱动来完成各个模块的处理操作,所以在图3.1中最终箭头是指向电机控制模块的。 3.1整体程序的构架程序框图如图3.1.1所示 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB95.tmp.png 图3.1.1 3.2红外遥控解码的实现因为各个模块的程序控制都放在了遥控模块这一单元里面,所以整个智能小车的主要线索就是红外遥控的解码,并且发挥了整个系统入口的作用。 每当遥控器上有按键被按下时,脉宽波形便被由1脚接收到由遥控器发送的红外信号所解码,于此同时促使主控芯片单片机产生中断,而且开启定时器、脉冲个数计数。记录出每一个脉冲所经历的时间和脉冲的总数,等到一帧的数据发送完成以后,单片机结束计数,并且关闭定时器。然后再进入判断阶段,首先判断这一帧数据中的脉冲个数,如果脉冲个数大于31个则将数据全部舍弃,要是刚刚好则判断接收到的脉冲是1还是0,接收完之后将数据保存起来,再来比对数据的是否正确,首先比对前导码是否符合,也就是看一下使用中的遥控器是不是与小车匹配的遥控器,如果都正确之后再来将码值存起来。主程序只需要调用一个swich函数来对相应码值进行对应函数的调用就可以了,比如手动按下了下 键,则调用后退函数来完成小车的后退动作。如图3.2所示 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB96.tmp.png 图3.2
3.3电机驱动从整体上上来看,电机驱动在小车运行中占主导作用,就像是人体的四肢,它用来执行小车的所有动态操作,任何一个模块所执行命令的外在表现。 电机驱动包括驱动控制直流电机的前进、后退、左转、右转以及暂停这五个功能,这五个功能不仅仅只是遥控器按下上下左右之后才执行,而是每一个模块都会有执行电机驱动模块的操作,所以在设计程序时,最合理的设计应该是将这些前进、后退、左右转向单独编译成一个个的函数块,每一个子模块的运行就只需调用这些函数就可完成。这样做就节省了很大的程序空间。举个例子,在编写前进函数时,为了满足小车前进功能,只需将P0.0—P0.3赋值1010就可完成,其他左转右转只是改变相应P0.0—P0.3的码值则可实现。
3.4 小车寻迹当主人打开寻迹模块功能后,就会不停地扫描单片基中与四个前方探测器相连接的IO端口,每当检测到哪个探测器有信号进入了,就会立刻进入之前编写过的判断处理程序,,当左面的第一和第二级传感器检测到了黑线,就会使小车左转向,当小车右面的第一第二级传感器检测到了黑线,则会使小车右转向,在经过不断地调整后,小车会继续延着黑线行驶,并不断地重复上诉动作,从而实现了小车的寻迹功能。 图3.4为小车寻迹模块的程序流程图
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB97.tmp.png 图3.4 寻迹程序流程图 3.5 小车防撞报警当开启防撞报警功能的时候,智能小车就会进入防撞报警函数,控制小车该模块功能的单片机IO口是P3.7,首先判断小车前方是否有悬崖或者障碍物,如果没有则继续前进,如果有则会后退并且报警,进而再坐转弯而避免危险,图3.5为防撞报警模块的程序流程图。
图3.5 防撞报警程序流程图
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB98.tmp.png
4 小车系统原理图硬件电路总设计图如图4.1所示 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB99.tmp.jpg
图4.1 硬件电路原理图
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB9A.tmp.jpg最终主板PCB图
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsB9B.tmp.png前板PCB 致谢时间犹如白驹过隙,转眼间毕业论文就要完成了,同时也意味着我们即将离开美好的大学校园到社会上去实现自身的人身价值了。可以说经历了这次的毕业设计和论文真的让我成长了好多,从一开始拿到题目的迷茫无助,努力的翻阅资料到后来完成题目时的欣悦,这一整个过程都历历在目,这种将成为大学生活中一段美好的回忆。
很早以前就想做一个智能小车玩玩,所以在毕业设计选题目的时候我就直接没有考虑其他的项目了,当拿到这个题目的时候,我的毕业指导老师着重强调了对软件的学习和对电路的设计,智能小车所涉及到的功能模块比较多并且电路的复杂度也不低,对于一个新手来说从开始的设计电路到仿真和焊接这一系列的步骤能一气呵成的完成实属不易,但是在指导老师的悉心教导以及自己的努力下终于还算是小有成就的完成了。 在不断的努力下我的毕业设计终于完成了。开始的时候,我还以为所谓的毕业设计和毕业论文只是对所学知识的总结,并非难事,到后来遇到了好多困难,举步维艰,之前学习的理论知识太多了,都没有用到实践中去,真正做起来的时候不知道从哪里入手,不知道自己为实现什么样的目的要怎么规划达到目的的过程, 才明白了“纸上得来终觉浅,才知此事要躬行”的道理。毕业设计不仅是对所学知识的总结和应用,更是在实际应用中培养自身如何做一项完整事情的培训,可以说是学校在毕业前对学生踏入社会的一次做事能力的培训。
参考文献[1] 杨永辉.《现代电子技术》[J] .智能小车的多传感器数据融合.2005 [2] 何立民.《单片机与嵌入式系统应用》[J].基于HCS12的小车智能控制系统设计.2007 [3] 谭浩强.《C程序设计》.北京:清华大学出版社,2005,7 [4] 张立.《电子世界》[J].电动小车的循迹.2004 [5] 武庆生,仇梅.单片机原理与应用(M).电子科技大学出版,1998,12 [6] 徐科军.传感器与检测技术[M].电子工业出版社,2007 [7] 刘瑞新.单片机原理及应用教程 .机械工业出版社,2003,7 [8] 刘湘涛,江世明.单片机原理与应用[M].电子工业出版社,2006 [9] 何立民.单片机初级教程[M].北京航空航天大学出版社,1999 [10] 熊建云. Protel99 SE.北京:机械工业出版社,2007 [11] 郑郁正.单片机原理及应用.四川大学出版杜,2003 [12] 卢静,陈非凡,张高飞等.基于单片机的无刷直流电动机控制系统设计.北京机械工业学院学报,2002,10 [13] 张燕,曾光宇.光电式传感器的应用与发展[J].科技情报开发与经济,2007 [14] 曹开田.基于单片机的红外遥控密码锁的设计与实现[J].应用研究,2010 [15] 裴彦纯.陈志超.基于单片机系统的红外遥控器应用[J].现代仪器,2004 [16] 赖麒文.8051单片机C语言彻底应用[M].科学出版社,2002 [17] 郭天祥.51单片机C语言教程.北京:电子工业出版社, 2009
附录元件清单
系统程序#include <reg52.h> //包含51单片机相关的头文件 #include <intrins.h> sbit LeftLed=P2^0; //定义前方左侧指示灯端口 sbit RightLed=P0^7; //定义前方右侧指示灯端口 sbit FontLled=P1^7;
sbit LeftIR=P3^5; //定义前方左侧红外探头端口 sbit RightIR=P3^6; //定义前方右侧红外探头端口 sbit FontIR=P3^7; //定义前方正前方红外探头端口
sbit M1A=P0^0; //定义左侧电机驱动A端 sbit M1B=P0^1; //定义左侧电机驱动B端
sbit M2A=P0^2; //定义右侧电机驱动A端 sbit M2B=P0^3; //定义右侧电机驱动B端
sbit B1=P0^4; //定义语音识识别传感器端口 sbit SB1=P0^6; //定义蜂鸣器端口 sbit IRIN=P3^3; //定义红外接收端口
unsigned char code LedShowData[]={0x03,0x9F,0x25,0x0D,0x99, //定义数码管显示数据 0x49,0x41,0x1F,0x01,0x19};//0,1,2,3,4,5,6,7,8,9 unsigned char code RecvData[]={0x19,0x46,0x15,0x43,0x44,0x40,0x0D,0x0E,0x00,0x0F}; unsigned char IRCOM[7]; static unsigned int LedFlash; //定义闪动频率计数变量 bit EnableLight=0; //定义指示灯使能位 #define ShowPort P2 //定义数码管显示端口 unsigned char temp = 1; void tingzhi() { M1A=0; //将M1电机A端初始化为0 M1B=0; //将M1电机B端初始化为0 M2A=0; //将M2电机A端初始化为0 M2B=0;
}
void qianjin() { M1A=1; M1B=0; M2A=1; M2B=0; }
void houtui() { M1A=0; M1B=1; M2A=0; M2B=1; }
void zuozhuan() { M1A=0; M1B=1; M2A=1; M2B=0; }
void youzhuan() { M1A=1; M1B=0; M2A=0; M2B=1; }
void Delay1ms(unsigned int i) { unsigned char j,k; do{ j = 10; do{ k = 50; do{ _nop_(); }while(--k); }while(--j); }while(--i);
}
void delay_nus(unsigned int i) //延时:i>=12 ,i的最小延时单12 us { i=i/10; while(--i); } void delay_nms(unsigned int n) //延时n ms { n=n+1; while(--n) delay_nus(900); //延时 1ms,同时进行补偿
}
void delayms(unsigned char x) //0.14mS延时程序 { unsigned char i; //定义临时变量 while(x--) //延时时间循环 { for (i = 0; i<13; i++) {} //14mS延时 } }
void Delay() //定义延时子程序 { unsigned int DelayTime=30000; //定义延时时间变量 while(DelayTime--); //开始进行延时循环 return; //子程序返回 } void ControlCar(unsigned char ConType) //定义电机控制子程序 {
tingzhi(); switch(ConType) //判断用户设定电机形式 { case 1: //前进 //判断用户是否选择形式1 { //tingzhi(); //进入前进之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 //Delay1ms(50); LeftLed = 0 ; qianjin(); break; } case 2: //后退 //判断用户是否选择形式2 { // tingzhi(); //进入后退之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 // Delay1ms(50); LeftLed = 1 ; houtui(); //M2电机反转 break; } case 3: //左转 //判断用户是否选择形式3 { //tingzhi(); //进入左转之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 // Delay1ms(50); zuozhuan(); //M2电机正转 break; } case 4: //右转 //判断用户是否选择形式4 { // tingzhi(); //进入右转之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 // Delay1ms(50); youzhuan(); //M1电机正转 //M2电机反转 break; } case 8: //停止 //判断用户是否选择形式8 { tingzhi(); break; //退出当前选择 } } }
void ControlCar_yaokong(unsigned char ConType) //定义电机控制子程序 (红外遥控单独设置一个 switch case 语句 ) {
tingzhi(); switch(ConType) //判断用户设定电机形式 { case 1: //前进 //判断用户是否选择形式1 { tingzhi(); //进入前进之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 Delay1ms(150); LeftLed = 0 ; qianjin(); break; } case 2: //后退 //判断用户是否选择形式2 { tingzhi(); //进入后退之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 Delay1ms(150); LeftLed = 1 ; houtui(); //M2电机反转 break; } case 3: //左转 //判断用户是否选择形式3 { tingzhi(); //进入左转之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 Delay1ms(150); zuozhuan(); //M2电机正转 break; } case 4: //右转 //判断用户是否选择形式4 { tingzhi(); //进入右转之前 先停止一段时间 防止电机反向电压冲击主板 导致系统复位 Delay1ms(150); youzhuan(); //M1电机正转 //M2电机反转 break; } case 8: //停止 //判断用户是否选择形式8 { tingzhi(); break; //退出当前选择 } } } void Robot_Avoidance() //机器人避障子程序 {
LeftLed=LeftIR; //前方左侧指示灯指示出前方左侧红外探头状态 RightLed=RightIR; //前方右侧指示灯指示出前方右侧红外探头状态 FontLled= FontIR; SB1=FontIR;
if(FontIR == 0) //如果前面避障传感器检测到障碍物 { ControlCar(8); //停止 delay_nms (300); //停止300MS 防止电机反相电压冲击 导致系统复位 ControlCar(2); //后退 delay_nms (1000); //后退1500MS ControlCar(3); // delay_nms (1800); } else { ControlCar(1); //右侧没有信号时,开始向左转一定的角度 delay_nms (10); } ControlCar(1); } //机器人循迹子程序 void Robot_Traction() //机器人循迹子程序 { LeftLed=LeftIR; //前方左侧指示灯指示出前方左侧红外探头状态 RightLed=RightIR; //前方右侧指示灯指示出前方右侧红外探头状态 FontLled= FontIR; SB1=LeftIR; if(LeftIR == 0 && RightIR == 0) //三个红外检测到黑线,就前进 { ControlCar(1); //左侧没有信号时,开始向右转一定的角度 delay_nms (10); }
else if(LeftIR == 0 && RightIR == 1) { ControlCar(3); //右侧没有信号时,开始向左转一定的角度 delay_nms (10); }
else if(LeftIR == 1 && RightIR == 0) { ControlCar(4); //右侧没有信号时,开始向左转一定的角度 delay_nms (10); } ControlCar(8); }
void main() //主程序入口 {
bit RunFlag=0; //定义小车运行标志位 LedFlash=3000; //对闪灯数据进行初始化 //EX1=1; //同意开启外部中断1 IT1=1; //设定外部中断1为低边缘触发类型 EA=1; //总中断开启 ControlCar(8); //初始化小车运行状态 while(1) //程序主循环 { if(P3_2 == 0) { delay_nms(10); if(P3_2 == 0) { temp++; while(!P3_2); } } if(temp > 3) { temp = 1; } switch(temp) { case 1: ShowPort = LedShowData[1];Robot_Traction();EX1 = 0;break; case 2: ShowPort = LedShowData[2];Robot_Avoidance();EX1 = 0;break; case 3: ShowPort = LedShowData[3];EX1 = 1;break; } } } //----------红外遥控------------------------------------------------------------- void IR_IN() interrupt 2 using 0 //定义INT2外部中断函数 { unsigned char j,k,N=0; //定义临时接收变量
EX1 = 0; //关闭外部中断,防止再有信号到达 delayms(15); //延时时间,进行红外消抖 if (IRIN==1) //判断红外信号是否消失 { EX1 =1; //外部中断开 return; //返回 }
while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。 { delayms(1); //延时等待 }
for (j=0;j<4;j++) //采集红外遥控器数据 { for (k=0;k<8;k++) //分次采集8位数据 { while (IRIN) //等 IR 变为低电平,跳过4.5ms的前导高电平信号。 { delayms(1); //延时等待 }
while (!IRIN) //等 IR 变为高电平 { delayms(1); //延时等待 }
while (IRIN) //计算IR高电平时长 { delayms(1); //延时等待 N++; //计数器加加 if (N>=30) //判断计数器累加值 { EX1=1; //打开外部中断功能 return; //返回 } }
IRCOM[j]=IRCOM[j] >> 1; //进行数据位移操作并自动补零
if (N>=8) //判断数据长度 { IRCOM[j] = IRCOM[j] | 0x80; //数据最高位补1 } N=0; //清零位数计录器 } }
if (IRCOM[2]!=~IRCOM[3]) //判断地址码是否相同 { EX1=1; //打开外部中断 return; //返回 }
for(j=0;j<10;j++) //循环进行键码解析 { if(IRCOM[2]==RecvData[j]) //进行键位对应 { // ControlCar(j); ControlCar_yaokong(j); //数码管显示相应数码 } } EX1 = 1; //外部中断开 } //-------------------------------------------------------------------------------------------------------
蓝牙模块程序: #include<reg52.h>
//HL-1小车驱动接线定义 #define Left_moto_go {P0_0=1,P0_1=0;} //左边电机向前走 #define Left_moto_back {P0_0=0,P0_1=1;} //左边电机向后转 #define Left_moto_Stop {P0_0=0,P0_1=0;} //左边电机停转 #define Right_moto_go {P0_2=1,P0_3=0;} //右边电机向前走 #define Right_moto_back {P0_2=0,P0_3=1;} //右边电机向后走 #define Right_moto_Stop {P0_2=0,P0_3=0;} //右边电机停转
#define left 'C' #define right 'D' #define up 'A' #define down 'B' #define stop 'F'
#define uint unsigned int //重定义无符号整数类型 #define uchar unsigned char //重定义无符号字符类型
char code str[] = "收到指令,向前!\n"; char code str1[] = "收到指令,向后!\n"; char code str2[] = "收到指令,向左!\n"; char code str3[] = "收到指令,向右!\n"; char code str4[] = "收到指令,停止!\n";
bit flag_REC=0; bit flag =0;
unsigned char i=0; unsigned char dat=0; unsigned char buff[5]=0; //接收缓冲字节 uchar code LedShowData[]={0x03,0x9F,0x25,0x0D,0x99, //定义数码管显示数据 0x49,0x41,0x1F,0x01,0x19};//0,1,2,3,4,5,6,7,8,9
#define ShowPort P2 //定义数码管显示端口
/************************************************************************/ //延时函数 void delay(unsigned int k) { unsigned int x,y; for(x=0;x<k;x++) for(y=0;y<2000;y++); }
/************************************************************************/ //字符串发送函数 void send_str( ) // 传送字串 { unsigned char i = 0; while(str != '\0') { SBUF = str; while(!TI); // 等特数据传送 TI = 0; // 清除数据传送标志 i++; // 下一个字符 } } void send_str1( ) // 传送字串 { unsigned char i = 0; while(str1 != '\0') { SBUF = str1; while(!TI); // 等特数据传送 TI = 0; // 清除数据传送标志 i++; // 下一个字符 } }
void send_str2( ) // 传送字串 { unsigned char i = 0; while(str2 != '\0') { SBUF = str2; while(!TI); // 等特数据传送 TI = 0; // 清除数据传送标志 i++; // 下一个字符 } }
void send_str3() // 传送字串 { unsigned char i = 0; while(str3 != '\0') { SBUF = str3; while(!TI); // 等特数据传送 TI = 0; // 清除数据传送标志 i++; // 下一个字符 } }
void send_str4() // 传送字串 { unsigned char i = 0; while(str4 != '\0') { SBUF = str4; while(!TI); // 等特数据传送 TI = 0; // 清除数据传送标志 i++; // 下一个字符 } }
/************************************************************************/ //前速前进 void run(void) {
Left_moto_go ; //左电机往前走 Right_moto_go ; //右电机往前走 }
//前速后退 void backrun(void) {
Left_moto_back ; //左电机往后走 Right_moto_back ; //右电机往后走 }
//左转 void leftrun(void) {
Left_moto_go ; //左电机往前走 Right_moto_back ; //右电机往后走 }
//右转 void rightrun(void) {
Left_moto_back ; //左电机往前走 Right_moto_go ; //右电机往前走 } //STOP void stoprun(void) {
Left_moto_Stop ; //左电机往前走 Right_moto_Stop ; //右电机往前走 } /************************************************************************/ void sint() interrupt 4 //中断接收3个字节 {
if(RI) //是否接收中断 { RI=0; dat=SBUF; if(dat=='O'&&(i==0)) //接收数据第一帧 { buff=dat; flag=1; //开始接收数据 } else if(flag==1) { i++; buff=dat; if(i>=2) {i=0;flag=0;flag_REC=1 ;} // 停止接收 } } } /*********************************************************************/ /*--主函数--*/ void main(void) { TMOD=0x20; TH1=0xFd; //11.0592M晶振,9600波特率 TL1=0xFd; SCON=0x50; PCON=0x00; TR1=1; ES=1; EA=1;
while(1) /*无限循环*/ { if(flag_REC==1) // { flag_REC=0; if(buff[0]=='O'&&buff[1]=='N') //第一个字节为O,第二个字节为N,第三个字节为控制码 switch(buff[2]) { case up : // 前进 send_str( ); run(); ShowPort=LedShowData[1]; break; case down: // 后退 send_str1( ); backrun(); ShowPort=LedShowData[2]; break; case left: // 左转 send_str3( ); leftrun(); ShowPort=LedShowData[3]; break; case right: // 右转 send_str2( ); rightrun(); ShowPort=LedShowData[4]; break; case stop: // 停止 send_str4( ); stoprun(); ShowPort=LedShowData[0]; break;
}
} } } |