单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 111|回复: 0
打印 上一主题 下一主题
收起左侧

基于AVR单片机的多功能智能小车系统设计文档 含原理图 源代码

[复制链接]
跳转到指定楼层
楼主
1531585571 发表于 2018-12-28 12:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
作为现代社会的新发明,多种高科技技术的集中体现,智能车辆将会是未来车辆发展的一个必然趋势。它可以在无人参与的情况下,根据预习设定的信息,自动地完成一系列的工作,从而将许多人从繁重地劳动中解脱出来。与传统汽车相比,智能车辆更加安全、节能、环保,可以大大地提高人们的生活质量。目前为止,由最新技术生产的智能车辆已将在交通、运输、航天、工业等方面发挥出来举足轻重地作用[1]。
单片机又名微控制器,它将一个大型计算机的几乎所有功能都集中在了一个小小的芯片上,它体积小、质量轻、功耗低,十分适合初学者进行学习和开发使用,并且,单片机的结构与真正的计算机几乎相同,学习单片机是了解计算机原理和结构的最佳选择[2]。
在本次课题中,以AVR单片机为控制核心,以RPR220型光电对管、E18-D80NK传感器等传感器为辅助器件,设计并实现了智能小车系统。小车是一个二轮驱动小车,后方由一个万向轮可以灵活转向。在本文中,详细介绍了智能小车的整体设计思路,以及各个部分的软硬件设计。小车通过RPR220型光电对管实现了循迹功能,通过E18-D80NK传感器实现了避障功能,并通过单片机将这些模块有机的整合到一起,利用C语音进行编程设计,使用ICC7.22开发环境对小车进行程序开发。小车具有运行稳定、价格便宜、能耗低等优点

目录
摘   要
Abstract
第1章 绪论
1.1 研究的背景和意义
1.2 国内外研究现状及发展前景
1.3 本次设计的主要任务
第2章 系统方案设计
2.1 总体设计框图
2.2 核心控制单元的选择
2.3 循迹方案设计
2.4 避障方案设计
2.5 电机驱动方案选
2.6 电机选择
第3章 系统硬件电路设计
3.1 最小系统电路
3.2 循迹模块电路
3.3 避障模块
3.4 电机驱动模块
3.4.1 L298N电机驱动芯片
3.4.2 PWM调速原理
3.4.3 驱动电路
第4章 系统软件设计
4.1 ICCAVR简介
4.2 主控制模块主程序设计
4.3 红外循迹模块子程序设计
4.4 红外避障模块子程序设计
4.5 电机驱动模块子程序设计
第5章 结论
参考文献
致    谢
附 录A 总电路图
附 录B 源程序

第1章 绪论
1.1 研究的背景和意义
智能车辆技术集成了机械、电子、自动化等多学科的发展,代表了现代技术发展的前沿。是未来车辆发展的必然趋势。在实际生活中,智能车辆通常需要根据人们的预设程序完成跟踪和避障。其中,大多数依靠传感器技术来获取路线和周围的环境。
本文以AVR作为控制核心,设计制作了智能寻线小车。它使用光线对管和红外传感器收集周围的各种信息,自动沿着地面设定的路线行走,并且可以在行走过程中自动躲避障碍物。智能小车采用前轮驱动,两轮采用直流电机,后轮采用万向轮。为了确保小车平稳正常地运行,我们采用PID算法控制直流电机地运行。本系统具有操作简单、成本低、可靠性高、结构紧凑等特点[4]。
1.2 国内外研究现状及发展前景
智能车辆系统是一种集中了计算机技术、自动化技术、传感器技术等多种高科技技术于一体的综合系统。从目前的发展趋势来看,智能车辆将是未来世界汽车行业发展的最终形态。相比于传统汽车,智能车辆拥有无法比拟的巨大优势。
首先,智能车辆是由智能计算机系统控制、连接互联网自动驾驶,相比于传统汽车,不仅将驾驶人员从繁重的驾驶工作中解放了出来,还可以大大地提高汽车行驶的安全系数。据谷歌调查,大部分交通事故都是人为造成的。目前随着辅助驾驶技术、半自动驾驶技术的发展普及,智能驾驶系统可以实时监控驾驶人员的状态,防止驾驶人员醉酒驾驶、疲劳驾驶、不遵守交通规则驾驶等行为,交通事故的发生率降低了50%~60%。在未来,随着技术的发展,全自动驾驶普及后,完全不需要驾驶人员,甚至可以完全避免交通事故的发生。
其次,智能车辆拥有更为先进的人机交互界面。智能车辆不仅搭载有智能驾驶系统,还拥有智能生活系统,使驾驶人员和乘客可以更舒适的享受在车上的时光。假如乘客有什么突发情况,智能生活系统还可以提供紧急解决方案。例如,在行驶过程中,如果乘客突发疾病,智能生活系统会主动提出医疗知识提示,防止周围的朋友因为不懂医疗知识而妄动患者造成二次伤害。并且,智能生活系统会自动将情况上传至互联网,将病情告知医院。而且,智能生活系统还会凭借车联网疏散通往医院车辆,使得汽车可以尽快到达医院,使病人得到及时的治疗。
最后,相比传统汽车,智能车辆更为节能、环保。据谷歌调查,传统汽车大部分时间都处于停用状态,利用率较低。智能车辆可以整合车辆信息,将车辆按需分配,提高车辆的利用率,从而减少车辆数量,达到节能、环保的效果。
国外许多发达国家大约在1950年左右就开始研究智能车辆了,截止到目前,一些简单地半自动智能车已经得到广泛地应用,但是,全自动智能汽车仍然遥遥无期。2017年9月,美国运输部对汽车的无人驾驶系统的安全性做出了评估,为以后在国家层面制定相关法律法规奠定了基础。截止现在,美国已经有22个州以上通过了相关的法律。目前,辅助驾驶技术和半自动驾驶技术已经得到广泛的普及,世界汽车巨头正在致力于发展第三阶段的全自动驾驶。
与美国等发达国家相比,我国的智能车辆技术的发展之路还比较漫长。我国的智能车辆技术大约是从1980年左右开始起步研究的,目前在一些沿海城市有了很大的发展。在我国,人们正在不断地加深对智能车辆的重视程度,国家正在不断加大对智能车辆的研发资金投入力度。相信经过我国的大力研究,以及庞大的市场刺激,我国戴尔智能车辆技术将会飞速提高。据大数据调查分析,未来我国对智能车辆的需求非常大,在2020年左右,半自动驾驶汽车的市场占有率将达到30%,在2025年左右,将达到50%。在2018年,中国的智能汽车将达到50万辆。到时候,巨大的市场将会推动技术的快速发展,刺激我国的汽车产业寻求技术突破,促进智能汽车产业的优胜劣汰。如图1-1为常见的智能小车。

