当前位置:   article > 正文

两相四线步进电机原理和各种驱动方法理解与应用_两相四线步进电机驱动程序

两相四线步进电机驱动程序

有时候软件工程师理解硬件知识,那就是十窍通了九窍,简称一窍不通(悲)。

今天我们来说说步进电机

步进电机

从名字上面来理解,就是一步一步前进的电机。

既然如此,如何一步一步走呢?

根据高中物理知识,电机的旋转,无非就是电生磁,然后转化成动能。

而步进电机,只是三千弱水其中一瓢。

(图片来自网络)

大概就是长这个样子,但不是每一种步进电机都长这个样子。有腿多的,也有腿少的(相数线数不同)。

从不同的方向通电,就向不同的方向转动,通电电流大小不同,转动速度就不同。这也就是改变了电机转动的方向和转速。

以三相步进电机为例,定子按 A→B→C→A相轮流通电,则磁场沿A、B、C方向转动360°角,转子沿ABC方向转动了一个齿距的位置。

中间没啥复杂计算过程,纯纯物理控制,1就是1,因此步进电机没有累计误差的特点,广泛的用于各种开环控制。

相关参数

相数——步进电机的线圈对数

拍数——转子转动一周,定子绕组通电的次数

步距角——步进电机接收到一个脉冲信号后,驱动电机按设定的方向转动的一个固定角度

步距角θ=360°/mzc(m为定子相数;z为转子齿数;c为通电方式(1:单相轮流通电,双向轮流通电;2:单双向轮流通电方式))

转速公式:n=f*θ/x*360°(n为转速;f为脉冲频率;θ为步距角,x是细分数)

细分控制

细分数是什么?这就要说说所谓细分。

细分的目的主要是为了改善步进电机的运行性能,比如四步的转动扭矩会小于八步的,其次提高了步进电机的精度。

细分功能完全是由外部驱动电路精确控制电机的相电流产生的,和具体电机无关。

步进电机之所以能实现步进就是因为在硬件结构上做了拆分(定子上有不同的通电相,转子上有齿),使其一次转动不是一圈,而是一步一步的按固定的角度转动。这一步所转过的角度就是步距角。

细分控制是指对步距角再进行详细的分步控制。

例如,对一个步距角为1.8°的两相四拍电机进行四细分控制,就是使得电机转动一步是1.8除以4,也就是0.45°来运转。

细分越大精度的确可以提高,并且电机运行更平稳,但是相对的来说脉冲频率就变大,所以一些控制器的脉宽不够,导致电机失步、堵转,所以选择细分要根据实际来调,不是越大越好。

步进电机控制

控制器控制的是什么呢?还是拿STM32F103C8T6举例:

实际上,控制器能做的也就是控制引脚的输出,最最简单的引脚输出,要么高电平,要么低电平。如果上点难度,那就是快速切换高低电平,这样因为人来不及反应,你就感觉这个电平变化的五彩缤纷。

这也就是所谓PWM的原理。

那如果使用PWM方式来进行控制,我们需要的就是打开一个timer,然后用PWM方式start。(详细见上回舵机控制

比如:

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);

接着,因为控制电机不仅需要这个变花样的信号,还需要最基本的方向控制和使能,那就再加两个引脚,分别控制即可。

  1. GPIO_InitTypeDef GPIO_InitStruct;
  2. /* GPIO Ports Clock Enable */
  3. __HAL_RCC_GPIOD_CLK_ENABLE();
  4. __HAL_RCC_GPIOA_CLK_ENABLE();
  5. /*Motor 方向引脚 初始化*/
  6. GPIO_InitStruct.Pin = GPIO_PIN_1;
  7. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  8. GPIO_InitStruct.Pull =GPIO_PULLUP;
  9. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  10. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  11. /*Motor 使能引脚 初始化*/
  12. GPIO_InitStruct.Pin = GPIO_PIN_2;
  13. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  14. GPIO_InitStruct.Pull =GPIO_PULLUP;
  15. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  16. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  17. /*Motor 脉冲引脚 初始化*/
  18. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  19. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  20. GPIO_InitStruct.Pull =GPIO_PULLUP;
  21. GPIO_InitStruct.Pin = GPIO_PIN_8;
  22. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

