利用stm32控制步进电机 速度&&加速度控制

因为想申请 CSDN 博客认证需要一定的粉丝量,而我写了五年博客才 700 多粉丝,本文开启关注才可阅读全文,很抱歉影响您的阅读体验

利用stm32控制步进电机

尝试用42系步进电机做倒立摆,总结步进电机控制

  • stm32f407控制
  • Microstep Driver驱动器

一、Miocrostep Driver驱动

高精度系列二相混合式步进电机多细分驱动器

1、使用说明:

1、VCC&GND:20~40V DC;
2、A+A- B+B-:接二相混合式步进电机的2相;
3、工作额定电流:3A;
4、拨码开关SW1~SW8:下拨代表ON(驱动器上有文字指示),上拨代表OFF;
5、拨码开关SW4~SW6:选择下拨(ON)或(OFF)时,M403列对应电流值;
6、拨码开关SW1~SW3:ON和OFF选择对应细分数;
7、Ena- Ena+:使能信号输入;(拉低使能
8、Pul- Pul+:脉冲信号输入;
9、Dir- Dir+:方向信号输入; (从正面看,拉高逆时针,拉低正时针

2、特性:

1、外壳上标注参数直观清晰;
2、单/双脉冲输入兼容;
3、双极恒流斩波方式驱动、微步控制、电源损耗低效率高;;
4、直流宽电压范围供电,DC20~40V;
5、最大驱动电流3A/相;
6、高细分:最高可定制为256细分;
7、所有控制信号光电隔离;
8、输入脉冲频率最大400KHz;
9、驱动器外壳与地电绝缘。
10、静止时锁定电流可在0~100%范围内选择。
11、可通过调节改善电机振动。
12、输入信号TTL兼容,同时可接受差分信号输入;
13、20KHz斩波频率;
14、高可靠性:采用多层板和表面贴封,功率器件留有足够裕量;

二、控制

步进电机通过发送脉冲信号控制,每收到一个脉冲就转一个步进角,因此,在细分数数一定的情况下

  • 加大(减小)脉冲频率,可以加(减)转速
  • 加大(减小)改变脉冲频率的速率,可以加(减)加速度

1、初始化设置

脉冲生成有3种方法:延时PWM中断,后两种可靠性较高,这里采用定时器中断生成脉冲

1、使能i/o

void DJ_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6; //DRIVER_DIR/DRIVER_OE
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOE, &GPIO_InitStructure);
	//--------------------------------------------------------------	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //STEP_PULSE
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	//---------------------------------------------------------------
	GPIO_SetBits(GPIOE,GPIO_Pin_5);//拉高,正转
	GPIO_ResetBits(GPIOE,GPIO_Pin_6);//拉低,使能
}

2、定时器配置

void TIM4_Int_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); 
	
	TIM_TimeBaseInitStructure.TIM_Period = arr; 
	TIM_TimeBaseInitStructure.TIM_Prescaler=psc; 
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); 

	NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn; 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM4,ENABLE); 
}

配置中断周期为10us

TIM4_Int_Init(10-1,84-1);	//84M/84=1Mhz(10^6)计数频率,计数10次为10us  (生成脉冲)

2、控制转速

我们利用中断生成脉冲,思想如下:从第一次进中断开始计数,进指定次数为一个周期,前若干次输出高电平,其余输出低电平。控制中断次数判断即可控制周期(转速)和高电平持续时间。

程序截选如下

//全局变量-------------------------------------------------------------------
u8 Start_Flag=0; //电机启动/锁定标志
u16 Pluse_High=10; //脉冲高电平中断次数      1->10us
u16 Pluse_Period=100;//脉冲周期中断次数 (转速)

