求救:STM32控制两个四线步进电机,每个电机运转都是一个循环,如何能实现两个循环同时运
我用的是单四拍驱动,首先是宏定义部分:
#define LEFT1 GPIO_SetBits(GPIOA, GPIO_Pin_0)
#define LEFT2 GPIO_SetBits(GPIOA, GPIO_Pin_1)
#define LEFT3 GPIO_SetBits(GPIOA, GPIO_Pin_2)
#define LEFT4 GPIO_SetBits(GPIOA, GPIO_Pin_3)
#define RIGHT1 GPIO_SetBits(GPIOA, GPIO_Pin_4)
#define RIGHT2 GPIO_SetBits(GPIOA, GPIO_Pin_5)
#define RIGHT3 GPIO_SetBits(GPIOA, GPIO_Pin_6)
#define RIGHT4 GPIO_SetBits(GPIOA, GPIO_Pin_7)
步进电机驱动相序部分(内有循环)
/*******************左电机驱动************************/
void leftcontrol()
{
int delaytime1=500;
while(1)
{
LEFT1;
delay(delaytime1);
LEFT2;
delay(delaytime1);
LEFT3;
delay(delaytime1);
LEFT4;
delay(delaytime1);
}
}
/*******************右电机驱动************************/
void rightcontrol()
{
int delaytime2=500;
while(1)
{
RIGHT1;
delay(delaytime2);
RIGHT2;
delay(delaytime2);
RIGHT3;
delay(delaytime2);
RIGHT4;
delay(delaytime2);
}
}
主函数部分
/************************main主函数*********************************/
void main()
{
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif
GPIO_CONFIG();
leftcontrol();
rightcontrol();
}
由于左右轮都是循环,所以,主函数运行时卡在leftcontrol();左轮转动,右轮不动,问题是:怎么能实现两轮同时转动?有没有什么好的思想?我先在这里拜谢各位大侠了。 是不是只能用定时器做,而不能用循环啊?如果用定时器的话,用什么输出模式呢?具体怎么实施呢?拜谢了。。。 http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4596522&bbs_page_no=1&bbs_id=1027
64楼你真幸运~~~~~~ 一般我没这耐性慢慢说 呵呵,拜谢了。会会,不过我的和你的不一样,你的是用数组驱动,而我的是用循环啊。做不了|运算。不知道STM32是否也能用数组进行赋值驱动。貌似我这个是用定时器的细分驱动做的。。。纠结。等高人。 用状态机,每个电机都有自己的运动状态步,这样可以在一个while(1)循环里执行状态机函数。
我用这样的方式控制了10个四线步进电机,带升降速控制。 补充一下,每个步进电机占用一个定时器通道,总共用到了3个定时器共10个通道。
在cc中断里给步进电机驱动脉冲。同时更新下一个CCR的值,依此调整升降速时期的脉冲频率。 mark 谢谢 Achin指点。那我的两个步进电机,就是用一个定时器的两个通道就可以了, 那这样的话,我们的控制方法属于细分驱动吗?还是就叫PWM控制步进电机?呵呵好馋 Achin 的控制代码啊!!! 可是 Achin一个通道连一个四线四个电机,怎么连啊?比如我用TIMM2的CH1,也就是PA0口,怎么控制四根线呢? 这个我建议可以用专用ic驱动 此帖已读,标记备用! 我还以为是讨论两个电机恒流控制多重细分的驱动方案呢.
居然用到了 stm32 的片子来控制. 现在我不用循环语句,用STM32的定时器PWM输出功能。1个定时器四路输出对应一个电机四个引脚。输出四路PWM的捕获值平均分配,电机还是不转。我想可能是由于通道输出的是电平,而不是脉冲。如图,可是定时器怎么输出脉冲呢?大侠们教教我啊。
http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_630498DIBLF6.png
(原文件名:四通道输出波形.png) 1个定时器四路输出还是很容易的。
你首先要解决的就是STM32的定时器的深度研究和使用,然后再来捣鼓这个电机。
要不然,你就使用一个最笨的办法,用一个定时器,然后电机的四个IO分别输出高低电平,不停的取反。不过这种效率是最不可取的,但可地。 谢谢kinsno。你后面给的那个办法应该是工作在toggle模式,可是toggle模式的翻转频率是固定的,也就是说高电平和低电平的延续时间一样,这样的话,相位就没办法调整了。我的理解对吗?不对的话,还望你点拨。谢谢 回复【13楼】kinsno
-----------------------------------------------------------------------
谢谢kinsno。你后面给的那个办法应该是工作在toggle模式,可是toggle模式的翻转频率是固定的,也就是说高电平和低电平的延续时间一样,这样的话,相位就没办法调整了。我的理解对吗?不对的话,还望你点拨。谢谢 同一个定时器的4路PWM不同输出,是可以输出不同频率不同脉宽的,任意调整。 回复【16楼】kinsno
-----------------------------------------------------------------------
输出比较模式可以输出不同频率不同脉宽的,但是不可以任意调整吧?输出波形周期与通道反应延时成正比关系,要想驱起来,只能是同频率的,所以反应延时也相同,这样没有相位差是驱动不起来的。而PWM只能输出同频率的波形,脉宽是可调。但是脉宽和相位差却是有关系的。不能得到我要的波形。如果我说的错了,能不能给我来个可以输出我的波形的程序呢?谢谢 外加个cpld很容易实现 STM32 驱动步进电机,不错 while(1)
{}
这是死循环,永远跳不出来,在主程序中调用,肯定卡在那儿,而且是一个电机一直转,永远停不下来! 顶一下,希望楼主弄出来
我以前是用的驱动IC,
只要用定时器输出 PWM 脉冲就好了 Achin 发表于 2011-4-12 21:10 static/image/common/back.gif
用状态机,每个电机都有自己的运动状态步,这样可以在一个while(1)循环里执行状态机函数。
我用这样的方式 ...
您好,请问状态及具体怎么设置啊?怎么在循环里调用状态机函数? 不用步进电机驱动器么?直接用STM32驱动么? Achin 发表于 2011-4-12 21:10 static/image/common/back.gif
用状态机,每个电机都有自己的运动状态步,这样可以在一个while(1)循环里执行状态机函数。
我用这样的方式 ...
您好,我有问题想请教。我用两个步进电机作为小车的动力。如果一个电机占用一个定时器通道。那么在中断函数里应该怎么写励磁顺序?怎么控制小车的前进,后退,左转,右转,停止呢?可否在中断里用一个switch,case语句?把步进电机的运动状态都列出来?到时候直接调用吗/
本帖最后由 Achin 于 2012-7-27 16:58 编辑
欢迎拍砖。
我的方案里是stm32控制tb62209,用tb62209驱动电机的。不知道你的控制方式是不是也是这样。
给脉冲的部分,也确实没有用pwm,而是定时器中断之后,控制IO给一个电平变化,前面有人说过这样是不可取的笨方法,不过在我的实际应用中,暂时没发现问题。
stm32的一个定时器输出4路PWM,占空比可以不同,频率能不能不同,我没验证过,后面试试,试出来的话,说不定会改变现在的控制方式。
我的应用里电机转动有角度要求,不带反馈,所以要对给出的脉冲进行计数。stm32的定时器级联可以做自动计数,现在不知道能否对低一级定时器4个通道分别计数,也是没验证过的。
撇开方向控制,步进电机的一次运动应该有加速、匀速(可以没有匀速过程)、减速,在此基础上增加三个状态:启动之前的空闲状态,启动状态和运动完成的停止状态,前面我提到的while(1)超循环里面用状态机,也就是判断这几个状态。这个做法有缺陷,后面再提。
确定好电机的加减速步数,用步进电机的加减速曲线计算出一个定时器ccr的变化表StpTab[]。
电机控制任务收到启动电机的数据后,对要运动的电机进行“启动”,将其从“空闲”状态改为“启动”状态,进入这个while循环,状态机中,电机处于启动状态时,要根据你的动作距离计算电机的两个变速点(从加速变为匀速,从匀速变为减速,这两个点可以是同一个点),然后进入加速状态。这个加速状态会统计当前电机的运动步数(在定时器中断里进行加加减减的操作),如果运动步数大于等于变速点1(从加速到匀速),则进入匀速状态。状态机的匀速状态也是进行运动步数和变速点的比较,运动步数大于等于变速点2(从匀速到减速)时,进入减速状态。减速状态是比较当前运动步数与目标位置,减速完成后,关闭跟这个电机关联的定时器通道中断。
中断中判断电机的状态机,如果是加速状态,则每次中断加载StpTab中的一个新的值,如果是匀速状态,则加载表的最后一个元素,以使电机运行在最大速度,如果是减速状态,同样也是加载StpTab中的新值,表有个index,加速时,index++,减速时,index从最大值自减。
前面说这个做法有缺陷,主要是没有解决在一次运动过程中,其目标位置发生改变的情况。这个工作现在正在做,基本思路还是这样来做的。
电机运动完成后,状态机函数在while循环里还是要执行,但是进入函数之后识别到电机无需运动,则立即退出。等所有的电机都运动完成,退出while循环,继续等待新的动作数据。
我现在做到电机的最大频率在15K,相当于67us给出一次脉冲,stm32工作在72M,67us的间隔可以跑4800条指令,对于带os的code,做切换还是可以的,但是效率确实不算好。只能说满足自己应用吧。 不错。有时间我也玩玩
页:
[1]