概述
正在做的项目需要用STM32控制步进电机,本篇主要讲解利用STM32定时器外设输出脉冲来控制步进电机转动。
STM32定时器
使用STM32芯片类型:STM32c8t6。
使用外设接口:选用TIM4的CH1通道,对应输出脉冲IO口为PB6。
步进驱动器介绍
(这里以两相步进驱动器为例,详细见说明书)
- 接口
步进驱动器可分为两部分:环形分配器、功率放大器。
环形分配器:接收3种信号分别为:脉冲信号(PUL),方向信号(DIR),脱机信号(ENA)。
脉冲信号:环形分配器对脉冲信号进行分配,去控制功率放大器相应的晶体管,使步进电机的线圈得电。所以,步进电机要运转就必须有脉冲输入,所以需要一个驱动器来给步进电机的各项绕组依次通电。
方向信号:控制AB通电的相序,A-B顺时针,B-A逆时针
脱机信号:步进电机停止时,AB线圈有一相得电,得电的功能使转子锁住,使转子不能动,需要收去拨动转子的时候,需要给脱机信号,使AB相绕组完全断电,转子处于自由转动状态。(也就是说控制电机停止除了不给脉冲之外,还可以控制脱机信号来锁死电机,此处用不着脱机信号)
- 细分
为了提高步进电动机控制的精度,现在的步进驱动器都有细分的功能,所谓细分,就是通过驱动器中电路的方法把步距角减小。比如把步进驱动器设置成5细分,假设原来步距角1.8°那么设成5细分后,步距角就是0.36°。也就是说原来一步可以走完的,设置成细分后需要走5步。一般步进电动机的细分表在驱动器上可以直接看到。(设置合适细分能够避免电机转动时震动过大,但过高的细分数会导致电机输出力矩减小)
- 驱动电源:
需要9-42V直流电源,需要使用变压器将220V交流电转为24V直流电
定时器频率与步进电机的关系
-
接线
将驱动器PUL+端接入STM32输出脉冲的IO口(PB6),PUL-端接地
将驱动器DIR+端接入STM32的任意一个闲置IO口(这里选PB5),DIR-端接地
驱动器ENA±端不接
A+、A-、B+、B-接入步进电机
电源接到变压器 -
频率与速度的关系
确定输出脉冲频率与电机转速的关系,对于两相步进电机而言:
转速 = 脉冲频率 * 60 /((360/T)*x) T是步进电机步距角(1.8°),x是驱动器细分倍数(16) 脉冲频率= 时钟频率(72Mhz)/ ((arr+1)*(psc+1))根据以上公式,可以得到:
Speed = 15r/min时,若确定arr为199,则psc为449
其他速度可根据需要自行设定。
代码
编写流程:TIM4配置 -> DIR对应IO口配置 -> main调用初始化函数并设置占空比
//TIM4配置
void TIM4_PWM_Init(u16 arr,u16 psc) //初始化arr=200,psc = 450得到电机速度为15r/min
{
//初始化结构体
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
//使能时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
//设置该引脚为复用输出功能,输出TIM4 CH1的PWM脉冲波形 GPIOB.6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //TIM4_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//计数模式
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
//定时中断配置
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); /
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//初始化TIM4 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM4, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
TIM_Cmd(TIM4,ENABLE); //使能定时器
}
void DIR_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
int main()
{
DIR_Init();
TIM4_PWM_Init(200,450);
TIM_SetCompare1(TIM4,200/2); //设置占空比为50%(=arr/2),不设置的话电机启动不了
while()
{
;
}
}
对应工程文件:
STM32c8t6启动步进电机