图1-1 智能小车

1.3 本次设计的主要任务
本次课题主要设计的是一个简易的智能电动车,采用AVR单片机作为小车的检测和控制核心。采用RPR220型光电对管来检测道路上的黑线,从而把反馈到的信号送单片机,是单片机按照预定的工作模式控制小车在各区域按预定的轨迹行驶。并且在小车的行驶过程中,可以自动识别障碍物并自动躲避。

第2章 系统方案设计
2.1 总体设计框图
在系统层面而言,本系统由四个部分组成。控制核心、循迹模块、避障模块、电机驱动模块。首先,循迹模块和避障模块获取周围的信息,然后将信息传递至控制核心,控制核心进行信息处理后,根据预习设定的程序,将信号传递至电机驱动模块,驱动电机运行。这样,就完成了小车的循迹和避障功能。系统组成框图如图2-1所示[5]。

图2-1 总体设计框图

2.2 核心控制单元的选择
本课题采用ATmega16单片机作为核心控制单元,ATmega16单片机是采用 RISC结构的AVR内核单片机。ATmega16单片机拥有131个机器指令,32个8位通用工作寄存器等,并且在内部具有2个时钟周期的硬件乘法器。ATmega16单片机功耗低、价格便宜、运行速度快,十分适合作为嵌入式控制核心。ATmega16单片机的实物图如图2-2所示。

图2-3 ATmega16单片机的实物图