//脉冲中断服务函数------------------------------------------------------------
u32 TimeCount=0;//进中断计数
void TIM4_IRQHandler(void)//10us
{
	if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)//溢出中断
	{		
		if(Start_Flag==0)
			GPIO_SetBits(GPIOE,GPIO_Pin_6);//motor_disable;
		else if(Start_Flag==1)
		{
			GPIO_ResetBits(GPIOE,GPIO_Pin_6);//motor_enable;
			TimeCount++;

			if(TimeCount<Pluse_High)//脉冲高电平
				GPIO_SetBits(GPIOB,GPIO_Pin_8);
			else if(TimeCount>Pluse_High)
				GPIO_ResetBits(GPIOB,GPIO_Pin_8);
			
			if(TimeCount>Pluse_Period)//周期控制(转速控制)
				TimeCount=0
		}
	}
	TIM_ClearITPendingBit(TIM4,TIM_IT_Update);  //Çå³ýÖжϱê־λ
}

注意到中断周期为:T=Pluse_Period * t
则脉冲频率为:f=1/T=1/(Pluse_Period * t), 注意此值与速度成正比
因此,虽然可以简单地通过控制全局变量Pluse_Period控制转速,但是此值与转速成反比例关系,不适合控制;

较好的方法是,设全局变量temp_x ,使Pluse_Period=1000/temp_x (1000可以为任意常数)
则脉冲频率为:f=1/T=1/(Pluse_Period * t)=temp_x/(1000*t)
此时全局变量temp_x 与转速成正比,适于控制

3、加速度控制

使用temp_x修改速度控制后,可以方便地进行加速度控制,按一定中断次数均匀地使temp_x递增(减)即可
程序修改如下:

#define MaxSpeed 20
//全局变量-------------------------------------------------------------------
float temp_x=1;
float Acc=1.5;//加速度
u32 TimeCount=0;
u32 AccCount=0;
//加速度控制函数--------------------------------------------------------------
void acc(float a)
{
	temp_x+=a;
	if(temp_x>0)//temp_x==0时发生换向
	{
		GPIO_ResetBits(GPIOE,GPIO_Pin_5);
		Pluse_Period=1000/temp_x;
	}
	else
	{
		GPIO_SetBits(GPIOE,GPIO_Pin_5);
		Pluse_Period=-1000/temp_x;
	}
	
	if(Pluse_Period<MaxSpeed )//控制速度上限,防止电机抱死
		Pluse_Period=MaxSpeed ;
}

//修改后的脉冲中断服务函数------------------------------------------------------------
u32 TimeCount=0;//进中断计数
void TIM4_IRQHandler(void)//10us
{
	if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)//溢出中断
	{		
		if(Start_Flag==0)
			GPIO_SetBits(GPIOE,GPIO_Pin_6);//motor_disable;
		else if(Start_Flag==1)
		{
			GPIO_ResetBits(GPIOE,GPIO_Pin_6);//motor_enable;
			TimeCount++;
			AccCount++;
			
			if(TimeCount<Pluse_High)//脉冲高电平
				GPIO_SetBits(GPIOB,GPIO_Pin_8);
			else if(TimeCount>Pluse_High)
				GPIO_ResetBits(GPIOB,GPIO_Pin_8);
			
			if(TimeCount>Pluse_Period)//周期控制(转速控制)
				TimeCount=0
		}
		
		if(AccCount>1000)
			AccCount=0,acc(ACC);
	}
	TIM_ClearITPendingBit(TIM4,TIM_IT_Update);  //Çå³ýÖжϱê־λ
}

经测试,上述代码可以很好地执行步进电机的 速度&加速度 控制任务

三、完整代码下载

就像文章开头说的,这个代码是我那天下午研究完步进电机用法后快速写的测试程序,写的很快,所以程序结构比较混乱,仅供参考

  • github下载地址:https://github.com/wxc971231/stm32F4-Stepper_Motor_Test
  • 百度云:https://pan.baidu.com/s/1ciTir1q-HgDOw-9PcTfPPg 密码ubn3
  • 82
    点赞
  • 506
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 53
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云端FFF

所有博文免费阅读,求打赏鼓励~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值