迷宫电脑鼠的设计报告 本文关键词:迷宫,报告,设计,电脑
迷宫电脑鼠的设计报告 本文简介:综合课程设计报告题目:迷宫电脑鼠的设计二级学院计算机科学与工程学院专业计算机科学与技术班级学生姓名学号指导教师时间20150117II重庆理工大学综合课程设计报告III目录目录I摘要II1、课程设计的目的及要求11.1课程设计目的11.2课程设计要求12、题目分析12.1功能分析12.2性能需求分析
迷宫电脑鼠的设计报告 本文内容:
综合课程设计报告
题目:
迷宫电脑鼠的设计
二级学院
计算机科学与工程学院
专
业
计算机科学与技术
班
级
学生姓名
学号
指导教师
时
间
2015
01
17
II
重庆理工大学综合课程设计报告
III
目
录
目
录I
摘
要II
1、课程设计的目的及要求1
1.1
课程设计目的1
1.2课程设计要求1
2、题目分析1
2.1
功能分析1
2.2
性能需求分析1
2.3
算法分析1
3、系统设计2
3.1系统整体设计2
3.2硬件设计3
3.2.1
硬件结构设计3
3.2.2
传感器组设计4
3.2.3
电机驱动电路设计7
3.3软件设计8
3.3.1
电脑鼠正常行走程序设计8
3.3.2
电脑鼠找终点程序设计11
3.3.3
程序设计12
4
总结27
4.1
所遇问题及解决办法27
4.2
心得体会28
摘
要
“电脑鼠”是使用单片机微控制器,传感器和机电运动部件构成的一种智能行走装置。一只电脑鼠是具有机电知识整合的基本构架,本身就像是一个智能的机器人。要在指定的迷宫中比赛,就像是一个人置身竞赛中一样,必须要靠自己的判断力,敏捷动作及正确探查周边坏境。一般来说一只电脑鼠具备有以下两个基本能力:拥有稳定且快速的行走能力;正确判断能力。
重庆理工大学综合课程设计报告
1、课程设计的目的及要求
1.1
课程设计目的
(1)了解并熟悉电子元器件焊接技术与方法。
(2)了解并熟悉电子元器件工作原理和功能特性。
(3)掌握单片机对编码电机的控制与红外发射与接收的控制。
(4)熟练运用keil软件进行单片机的C语言编程。
1.2课程设计要求
走有一定弯度、曲折度、路线单一的迷宫。
2、题目分析
2.1
功能分析
(1)迷宫电脑鼠能够在迷宫中随意穿行。
由于迷宫中有很多挡板,要使电脑鼠能够在迷宫中随意穿行,就要让电脑鼠遇到挡板的时候能够转弯找到一条可通行的路,所以就要用到用来检测挡板的传感器。还要电脑鼠能够左转、右转和前进,所以必须要写出这四个功能函数,不然电脑鼠就不能在迷宫中行走。
2.2
性能需求分析
1、迷宫电脑鼠外形合理,符合8×8迷宫场地需求。
2、迷宫电脑鼠运行稳定,能够正常在迷宫中随意穿行。
2.3
算法分析
此次迷宫电脑鼠主要用到了这几个算法:左手法则、右手法则和车头方向、转弯算法、修正算法。
转弯算法:当遇到障碍物向左转90度或者右转90度或者向后转。
修正算法:当在迷宫中走偏后能够自动修正方向。
左手法则:小车在搜过程中有两个以上的搜索方向时,优先选择向左转,其次是向前行进,最后才考虑向右转弯。
右手法则:小车在搜过程中有两个以上的搜索方向时,优先选择向右转,其次是向前行进,最后才考虑向左转弯。
车头方向:迷宫机器鼠的车头有绝对方向和相对方向之分。绝对方向:以小车刚开始运行的时候车头面向的方向作为“上”,其它方向类推。相对方向:顾名思义,相对于当前小车所朝向的方向的方向。机器鼠转弯时要修整方向为绝对方向。用数字0,1,2,3分别表示上,右,下,左,修正公式为:转弯后的绝对方向=(转弯前的绝对方向+转弯数值)%
4,如图所示。
绝对方向
转弯前的方向
转弯方向
转弯后的方向
0(上方)
向左(+3)
向左(0+3)%4
=
3
0(上方)
向右(+1)
向右(0+1)%4
=
1
0(上方)
向后(+2)
向后(0+2)%4
=
2
1(右方)
向左(+3)
向上(1+3)%4
=
0
1(右方)
向右(+1)
向下(1+1)%4
=
2
1(右方)
向后(+2)
向左(1+2)%4
=
3
2(下方)
向左(+3)
向右(2+3)%4
=
1
2(下方)
向右(+1)
向左(2+1)%4
=
3
2(下方)
向后(+2)
向上(2+2)%4
=
0
3(左方)
向左(+3)
向下(3+3)
%4
=
2
3(左方)
向右(+1)
向上(3+1)%4
=
0
3(左方)
向后(+2)
向右(3+2)
%4
=
1
3、系统设计
3.1系统整体设计
系统的功能函数:
延时函数功能:延时
电机驱动函数功能:启动和停止左右电机
电机初始化函数功能:初始化电机
中断函数功能:T0、T1用来计数左右电机的脉冲数;T2用来产生红外信号
系统初始化函数功能:初始化整个系统
红外传感器函数功能:当遇到障碍物时点亮LED灯
转弯函数1功能:左转和右转任意角度
转弯函数2功能:左转90度,右转90度,向后转
前进一步函数功能:电脑鼠在迷宫前进一个方格距离
主程序流程图:
3.2硬件设计
3.2.1
硬件结构设计
硬件电路部分主要由单片机最小系统电路、传感器电路、电机驱动电路构成。如图所示,是硬件电路部分结构框图。
单片机
传感器组5
传感器组4
传感器组3
传感器组2
传感器组1
38KHz载波发生器
3-8译码选择器
显示器
蜂鸣器
电机1
电机2
驱动电路1
驱动电路2
操作按键
1、微控制器
微控制器是电脑鼠的核心,可以选择单片机,若RAM需求量大或者算法复杂或者性能要求高时,需要使用ARM等高性能的微处理器。
2、传感器
传感器的作用是用来感知环境,探测电脑鼠的左、前、右是否有路可走。本设计中采用的是红外线方式,发射和接收分别受微控制器控制。由硬件电路部分结构框图可知,在电脑鼠的前、左、右、左前、右前方共有5组,其中左、右、前三组传感器是用于探测电脑鼠在当前迷宫格左、右、前三个方向上是否有支路的,左前、右前两组传感器呈45度安装,用于电脑鼠行进过程中进行姿态矫正,防止电脑鼠走偏而撞到迷宫墙。
3、显示器
显示器是用来显示当前位置等相关信息的,是电脑鼠的可选部分。
4、电源
电源用来为单片机供电,选择哪种电池,这也将影响电路的设计。
5、蜂鸣器
当电脑鼠到底终点、或是返回到起点,可以用蜂鸣器来提示,是电脑鼠的可选部分。
3.2.2
传感器组设计
(1)传感器的选择
电脑鼠有5组传感器。这5组传感器分别安装于电脑鼠的左、左前、前、右前、右5个不同的方向,其中左、右、前三组传感器是用于探测电脑鼠在当前迷宫格左右前三个方向上是否有支路的,左前、右前两组传感器呈45度安装,用于电脑鼠行进过程中进行姿态矫正,防止走偏而撞到迷宫墙。如图所示,是用于电脑鼠环境感知的传感器组电路。传感器组电路由红外发射LED和红外一体化接收头HS0038构成,红外LED由前面载波发生器产生的CLOCK信号驱动产生38KHz红外调制光。RP1为可调电阻,通过调节RP1来调节红外LED发光强度,从而调整传感器组检测迷宫墙障碍物的距离,RP1电阻越大,检测距离越近,电阻越小,检测距离越远。irT1用于控制该组传感器是否工作,连接到3-8译码选择电路。红外调制光经障碍物反射由HS0038红外一体化接收头接收,进行放大滤波、解调等处理后由irR1输出,单片机通过识别irR1位的高低电平来判断传感器前面是否有障碍物。这里只给出了一组传感器,另外四组传感器也与该组传感器相同的。电脑鼠通过对这五组传感器信息的融合,实现环境感知功能。
(2)74HC138译码器
74HC138译码器可接受3位二进制加权地址输入(A0,A1和A2),并当使能时,提供8个互斥的低有效输出(Y0至Y7)。74HC138特有3个使能输入端:两个低有效(E1和E2)和一个高有效(E3)。除非E1和E2置低且E3置高,否则74HC138将保持所有输出为高。
1、74HC138的引脚如图所示:
2、74HC138的译码/真值表如下表所示:
译码/真值表
应用:
例如A0A1A2地址为000时,74HC138输出Y0有效,从而使第一组传感器工作,而其他组传感器处于没有工作的状态。这样就可以实现单片机的3个引脚控制5个或者更多的传感器组。如图所示,是硬件电路部分3-8译码选择器电路。
(3)载波发生器
传感器组是由38KHz的红外一体化接收头和红外发射管构成的障碍感测器。为了能够让传感器组正常工作,红外发射管需要一个38KHz的方波来驱动,使红外发射管发射出调制频率与接收头接收频率匹配的红外光。如图所示,是产生38KHz方波的载波发生器电路。
(4)传感器的调试
(主要写每组传感器如何进行调试。)
1、左右两边的传感器检测是否有墙壁。
2、左前和右前45°角的两组传感器用于电脑鼠在行走过程中的微调。
3、传感器上标的1、2、3、4、5对应led的1、2、3、4、5(里面往前数)。
4、传感器的测距是通过条对应的可调电阻来实现的,可调电阻顺时针转动调近,逆时针调远传感器的测试距离。
3.2.3
电机驱动电路设计
如图所示,是用来驱动电脑鼠伺服电机的驱动电路。由于单片机I/O口电流输出能力有限,不能直接驱动电机转动。为了能让单片机控制电机运转,需要使用电机驱动电路,将单片机I/O口弱电流放大到足以驱动电机的电流。
1、L9110器件的管脚图如图所示。
2、
管脚定义如下:
3、通过L9110驱动芯片IA、IB输入的逻辑值的组合,不同高低电平的输入输出,控制电机正转、反转、停转。L9110的逻辑关系表如下表所示:
L9110逻辑关系
IA
IB
OA
OB
H
L
H
L
正转
L
H
L
H
反转
L
L
L
L
停止
H
H
L
L
停止
3.3软件设计
3.3.1
电脑鼠正常行走程序设计
电脑鼠正常行走包括直走、左转弯、右转弯和向后转弯四个功能函数。这四个功能函数中要用到T0、T1定时/计数器;所以函数中首先初始化T0、T1。T0初始化:打开总开关EA=1;开T0中断ET0=1;设定T0模式2,8位自动重装值定时计数器TMOD
TMOD|=0x06;
设定T0计数初值,定义中断脉冲数TH0=256-ICP;TL0=256-ICP;
//启动T0计数TR0=1;T1初始化也是一样的。
为了使左右电机的转速尽可能相同,我们可以设定一个值,在这个值内,如果T0的脉冲数Count0大于T1的脉冲数Count1,就停止左电机,转动右电机;当Count0Count1时,停止右电机,反转左电机;当Count0Count1时,停止右电机,正转左电机;当Count0Count1时,停止右电机,正转左电机;当Count0前>左>后。
规定电脑鼠起点车头方向为北,顺时针依次为北、东、南、西,分别用0、1、2、3代表;在左转右转和后转中,每转一次向就更新一次当前的绝对方向,然后向前行进一步并更新当前坐标,然后将当前坐标与终点坐标比较,若当前坐标为终点坐标,则蜂鸣器响一声表示已到达终点坐标;否则继续用右手法则探路直到到达终点坐标为止。
右手法则:
3.3.3
程序设计
1.头文件
#include
#define
ICP
35
//位定义左右电机
sbit
ML1=P2^0;
sbit
ML2=P2^1;
sbit
MR1=P2^2;
sbit
MR2=P2^3;
//指示灯接口定义
sbit
LED1=P0^0;
sbit
LED2=P0^1;
sbit
LED3=P0^2;
sbit
LED4=P0^3;
sbit
LED5=P0^4;
sbit
LED6=P0^5;
sbit
LED7=P0^6;
sbit
LED8=P0^7;
//红外地址接口定义(74HC138译码器
sbit
A0=P1^2;
sbit
A1=P1^3;
sbit
A2=P1^4;
//红外传感器接口定义
sbit
irR1=P2^5;//左外
sbit
irR2=P2^6;//中
sbit
irR3=P2^7;//右外
sbit
irR4=P3^6;//左
sbit
irR5=P3^7;//右
//按键接口定义
sbit
key=P1^0;
//蜂鸣器接口定义
sbit
SPEAK=P2^4;
2.符号定义
#include“hys.h“bit
irL,irR,irZ,irZL,irZR;
//依次为左、右、前、左前、右前
unsigned
char
endX,endY,X,Y,exchangeX,exchangeY,Count0,Count1;
unsigned
char
now_direct;
//绝对方向
unsigned
char
arrived;
//定义到达终点坐标时要用到的的一个符号
3.延时函数代码
//在24M晶振下,延时1ms,12M倍频
void
delay(unsigned
char
ms)
{
unsigned
char
X;
while(ms--)
{
X=250;
while(--X);//延时250us
X=250;
while(--X);//延时250us
X=250;
while(--X);//延时250us
X=250;
while(--X);//延时250us
}
}
4.驱动配置代码
/****************************电机驱动函数*********************************/
//左电机停止
void
STOPML()
{
ML1=0;
ML2=0;
}
//右电机停止
void
STOPMR()
{
MR1=0;
MR2=0;
}
//启动左电机
void
RUNML(bit
i)
{
if(i)
{
ML1=1;
ML2=0;
}
else
{
ML1=0;
ML2=1;
}
}
//启动右电机
void
RUNMR(bit
i)
{
if(i)
{
MR1=1;
MR2=0;
}
else
{
MR1=0;
MR2=1;
}
}
/*******************************电机初始化函数******************************/
void
init_motor()
{
ML1=0;
ML2=0;
MR1=0;
MR2=0;
}
5.中断函数代码
//T2中断周期设定函数,最大30ms
void
set_Timer2(unsigned
int
m)
{
TH2=RCAP2H=(65535-m)/256;
TL2=RCAP2L=(65535-m)%256;//设定T2自动重装载寄存器和计数器初值
}
void
init_Timer2(unsigned
int
m)//中断定时获取
传感器返回的值
{
EA=1;
ET2=1;
TH2=RCAP2H=(65535-m)/256;
TL2=RCAP2L=(65535-m)%256;//设定T2自动重装载寄存器和计数器初值///捕捉/自动重载寄存器
TR2=1;
}
/************************中断函数*************************************/
//T0中断函数//右电机
void
timer0()
interrupt
1//外部中断1
{
//工作模式2.自动重装初值
Count0++;
}
//T1中断函数//左电机
void
timer1()
interrupt
3
//外部中断2
{
//工作模式2.自动重装初值
Count1++;
}
//T2中断函数
void
Timer2()
interrupt
5
{
static
unsigned
char
intC=1,irNo=1;
TF2=0;//软件清除溢出中断标志位
//中断服务代码
if(intC==1)
{
switch(irNo)
{
case
1:
{
A0=0;
A1=0;
A2=0;
intC=1;
set_Timer2(2000);//发射2us
break;
}
case
2:
{
if(irR1)
//如果irR1为高电平
{
irZL=0;
//没有障碍物
置低电平0
LED1=1;
//熄灭LED灯
}
else
//如果irR1低电平
{
irZL=1;
//有障碍物
置高电平1
LED1=0;
//点亮LED灯
}
A0=1;
A1=0;
A2=0;
intC=1;
set_Timer2(2000);
break;
}
case
3:
{
if(irR2)
{
irZ=0;
LED2=1;
}
else
{
irZ=1;
LED2=0;
}
A0=0;
A1=1;
A2=0;
intC=1;
set_Timer2(2000);
break;
}
case
4:
{
if(irR3)
{
irZR=0;
LED3=1;
}
else
{
irZR=1;
LED3=0;
}
A0=1;
A1=1;
A2=0;
intC=1;
set_Timer2(2000);
break;
}
case
5:
{
if(irR4)
{
irL=0;
LED4=1;
}
else
{
irL=1;
LED4=0;
}
A0=0;
A1=0;
A2=1;
intC=1;
set_Timer2(2000);
break;
}
case
6:
{
if(irR5)
{
irR=0;
LED5=1;
}
else
{
irR=1;
LED5=0;
}
A0=1;
A1=1;
A2=1;
intC=2;
set_Timer2(20000);
break;
}
}
if(irNoCount1)
{
STOPMR();//右轮停止
RUNML(1);//正转左轮
}
else
{
STOPML();//左轮停止
RUNMR(1);//正转右轮
}
}
xy_repair();
//更新当前坐标
arrive();
//判断是否到达指定坐标
init_motor();//初始化电机
}
10.右手法则
/*****************************右手法则*************************************/
void
righthand()
{
switch(now_direct)
{
case
0:
//
当前方向向北
{
if(!irR)
//如果右边没有障碍
{
turnright();
//先向右转并更新绝对方向
Go_one_step();//再前进一步并且更新坐标并判断是否到达指定坐标
break;
}
if(!irZ)
//如果前方没有障碍
{
Go_one_step();//向前走一步并且更新坐标并判断是否到达指定坐标
break;
}
if(!irL)
//如果左方没有障碍物
{
turnleft();
//先左转并更新绝对方向
Go_one_step();
//再前进一步并且更新坐标并判断是否到达指定坐标
break;
}
else
//如果左、右、前方都有障碍物
{
turnback();//先向后转并更新绝对方向
Go_one_step();//再前进一步并且更新坐标并判断是否到达指定坐标
break;
}
}
case
1://当前方向向东
{
if(!irR)
{
turnright();
Go_one_step();
break;
}
if(!irZ)
{
Go_one_step();
break;
}
if(!irL)
{
turnleft();
Go_one_step();
break;
}
else
{
turnback();
Go_one_step();
break;
}
}
case
2://当前方向向南
{
if(!irR)
{
turnright();
Go_one_step();
break;
}
if(!irZ)
{
Go_one_step();
break;
}
if(!irL)
{
turnleft();
Go_one_step();
break;
}
else
{
turnback();
Go_one_step();
break;
}
}
case
3:
//当前方向向西
{
if(!irR)
{
turnright();
Go_one_step();
break;
}
if(!irZ)
{
Go_one_step();
break;
}
if(!irL)
{
turnleft();
Go_one_step();
break;
}
else
{
turnback();
Go_one_step();
break;
}
}
}
}
11.主函数
void
main()
{
char
s1=key;//按键开关
init_system();//初始化系统
if(s1)//按下开关键
{
delay(500);
while(1)
{
//ir_Test();//可以不调用这个函数
righthand();
//右手法则寻路
if(arrived==1)
//到达终点
{
arrived=0;
turnback();
//向后传
exchangeX=X;
//交换终点坐标和起点坐标的值
exchangeY=Y;
X=endX;
Y=endY;
endX=exchangeX;
endY=exchangeY;
delay(500);
//延时
while(1)
{
lefthand();//左手法则原路返回
if(arrived==1)
while(1);//程序停止
}
}
}
}
}
4
总结
此次课程设计中遇到了不少的问题,比如硬件焊接中硬件焊接错误,软件设计中电脑鼠如何在迷宫中行走,遇到障碍物能转弯,找到终点算法等问题,不过还好的是这些问题都一个一个得解决了。
本次课程设计提高了我的写程序能力和算法思想,虽然有些算法没用到,但还是理解到了。最重要的是让我学会了如何把想法变成程序,这是一个艰难而有趣的过程,它不仅锻炼了我的思维方式,还教会了我要一步一步地去做,脚踏实地才能保证正确。通过这次课程设计自己的写程序能力和思维方式得到了提升,这是需要实践才能得到的。
4.1
所遇问题及解决办法
问题:硬件焊接时芯片方向焊接反了。
解决方法:学长帮忙把芯片取下来重新焊接好。
问题:电脑鼠行走中的算法问题。
解决方法:通过学长的发的文档了解了向心法则和单一法则,最后选择了单一法则作为探寻路径的算法。
问题:如何让电脑鼠记住挡板信息和最短路径。
解决方法:选择从起点到达终点,再从终点原路返回到起点的方案,所以不用最短路径,也不用记住挡板信息,直接用左手法则和右手法则。
问题:电脑鼠如何走一步更新一步坐标。
解决方法:通过询问学长更新坐标的原理,再结合学长给的代码,自己写出了走一步更新一步坐标的函数代码。
4.2
心得体会
在这次课程设计中,硬件焊接过程中,有些零件太小导致一个人并不是很好焊接,这时也许需要其他同学的帮助,同学之间相互帮助也许能更快完成工作;在软件设计中,当遇到了一个问题而找不到解决方法时,沟通交流是最好的解决方法。所以在遇到不懂的问题时要多和同学、老师交流请教。把问题弄懂了就是自己的知识了,以后在遇到类似的问题就能更好的解决了。
27