悬挂运动控制系统(E题)设计报告_第1页
悬挂运动控制系统(E题)设计报告_第2页
悬挂运动控制系统(E题)设计报告_第3页
悬挂运动控制系统(E题)设计报告_第4页
悬挂运动控制系统(E题)设计报告_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

悬挂运动限制系统(E题)设计报告摘要:本悬挂限制系统是一个电机限制系统,限制物体在80cm×100cm的范围内作直线、圆、寻迹等运动,并且在运动时能显示运动物体的坐标。设计采纳AT89S52单片机作为核心限制器件,采纳57BYG007-4型步进电机和高细分步进电机驱动器SM-60作为动力装置,采纳红外反射式光电传感器实现画板上黑色线寻迹检测,显示部分用液晶显示模块LCD1602实现。关键词:悬挂限制、单片机、步进电机、红外反射式光电传感器一、设计要求1、任务设计一电机限制系统,限制物体在倾斜(仰角≤100度)的板上运动。在一白色底板上固定两个滑轮,两只电机(固定在板上)通过穿过滑轮的吊绳限制一物体在板上运动,运动范围为80cm×100cm。物体的形态不限,质量大于100克。物体上固定有浅色画笔,以便运动时能在板上画出运动轨迹。板上标有间距为1cm的浅色坐标线(不同于画笔颜色),左下角为直角坐标原点,示意图如下。2、基本要求:(1)限制系统能够通过键盘或其他方式随意设定坐标点参数;(2)限制物体在80cm×100cm的范围内作自行设定的运动,运动轨迹长度不小于100cm,物体在运动时能够在板上画出运动轨迹,限300秒内完成;(3)限制物体作圆心可随意设定、直径为50cm的圆周运动,限300秒内完成;(4)物体从左下角坐标原点动身,在150秒内到达设定的一个坐标点(两点间直线距离不小于40cm)。3、发挥部分(1)能够显示物体中画笔所在位置的坐标;(2)限制物体沿板上标出的随意曲线运动(见示意图),曲线在测试时现场标出,线宽1.5cm~1.8cm,总长度约50cm,颜色为黑色;曲线的前一部分是连续的,长约30cm;后一部分是两段总长约20cm的间断线段,间断距离不大于1cm;沿连续曲线运动限定在200秒内完成,沿间断曲线运动限定在300秒内(3)其他。4、评分标准项目满分基本要求设计与总结报告:方案比较、设计与论证,理论分析与计算,电路图及有关设计文件,测试方法与仪器,测试数据及测试结果分析。50实际制作完成状况50发挥部分完成第(1)项10完成第(2)项中连续线段运动14完成第(2)项中断续线段运动16其他105、说明1、物体的运动轨迹以画笔画出的痕迹为准,应尽量使物体运动轨迹与预期轨迹吻合,同时尽量缩短运动时间;2、若在某项测试中运动超过限定的时间,该项目不得分;3、运动轨迹与预期轨迹之间的偏差超过4cm时,该项目不得分;4、在基本要求(3)、(4)和发挥部分(2)中,物体起先运动前,允许手动将物体定位;起先运动后,不能再人为干预物体运动;5、竞赛结束时,限制系统封存上交赛区组委会,测试用板(板上含空白坐标纸)测试时自带。二、方案论证与选择1.核心限制模块的选择方案一:FPGA/CPLD方式。即用FPGA/CPLD完成键盘定义与识别、电机工作状态选择与切换、液晶电路的驱动与限制等功能。这种方案的优点在于系统结构紧凑、操作便利,而且可以运用的I/O口线许多;缺点是调试时须要接许多接线,过程繁琐,而且运用CPLD时,由于其内部没有ROM,对功能的实现有所限制。方案二:单片机方式。即由单片机、电机驱动电路及电机等组成系统。运用单片机也可以完成键盘定义与识别、电机工作状选择与切换等功能,组成的系统规模较小,有肯定敏捷性,而且可以运用我们比较熟识的单片机最小系统电路板,削减了工作量。该限制方式须要单片机具有较大的程序存储量,所以可选择存储量为8K的AT89S52单片机。基于以上分析,拟选用方案二。2.电机及其驱动模块的选择

电机驱动模块是本系统的执行机构,用于限制悬挂物体的运动。

方案1:采纳一般小型直流电机。一般直流电机由于其自身结构的限制,限制精度很低,无法达到系统要求的指标,这里不予采纳。

方案2:采纳专用步进电机驱动器及与其配套的步进电机。用这种方案的限制精度、效率和牢靠性都很高。

依据精度要求选择方案二。

