STM32103的proteus仿真之步进电机使用

1.步进电机的简介

步进电机(Stepper Motor)是一种电磁执行元件,它能够将电脉冲信号转换为角位移或线位移。步进电机通过接收一系列电脉冲来控制其转动的步数,每接收一个脉冲,电机转动一个步距角(Step Angle)。步进电机的工作原理是利用其内部的电磁线圈产生的磁场,与转子的永磁体相互作用,从而实现精确的步进转动。

2.步进电机的特点

  1. 精确控制:步进电机能够精确地控制其转动的角度,这使得它在需要精确定位的场合非常有用。

  2. 无需传感器:步进电机通常不需要位置反馈传感器,因为它的转动是直接由输入的脉冲序列控制的。

  3. 低速高扭矩:在低速运行时,步进电机可以提供较高的扭矩,适合于启动和精确控制。

  4. 控制简单:步进电机的控制相对简单,可以通过简单的脉冲和方向信号进行操作。

  5. 响应快速:步进电机可以快速响应控制信号,实现快速启动和停止。

  6. 使用寿命长:由于步进电机的转动不依赖于机械接触,因此它的使用寿命相对较长。

  7. 可变步距角:通过改变接收到的脉冲数量,步进电机可以实现不同的步距角,从而适应不同的应用需求。

3.步进电机的仿真

步进电机以及其驱动在proteus中的名字

(步进电机:MOTOR-STEPPER    驱动名字:ULN2003A)

974e848eba134b09bccced689c83a72e.png

 

四相步进电机有单四拍(A-B-C-D)和双四拍(AB-BC-CD-DA)和八拍(A-AB-B-BC-C-CD-D-DA)这三种工作方式。第一种工作方式扭矩小,功耗小,但震动大。第二种工作方式扭矩较大,功耗也大,震动小。第三种工作方式步距角小,输出更平滑,推荐采用这种方式(但这个在仿真中是无法精确的控制的,因为你并不知道仿真的齿轮比,无法精确的测出)。所以我们采用直接控制的方式来达到一个特殊的角度。

 

3.步进电机的仿真整体框架

83463410c5bf40c3b7cc106b276d2a88.png

 

4.cubemx的相关配置

第一种方法)4个引脚配置成上拉高速输出模式(我用了B1,B2,B3,B4)

50f747d4082940e2b495e935c17f6c76.png

第二种方法)直接写代码配置IO口

//可直接使用这个函数进行初始化,不需要在cubemx配置了
void bujin_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;

    __HAL_RCC_GPIOB_CLK_ENABLE();           	//开启GPIOB时钟
	
    GPIO_Initure.Pin=GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4;
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  	//推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;          	//上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;    	 	//高速
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);
    
}

 

5.相关代码和一些解释(仿真写法)

首先是一些相位的测定:根据测的数据 A相在45度   B相在-45度   C相在135度    D相在-135度

转的角度为90或者-90时=两相位之和除以2

+-45度可以直接根据一相得出

180度与0度相同(两相位之和除以2)

void control_motor(int angle)
{
	if(angle==90)
	{
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,1);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D     
	}
	else if(angle==45)
	{
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,1);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D    
	}
	else if(angle==-90)
	{
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,1);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,1);//D  
	}
	else if(angle==-45)
	{
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,1);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D  
	}
	else if(angle==0)
	{
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D  
	}
	else if(angle==180)
	{
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,1);//D  
	}
}

(仅供参考,不是很好)

  /* USER CODE BEGIN 2 */
  
  bujin_Init();//步进电机的初始化,保证在0位置
  control_motor(180);

  /* USER CODE END 2 */

 

6.最终效果

aedc56d4abd3463a990e146358cb19fc.png

(其他角度也是类似)

7.实物的话建议采用四相八拍的模式

顺转:A-AB-B-BC-C-CD-D-DA

反转:将正转的顺序取反就行

//采用四相八拍(即八个节拍)

//顺转
void bujin_control(int count)
{
    if(count==0)//A
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,1);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D
    }
    if(count==1)//AB
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,1);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,1);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D        
    }
    if(count==2)//B
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,1);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D          
    }
    if(count==3)//BC
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,1);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D          
    }
    if(count==4)//C
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D            
    }
    if(count==5)//CD
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,1);//D           
    }
    if(count==6)//D
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,1);//D           
    }
    if(count==7)//DA
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,1);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,1);//D         
    }

}

//反转(将顺转反即可)
void bujin_control_fanzhuan(int count)
{
    if(count==7)//A
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,1);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D
    }
    if(count==6)//AB
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,1);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,1);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D        
    }
    if(count==5)//B
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,1);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D          
    }
    if(count==4)//BC
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,1);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D          
    }
    if(count==3)//C
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);//D            
    }
    if(count==2)//CD
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,1);//D           
    }
    if(count==1)//D
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,1);//D           
    }
    if(count==0)//DA
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,1);//A
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);//B
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);//C
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,1);//D         
    }

}

void bujin_stop(void)
{
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,0);
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,0);
}






//控制电机正转还是反转某个角度
//direction方向,1为正转,0为反转
//angle角度,可为0-360具有实际意义
void bujin_control_angle(int direction, int angle)
{
	u16 j,i;
	if(direction == 1)
	{
		for(j=0;j<64*angle/45;j++) 
		{
			for(i=0;i<8;i++)
            {
                bujin_control(i);
                delay_ms(1);
            }
		}
		 bujin_stop();//停止
    }
	else
	{
		for(j=0;j<64*angle/45;j++) 
		{
			for(i=0;i<8;i++)
            {
                bujin_control_fanzhuan(i);
                delay_ms(1);
            }			
		}
		 bujin_stop();//停止
	}
}

 

仿真和实物实在是相差大,所有仿真用了仿真的方法,四相八拍在仿真中难以实现控制固定的角度。

 

 

  • 30
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值