2.3 循迹方案设计
方案1:用光敏电阻组成光敏探测器
光敏电阻的阻值会随着周围环境中的光线强度变化而变化,光照越强,阻值就越低。当小车行驶时,光敏探测器会不断地对周围的环境进行探测。小车的行驶环境为纯白色背景下的黑色轨迹。当光敏探测器探测到白色背景时,反射光强度较强,光敏电阻的阻值会降低;当探测到黑色轨迹时,由于黑色的吸光作用,发射光的强度将会降低,光敏电阻的阻值将会变大。正是根据以上原理,小车可以使用光敏探测器进行循迹检测。但是由于光敏探测器受环境中光照强度的影响较大,不能稳定的工作。
方案2:用CCD摄像头传感器
线性CCD传感器摄像头可以将光线信号转换为电荷信号,再传送至单片机进行处理。CCD摄像头传感器的优点是探测距离远,可以提前探测道路情况,以便做出减速转弯等操作。使得小车的整体平均速度得到提高,具有良好的前瞻性。但是CCD摄像头传感器对于单片机小车来说,消耗资源略大,而且在实际过程中,发现CCD摄像头在市场上比较稀少,购买难度较大。
方案3:用RPR220型光电对管
RPR220与光敏探测器相似,是一款反射型的光电探测器。首先,RPR220型光电对管会发射出红外线,当红外线传至白色背景时,会反射回来重新被探测器接收,进而输出一个高电平;若红外线传至黑色轨迹时,黑色轨迹会将红外吸收,探测器检测不到反射光,就会输出低电平。RPR220型光电对管具有体积小、结构紧凑、电路简单、性能稳定等优点。
由于光敏电阻易受周围环境光照强度影响,CCD 摄像头对单片机片内资源消耗大等原因,本课题最终确定选择方案3 。
2.4 避障方案设计
方案1:使用超声波探测器
超声波探测器的原理是由探测器发出人耳不可听见的超声波,超声波触碰到物体后反射回探测器。通过检测超声波从发射到反射回来所使用的时间,就可以计算出与物体的距离。超声波探测器的优点是可以在较差的环境中正常工作,缺点是探测精度较低,使用成本较高。
方案2:使用激光测距传感器
激光测距传感器的测距原理与超声波探测器类似,传感器发射出激光,经反射后回到传感器,经过处理计算后即可得到相应的距离。激光测距传感器的优点是测量距离较长,测量精度较高;缺点是对资源的消耗较大,价格略昂贵。
方案3:使用红外避障传感器
E18-D80NK传感器的逻辑非常简单,它由发射器和红外接收器组成,负责感知某个物体的存在。它有一个圆柱形主体,通过钻孔可以很容易地安装到原型中,其中2个环用于固定,一个在内部,另一个在原型外部。它的连接通过3个引脚完成,传感器可以有两种不同的连接模式,它有两个信号电平,低电平(0.3到1.5V)和高电平(2.3到5V)。检测距离可以在3到80厘米之间进行调整,通过位于传感器底部的电位计进行。
由以上分析,本课题最终确定选择方案3。
2.5 电机驱动方案选
方案1:采用由晶体管组成的H桥电路
H桥电路可以将直流电逆变为可变频率的交流电,采用PWM 方式控制电机的运行。PWM是一种脉冲宽度调制方式,其原理是通过调整脉冲的占空比来调整一个周期内电机的通电时间,进而调节电机的运转速度。H桥电路的优点是稳定性好,应用广泛。
方案2:采用L298N驱动芯片
L298N属于H桥集成电路,可驱动大功率直流电机、步进电机等。L298N的优点是它的输入端可以直接与单片机相连,这样,可以便于直接受单片机控制。最重要的是,L298N可以同时驱动两台直流电机,恰好与本课题相符。
由于以上分析,本课题最终确定选择方案2 。
2.6 电机选择
方案1:采用步进电机
步进电机是由脉冲信号驱动转动的,其特点是可以精确地定位其转过的角度,进而精确地确定其行驶的距离。但是,步进电机难以获得较大的转矩,难以获得较大的转速,资源利用率略低,更多地使用在数控机床等需要精确控制的地方[6]。
方案2:采用直流减速电机
直流减速电机是指在普通直流电机的基础上,配套齿轮减速箱。具有节省空间、能耗低、性能稳定等优点,广泛地应用于自动化行业中。
由以上分析,步进电机不适用于本次设计的要求,故本课题最终确定采用方案2。

第3章 系统硬件电路设计
3.1 最小系统电路
本课题的中央处理器是ATMEGA16单片机,其主要功能是不停地接收由寻迹模块和避障模块中的传感器发送过来的信号,经过处理后将信息发送至电机驱动模块,从而实现对周围环境的实时响应。如图3-1是较为常见的带烧录接口的单片机最小系统图。

图3-1 最小系统电路

3.2 循迹模块电路
循迹模块电路所用传感器是RPR220型光电对管,如图3-2所示。RPR220是一款集成式光电探测器,其发射极为GaAs红外发射二极管,接收器为高灵敏度硅平面光电晶体管。

图3-2 RPR220

GaAs红外发射二极管向目标发射红外线,光电晶体管接收到由目标反射的红外线后,向单片机发射电平跳变信号。当小车行驶在白色背景上时,安装在小车下方的发射极对地面发射红外光,经白色背景反射后,光电晶体管将打开。寻迹模块电路如图3-3所示。

图3-3寻迹模块电路图

当小车行驶在黑色轨迹上时,红外光被黑色背景吸收,光电晶体管不能接收到反射光,LM339电压比较器截止,输出低电平至单片机。因此,根据单片机I/O口接收电平不同,即可判断小车的行驶情况。
为了保证小车沿黑线行驶,采用了四个检测器并行排列,检测器排列位置如图3-4所示。其编号1至4对应的硬件电路分别接在单片机的PA0、PA1、PA2、PA3端口。在小车运动过程中,结合查询方式,通过程序控制小车运动轨迹。如果2号红外对管和3号红外对管检测到黑线,则单片机控制小车向前直走;如果2号红外对管偏离黑线,3号红外对管检测到黑线,则单片机控制小车轻微左移;如果3号红外对管偏离黑线,2号红外对管检测到黑线,则单片机控制小车轻微右移;如果2号和3号红外对管偏离黑线,1号红外对管检测到黑线,则单片机控制小车向左移动;如果2号和3号红外对管偏离黑线,4号红外对管检测到黑线,则单片机控制小车向左移动[7]。