3.黑线探测模块方案一:采纳多路阵列式光敏电阻组成的光电探测器。因为光敏电阻探测到黑线时,黑线上方的电阻值发生改变,经过电压比较器比较将信号送给单片机处理,从而限制物体做相应的动作。但由于光敏电阻对环境光的识别,简洁受到外界环境光的影响。,方案二:采纳红外反射式探测,即用已调的红外线垂直射到板面,经反射后转换为电信号送入单片机处理。由于运用的是红外线,不受外界自然光的影响,循迹效果好。基于上面的探讨,选用了抗干扰实力强的方案二。4.显示方案的选择方案一:采纳LED数码管显示器。LED数码管亮度高,醒目,但是其电路困难,显示信息量较小,且动态扫描须要占用大量单片机时间,无法做到实时显示。方案二:采纳汉字LCD液晶显示器。LCD有明显的优点:微功耗、尺寸小,超薄灵巧、显示信息量大、字迹清楚、美观、视觉舒适。本设计中采纳1602字符型LCM。1602字符型LCM克服了LED数码管的缺点,具有显示容量大、占用单片机口线少、节约单片机时间、功耗低等优点,完全符合本系统要求。5.位置传感模块

位置传感模块用于实现"显示画笔位置"的功能。对于这个模块可以有硬件和软件两类解决方案。

方案1:在物体上安装水平和垂直方向的两只激光笔,在板边缘每条坐标线旁边安装一光电传感器,物体坐标所在处的传感器接收到激光笔,即可确定物体位置。可见本方案共须要180个光电传感器,造成此方案几乎不行实现。

方案2:采纳软件的方法确定物体位置。单片机限制物体从某个已知的坐标位置动身,并且记录步进电机的每一次移动状况,就可以通过肯定的算法计算出物体的位置。这种方案没有位置传感器,精度较低,但是系统简洁。避开了硬件方案过于困难的缺点。

本设计运用方案2。6.键盘模块

本模块采纳即插型按键,接在最小系统的P2.0—P2.7,采纳了4×4的16点阵键盘。可以键入1—9的数字,即可以输入点的坐标值(X,Y),以及清除,确定,等功能按键。 三、系统详细设计实现1、硬件电路的设计(1)系统的总体设计方案

如图3-1所示采纳AT89S52单片机作为运动物体的限制中心,进行数学计算、对光电传感器送来的信号进行处理来限制运动物体的运行方向、计算运行物体的坐标位置、LCD数据显示、键盘限制等。

图3-1系统方框图(2)黑线检测模块电路黑线检测模块电路图3-2所示。当红外线反射式光电传感器ST178位于黑线之上时,光电开关输出高电平;反之,输出低电平。光电传感器输出电平后接反相器74LS04以稳定电平和增大驱动实力。本设计采纳8个红外传感器实现对黑线的检测,通过并口转串口芯片74LS165将数据串行传送到单片机。图3-2黑线检测模块电路(3)键盘电路本设计采纳4x4矩阵键盘实现数字的输入和功能的选择,键盘接到AT89S52单片机的P2口,通过单片机对键盘的行列扫描实现按键的识别。键盘电路如图3-3所示:图3-34x4键盘电路对应的按键码如下:789/456/123/清除0确认/(4)单片机电源电路单片机限制电路、红外传感器模块电路和液晶显示模块均采纳+5V供电,采纳集成稳压芯片7805来实现,电路图如图3-4所示。图3-4单片机电源电路(5)步进电机驱动电路本设计采纳57BYG007-4型步进电机和专用高细分步进电机驱动器SM-60作为动力装置。57BYG007-4型步进电机为四相混合式步进电机,由于试验室现有电机驱动器为两相的,固步进电机作两相运用,步距脚为1.8度,通过步进电机驱动器SM-60细分实现步距脚0.9度。电机驱动器SM-60接口如下

:☆GND端为外接直流电源,直流电压为12v

A+,A-端为电机A相,B+,B-端为电机B相。

+COM端为光电隔离电源公共端,接单片机供电电源为+5V,☆

CP端为脉冲信号,下降沿有效。

DIR端为方向限制信号,电平凹凸确定电机运行方向。

FREE端为驱动器使能,高电平或悬空电机可运行。低电平驱动器无电流输出,电机处于自由状态。2、软件及算法设计(1)物体位置的计算

图3-5物体位置示意图坐标点参数的计算

将画笔所在的位置设定为整个物体的位置。如图3-5

设定物体位置的初值坐标为(X,Y)

L1=

L2=

设电机A

的步进为acm,电机B的步进为bcm,物体高度为hcm。

如图8为物体在画板某一位置,则有:

解得X轴点位置和h为

则Y轴点位置

Y=115-h

限制物体从一点到另一点的实现就是当X、Y已知条件,求电机的步进过程。由图8解得:

解得

(cm)

(cm)

