打印

关于单片机同时驱动两个步进电机工作的问题!

[复制链接]
5975|21
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhlking|  楼主 | 2007-5-7 09:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位大虾,早上好!
我现在用了一个AT89S52单片机驱动2个步进电机A、B同时工作,电机的运行程序都在中断里实现的.我用T0中断控制A,T2中断控制B,并把T2的优先级设为高。如果两个定时器中断程序只控制电机转动不会出现问题,2个电机同时转动也很平滑。但我想记录每个电机走的步数(正向转则步数加,反向则减),但我把这段程序加入T2中断里面后,就出现了转动不连续的情况。后来单步调试发现:由于T2中断程序里加了这段“记录电机步数程序”后T2子程序工作时间太长,T2子程序还没有返回的时候T0的中断已经到来,但T2的中断优先级较高,故T0无法响应,所以导致电机工作不连续。如果把这段程序去掉后就没问题,但我又想记录电机走的步数来确定其位置,这样应该只能在中断里才可以实现,请问各位大侠有没有什么好的方法?

内容有点长,麻烦大家能仔细看一下,帮帮我,也可以为以后他人的学习提供参考,谢谢了!

相关帖子

沙发
tyw| | 2007-5-7 09:23 | 只看该作者

中断里话不要太多,做个标记,有话到外面去说

尽可能拉长中断间隔
最后一招,有可能的话提高时钟频率

使用特权

评论回复
板凳
conwh| | 2007-5-7 09:26 | 只看该作者

一般计数程序都不会太长的。另外,在中断中不要写过多的

将主要程序放到主程序中执行,使用定时器来分配。实际即使驱动2个电机也可使用一个定时器,时间常数取公共最小数。

使用特权

评论回复
地板
zhlking|  楼主 | 2007-5-7 09:33 | 只看该作者

谢谢了~

谢谢了~
先针对楼上2位我回答以下几点:
1、我中断尽可能缩短了,但中断程序还是比较长,因为里面有细分程序,转动方向判断等。
2、因为2个电机转动的速度不一致,故用一个定时器恐怕实现不了。
3、我时钟频率够高了:22.1184MHZ,而且我不想更改硬件。
4、单就中断部分的主程序里也做了一些寄存器、计数器之类的初始化。

使用特权

评论回复
5
conwh| | 2007-5-7 09:48 | 只看该作者

也可以在长的中断中间用RETI来对程序的链接

另外也可选STC12C2052AD,它具有双指令周期的操作,可以提供执行速度。

使用特权

评论回复
6
zhlking|  楼主 | 2007-5-7 09:54 | 只看该作者

可以不动硬件吗?

能不能不动硬件?
问题就在中断子程序过长,我想问一下计算电机走的步数是不是只能中断程序里面啊?

使用特权

评论回复
7
conwh| | 2007-5-7 10:07 | 只看该作者

不用改动硬件部分,完全兼容。

中断程序太长就使用我说的RETI链接,但要注意:一定要满足该中断不能重复中断(就是这个子程序的长度不能大于定时器的长度)。
计数的就不一定要在中断中进行,不知道你的结构,不便多说。

使用特权

评论回复
8
zhlking|  楼主 | 2007-5-7 10:18 | 只看该作者

谢谢conwh!

你所说的RETI链接的意思是提前结束中断,然后把中断后面部分的程序放如到主程序里面去,对吗?

使用特权

评论回复
9
happystar| | 2007-5-7 10:27 | 只看该作者

在中断里只置标志位即可,在主程序判断执行

比如:在T2中断执行程序中只加这一句 flag_t2_int = 1;
在T0中断执行程序中只加这一句 flag_t0_int = 1;
主程序中:
if(flag_t2_int){flag_t2_int = 0; task2();}
if(flag_t0_int)){flag_t0_int = 0; task0();}
这样就避免了"T2子程序还没有返回的时候T0的中断已经到来,但T2的中断优先级较高,故T0无法响应,所以导致电机工作不连续。"

使用特权

评论回复
10
conwh| | 2007-5-7 10:28 | 只看该作者

不是

TIMER-1-0:
      :
      :
ARTH:
      :
      RETI
改为
TIMER-1-0:
      :
      :
      MOV   DPTR,    #ARTH
      PUSH  DPL
      PUSH  DPH
      RETI
ARTH:
      :
      RET

使用特权

评论回复
11
zhlking|  楼主 | 2007-5-7 10:51 | 只看该作者

恩,收到~

谢谢大家的支持及帮助,我先按你们说的方法试一下,有人点拨就是比一个人的脑子好使,呵呵~

使用特权

评论回复
12
zhlking|  楼主 | 2007-5-8 09:28 | 只看该作者

还是不行~~

利用LS说的方法都还是行不通啊,conwh说的这种方法在第二个RET处会返回最近的一个CALL 处.happystar说的方法我也试过,但每次返回主程序中还没有来得及执行相应的代码,下一次中断又来了.....,这样每次都没有办法执行到那段代码,看来还是我两个中断定时时间配合得不够好,但一直都没有找到比较好的解决办法,郁闷~~~,还有没有仁兄有其他好的办法么?

使用特权

评论回复
13
conwh| | 2007-5-8 09:31 | 只看该作者

不会的,因为处中断外,在ARTH是最近的CALL了

使用特权

评论回复
14
zhlking|  楼主 | 2007-5-8 09:37 | 只看该作者

re conwh

对呀,就是要返回最近的那个CALL,而我控制电机的主程序在CALL **程序里面,这样返回就直接跳出该程序了,那不是电机就不转动了~~

使用特权

评论回复
15
conwh| | 2007-5-8 09:41 | 只看该作者

实际上使用RETI链接就跟你在一个程序中(中断)没有区别的

所不同的就是提前交出中断权利

使用特权

评论回复
16
zhlking|  楼主 | 2007-5-8 09:48 | 只看该作者

还是有不同~~

肯定有不同啊,返回地址都变了,在一个程序中是返回中断处,还是在CALL**主程序里面,而这样是直接调出该调用程序了....,不过这个都不是重点,我想问一下conwh你还有没有其他办法,老板催得紧啊,没办法,我都自己试了好多方法,就是解决不了问题,昨晚都没休息好,做技术的命苦哇~~~

使用特权

评论回复
17
conwh| | 2007-5-8 09:58 | 只看该作者

你不要把你原来的程序拆散,就直接在中间加这么几个代码

不知道你使用的频率是多少?使用24M(好象它的最高频).由于不知道你的详情,不好说其他的什么办法,你也可压缩程序,尽量优化,能不使用通用程序就不用,不要套用,多费点事压缩指令周期.如果不保密的话,你发到我的邮箱里,我这2天事情不多.

使用特权

评论回复
18
zhlking|  楼主 | 2007-5-8 10:07 | 只看该作者

好的

我加你QQ吧,这样聊方便些~~,我的代码太长了,2000多行,而且写得有点乱,可以发给你,但看起来可能比较费力~~

使用特权

评论回复
19
cootec| | 2007-5-8 18:01 | 只看该作者

两个电机驱动还是放到一个定时器好些

可以取最小公约数, 将步数和方向处理全部放到外面, 这样中断程序
很短的。

使用特权

评论回复
20
zhlking|  楼主 | 2007-5-9 10:49 | 只看该作者

谢谢conwh~~

目前遇到的这个问题解决了,就是按CONWH说的那个方法~~,我现在还是用的2个定时器分别控制2个电机,但提前交出中断权力,现在运行没有发现什么问题.还是感谢各位大虾的支持,特别要感谢conwh,又让我学到了不少东西~~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

116

帖子

0

粉丝