图3-4 检测器位置

3.3 避障模块
避障模块采用型号为E18-D80NK的红外避障传感器,如图3-5所示。

图3-5 E18-D80NK

E18-D80NK传感器的逻辑非常简单,它由发射器和红外接收器组成,负责感知某个物体的存在。它有一个圆柱形主体,通过钻孔可以很容易地安装到原型中,其中2个环用于固定,一个在内部,另一个在原型外部。它的连接通过3个引脚完成,传感器可以有两种不同的连接模式,它有两个信号电平,低电平(0.3到1.5V)和高电平(2.3到5V)。检测距离可以在3到80厘米之间进行调整,通过位于传感器底部的电位计进行[8]。

图3-6 E18-D80NK原理图

E18-D80NK电气特性如表3-1。

表3-1 E18-D80NK电气特性

红色

绿色

黄色

工作电压

工作电流

驱动电流

感应距离

VCC

GND

OUT

5VDC

10-15mA

100mA

3-80CM


E18-D80NK红外避障传感器在小车正常运行时,输出高电平;当检测到前方有障碍物时,输出低电平,黄色的线作为E18-D80NK红外避障传感器的输出口,直接与单片机相连,将检测信号送入单片机中,经进一步处理后,使小车做出相应的变化。避障模块电路如图3-7所示。避障模块采用三只红外避障传感器,安装于小车两侧及下中央,可以检测两侧和正前方是否有障碍,检测后将信号送入单片机,单片机对信号进行处理并发出相应的信号驱动小车电机,使小车躲避障碍。其左中右三个传感器的硬件电路分别接到单片机的PB0、PB1、PB2 端口。当三个传感器检测到无障碍时,小车正常前进行驶;当前侧传感器检测到有障碍时,小车右转;当左侧或左及前侧传感器检测到障碍时,小车右转;当右侧或右侧及前侧传感器检测到障碍时,小车左转;当三个传感器都检测到有障碍或左右侧传感器检测到有障碍时,小车停止[9]。

            

图3-7避障模块电路

3.4 电机驱动模块
3.4.1 L298N电机驱动芯片
L298N是由意法半导体公司研发制造的一款双全桥大电流(2A*2)电机驱动芯片,比较常见的是15脚MulTIwatt封装的L298N,内部同样包含4通道逻辑驱动电路。可以方便的驱动两个直流电机,其实物图及直流电机实物如图3-8所示。

图3-8 L298N及电机实物图

L298N属于H桥集成电路,可驱动大功率直流电机、步进电机等。L298N的平均输出电流为2A,最大时甚至可达到4A,其输入端可以直接与单片机相连,从而很方便地受单片机的控制。
图3-9为L298N的引脚图,图中Current sensing为电流感应电阻,可以在Current sensing连接电流表,以此来检测L298N中流过的电流。OUTPUT为L298N的输出端,其中,OUTPUT 1和OUTPUT 2为A相的两个输出,OUTPUT 3和OUTPUT 4为B相的两个输出,可以用来连接电机。INPUT是L298N的输入端,INPUT的电平决定了相应编号的OUTPUT的电平。ENABLE为L298N的使能端,若ENABLE为高电平,则OTPUT就会与INPUT保持一致,否则,OUTPUT不与任何端口相连。LOGIC SUPPLY VOLTAGE VSS是L298N的逻辑电压,为L298N中的逻辑器件提供电源。GND为L298N的接地端。SUPPLY VOLTAGE VSS为L298N的驱动电压,为电机提供电源[10]。

图3-9 L298N引脚

3.4.2 PWM调速原理
脉冲宽度调制(PWM)是英文“Pulse Width Modulation”的缩写,简称脉宽调制。PWM调速的原理是调节在一个周期内驱动脉冲的占空比,进而调节电机的供电时间比例。在一个周期内,占空比越大,则电机的供电时间越长,电机的运转速度就越快。因此,电机的调速范围最小为零,最大为持续供电的电机转速[11]。
3.4.3 驱动电路
直流电机驱动电路使用H型全桥式驱动电路。这种驱动电路可以很方便实现直流电机的四象限运行,分别对应正转、正转制动、反转、反转制动。在本设计中电机驱动电路由集成驱动芯片L298N构成,并结合PWM进行调速。ATmega16单片机本身带有四个PWM输出端口,通过设定其内部参数来控制PWM的输出,来改变脉冲宽度调制的占空比。本设计选用四个I/O口中的PD4及PD5为PWM信号的输出端口。它的基本原理图如图3-10所示[12]。

图3-10 驱动电路

该驱动电路可以驱动两路直流电机,使能端ENA、ENB为高电平时有效,控制方式及直流电机状态图如表3-1所示。

