资源描述
悬挂运动控制系统(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
其它
10
5、说明
1、物体运动轨迹以画笔画出痕迹为准,应尽可能使物体运动轨迹和预期轨迹吻合,同时尽可能缩短运动时间;
2、若在某项测试中运动超出限定时间,该项目不得分;
3、运动轨迹和预期轨迹之间偏差超出4cm时,该项目不得分;
4、在基础要求(3)、(4)和发挥部分(2)中,物体开始运动前,许可手动将物体定位;开始运动后,不能再人为干预物体运动;
5、竞赛结束时,控制系统封存上交赛区组委会,测试用板(板上含空白坐标纸) 测试时自带。
二、方案论证和选择
1.关键控制模块选择
方案一:FPGA/CPLD方法。即用FPGA/CPLD完成键盘定义和识别、电机工作状态选择和切换、液晶电路驱动和控制等功效。这种方案优点在于系统结构紧凑、操作方便,而且能够使用I/O口线很多;缺点是调试时需要接很多接线,过程繁琐,而且使用CPLD时,因为其内部没有ROM,对功效实现有所限制。
方案二:单片机方法。即由单片机、电机驱动电路及电机等组成系统。使用单片机也能够完成键盘定义和识别、电机工作状选择和切换等功效,组成系统规模较小,有一定灵活性,而且能够使用我们比较熟悉单片机最小系统电路板,降低了工作量。该控制方法需要单片机含有较大程序存放量,所以可选择存放量为8KAT89S52单片机。
基于以上分析,拟选择方案二。
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×416点阵键盘。能够键入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-3 4x4键盘电路
对应按键码以下:
7
8
9
/
4
5
6
/
1
2
3
/
清除
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 步进为a cm, 电机B步进为b cm,物体高度为h cm。
图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毫米圆周上安装了8个反射式红外对管作为轨迹探测传感器,安装方法图3所表示。
0
7
6
5
4
3
2
1
-
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步,确保循迹正确停止。在取平均值时,需对7à0和0à7转变作特殊处理,不然可能犯错。
实践证实,根据上面措施循迹快速稳定,而且不会受交叉线影响。因为轨迹线有一定宽度,实际轨迹不可能转折得十分快速,当步进距离较小时,甚至能够完成锐角循迹。本系统使用步进距离是5毫米,效果很好。
(5)系统主程序步骤框图
上电,初始化液晶显示
等候按键,选择所需功效
1
直线
2
正方形
3
圆
4
循迹
输入起 点
终点坐 标
根据事先设定运 行
设定圆心手动到 点
手动到循迹起始 点
执 行 部 件
返回显示程序
按键确定,进入对应程序
图3-9系统主程序步骤框图
四、系统测试
1.测试仪器
DT9205A型数字万用表;
秒表、卷尺;
+12V直流稳压电源。
2.测量结果
(1) 直线测试
次数
设定起点坐标
设定终点坐标
实际坐标
误差
用时
1
(0,0)
(50,50)
(50.2,51.3)
2cm
75s
2
(0,0)
(80,99)
(80.1,100.5)
1.5cm
134s
(2) 画圆测试
次数
圆心坐标
半径
最大误差
用时
1
(25,25)
25
1cm
130s
2
(3) 循迹测试
连续线段线长
间断线段长度
60cm
46cm
用时
28.1s
24.3s
3.误差分析及改善方法
(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>
#define uchar unsigned char //无符号字符类型定义
#define uint unsigned int //无符号整数类型定义
/******************************************************************/
//步进电机驱动器引脚连接定义
sbit Motor_Left_CP =P1^0; //左步进电机脉冲
sbit Motor_Left_DIR=P1^1; //左步进电机方向控制端
sbit Motor_Right_CP =P1^2; //右步进电机脉冲
sbit Motor_Right_DIR=P1^3; //右步进电机方向控制端
sbit Motor_FREE =P1^4; //电机使能端(高电平有效,低电平是电机处于自由状态)
sbit SHLD = P1^5;
sbit S_clk = P1^6;
sbit S_data = P1^7;
sbit jiesu=P3^6;
/**************************************************/
#define pai 3.141592 //圆周率
#define a 15 //80cm x 100cm场地到两电机连线垂直距离(厘米)
#define b 15 //80cm x 100cm场地到边线(顶端滑轮和电机连线)垂直距离(厘米)
#define r 0.8276 //滑轮半径(厘米)
#define stepz 0.0122 //左步进电机每步弧长(厘米)
#define stepy 0.0122 //右进步点击每步弧长(厘米)
#define step 0.0125 //步进电机每步弧长(厘米)
#define radius 25 //圆周半径长度
#define Motor_FREE 1
/**************************************************/
//LCD1602液晶模块引脚连接定义
#define LCD_Data P0 //16028位数据线连接到P0口
sbit RS=P3^5; //1602数据/命令选择端RS连接到P1.0
sbit RW=P3^4; //1602读/写选择端连接到P1.1
sbit EN=P3^3; //1602使能信号引脚连接到P1.2
/**************************************************/
uchar code kaiji0[16]={">>> WELCOME! <<<"};
uchar code kaiji1[16]={"LOADDOWNING....."};
uchar code table0[16]={"1.Line 2 Rectan"};
uchar code table1[16]={"3.Circu 4.Follow"};
uchar code table3[16]={" Draw a Line "};
uchar code table4[16]={"Draw Circularity"};
uchar code table5[16]={"Follow the Line "};
uchar code table6[16]={"( , );( , ) "};
uchar code table7[16]={"( , ); r= cm "};
uchar code table8[16]={"( cm, cm) "};
uchar code table9[16]={" ENTER to Begin "};
uchar code table10[16]={"Executing .... x"};
uchar code table11[16]={"Rectan perform. "};
uchar code table12[16]={"(25,25)-(50,25) "};
uchar code table13[16]={"(50,50)-(25,50) "};
uchar code table14[16]={"have completed!!"};
uchar code wrong[16]={"Wrong Coordinate"};
uchar code agian[16]={"Input Agian ? "};
uchar code number[10]={""};
/**************************************************/
int x0,y0,x1,y1;
/*******************************************************************/
//函数申明
void Delay_1ms(int time); //延时1ms*time
void LCD1602_Busy_Check(void); //LCD1602忙检验函数
void Write_LCD1602(uchar udata,bit command); //LCD1602写数据和写指令函数
void Write_Byte_Locate(uchar x,uchar y,uchar udata); //把数据显示在LCD1602指定位置
void Init_LCD1602(); //LCD1602初始化函数
uchar Keyboard_Scan(void); //键盘扫描函数,返回键盘扫描码
uchar Scan_Code_Transform(uchar scancode); //键码识别函数
//void Motot_ld(int );
void Motor_Left_Step(bit Dir); //左电机转动一步,Dir=0时反转(顺时针),即松开线;Dir=1时正转(逆时针),即收紧线
void Motor_Right_Step(bit Dir);//右电机转动一步,Dir=0时反转(顺时针),即收紧线;Dir=1时正转(逆时针),即松开线
void Draw_Circular(int x,int y); // 画圆函数
void currentdisp(int line,int x,int y);//目前显示
void linedisp(int,int,int,int,int); //目前直线点显示
void display(uchar table[16],bit line);//提醒显示
void line(int,int,int,int); //画直线函数
void Draw_line();
//void buchang(float,float,float,float);//确定左右电机移动步数
void Returndata();//读取对光二极管值
void follow();//循迹函数
void zouxiang(int);//循迹电机驱动函数
/*******************************************************************/
//延时函数,延时时间=1ms*time(晶振12MHz)
void Delay_1ms(int time)
{
uchar i,j;
do{
for(i=0;i<15;i++)
for(j=0;j<20;j++);
}while((time--)!=0);
}
/*******************************************************************/
/**********************************LCD1602液晶操作函数部分**********/
//LCD1602液晶检验忙函数
void LCD1602_Busy_Check(void)
{
EN=0;
RW=1;
RS=0;
EN=1;
while(LCD_Data&&0x80==1);
EN=0;
Delay_1ms(1);
}
/**************************************************/
//LCD1602写数据和写指令函数
//把写数据和指令二个合在一起,用一个变量command来判定
void Write_LCD1602(uchar udata,bit command)
{
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行
void Write_Byte_Locate(uchar x,uchar y,uchar udata)
{
if(y){x+=0x40;}//判定显示哪行,显示第二行LCD存放区加40H
x+=0x80; //假如没有加0X40则显示第一行
Write_LCD1602(x,0); //写指令
Write_LCD1602(udata,1);//写显示数据
}
/**************************************************/
//LCD1602初始化函数
void Init_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输入
uchar Keyboard_Scan(void)
{
uchar scancode,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);
}
else scancode=(scancode<<1)|0x01;
}
}
return(0);
}
/**************************************************/
//键码识别函数
uchar Scan_Code_Transform(uchar scancode)
{
switch (scancode) {/*将按键码转换成键值*/
case 0xde: return 0;
case 0xed: return 1;
case 0xdd: return 2;
case 0xbd: return 3;
case 0xeb: return 4;
case 0xdb: return 5;
case 0xbb: return 6;
case 0xe7: return 7;
case 0xd7: return 8;
case 0xb7: return 9;
case 0xee: return 10;
default : return 0xff;
}
}
/*******************************************************************/
/********************步进电机基础操作部分***************************/
//左电机转动一步,Dir=0时反转(顺时针),即松开线;Dir=1时正转(逆时针),即收紧线
void Motor_Left_Step(bit Dir)
{
Motor_Left_DIR=Dir;
Motor_Left_CP=1;
Delay_1ms(1);
Motor_Left_CP=0;
Delay_1ms(1);
}
/**************************************************/
//右电机转动一步,Dir=0时反转(顺时针),即收紧线;Dir=1时正转(逆时针),即松开线
void Motor_Right_Step(bit Dir)
{
Motor_Right_DIR=Dir;
Motor_Right_CP=1;
Delay_1ms(1);
Motor_Right_CP=0;
Delay_1ms(1);
}
/*************************************************/
/* 圆形目前坐标显示模块*/
void currentdisp(int line,int x,int y)
{
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]);
}
/* *********** 直线目前坐标实现模块*************** */
/* “(,);(,)” */
void linedisp(int line,int x,int y,int xz,int yz)
{ 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]);
}
/*******************************************************************/
/*******************************功效实现部分************************/
/****************** 步数确定函数 *********************/
void buchang(float x,float y,float nextx,float nexty)//,int *znum1,int *ynum1)
{
float zb,yb;
int znum,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=ab
展开阅读全文