由此,利用软件实现以上算法来分别限制两个步进电机的步进a,b,这样就可以向限制系统输入起点坐标和终点坐标让物体在画板置随意行走。(2)直线算法:目前画直线的算法也算是有许多,比如:逐点比较直线插补,脉冲增量插补和数据采集插补,本设计依据实际所学学问,选择了逐点比较直线插补法,详细如下:逐点比较法的基本原理是,在刀具按要求轨迹运动加工零件轮廓的过程中,不断比较刀具与被加工零件轮廓之间的相对位置,并依据比较结果确定下一步的进给方向,使刀具向减小偏差的方向进给。图3-6第一象限直线如图3-6所示,设直线的起点为坐标原点,终点坐标为A(,),点m(,)为加工点(动点)。定义偏差公式为。若=0,表明点m在OA直线段上;若>0,表明点m在OA直线段上方,即点m’处;若<0,表明点m在OA直线段下方,即点m’’处。由此可得第一象限直线逐点比较法插补的原理是:从直线的起点动身,当0时,沿+x轴方向走一步;当<0时,沿+y轴方向走一步;当两方向所走的步数与终点坐标(,)相等时,发出终点到信号,停止插补。可以将上面所定义的偏差公式进一步简化,推导出偏差的递推公式。当0时,沿+x轴方向进给一步,(1)②当<0时,沿+y轴方向进给一步,(2)式(1)和式(2)是简化后偏差的计算公式,在公式中只有一次加法或减法运算,新加工点的偏差都可由前一点偏差和终点坐标相加或相减得到。本体设计中采纳以上原理,不过对于非原点起先的直线,采纳起点坐标归零思想,结果也证明白改思路的可行性。(3)画圆算法:画圆算法采纳圆弧插补法。圆弧插补法也是在绘图系统中常用的一种方法,它和直线插补法原理相同,也是逐点比较算法。

若F=0,表明加工点在圆弧上;

F>0,表明加工点在圆弧外;

F<0,表明加工点在圆弧内。

若F≥0,为靠近圆弧,下一步向-X轴进给一步,并计算出新的偏差值;

F<0,为靠近圆弧,下一步向+Y轴进给一步,并计算出新的偏差值。各象限插补公式如下在实际操作中,可以以圆心为假设的坐标原点,再依据上面的原理设计算法。(4)循迹黑线的探测及循迹算法在以画笔为中心,半径20毫米0707654321-1+1图3-7轨迹探测传感器安装方式图3-8方向调整示意图依据图3-7安装方式及安装半径,只要系统的采样频率足够高,轨迹是无法脱离探测范围的。但由于运用了8个传感器,不同传感器信号间的组合太多,运用一般穷举方法难以实现循迹限制,因此自己设计了一套循迹算法。如图3-8,定义了物体循迹时运动的8个方向,图中黑箭头(1号方向上)表示物体当前的循迹方向。循迹时,运用变量Direct表示当前物体运动方向,物体每次运动时先按当前方向向前步进一段固定的距离,然后检测采样传感器信号并调整Direct,再沿新的Direct方向步进。由于所给的曲线是连续的,所以每次调整Direct只能是+1或-1。如图3-8所示,Direct在需向左偏时则Direct加1,需向右偏则减1,接着前进则保持不变。由于只有8个运动方向,所以对Direct的运算需在模8的范围内(0~7)进行。现在考虑如何确定左偏或右偏的问题,运用上述调整方法只须要依据Direct的前后方向及左右方向的四个信号对Direct调整即可。如图4中仅需依据1、3、5、7方向的信号对Direct调整。由于每个方向上±1和保持不变的传感器信号是肯定的,故对8个方向上的调整策略用一个静态数组的形式保存起来,调整时干脆查表即可,便利编程。这种循迹算法大大地削减了循迹运动的调试时间,为整个作品胜利的完成打下了基础。当每次步进的距离较小时,若在Direct方向的前、左、右三处的传感器同时发觉是白纸,则表明传感器探测到了曲线的间断部分或终点,此时应依据前几次(2~3次)Direct的平均值作为探究方向,再向前步进2~3步,保证循迹的正确停止。在取平均值时,需对70和07的转变作特别处理,否则可能出错。实践证明,依据上面的方法循迹快速稳定,并且不会受交叉线的影响。由于轨迹线有肯定宽度,实际的轨迹不行能转折得非常快速,当步进距离较小时,甚至可以完成锐角的循迹。本系统运用的步进距离是5毫米(5)系统主程序流程框图上电,初始化液晶显示上电,初始化液晶显示等待按键,选择所需的功能1直线2正方形3圆4循迹输入起点终点坐标依据事先设定运行设定圆心手动到点手动到循迹起始点执行部件返回显示程序按键确认,进入对应程序图3-9系统主程序流程框图四、系统测试1.测试仪器DT92秒表、卷尺;+12V直流稳压电源。2.测量结果(1)直线测试次数设定起点坐标设定终点坐标实际坐标误差用时1(0,0)(50,50)(50.2,51.3)2cm75s2(0,0)(80,99)(80.1,100.5)1.5cm134s(2)画圆测试次数圆心坐标半径最大误差用时1(25,25)251cm130s2(3)循迹测试连续线段线长间断线段长度60cm46用时28.1s24.3s3.误差分析及改进措施(1)坐标转换的误差。(X,Y)坐标向(L,R)坐标转换时运用几何分析的方法,但为了处理便利,将悬挂滑轮视为一点,没有考虑其半径。本作品以减小其半径的方法降低误差。同时,进行坐标变换时,单片机在计算精度上也会引进误差,由于运用浮点运算,该误差不大。(2)笔尖和悬挂点不在同一平面引入误差,应尽量使三点处于与地板平行的平面以减小误差。(3)步进电机的步进脉冲个数和步进线距离之间的折算误差。作品运用了干脆测量一段距离和步进个数再求平均值的方法降低误差。(4)牵引线引入的误差,包括拉伸误差和由松弛产生的误差。改进措施是运用变形系数小的牵引线和增加悬挂物体的重量。(5)绕线产生的误差。解决方法是依据力学分析采纳机械的方法保证绕线不重叠,并且运用半径小的牵引线使绕线在横向延长的距离削减,从而削减误差。(6)读数误差。初始定位时需供应物体坐标,测量结果需人为读数,这会引入误差。五、结论本设计以AT89S52单片机为核心,利用软件编程,实现了定点直线运动,圆形轨迹运动,间断黑线循迹以及坐标的实时显示。测试结果表明,本设计很好地完成了题目基本部分和发挥部分的全部要求,速度快、精度高。整个系统从软件到硬件都体现优良简约的风格。主要有以下几个优点:

(1)采纳步进电机及专用细分驱动器,悬绳收放限制较精确;

(2)程序算法优良,易于误差处理和提高精确度;

(3)LCD液晶显示,界面友好。六、参考文献1、王琼.单片机原理及应用.合肥工业高校出版社2、求是科技.单片机典型模块设计实例导航.人民邮电出版社3、高祥瑞.全国高校生电子设计竞赛培训教程-数字系统与自动限制系统设计.电子工业出版社附录一电路原理图1、限制部分电路图:2、循迹模块电路图:附录二源代码/*******************************************************************/#include<reg52.h>#include<intrins.h>#include<string.h>#include<math.h>#defineucharunsignedchar//无符号字符类型定义#defineuintunsignedint//无符号整数类型定义/******************************************************************///步进电机驱动器引脚连接定义sbitMotor_Left_CP=P1^0;//左步进电机脉冲sbitMotor_Left_DIR=P1^1;//左步进电机方向限制端sbitMotor_Right_CP=P1^2; //右步进电机脉冲sbitMotor_Right_DIR=P1^3; //右步进电机方向限制端sbitMotor_FREE=P1^4; //电机使能端(高电平有效,低电平是电机处于自由状态)sbitSHLD=P1^5;sbitS_clk=P1^6;sbitS_data=P1^7;sbitjiesu=P3^6;/**************************************************/#definepai3.141592//圆周率#definea15 //80cmx100cm场地到两电机连线的垂直距离(厘米)#defineb15 //80cmx100cm场地到边线(顶端滑轮和电机的连线)的垂直距离(厘米)#definer0.8276//滑轮半径(厘米)#definestepz0.0122//左步进电机每步弧长(厘米)#definestepy0.0122//右进步点击每步弧长(厘米)#definestep0.0125//步进电机每步弧长(厘米)#defineradius25 //圆周半径长度#defineMotor_FREE1/**************************************************///LCD1602液晶模块引脚连接定义#defineLCD_DataP0 //1602的8位数据线连接到P0口sbitRS=P3^5; //1602的数据/吩咐选择端RS连接到P1.0sbitRW=P3^4; //1602的读/写选择端连接到P1.1sbitEN=P3^3; //1602的使能信号引脚连接到P1.2/**************************************************/ucharcodekaiji0[16]={">>>WELCOME!<<<"};ucharcodekaiji1[16]={"LOADDOWNING....."};ucharcodetable0[16]={"1.Line2Rectan"};ucharcodetable1[16]={"3.Circu4.Follow"};ucharcodetable3[16]={"DrawaLine"};ucharcodetable4[16]={"DrawCircularity"};ucharcodetable5[16]={"FollowtheLine"};ucharcodetable6[16]={"(,);(,)"};ucharcodetable7[16]={"(,);r=cm"};ucharcodetable8[16]={"(cm,cm)"};ucharcodetable9[16]={"ENTERtoBegin"};ucharcodetable10[16]={"Executing....x"};ucharcodetable11[16]={"Rectanperform."};ucharcodetable12[16]={"(25,25)-(50,25)"};ucharcodetable13[16]={"(50,50)-(25,50)"};ucharcodetable14[16]={"havecompleted!!"};ucharcodewrong[16]={"WrongCoordinate"};ucharcodeagian[16]={"InputAgian?"};ucharcodenumber[10]={"0123456789"};/**************************************************/intx0,y0,x1,y1;/*******************************************************************///函数声明voidDelay_1ms(inttime); //延时1ms*timevoidLCD1602_Busy_Check(void);//LCD1602忙检查函数voidWrite_LCD1602(ucharudata,bitcommand);//LCD1602写数据和写指令函数voidWrite_Byte_Locate(ucharx,uchary,ucharudata);//把数据显示在LCD1602的指定位置voidInit_LCD1602(); //LCD1602初始化函数ucharKeyboard_Scan(void); //键盘扫描函数,返回键盘扫描码ucharScan_Code_Transform(ucharscancode); //键码识别函数//voidMotot_ld(int);voidMotor_Left_Step(bitDir);//左电机转动一步,Dir=0时反转(顺时针),即松开线;Dir=1时正转(逆时针),即收紧线voidMotor_Right_Step(bitDir);//右电机转动一步,Dir=0时反转(顺时针),即收紧线;Dir=1时正转(逆时针),即松开线voidDraw_Circular(intx,inty);//画圆函数voidcurrentdisp(intline,intx,inty);//当前显示voidlinedisp(int,int,int,int,int);//当前直线点显示voiddisplay(uchartable[16],bitline);//提示显示voidline(int,int,int,int); //画直线函数voidDraw_line();//voidbuchang(float,float,float,float);//确定左右电机移动的步数voidReturndata();//读取对光二极管的值voidfollow();//循迹函数voidzouxiang(int);//循迹电机驱动函数/*******************************************************************///延时函数,延时时间=1ms*time(晶振12MHz)voidDelay_1ms(inttime){uchari,j;do{for(i=0;i<15;i++)for(j=0;j<20;j++);}while((time--)!=0);}/*******************************************************************//**********************************LCD1602液晶操作函数部分**********///LCD1602液晶检查忙函数voidLCD1602_Busy_Check(void){EN=0;RW=1;RS=0;EN=1;while(LCD_Data&&0x80==1);EN=0;Delay_1ms(1);}/**************************************************///LCD1602写数据和写指令函数//把写数据和指令二个合在一起,用一个变量command来推断voidWrite_LCD1602(ucharudata,bitcommand){LCD1602_Busy_Check();//忙检查RS=command; //command=0时写入指令,command=1时写入数据RW=0; //把LCD设置成写状态EN=1; //E=高脉冲,把数据/指令写入LCD_Data=udata;EN=0;}/**************************************************///把数据显示在LCD1602的指定位置//x,y是坐标,udata是须要显示的数据//x不能大于15,每行最多显示16字符//y不能大于1,最多显示2行voidWrite_Byte_Locate(ucharx,uchary,ucharudata){if(y){x+=0x40;}//推断显示哪行,显示其次行LCD存储区加40Hx+=0x80; //假如没有加0X40则显示第一行Write_LCD1602(x,0);//写指令Write_LCD1602(udata,1);//写显示数据}/**************************************************///LCD1602初始化函数voidInit_LCD1602(){Write_LCD1602(0x38,0);//显示模式设置Delay_1ms(20);Write_LCD1602(0x01,0);//清除屏幕Write_LCD1602(0x06,0);//显示光标移动设置Write_LCD1602(0x0c,0);//开显示}/*******************************************************************//*******************键盘扫描和键码识别函数部分**********************///键盘扫描函数,返回键盘扫描码//P2.0~P2.3输出,P2.4~P2.7输入ucharKeyboard_Scan(void){ucharscancode,tmpcode;P2=0xf0;while(P2==0xf0);//等待有键按下Delay_1ms(20); //延时10ms去抖动if(P2!=0xf0){scancode=0xfe;//逐行扫描while(scancode!=0xef) //还没有扫描完4行{ P2=scancode;if((P2&0xf0)!=0xf0)//本列有键按下{ tmpcode=(P2&0xf0)|(scancode&0x0f); while((P2&0xf0)!=0xf0);//等待键释放 return(tmpcode);}elsescancode=(scancode<<1)|0x01;}} return(0);}/**************************************************///键码识别函数ucharScan_Code_Transform(ucharscancode){switch(scancode){/*将按键码转换成键值*/case0xde:return0;case0xed:return1;case0xdd:return2;case0xbd:return3;case0xeb:return4;case0xdb:return5;case0xbb:return6;case0xe7:return7;case0xd7:return8;case0xb7:return9;case0xee:return10;default:return0xff;}}/*******************************************************************//********************步进电机基本操作部分***************************///左电机转动一步,Dir=0时反转(顺时针),即松开线;Dir=1时正转(逆时针),即收紧线voidMotor_Left_Step(bitDir){Motor_Left_DIR=Dir;Motor_Left_CP=1;Delay_1ms(1);Motor_Left_CP=0;Delay_1ms(1);}/**************************************************///右电机转动一步,Dir=0时反转(顺时针),即收紧线;Dir=1时正转(逆时针),即松开线voidMotor_Right_Step(bitDir){Motor_Right_DIR=Dir;Motor_Right_CP=1;Delay_1ms(1);Motor_Right_CP=0;Delay_1ms(1);}/*************************************************//*圆形当前坐标显示模块*/voidcurrentdisp(intline,intx,inty){Write_Byte_Locate(1,line,number[x/10]); Write_Byte_Locate(2,line,number[x%10]);Write_Byte_Locate(4,line,number[y/10]);Write_Byte_Locate(5,line,number[y%10]);}/************直线当前坐标实现模块****************//*“(,);(,)”*/voidlinedisp(intline,intx,inty,intxz,intyz){ display(table6,line);Write_Byte_Locate(1,line,number[x/10]); Write_Byte_Locate(2,line,number[x%10]); Write_Byte_Locate(4,line,number[y/10]); Write_Byte_Locate(5,line,number[y%10]); Write_Byte_Locate(9,line,number[xz/10]); Write_Byte_Locate(10,line,number[xz%10]); Write_Byte_Locate(12,line,number[yz/10]); Write_Byte_Locate(13,line,number[yz%10]);}/*******************************************************************//*******************************功能实现部分************************//******************步数确定函数*********************/voidbuchang(floatx,floaty,floatnextx,floatnexty)//,int*znum1,int*ynum1){floatzb,yb; intznum,ynum,fhz,fhy;zb=(sqrt((114.3-y)*(114.3-y)+(14.4+x)*(14.4+x))-sqrt((114.3-nexty)*(114.3-nexty)+(14.4+nextx)*(14.4+nextx)))/stepz;yb=(sqrt((114.3-y)*(114.3-y)+(94.4-x)*(94.4-x))-sqrt((114.3-nexty)*(114.3-nexty)+(94.4-nextx)*(94.4-nextx)))/stepy;if(zb>0) {znum=(int)(zb+0.5); fhz=1;} else {znum=abs((int)(zb-0.5)); fhz=0;} if(yb>0) {ynum=(int)(yb+0.5); fhy=0;} else {ynum=abs((int)(yb-0.5)); fhy=1;} while(znum--) { Motor_Left_Step(fhz); } while(ynum--) { Motor_Right_Step(fhy); }// return0;}/*floatsumz1=0.0;floatsumz2=0.0;floatsumy1=0.0;floatsumy2=0.0;voidbuchang(floatx,floaty,floatnextx,floatnexty)//,int*znum1,int*ynum1){floatzb,yb;floatd; intznum,ynum,fhz,fhy;zb=(sqrt((114.7-y)*(114.7-y)+(14.4+x)*(14.4+x))-sqrt((114.7-nexty)*(114.7-nexty)+(14.4+nextx)*(14.4+nextx)))/stepz;yb=(sqrt((114.5-y)*(114.5-y)+(94.4-x)*(94.4-x))-sqrt((114.5-nexty)*(114.5-nexty)+(94.4-nextx)*(94.4-nextx)))/stepy;if(zb>0) {d=zb-(int)(zb);sumz1+=d; fhz=1;if(sumz1>=1){sumz1-=1;znum=(int)(zb)+1;}elseznum=(int)(zb);} else {d=zb-(int)(zb);sumz2+=d; fhz=0;if(sumz2<=-1){sumz2+=1;znum=abs((int)(zb)-1);}elseznum=abs((int)(zb));} if(yb>0) {d=yb-(int)(yb);sumy1+=d; fhy=0;if(sumy1>=1){sumy1-=1;ynum=(int)(yb)+1;}elseynum=(int)(yb);} else {d=yb-(int)(yb);sumy1+=d; fhy=1;if(sumy1<=-1){sumy1+=1;ynum=abs((int)(yb))+1;}elseynum=abs((int)(yb)); } while(znum--) { Motor_Left_Step(fhz); } while(ynum--) { Motor_Right_Step(fhy); }// return0;}*//****************************************************************//*****************画直线函数*************************/voidline(inta0,intb0,inta1,intb1){intcnt;floatx,y,nextx,nexty;intzx,zy,sx,sy;intfm;intcnt1;cnt=(int)((abs(a1-a0)+abs(b1-b0))/(8*step));x=0.0;y=0.0;fm=0;sx=a1-a0;sy=b1-b0;zx=abs(a1-a0);zy=abs(b1-b0);while(cnt--){if((sx>0)&&(sy>=0)){if(fm>=0){if(fm==0) {nextx=x+8*step; nexty=y; buchang((x+a0),(y+b0),(nextx+a0+0.003),(nexty+b0)); fm=fm-zy; } else { nextx=x+8*step; nexty=y; buchang((x+a0),(y+b0),(nextx+a0),(nexty+b0)); fm=fm-zy; }} else{ nexty=y+8*step; nextx=x;; buchang((x+a0),(y+b0),(nextx+a0),(nexty+b0)); fm=fm+zx;} }elseif((sx<=0)&&(sy>0))//2{if(fm>=0){nextx=x-8*step; nexty=y; buchang((x+a0),(y+b0),(nextx+a0),(nexty+b0));fm=fm-zy;}else { nexty=y+8*step; nextx=x; buchang((x+a0),(y+b0),(nextx+a0),(nexty+b0)); fm=fm+zx;} }elseif((sx<0)&&(sy<=0))//3{if(fm>=0){nextx=x-8*step; nexty=y; buchang((x+a0),(y+b0),(nextx+a0),(nexty+b0)); fm=fm-zy;}else{ nexty=y-8*step; nextx=x; buchang((x+a0),(y+b0),(nextx+a0),(nexty+b0)); fm=fm+zx;}}elseif((sx>=0)&&(sy<0))//4{if(fm>=0){nextx=x+8*step; nexty=y; buchang((x+a0),(y+b0),(nextx+a0),(nexty+b0));fm=fm-zy;}else { nexty=y-8*step; nextx=x; buchang((x+a0),(y+b0),(nextx+a0),(nexty+b0)); fm=fm+zx; } }x=nextx; y=nexty; nextx=x+a0;nexty=y+b0; cnt1++; if(cnt1==10) { linedisp(1,a0,b0,nextx,nexty); cnt1=0; } }}voidDraw_line(){if((x0==0)&&(y0==0)) { linedisp(0,x0,y0,x1,y1); line(x0,y0,x1,y1); } else { linedisp(0,0,0,x0,y0); line(0,0,x0,y0); Delay_1ms(100); linedisp(0,x0,y0,x1,y1);line(x0,y0,x1,y1); }}/*************************************************************//*********************画圆程序****************************/ //采纳逐点比较法画圆voidDraw_Circular(intx,inty){floatpointx,pointy,nextx,nexty;floatresult;floatsize=0.15; intcnt; intcnt1=0; cnt=(8*radius)/size;pointx=x;pointy=y-25; display(table7,0);currentdisp(0,x,y); Write_Byte_Locate(11,0,number[radius/10]); Write_Byte_Locate(12,0,number[radius%10]);while(cnt--){result=((pointx-25)*(pointx-25)+(pointy-25)*(pointy-25))>625?1:0;if(result){if((pointx>x)&&(pointy>=y)){nextx=pointx-size;nexty=pointy;buchang(pointx,pointy,nextx,nexty);}elseif((pointx<=x)&&(pointy>y)){nextx=pointx;nexty=pointy-size;buchang(pointx,pointy,nextx,nexty);}elseif((pointx<x)&&(pointy<=y)){nextx=pointx+size;nexty=pointy;buchang(pointx,pointy,nextx,nexty);}elseif((pointx>=x)&&(pointy<y)){nextx=pointx;nexty=pointy+size;buchang(pointx,pointy,nextx,nexty);}}else{if((pointx>x)&&(pointy>=y)){nextx=pointx;nexty=pointy+size;buchang(pointx,pointy,nextx,nexty);}elseif((pointx<=x)&&(pointy>y)){nextx=pointx-size;nexty=pointy;buchang(pointx,pointy,nextx,nexty);}elseif((pointx<x)&&(pointy<=y)){nextx=pointx;nexty=pointy-size;buchang(pointx,pointy,nextx,nexty);}elseif((pointx>=x)&&(pointy<y)){nextx=pointx+size;nexty=pointy;buchang(pointx,pointy,nextx,nexty);}}pointx=nextx;pointy=nexty; cnt1++; if(cnt1==10) { display(table7,1);//在1602其次行显示table6中的字符 currentdisp(1,nextx,nexty); Write_Byte_Locate(11,1,number[radius/10]); Write_Byte_Locate(12,1,number[radius%10]);cnt1=0; }} }/*voidDraw_Circular(intx,inty){floatpointx,pointy,nextx,nexty;floatresult;floatsize=0.15; intcnt; intcnt1=0; cnt=(8*radius)/size;pointx=x;pointy=y-25; display(table7,0);currentdisp(0,x,y); Write_Byte_Locate(11,0,number[radius/10]); Write_Byte_Locate(12,0,number[radius%10]);while(cnt--){result=((pointx-25)*(pointx-25)+(pointy-25)*(pointy-25))>625?1:0;if(result){if((pointx>x)&&(pointy>=y)){nextx=pointx;nexty=pointy-size;buchang(pointx,pointy,nextx,nexty);}elseif((pointx<=x)&&(pointy>y)){nextx=pointx+size;nexty=pointy;buchang(pointx,pointy,nextx,nexty);}elseif((pointx<x)&&(pointy<=y)){nextx=pointx;nexty=pointy+size;buchang(pointx,pointy,nextx,nexty);}elseif((pointx>=x)&&(pointy<y)){nextx=pointx-size;nexty=pointy;buchang(pointx,pointy,nextx,nexty);}}else{if((pointx>x)&&(pointy>=y)){nextx=pointx+size;nexty=pointy;buchang(pointx,pointy,nextx,nexty);}elseif((pointx<=x)&&(pointy>y)){nextx=pointx;nexty=pointy+size;buchang(pointx,pointy,nextx,nexty);}elseif((pointx<x)&&(pointy<=y)){nextx=pointx-size;nexty=pointy;buchang(pointx,pointy,nextx,nexty);}elseif((pointx>=x)&&(pointy<y)){nextx=pointx;nexty=pointy-size;buchang(pointx,pointy,nextx,nexty);}} pointx=nextx;pointy=nexty; cnt1++; if(cnt1==10) { display(table7,1);//在1602其次行显示table6中的字符 currentdisp(1,nextx,nexty); Write_Byte_Locate(11,1,number[radius/10]); Write_Byte_Locate(12,1,number[radius%10]);cnt1=0; } }} *///循迹功能程序voidzouxiang(intn){intznum,ynum;switch(n)//0表示→1表示↘2表示↓3表示↙4表示←5表示↖6表示↑7表示↗{case0:znum=20;ynum=15;while(znum--){Motor_Left_Step(0);}while(ynum--){Motor_Right_Step(0);}break;case1:znum=52;ynum=12;while(znum--){Motor_Left_Step(0);}while(ynum--){Motor_Right_Step(0);}break;case2:znum=27;ynum=29;while(znum--){Motor_Left_Step(0);}while(ynum--){Motor_Right_Step(1);}break;case3:znum=10;ynum=50;while(znum--){Motor_Left_Step(0);}while(ynum--){Motor_Right_Step(1);}break;case4:znum=20;ynum=15;while(znum--){Motor_Left_Step(1);}while(ynum--){Motor_Right_Step(1);}break;case5:znum=52;ynum=12;while(znum--){Motor_Left_Step(1);}while(ynum--){Motor_Right_Step(1);}break;case6:znum=29;ynum=27;while(znum--){Motor_Left_Step(1);}while(ynum--){Motor_Right_Step(0);}break;case7:znum=15;ynum=50;while(znum--){Motor_Left_Step(1);}while(ynum--){Motor_Right_Step(0);}break;default:break;}}voidfollow(){inti,j; intarray[9]; array[8]=0; i=0; //display(table11,1); SHLD=0;//将8路检测器的电平置入74LS165寄存器中 SHLD=1;//串行移位限制 for(j=0;j<=7;j++) { array[j]=S_data; S_clk=0; S_clk=1; } Delay_1ms(10);while(array[i]){ //Delay_1ms(20);zouxiang(i); Write_Byte_Locate(15,1,number[i]); SHLD=0;//将8路检测器的电平置入74LS165寄存器中 SHLD=1;//串行移位限制 for(j=0;j<=7;j++) { array[j]=S_data; S_clk=0; S_clk=1; } Delay_1ms(10);if(array[i%8]){i=i%8;}elseif(array[(i+1+8)%8]){i=(i+1+8)%8;}elseif(array[(i-1+8)%8]){i=(i-1+8)%8;}//elseif(array[(i-2+8)%8])//{i=(i-2+8)%8;}//elseif(array[(i+2+8)%8])//{i=(i+2+8)%8;}else{ //Delay_1ms(20);zouxiang(i);zouxiang(i); Write_Byte_Locate(15,1,number[i]); SHLD=0;//将8路检测器的电平置入74LS165寄存器中 SHLD=1;//串行移位限制 for(j=0;j<=7;j++) { array[j]=S_data; S_clk=0; S_clk=1; } Delay_1ms(100);if((array[i%8]==0)&&(array[(i+1+8)%8]==0)&&(array[(i-1+8)%8]==0))//&&(array[(i+2+8)%8]==0)&&(array[(i-2+8)%8]==0)){i=8;}elseif(array[i%8]){i=i%8;}elseif(array[(i+1+8)%8]){i=(i+1+8)%8;}elseif(array[(i-1+8)%8]){i=(i-1+8)%8;}//elseif(array[(i-2+8)%8])//{i=(i-2+8)%8;}//elseif(array[(i+2+8)%8])//{i=(i+2+8)%8;}}}}/*******************************************************************/ucharGet_Number(intmin,intmax){ucharscancode,key;scan:scancode=Keyboard_Scan(); //键盘扫描函数,返回键盘扫描码key=Scan_Code_Transform(scancode); //键码识别if(key<min||key>max) { gotoscan; } elsereturn(key);}/*******************************************************************/voiddisplay(uchartable[16],bitline){uchari;for(i=0;i<=15;i++)Write_Byte_Locate(i,line,table[i]);}/*******************************************************************/intinput(intline){intx,key;x=Get_Number(0,10); Write_Byte_Locate(line+1,1,number[x]); key=Get_Number(0,9); Write_Byte_Locate(line,1,number[x]); Write_Byte_Locate(line+1,1,number[key]);x=x*10+key;returnx;}voidmain(){ucharscancode;intkey;Init_LCD1602();display(kaiji0,0);display(kaiji1,1);Delay_1ms(2000);main:display(table0,0);//在1602第一行显示table0中的字符display(table1,1);//在1602其次行显示table1中的字符

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论