表3-1 电机驱动控制方式及直流电机状态

ENA

IN1

IN2

直流电机状态

0

X

X

停止

1

0

0

制动

1

0

1

正转

1

1

0

反转

1

1

1

制动


若要对直流电机进行PWM调速,需设置IN1和IN2,确定电机的转动方向,然后对使能端输出PWM脉冲,即可实现调速。注意,当使能信号为0时,电机处于停止状态;当使能信号为1时,00和11的IN1和IN2,制动电机,停止电机旋转[13]。
对于汽车的转向控制,需要向ENA和ENB输入不同的PWM信号,以实现直流电动机的转速差,从而实现汽车转向。本设计中有微调转弯和转弯两种转弯状态,微调转弯是其中一个PWM信号不变,另一个的占空比减少一半;转弯是其中一个PWM信号不变,另一个无PWM信号输出[14]。
1


沈阳工业大学本科生毕业论文
第4章 系统软件设计
本课题的系统软件部分采用模块化设计方案。模块化设计方案不仅逻辑清晰,而且便于编程,发现错误后,更是便于修改。系统软件共分为四个模块,分别为主程序模块、寻迹模块、避障模块以及电机驱动模块。寻迹模块和避障模块不断采集周围环境的信息发送至处理器,再由处理器处理后发送至电机驱动模块,以便于小车可以随环境变化而做出改变。本设计的源程序见附录B。
4.1 ICCAVR简介
该设计使用的开发环境为ICCAVR开发环境。 ICCAVR是ATMEL公司专门为AT90系列单片机开发的编译工具。ICCAVR是一个集成的工作环境,简称IDE,它综合了编辑器和工程管理器等功能,并且可以根据开发的单片机的不同,选择不同的初始值,以及是否使用定时器等功能,十分强大,是一个被众多单片机开发人员广泛使用的开发环境。

图4-1 ICCAVR 界面

4.2 主控制模块主程序设计
主控制模块主程序流程图如图4-2,它的作用是整合小车的各个模块,使其正常、协调的运行。当小车开始运行后,初始化各个变量,并负责接收各个子模块的信息,综合处理后再按照预先的设定不断的做出反应,从而实现本课题的设计要求[15]。


图4-2主程序流程图

4.3 红外循迹模块子程序设计
循迹模块的功能主要是不断的采集周围环境中的信息,并将其发送至控制核心单元,以便于小车进行下一步操作。流程图如图4-3所示。
红外跟踪模块子程序接收外围红外检测电路信号并对接收到的信号进行编码,红外检测外围电路红外对管位置如图3-4。当红外对管检测到白色背景时输出高电平,检测到黑色轨迹时输出低电平。外围电路红外对管状态进行信号编码后对应表格如表4-1,将信号进行处理编码之后,判断信号类型,当信号为:1000,1100,1110,0100时,单片机送出左转信号;当信号为:0001,0011,0111,0010时,单片机送出右转信号;当信号为:0111,1111时,单片机送出直走信号;当信号为:0000时,停止。信号0101,1010,1101,1011,1001为无效信号[16]。

图4-3 红外循迹模块子程序流程图


表4-1 外围电路红外对管状态进行信号编码后对应表

外围红外对管输出状态

信号编码结果

外围红外对管输出状态

信号编码结果

1号低2号低3号低4号低

0000

1号低2号低3号高4号低

0010

1号高2号高3号高4号高

1111

1号低2号高3号高4号低

0110

1号高2号低3号低4号低

1000

1号低2号低3号高4号高

0011

1号高2号高3号低4号低

1100

1号低2号低3号低4号高

0001

1号低2号高3号低4号低

0100

1号低2号高3号高4号高

0111

1号高2号高3号高4号低

1110


4.4 红外避障模块子程序设计
红外避障模块子程序流程图如图4-4所示。避障模块采用E18-D80NK传感器来探测前方的道路上15厘米的距离之内有无障碍物,进而将探测结果发送至核心控制单元,等待控制单元做出下一步的处理[17]。

图4-4 红外避障程序流程图


避障模块不断的通过传感器采集周围环境中的信息,当前方15厘米内没有障碍物时,小车保持前进状态,若有障碍物则可通过小车前方及左右方的红外避障传感器,获得障碍物的具体情况进行信息处理编码,编码方式如下表4-2。
将外部信息进行编码后,通过对信号的判断,控制小车的移动方向:探测结果111,表明前方15cm内无障碍物单片机送出“前进”指令,小车保持前进状态;探测结果000,表明前方及左右两边15cm内均有障碍物,单片机送出“停止”指令;探测结果101,表明前方15cm内有障碍物左右两边均无障碍物,单片机送出“右转”指令(左右均无障碍物默认右转);探测结果001,表明前方及左边15cm内有障碍物,单片机送出“右转”指令;探测结果100,表明前方及右边15cm内有障碍物,单片机送出“左转”指令;探测结果110,表明右边15cm内有障碍物,单片机送出“左转”指令;探测结果011,表明左边15cm内有障碍物,单片机送出“右转”指令;探测结果010,表明左边及右边15cm内有障碍物,单片机送出“停止”指令[18]。