如果你用的是比较输出方式,也差不多,在输出比较电路会比较CNT和CCR的值,CNT计数自增,CCR是我们给定的一个值,当CNT大于CCR、小于CCR、等于CCR时,输出就会输出对应的置1或置0。

驱动器、控制器、电机法原理

刚刚我们说了使用PWM(PWM输出)和OC(比较输出)方法控制电机,整个过程在于stm控制芯片输出波形信号给驱动器,驱动器根据这些信号的发送频率和占空比等等转换成不同速度和信号强度(电流大小),也会根据用户想要的拍数不同来切换不同位置,变化的发出0和1控制引脚电平变化。

但是!

你这也太超前了,如果我没有驱动器呢?咋办啊。

控制器、电机法原理

如果没有驱动器,那就是stm控制芯片直接控制电机,其实更简单了,为啥捏?

因为我们不用计算复杂的信号频率,旋转角度这些东西了,直接对引脚写0和1,速度也由自己控制,改变每次转换引脚电平的延时即可。

将以下代码封装成函数,加在mian函数的while循环里面,就会得到直接控制电机的程序啦。

注意,引脚电平高低顺序谁先谁后得看你自己的板子,这里只是举个例子。

如果你发现自己的步进电机没法转起来,大概率是线序错误,请看电机伸出的接线线序和板子设置的A+A-B+B-来检查线序!

  1. //正转,四步法
  2. PINA1_ON;
  3. PINA2_ON;
  4. PINB1_OFF;
  5. PINB2_ON;
  6. Self_Delay(delay);
  7. PINA1_ON;
  8. PINA2_OFF;
  9. PINB1_ON;
  10. PINB2_ON;
  11. Self_Delay(delay);
  12. PINA1_OFF;
  13. PINA2_ON;
  14. PINB1_ON;
  15. PINB2_ON;
  16. Self_Delay(delay);
  17. PINA1_ON;
  18. PINA2_ON;
  19. PINB1_ON;
  20. PINB2_OFF;
  21. Self_Delay(delay);
  22. //反转,四步法
  23. PINA1_ON;
  24. PINA2_ON;
  25. PINB1_ON;
  26. PINB2_OFF;
  27. Self_Delay(delay);
  28. PINA1_OFF;
  29. PINA2_ON;
  30. PINB1_ON;
  31. PINB2_ON;
  32. Self_Delay(delay);
  33. PINA1_ON;
  34. PINA2_OFF;
  35. PINB1_ON;
  36. PINB2_ON;
  37. Self_Delay(delay);
  38. PINA1_ON;
  39. PINA2_ON;
  40. PINB1_OFF;
  41. PINB2_ON;
  42. Self_Delay(delay);

改变delay的大小,就可以改变电机转动速度。

有好学的朋友可能要问了,那我如果想要高级一点,变速运动呢?

我只能说,问得好!(叉腰)

我们只要动态改变延时长度,那不就好啦!(变量大小老规矩,还是自己写噢)

  1. void trapezoidal_motion() {
  2. for (int i = 0; i < SHORT_STEPS; i++) {//先加速
  3. speed_delay_time-=acceleration;
  4. test(speed_delay_time);//正转函数
  5. }
  6. for(int i=0;i<LONG_STEPS;i++)
  7. test(speed_delay_time); // 匀速阶段
  8. for (int i = 0; i < SHORT_STEPS; i++) {
  9. speed_delay_time+=acceleration;
  10. test(speed_delay_time);//再减速
  11. }
  12. }
  13. void trapezoidal_motion_in() {
  14. for (int i = 0; i < SHORT_STEPS; i++) {
  15. speed_delay_time-=acceleration;
  16. test1(speed_delay_time);//反转函数
  17. }
  18. for(int i=0;i<LONG_STEPS;i++)
  19. test1(speed_delay_time); // 匀速阶段
  20. for (int i = 0; i < SHORT_STEPS; i++) {
  21. speed_delay_time+=acceleration;
  22. test1(speed_delay_time);
  23. }
  24. }
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号