机电课程设计报告汇总.docx
《机电课程设计报告汇总.docx》由会员分享,可在线阅读,更多相关《机电课程设计报告汇总.docx(18页珍藏版)》请在冰点文库上搜索。
机电课程设计报告汇总
机电测控综合训练课程设计报告
姓名:
梁志开
班级:
机实1001班
学号:
U201010585
指导老师:
何岭松
陶凌阳
林向南
时间:
2014年3月7日
一、设计背景·······································3
二、设计内容·······································3
三、程序框图·······································4
四、程序编写·······································6
五、设计小结·······································9
六、程序附件·······································9
一、设计背景
本次课程设计名为机电测控综合训练课程设计,以课程提供的
测控实践平台的实验条件为基础,自选一个机电测控方面的题目,在3周时间内完成一个小型机电测控系统的设计与制作工作。
课程设计旨在帮助我们了解和掌握机电测控产品设计、开发的实施过程和主要环节,培养根据工程任务,综合应用四年所学光、机、电、计算机等知识,提出解决方案、实施解决方案、完成工程任务的能力以及理论联系实际的设计思想和解决工程实际问题的能力。
本次课程设计所选的机器人小车为德普施科技有限公司生产的宝贝车机器人,采用的51单片机问8位的AT89S52单片机,可反复擦写1000次,配置十分灵活,可扩展性强。
二、设计内容
根据本次课程设计的宗旨与条件,我们组经过思考确定了设计
项目,即安全指南车。
本组安全指南车的项目采用的机器人小车为德普施科技有限公司友情提供的宝贝车机器人,采用AT89S52单片机对小车轮上的舵机进行控制,传感器使用的是HM55B指南针模块和超声波传感器各一个。
经过硬件的组装与调试之后,通过HM55B指南针模块能够对该车进行持续不断的角度测量,并通过舵机控制使该样车实现在初始方向任意的情况下均能自动转向,最终指向南方行驶;接着,又考虑到指南车在一直朝南行驶的途中可能会撞到障碍物,会给指南车带来安全问题,因此,本指南车又使用超声波传感器进行距离测量,当测量到与障碍物的距离达到危险距离的时候,程序控制指南车停止行驶,保障指南车的安全,是为安全指南车。
本次安全指南车的设计过程总共设计到三个设计内容,分别由本组的3个人分别承担完成。
三个设计内容包括传感器测控电路的设计、制作、调试(由本组的王健同学完成),单片机测控程序的设计、编写、调试(由本组的梁志开同学完成),LabView测控程序的设计、编写、调试(由本组的梅志远同学完成)。
下面的报告内容将着重介绍由我自己完成的keil单片机C程序的设计内容。
三、程序框图
任何程序的设计首先都需要进行程序思路的探索,本次课程设
计的安全指南车也经过了这一过程。
下图为安全指南车的程序思路流程图。
指南针指南程序
超声波传感器测距程序
停止行驶
朝南行驶
如上图可以知道本次设计的安全指南车的程序思路流程,首先小车执行指南针指南程序,能够在任意方位都转成朝南方行驶,接着执行超声波测距程序,持续与前方物体经行距离测量,遇到障碍物时,如果行驶至距离障碍物的安全距离以内时,单片机程序控制舵机停止转动进而使小车停止行驶,从而保证指南车的安全。
有了程序思路流程图之后,就需要设计正规的程序框图,下面即安全指南车的程序框图。
四、程序编写
本部分内容仅介绍几个重要部分的程序编写内容,更加完整的keil单片机C程序将会在第六节程序附件中展示。
1、指南针坐标值获取程序
由指南针传感器的工作原理可知,指南针的指南原理即算出地磁场的坐标在指南针所处位置坐标上的坐标值x、y,经过angleθ=arctan(-y/x)的计算即可算出方向角θ的值。
因此,必须首先获得x、y的值。
2、指南车指南程序
经过计算得出θ值之后,再转化为弧度即得到角度的测量。
然后通过if语句判断不同角度情况下调用不同的运动函数(因为指南针传感器安装时其前方并非对着车前方,而是有90度的偏离,故在程序中看到的判断角度与之前程序框图的角度有90度的偏离)。
指南车转向南方之后便跳出循环,进入dis()函数即超声波距离测量函数。
3、超声波测距程序
先经过初始化,然后在信号端给触发信号使超声波传感器发射超生波,然后经反射回来的超声波测出超声波反射时间,进而通过公式算出距离,然后判断与障碍物之间的距离,若距离大于安全距离则继续向前行驶,并继续重复超声波测距的程序,反之若小于安全距离则调用停止程序,并跳出超声波测距的循环程序。
五、设计小结
通过为期3周的机电测控综合训练课程设计,我认为自己在复习以前学过的知识的同时,也让我学到了不少工科生所应该具备的能力,动手实践的能力、团队合作的能力、与人沟通的能力等等。
在顺利完成本次课程设计的同时,也让我感受到学习机械的乐趣,将机械知识运用在实际生活娱乐中的乐趣,运用机械改善生活美化生活的乐趣。
下面就说一说在承担这个项目keil程序编写中遇到的几个问题以及解决方法吧。
1、完全指南无法实现
因为本程序是每次测量之后会调用相关的运动函数,故存在一个最小的运动角,所以本程序有南方左右误差10度。
2、如何提高指南车的运动精度与运动平稳性
同上,提高的方法有两个:
减小最小运动角,减小方向误差角度。
六、程序附件
以下是完整的keil程序。
#include
#include
#include
#include
#include
#include"serial.h"
#include"boebot.h"
#defineSIGP3_2
#defineHIGH_EN P2_2=1
#defineLOW_ENP2_2=0
#defineReset0x00
#defineMeasure0x08
#defineReport0x0C
#defineReady0x0C
#defineNegMask0xF800
intsucceed_flag,test,timeH,timeL,time,distance;
doubleangle;
intflag=0;
intx;
inty;
intcounter;
intradian;
intdegrees;
doubleangle;
voidStop(void)
{
for(counter=1;counter<=5;counter++)//停止
{
P1_1=1;
delay_nus(1500);
P1_1=0;
P1_0=1;
delay_nus(1500);
P1_0=0;
delay_nms(20);
}
}
voidFor_Ward(void)
{
for(counter=1;counter<=5;counter++)//向前
{
P1_1=1;
delay_nus(1700);
P1_1=0;
P1_0=1;
delay_nus(1300);
P1_0=0;
delay_nms(200);
}
}
voidLeft_Turn(void)
{
for(counter=1;counter<=5;counter++)//向左转1/4圈
{
P1_1=1;
delay_nus(1300);
P1_1=0;
P1_0=1;
delay_nus(1300);
P1_0=0;
delay_nms(20);
}
}
voidRight_Turn(void)
{
for(counter=1;counter<=5;counter++)//向右转1/4圈
{
P1_1=1;
delay_nus(1700);
P1_1=0;
P1_0=1;
delay_nus(1700);
P1_0=0;
delay_nms(20);
}
}
voidBack_Ward(void)
{
for(counter=1;counter<=5;counter++)//向后退
{
P1_1=1;
delay_nus(1300);
P1_1=0;
P1_0=1;
delay_nus(1700);
P1_0=0;
delay_nms(20);
}
}
voidIO_init()
{
//定时器0用于测量脉冲宽度
TMOD|=0x01;//定时器1为工作模式1(16位自动重装模式)
TF0=0;//溢出标志清零
TR0=0;//开启定时器,但定时器的触发由/INT0决定
IT0=0;//外部中断由低电平触发,也可设置为1,用下降沿触发,而在此时,是高电平;
ET0=1;//允许定时器0中断
EA=1;//全局允许中断
//定时器1用于硬件串口通信
TMOD|=0x20;//定时器0方式2.8位自动重装模式
SCON=0x50;//模式1,8位数据
TH1=0xFD;//波特率为9600
TL1=0xFD;
TR1=1;//起动定时器
TI=1;
}
voiddis()
{
IO_init();
test=0;
timeH=0;
timeL=0;
SIG=0;
while
(1)
{
EA=0;
SIG=1;
delay_nus(5);
SIG=0;
delay_nus(750);
succeed_flag=0;
SIG=1;
EA=1;
EX0=1;
TH0=0;
TL0=0;
TF0=0;
TR0=1;
delay_nms(20);
TR0=0;
EX0=0;
if(succeed_flag==1)
{
time=timeH*256+timeL;
distance=time/58;
printf("Thedistanceis");
printf("%dcm.\n",distance);
if(distance>=10)
{
For_Ward();
}
elseif(distance<10)
{
Stop();
break;
}
}
}
while
(1)
{Stop();
}
}
voidexter()interrupt0
{
timeH=TH0;
timeL=TL0;
succeed_flag=1;
EX0=0;
}
voidtimer0()interrupt3
{
TH0=0;
TL0=0;
}
voidCompass_Get_Axes()
{
unsignedcharstatus;
x=0x0000;
y=0x0000;
HIGH_EN;//EN为低电平有效
LOW_EN;
ShiftOut(MSBFIRST,Reset,4);//输入Reset指令,并执行
HIGH_EN;
LOW_EN;
ShiftOut(MSBFIRST,Measure,4);//输入测量指令,测量
status=0;
do
{HIGH_EN;
LOW_EN;
ShiftOut(MSBFIRST,Report,4);//输入Report指令,返回校验字符
status=ShiftIn(MSBFIRST,4);
}while(status!
=Ready);//若如校验字符为1100,则输出结果,即X\Y值
x=ShiftIn(MSBFIRST,11);
y=ShiftIn(MSBFIRST,11);
HIGH_EN;
if(y&0x0400)//对于最高位,即第十一位,即若结果为负,则十一位以上全部置1
y=y|NegMask;
if(x&0x0400)
x=x|NegMask;
}
voidmain()
{
uart_Init();
while
(1)
{
Compass_Get_Axes();//测量
angle=atan2(y,x);
radian=angle*100;
degrees=radian*57.297;
degrees=(degrees/10)+1800;
degrees=degrees/10;
printf("x=%d,y=%d,degrees=%d\n",x,y,degrees);
if(degrees>=100°rees<=270)
{Right_Turn();
}
elseif(degrees>=80°rees<=100)
{
break;}
elseLeft_Turn();
//delay_nms(100);
}
dis();
}