表4-2 红外避障模块外围电路信息处理编码表

外围电路障碍物探测结果

信息编码结果

左边无障碍物,前方无障碍物,右边无障碍物

111

左边有障碍物,前方有障碍物,右边有障碍物

000

左边无障碍物,前方有障碍物,右边无障碍物

101

左边有障碍物,前方有障碍物,右边无障碍物

001

左边无障碍物,前方有障碍物,右边有障碍物

100

左边无障碍物,前方无障碍物,右边有障碍物

110

左边有障碍物,前方无障碍物,右边无障碍物

011

左边有障碍物,前方无障碍物,右边有障碍物

010



4.5 电机驱动模块子程序设计
电机驱动模块不断的等待接受单片机发出的指令,并可以根据指令控制电机做出不同的反应,进而控制小车的运动[19]。流程图如图4-5所示。
当接收指令0x00:无数据,无PWM波,无方向信号。当接收指令0x01:小车前进,两个电机驱动器给予相同的PWM波,相同的方向信号。当接收指令0x02:小车后退,在前进的基础上改变方向信号。当接收指令0x03:小车停止,无PWM波,无方向信号。当接收指令0x04:结合循迹模块的信号向左微转或左转。当接收指令0x05:结合循迹模块的信号向右微转或右转。

图4-5电机控制程序流程图


第5章 结论
通过这个学期的不断深入学习,深入了解了AVR单片机的各个特性,以及ICCAVR的使用方法,设计并实现了可以自动循迹、避障的智能小车。大大提高了自己的动手能力以及独立学习的能力。通过本课题的学习研究,我深刻地认识到,只学习课本上的知识是远远不够的,必须紧跟时代的发展趋势,不断地学习新的知识,努力地提高自己,才能达到自己预期的目标。
在本课题中,以AVR单片机为控制核心,以RPR220型光电对管、E18-D80NK传感器等作为辅助模块,完成了可以自动循迹、避障的智能小车。小车实现了以下几个功能:
  • 小车可以自动沿着白色背景上的黑色轨迹行驶,一旦行驶过程中有所偏离,还可以自动回到黑色轨迹上来。
  • 小车在行驶过程中,可以自动检测前方的道路上有无障碍物。若有障碍物,可以实现自动躲避并继续行驶。
通过本次课题的学习,我不但掌握了很多以前学的不明白的知识,还学习了很多新知识,有了很大的收获。

致   谢
本论文的设计是在关新老师的悉心指导下完成的。从课题的选择、到具体的设计,无论在理论上还是在实践中都给了我许多指导和帮助,使我得以改进和提高。她严谨的治学态度,求真务实的学术作风,深厚的理论水平,丰富的项目经验,都深刻地影响着我,使我终身受益。值此论文完成之际,我谨向关新老师表示深深的感谢和崇高的敬意!
同时,在撰写毕业论文过程中,得到了我的同学李佳城、吴济等同学各方面的热诚帮助,使我能够顺利完成毕业论文,在此致以深深的谢意!

附 录A 总电路图

