控制程序(在Towanda Malone原程序的基础上做了部分改动):
#include
#include
#include
#define DATA 0x03bc /*注意你的并口的地址,根据实际情况来修改,同时在BIOS里要*/
/*把并口设置成EPP+ECP的模式*/
#define CW 1
#define CCW 0 /*定义磁头前进方向,1为后退,0为前进*/
int data = 0x00;
void Drive_dir (int dir); /*选择磁头前进方向*/
void Drive_step (int time); /*步进电机进动一步,可以根据time的不同来调整输出方波*/
/*的周期(对步进电机来说则意味着速度快慢)*/
void turn_motor (int dir, int time, int duration); /*步进电机在给定的方向,方波周期(表征*/
/*速度),运动时间3个参数下的运动*/
void pause_motor (int duration); /*停止进动一段间隔*/
void main_motor (int duration); /*主轴电机转动一段时间*/
void main (void) /*主函数从一个cmd.dat文件中读取命令,这个文件可以用*/
/*文本编辑器来编辑,保存时在“保存类型”中选择“所有文件”,*/
/*文件名为cmd.dat。一个cmd文件的例子:*/
/*T 0 25 5000 向前快速运动 5000 ms */
/*P 5000 暂停 5000 ms */
/*T 1 50 5000 向反方向以较慢速度运动 5000 ms */
/*M 5000 主轴电机转动5000 ms */
/*Q 退出*/
/*命令格式:T 运动方向(0或1) 速度(数值越小越快) 进动时间*/
/* M 进动时间*/
/* P 暂停时间*/
/* Q*/{
FILE *fr;
int x, dir, duration, speed, time;
char line[50], op;
fr = fopen( "a:\cmd.dat","rt");
while(1)
{
fgets (line, 50, fr);
switch(toupper(line[0]))
{
case 'P':
sscanf (line, "%c %d", &op, &duration);
pause_motor(duration);
break;
case 'Q':
fcloseall();
exit(0);
case 'T':
sscanf (line, "%c %d %d %d",
&op, &dir, &speed, &duration);
turn_motor (dir, speed, duration);
break;
case 'M' :
sscanf (line, "%c %d", &op, &duration);
main_motor (duration);
break;
default:
printf(" Unknown Command\n");
exit(0);
}
}
}
void main_motor (int duration)
{ data = data & (~0x04);
outport(DATA,data);
delay(duration);
data= data|0x04;
outport(DATA,data);
}
void turn_motor(int dir, int time, int duration)
{
struct timeb t_curr, t_start;
int t_diff;
ftime(&t_start);
Drive_dir( dir);
do
{
Drive_step(time);
ftime(&t_curr);
t_diff = (int) (1000.0 *(t_curr.time - t_start.time)
+ (t_curr.millitm - t_start.millitm));
}
while (t_diff}
void pause_motor (int duration)
{
struct timeb t_curr, t_start;
int t_diff;
ftime(&t_start);
outportb (DATA, 0x04); /*对应的并口数据为:D0--0,D1--0,D2--1*/
do
{
ftime(&t_curr);
t_diff = (int) (1000.0 * (t_curr.time - t_start.time)
+ (t_curr.millitm - t_start.millitm));
}
while (t_diff < duration);
}
void Drive_dir(int dir)
{
if ( dir == CW)
{
data = data|0x06;
outportb(DATA, data);
}
else
{
data = (data & (~0x02))|0x04;
outportb(DATA, data);
}
}
void Drive_step (int time)
{
data = data | 0x05;
outportb(DATA, data);
delay (time/2);
data = (data ^ 0x01)|0x04; /*与0X04取或的作用是使D2始终为1,禁止主轴电机转动*/
outportb(DATA, data);
delay (time/2);
}
以上程序可在TURBOC2的环境下编译通过,实验中运行状态良好,但是会偶尔会多一步或少一步,时间上也不是很准确,我觉得多少和PC机的环境有关系吧,特别是延时环节,毕竟现在的PC机主频都很高,以前用TURBOC编程就遇到类似的问题,同样的延时程序在P4和P2的机器上差别很大。我想,如果把这个实验移植到MCU,例如51上可能会比较理想些吧,同时,利用笔记本软驱的控制器可以节省51的许多I/O口资源,相对与3.5寸驱动器来说更有体积和功耗的优势,老笔记本淘汰了不少这样的软驱,基本上10元左右就能买到,在一些小型机器人的制作中其各方面的优势不亚于自己买的驱动芯片和电机,不过缺点也有,那就是步进电机都是带蜗杆的,主轴电机转速慢(约360转/分)个头大且固定,这就需要发挥我们的想象力和创造力了。另外注意电源方面,我实验的时候是利用PC的USB口来供电的,驱动能力大概在200mA左右,笔记本软驱电源要求是4.5V ~ 5.5V。
前一段时间打算做一个最简单的2关节机械手臂,本着节约的原则,想利用软驱上的一些电机和控制器,用打印口连到电脑上,软件上则利用一些运动算法,使用MATLAB进行动态仿真获得理论依据,毕竟MATLAB仿真环境不存在执行失误的情况,但实际中,在TC环境执行程序总是有或多或少的失误,从而电机的步长不能维持恒定,还有就是机械部分,阻力分布不均匀也导致了运动误差的产生,以上基本上都是随机产生的。做了一些准备工作后仔细思考才发现存在如此多的问题需要解决,当然了,只要舍得投入,以上的问题就不是什么大问题了,但这也失去了DIY的意义。我把自己的一些准备工作写下来,希望和大家分享,如果你也是个热忠于探索的DIYER,希望能一起讨论! 最近在学习ARM的BIOS,也许过一段时间再转到机械手臂上来。
作者联系方式:
menger11
沈阳 2006.06.21
QQ99899095
MAIL:menger11@sohu.com
转载声明:凡文章出处为www.RoboticFan.com的,系本站的原创文章。其它媒体在注明出处为RoboticFan.com并给出原始链接后可以自由转载,否则将视为侵权!
| 上一篇:科大“蓝鹰”创我国参加足球机器人世界杯最好成绩 下一篇:家庭机器人大市场已呼之欲出 |





