前言
这段时间项目功能写到步进电机这块。这段时间事情有点多,拖了好久才准备写这篇文章。其实也算有点怀疑,怀疑自己一直以来做的事有没有价值。前些天不经意看到顺利写的东西,大致知道他目前在做的事情,对比自己,羞愧难当。但是做总比不做强,就且先不管价值大不大了。三呆子说人活着要做很多很多有意义的事,老马问他什么叫有意义的事,他嘿嘿一笑,抓了抓头,说有意义的事就是好好活。那就好好活吧!如果有需要的人看到这篇文章能帮你节省点时间,也算是很它的价值了吧。废话少叙,开始吧。
其实步进电机实现起来十分简单,原来我虽然没用过,但是大致的原理知道一点,就是给一个脉冲,电机步进一步(这里说的是带驱动器的电机,这篇文章写的也是带驱动器的,至于不带驱动器的可能还要考虑相序的问题)。知道这一点之后就可以着手实现了。
器件
要用到的器件有步进电机、驱动器、电源以及若干杜邦线。其实各种型号的器件其实大同小异,原理一样的。
电机驱动器为最多8细分的,查阅使用手册知道,8细分时,每步进1600次转动一圈。
电机使用的是四线型的,外部有四根线,可以用万用表的通断档来区分哪两根线是相连的:通就是一根线,反之就是另一根。
然后把一根线的两端连到A+A-,另一根线连到B+B-即可。驱动器的V+连到电源的V+,GND连到COM端(此驱动器要求驱动电压在15V~36V之间)。
一般的电机驱动器分共阴和共阳接法:
共阳极接法:分别将Pul+,Dir+,EN+连接到STM32板子的输出电压上,脉冲输入信号通过Pul-接入;此时,Dir-,EN-在低电平有效。
共阴极接法:分别将Pul-,Dir-,EN-连接到控制系统的地端(与电源地隔离);此时脉冲输入信号通过Pul+加入,Dir+,EN+在高电平有效。
我这里用到的驱动器只有Pul-,Dir-,Ena-,所以应该默认的是共阳接法。因此,我将PC6口设置成脉冲输入口;PC7设置成方向控制口;PC8设置成使能口。
程序
准备好了之后,可以编写程序了。
//电机驱动初始化
void motorIO_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能时钟
//PC6口Pul:脉冲
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_6); //输出高电平(低电平有效)
//PC7口Dir:方向
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_7); //输出高电平(低电平有效)
//PC8口Ena:使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_8); //输出高电平(低电平有效)
}
//步进电机逆时针转
void motor_L(void)
{
u8 i;
GPIO_ResetBits(GPIOC,GPIO_Pin_7);//逆时针转
GPIO_SetBits(GPIOC,GPIO_Pin_8);//使能
for(i=0;i<50;i++)//制造下降沿,使电机步进(制造50次,不然一次步进角度太小了)
{
GPIO_SetBits(GPIOC,GPIO_Pin_6); //高
delay_ms(2);
GPIO_ResetBits(GPIOC,GPIO_Pin_6); //低
delay_ms(2);
}
}
//步进电机顺时针转
void motor_R(void)
{
u8 i;
GPIO_SetBits(GPIOC,GPIO_Pin_7);//顺时针转
GPIO_SetBits(GPIOC,GPIO_Pin_8);//使能
for(i=0;i<50;i++)//制造下降沿,使电机步进
{
GPIO_SetBits(GPIOC,GPIO_Pin_6); //高
delay_ms(2);
GPIO_ResetBits(GPIOC,GPIO_Pin_6); //低
delay_ms(2);
}
}
主函数里简单写一个测试程序:
//注:此处码出的是略去一众初始化语句的部分。
while(1)
{
if(!KEY_UP){ //检测上键按下没
delay_ms(20);
if(!KEY_UP){
motor_L(); //按下的话就逆时针转动
}
}
if(!KEY_DOWN){ //检测下键按下没
delay_ms(20);
if(!KEY_DOWN){
motor_R(); //按下的话就顺时针转动
}
}
}
这个程序里并没有用到PWM相关的东西,不用配置PWM相关的参数,只需让脉冲输出口输出高低电平就行了,理解起来十分方便,同时也可以满足大多数的需求。因此我称之为“最简单的方法”。大家完全可以通过这个程序来先让自己的步进电机动起来,这是从0到1的过程,也是最重要的过程。至于之后的从1到N,只需慢慢优化慢慢调即可。
一个重要的不可忽略的备注:由于STM32的GPIO口只能输出3.3V而不能输出5V的电平,但是这个型号的驱动器要求的高电平范围要在4~5V,因此你必须有一个3.3转5V的模块(51单片机可以直接输出5V的高电平)。我用的模块如下图:
欢迎大家一起交流讨论。如果加我QQ咨询请务必备注所在单位或机构。(前提是我还在负责改这个项目哈哈😂😂)