附 录B 源程序
  1. #include <iom16v.h>
  2. #include <macros.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. uchar count=0;//小车行走步数寻左
  6. void forward2(void);
  7. void forward1(void);
  8. void init_devices(void)
  9. {
  10. CLI(); //禁止所有中断
  11. MCUCR  = 0x00;
  12. MCUCSR = 0x80;//禁止JTAG
  13. GICR   = 0x00;
  14. SEI();//开全局中断
  15. }
  16. //定时T1初始化
  17. void timer1_init(void)
  18. {
  19. TCCR1B = 0x00;//停止定时器
  20. TIMSK |= 0x00;//中断允许
  21. TCNT1H = 0x00;
  22. TCNT1L = 0x00;//初始值
  23. OCR1AH = 0x00;
  24. OCR1AL = 0xF0;//匹配A值
  25. OCR1BH = 0x00;
  26. OCR1BL = 0xF0;//匹配B值
  27. ICR1H  = 0xFF;
  28. ICR1L  = 0xFF;//输入捕捉匹配值
  29. TCCR1A = 0xA1;
  30. TCCR1B = 0x01;//启动定时器
  31. }
  32. //*****************PWM 调速***************************//
  33. void leftspeed(uchar tempocra)
  34. {
  35. OCR1AH = 0x00;
  36. OCR1AL = tempocra;
  37. }
  38. void rightspeed(uchar tempocrb)
  39. {
  40. OCR1BH = 0x00;
  41. OCR1BL = tempocrb;
  42. }
  43. //*****************延时函数ms级***************************//
  44. void delayms(uint MS)   
  45. {
  46. uint i,j;
  47. for( i=0;i<MS;i++)
  48. for(j=0;j<1141;j++); //1141是在8MHz晶振下
  49. }

  50. /******************延时函数us级**************************/
  51. void delayus(uint US)   
  52. {
  53. uint i;
  54. US=US*5/4;      //5/4是在8MHz晶振下
  55. for( i=0;i<US;i++);
  56. }

  57. //****************校偏函数HEAD1前进******************************//
  58. void reviseL1(uchar discrepancy)//=0为直线 =1为左偏 =2右偏 =3严重左偏 =4严重右偏
  59. {
  60. if (discrepancy==0)
  61. {
  62.   PORTB=0X06;
  63.   return;
  64. }
  65.   if (discrepancy==1)
  66. {
  67.   PORTB=0X02;
  68.    delayms(20);
  69.   return;
  70. }
  71.   if (discrepancy==2)
  72. {
  73.   PORTB=0X04;
  74.    delayms(20);
  75.   return;
  76. }
  77.    if (discrepancy==3)
  78. {
  79.   PORTB=0X02;
  80.    delayms(40);
  81.   return;
  82. }
  83.    if (discrepancy==4)
  84. {
  85.   PORTB=0X04;
  86.    delayms(40);
  87.   return;
  88. }
  89. }
  90. //****************校偏函数HEAD2前进******************************//
  91. void reviseL2(uchar discrepancy)//=0为直线 =1为左偏 =2右偏 =3严重左偏 =4严重右偏
  92. {
  93. if (discrepancy==0)
  94. {
  95.   PORTB=0X09;
  96.   return;
  97. }
  98.   if (discrepancy==1)
  99. {
  100.   PORTB=0X08;
  101.   delayms(20);
  102.   return;
  103. }
  104.   if (discrepancy==2)
  105. {
  106.   PORTB=0X01;
  107.   delayms(20);
  108.   return;
  109. }
  110.    if (discrepancy==3)
  111. {
  112.   PORTB=0X08;
  113.   delayms(40);
  114.   return;
  115. }
  116.    if (discrepancy==4)
  117. {
  118.   PORTB=0X01;
  119.   delayms(40);
  120.   return;
  121. }
  122. }
  123. //***********************HEAD1向左拐*********************//
  124. void head1turnleft()
  125. {
  126. uchar time;
  127. leftspeed(200);
  128. rightspeed(200);
  129. PORTB=0x05;
  130. delayms(500);
  131. while(1)
  132. {
  133.   time=0x08&PINA;
  134.   if(time==0x08)
  135.   break;
  136.   else
  137.        continue;
  138.   }
  139. count=count+1;
  140. leftspeed(255);
  141. rightspeed(255);
  142. PORTB=0X06;
  143. return;
  144. }
  145. //***********************HEAD1向右拐*********************//
  146. void head1turnright()
  147. {
  148. uchar time1;
  149. leftspeed(200);
  150. rightspeed(200);
  151. PORTB=0x0a;
  152. delayms(500);
  153. while(1)

  154. {
  155.   time1=0x08&PINA;
  156.   if(time1==0x08)
  157.     break;
  158.   else
  159.        continue;
  160. }
  161. count=count+1;
  162. leftspeed(255);
  163. rightspeed(255);
  164. PORTB=0X06;
  165. return;
  166. }

  167. //***********************HEAD2向左拐*********************//
  168. void head2turnleft()
  169. {
  170. uchar time;
  171. leftspeed(200);
  172. rightspeed(200);
  173. PORTB=0x05;
  174. delayms(500);
  175. while(1)
  176. {
  177.   time=0x08&PINC;
  178.   if(time==0x08)
  179.   {
  180.   break;
  181.   }
  182.   else
  183.        continue;
  184. }
  185. count=count+1;
  186. leftspeed(255);
  187. rightspeed(255);
  188. return;
  189. }
  190. //***********************HEAD2向右拐*********************//
  191. void head2turnright()
  192. {
  193. uchar time;
  194. leftspeed(200);
  195. rightspeed(200);
  196. PORTB=0x0A;
  197. delayms(500);
  198. while(1)
  199. {
  200.   time=0x08&PINC;
  201.   if(time==0x08)
  202.     break;
  203.   else      continue;
  204.   }

  205. count=count+1;
  206. leftspeed(255);
  207. rightspeed(255);
  208. return;
  209. }

  210. //****************循迹函数HEAD1寻左**************************//
  211. void inlinel1()
  212. {
  213.   uchar state1;
  214.   state1=0x7e&PINA;
  215.   switch(state1)
  216.    {
  217.     case 0x08:reviseL1(0);break;//正在走直线
  218.     case 0x04:reviseL1(1);break;//略微左偏
  219.     case 0x10:reviseL1(2);break;//略微右偏
  220. case 0x02:reviseL1(3);break;//严重左偏
  221. case 0x20:reviseL1(4);break;//严重右偏
  222.    }
  223.    state1=0x40&PINA;
  224.    if (state1==0x40)
  225.    {
  226.      delayms(20);
  227.   if(state1==0x40);
  228. head1turnleft();
  229.    }
  230. }

  231. //****************循迹函数HEAD1寻右**************************//

  232. void inliner1()
  233. {
  234.   uchar state1;
  235.   switch(state1)
  236.    {
  237.     case 0x08:reviseL1(0);break;//正在走直线
  238.     case 0x04:reviseL1(1);break;//略微左偏
  239.     case 0x10:reviseL1(2);break;//略微右偏
  240.     case 0x02:reviseL1(3);break;//严重左偏
  241. case 0x20:reviseL1(4);break;//严重右偏
  242.    }
  243.    state1=0x01&PINA;
  244.   if (state1==0x01)
  245.    {
  246.     delayms(20);
  247. if(state1==0x01)
  248. head1turnright();
  249.    }
  250. }

  251. //****************循迹函数HEAD2寻左**************************//

  252. void inlinel2()
  253. {
  254.   uchar state1;
  255.   state1=0X7e&PINC;
  256.   switch(state1)
  257.    {
  258.     case 0x08:reviseL2(0);break;//正在走直
  259.     case 0x10:reviseL2(1);break;//略微左偏
  260.     case 0x04:reviseL2(2);break;//略微右偏
  261. case 0x20:reviseL2(3);break;//严重左偏
  262. case 0x02:reviseL2(4);break;//严重右偏
  263.    }
  264.    state1=0x01&PINC;
  265.    if (state1==0x01)
  266.    {
  267.     delayms(20);
  268. if(state1==0x01)
  269. head2turnleft();
  270.   }
  271. }

  272. //****************循迹函数HEAD2寻右**************************//

  273. void inliner2()
  274. {
  275.   uchar state1;
  276.   state1=0X7e&PINC;
  277.   switch(state1)
  278.    {
  279.     case 0x08:reviseL2(0);break;//正在走直线
  280.     case 0x10:reviseL2(1);break;//略微左偏
  281.     case 0x04:reviseL2(2);break;//略微右偏
  282. case 0x20:reviseL2(3);break;//严重左偏
  283. case 0x02:reviseL2(4);break;//严重右偏
  284.    }
  285.    state1=0x40&PINC;
  286.    if (state1==0x40)
  287.    {
  288.     delayms(20);
  289. if(state1==0x40)
  290. head1turnright();
  291.    }
  292. }

  293. //*********************HEAD2前进函数**********************//

  294. void forward2()
  295. {
  296. while(1)
  297. {
  298.   PORTB=0x09;
  299.      if((PIND&0X08)==0)
  300.     {
  301.     delayms(50);
  302. if((PIND&0X08)==0)
  303.     forward1();
  304.    }
  305.   switch (count)
  306.   {
  307.     case 12:inliner2();break;
  308.     case 23:inliner2();break;
  309.     case 24:inliner2();break;
  310.     case 25:inliner2();break;
  311.     case 26:inliner2();break;
  312.     case 33:inliner2();break;
  313. default:inlinel2();
  314.   }
  315. }
  316. }

  317. //*********************HEAD1前进函数**********************//

  318. void forward1()
  319. {
  320.   while(1)
  321. {
  322.    PORTB=0x06;
  323.    if((PIND&0X04)==0)
  324.    {
  325.     delayms(50);
  326. if((PIND&0X04)==0)
  327. forward2();
  328.    }
  329.    switch (count)
  330.   {
  331.    case 5:inliner1();break;
  332.    case 10:inliner1();break;
  333.    case 11:inliner1();break;
  334.    case 12:inliner1();break;
  335.    case 22:inliner1();break;
  336.    case 27:inliner1();break;
  337.    case 31:inliner1();break;
  338.    case 32:inliner1();break;
  339.    default:inlinel1();
  340.   }
  341. }
  342. }  

  343. //**********************主函数**************************//

  344. void main()
  345. {
  346. delayms(50);
  347. DDRA  = 0x00;
  348. DDRB  = 0x0F;
  349. DDRC  = 0x00;
  350. DDRD  = 0x30;
  351. PORTA = 0x00;
  352. PORTB = 0x06;
  353. PORTC = 0x00;
  354. PORTD = 0x3c;
  355. init_devices();
  356. timer1_init();
  357. while(1)
  358. {
  359.   forward1();
  360. }
  361. }
复制代码

完整的Word格式文档51黑下载地址:
基于 AVR 单片机的多功能智能小车系统设计.docx (1.48 MB, 下载次数: 2)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51黑电子论坛单片机.

Powered by 单片机教程网

快速回复 返回顶部 返回列表