最简单的步进电机教学,基于STM32实现控制电机转速,方向,圈数

前言

我们常见电机有直流电机,舵机,编码电机,步进电机,伺服电机。直流电机,舵机等尝适用于精度要求不是很高的场景,但对于一些精度要求比较高的功能上就需要使用到步进电机,伺服电机等电机。

电机

我们以42步进电机为例,图中为二相四线,分为A组,B组,拿到一个未知的步进电机我们可以将其中两根线短接在一起,扭动转子,如果能扭动,则这两根线不是一组,则换一根线,同样的方法,直到某两根线短接在一起,扭动转子时有阻力,则这两根线为一组

驱动

常见驱动有两种

今天讲解的是下面这款闭环驱动,

接口说明

 

接线

有共阴极和共阳极两种接法,效果都一样,只是在代码里改变引脚高低电平的顺序不一样,其他没什么区别,这里我们采用共阳级接法,

一,两根线将MF+,DR+,PU+短接一起,再用一根线节PU+到单片机+5v引脚口

二,DR-接PA4,PU-接PA3.

三,MF-可接可不接,强迫症的话接去单片机+5V引脚口

单片机与驱动的控制部分接线完成,接下来是,电机与驱动器的接线

一,用文章开头我说的方法将带电机的线分组

二,将每组分别接入驱动的A,B口,正负不用管。

电机与驱动的接线完成,现在只需要将驱动的+V,-V接到电源接线完成。带风扇这个是我的升压模块,因为没24V电源所以需要升压模块

接口讲解

我们只需要记住,PU是脉冲信号,用于控制电机转动。DR用于控制电机转动方向即可。

驱动拨挡讲解

Peak是驱动峰值电流,RMS是工作电流,两者对应关系是Peak = RMS * 1.4;

我们可以通过上图拨动SW1,SW2,SW3,选取我们想要的工作电流和峰值电流,本次讲解里我们用工作电流1.5A, 2.1A的峰值电流。将SW1拨动到ON即可,

电机精度拨挡

Pulse是脉冲数,数值越大,电机一个脉冲内转动角度就越小,对应电机精度就越高,拨挡方法同上,本次讲解我们用1600档,也就是带电机转动一圈需要1600个脉冲信号。

代码讲解

我们先来理解一下电机的部分知识,方便理解代码。

一般来说步进电机的步距为1.8度,则360 / 1.8 = 200步,则电机转动一圈需要200步,也就是200个脉冲信号,而我在前面提到的驱动器电机精度拨挡,拨到了1600档,也就是将电机转动一圈所需的步数从200增加到了1600步,这也就是说电机的精度被我们通过驱动提到了1.8度 / 8 = 0.225度,则一个脉冲电机走0.225步,走完一圈需要1600步,我们看上图,最大可以达到一圈需要40000步,这个精度就很高了吧,这款驱动可以用于医疗器械,当然这是题外话,医疗方面的嵌入式门槛比较高,回到正文,现在我们的代码需要给电机1600个脉冲信号。

脉冲信号可以用翻转电平来模拟,翻转一次就是一个脉冲信号

上才艺,家人们

关键代码

void Motor_Run(uint32_t dir, uint32_t num, uint32_t speed)
{
    // 根据dir的值设置电机方向
    if(dir == 1)
    {
        GPIO_SetBits(GPIOA, GPIO_Pin_4);
    }
    if(dir == 0)
    {
        GPIO_ResetBits(GPIOA, GPIO_Pin_4);
    }
    
    // 循环num*3200次,每次延迟speed微秒,翻转GPIOA的Pin3,实现电机转动
    for(uint32_t i = 0; i <= (num*3200); i++)
    {
        Delay_us(speed);
        GPIOA->ODR ^= GPIO_Pin_3;                                // 操作寄存器翻转GPIOA的Pin3
    }
}

dir 电机转动方向,num:电机转动圈数,speed:电机转动速度

我是用一个for循环来依次给电机脉冲信号,每循环一次,给一个脉冲信号。电机走一步。这样说就很简单了吧,当循环结束,脉冲信号也结束,电机走完1600步,转了一圈。

控制转速原理:

在for循环里加一个延时,这样每循环一次就等待一次延时,这样电机每步之间延时一定时间,1600步下来,不就达到控制转速原理了;

MOTOR.H

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

/**
  * 函    数:直流电机初始化
  * 参    数:无
  * 返 回 值:无
  */
void Motor_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);		//开启GPIOA的时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4  | GPIO_Pin_3;  
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);		

    GPIO_SetBits(GPIOA, GPIO_Pin_4 | GPIO_Pin_3);      //设置GPIOA的Pin4、Pin3为高电平
	
}


/**
 * @brief 控制电机运行
 * 
 * 该函数用于根据指定的方向、运行次数和速度控制电机运行。
 * 通过设置GPIOA的Pin4控制电机方向,通过翻转GPIOA的Pin3控制电机转动。
 * 
 * @param dir 电机运行方向,1表示正转,0表示反转。
 * @param num 电机运行的圈数,单位为圈。
 * @param speed 电机运行的速度,单位为us。
 */
void Motor_Run(uint32_t dir, uint32_t num, uint32_t speed)
{
    // 根据dir的值设置电机方向
    if(dir == 1)
    {
        GPIO_SetBits(GPIOA, GPIO_Pin_4);
    }
    if(dir == 0)
    {
        GPIO_ResetBits(GPIOA, GPIO_Pin_4);
    }
    
    // 循环num*3200次,每次延迟speed微秒,翻转GPIOA的Pin3,实现电机转动
    for(uint32_t i = 0; i <= (num*3200); i++)
    {
        Delay_us(speed);
        GPIOA->ODR ^= GPIO_Pin_3;                                // 操作寄存器翻转GPIOA的Pin3
    }
}

       我们只需要在需要的地方调用该接口就好了,如果挡位很高的话建议速度不要太快,不要问为什么,问就是作者亲测,血的教训!!!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值