1.1 步进电机相关概念
相数:产生不同对极N、S磁场的激磁线圈对数,常用 m 表示。例如:二相四线电机,就有两对极N、S磁场的激磁线圈,四个线圈。上图可知,A+,A- 是连通的,B+ 和B- 是连通的,分别记为A组、B组。在不知道电机接线图的情况下可以用万用表测试,即相互连通的为一组。
拍数:完成一个磁场周期性变化所需脉冲数或导电状态用n表示,或指电机转过一个齿距角所需脉冲数,以四相电机为例,有四相四拍运行方式即AB-BC-CD-DA,四相八拍运行方式即 A-AB-B-BC-C-CD-D-DA。
步距角:对应一个脉冲信号,电机转子转过的角位移用θ表示。θ=360度(转子齿数J运行拍数),以常规二、四相,转子齿为50齿电机为例。四拍运行时步距角为θ=360度/(50 × 4 50\times 450×4)=1.8度(俗称整步),八拍运行时步距角为θ=360度/(50 × 8 50\times 850×8)=0.9度(俗称半步)。
定位转矩:电机在不通电状态下,电机转子自身的锁定力矩(由磁场齿形的谐波以及机械误差造成的)。
静转矩:电机在额定静态电作用下,电机不作旋转运动时,电机转轴的锁定力矩。此力矩是衡量电机体积(几何尺寸)的标准,与驱动电压及驱动电源等无关。
#include "sys.h"
#ifndef _L298N_H
#define _L298N_H
#define IN1 PBout(12)
#define IN2 PBout(13)
#define IN3 PBout(14)
#define IN4 PBout(15)
#define ENA GPIO_Pin_7 //TIM3通道2,PWM通道
#define ENB GPIO_Pin_6 //TIM3通道1
#define ENAZERO GPIOA->BSRR&=~(1<<6)
#define ENBZERO GPIOA->BSRR&=~(1<<7)
#define ENASTART GPIOA->BSRR|=(1<<6)
#define ENBSTART GPIOA->BSRR|=(1<<7)
#define MOTOR_STEP_COUNT 400
void Static_init();
void Motor_en_init(int arr,int psc);
void Motor_speed_adjust(TIM_TypeDef* TIMx,int arr,float Dutycycle); //调节函数只针对通道一
void Stop1(void );
void Stop2(void );
void Stop_all(void );
void ZRotate1();
void ZRotate2();
void Z_Rotate_all();
void FRotate1();
void FZRotate2();
void F_Rotate_all();
void SetMotor(unsigned char InputData);
void Control_4();
void Control_dou4();
void Control_8();
#endif
L298N源文件
#include "stm32f10x.h"
#include "pwm.h"
#include "L298N.h"
#include "delay.h"
void Static_init()//全部默认为0
{
ENAZERO;//A电机停转
ENAZERO;//B电机停转
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE);//使能,开启GPIOB的外设时钟
//IN1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
//IN2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pin_13);
//IN3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pin_14);
//IN4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pin_15);
}
void Motor_en_init(int arr,int psc)
{
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA,ENABLE);//使能,开启GPIOC的外设时钟
ENASTART,ENBSTART;
TIM3_PWM_Init(arr,psc);//100HZ
// TIM_Cmd(TIM3, ENABLE);
}
//调节函数只针对通道一
void Motor_speed_adjust(TIM_TypeDef* TIMx,int arr,float Dutycycle)
{
//Set_Pwm2_Dutycycle( TIM3,10000,0.5);
Set_Pwm2_Dutycycle( TIMx,arr,Dutycycle);
}
//以下函数默认电机使能,针对直流电机而言
//一电机停止
void Stop1( )
{
IN1=0;
IN2=0;
}
//二电机停止
void Stop2( )
{
IN3=0;
IN4=0;
}
void Stop_all()
{
IN1=0;
IN2=0;
IN3=0;
IN4=0;
}
void ZRotate1()
{
IN1=0;
IN2 =1;
}
void ZRotate2()
{
IN3=0;
IN4=1;
}
//全部正转
void Z_Rotate_all()
{
IN1=0;
IN2 =1;
IN3=0;
IN4=1;
//...
}
//反转
void FRotate1()
{
IN1=1;
IN2 =0;
}
void FZRotate2()
{
IN3=1;
IN4=0;
}
//全部反转
void F_Rotate_all()
{
IN1=1;
IN2 =0;
IN3=1;
IN4=0;
}
//单四拍控制通电方式
void Control_4()
{
IN1=1,IN2=0,IN3=0,IN4=0;
delay_ms(1);
IN1=0,IN2=0,IN3=1,IN4=0;
delay_ms(1);
IN1=0,IN2=1,IN3=0,IN4=0;
delay_ms(1);
IN1=0,IN2=0,IN3=0,IN4=1;
delay_ms(1);
}
//双四拍控制通电方式
void Control_dou4()
{
IN1=1,IN2=0,IN3=1,IN4=0;
delay_ms(1);
IN1=0,IN2=1,IN3=1,IN4=0;
delay_ms(1);
IN1=0,IN2=1,IN3=0,IN4=1;
delay_ms(1);
IN1=1,IN2=0,IN3=0,IN4=1;
delay_ms(1);
}
//单八拍控制通电方式,一拍0.9度
void Control_8()
{
IN1=1,IN2=0,IN3=0,IN4=0;
delay_ms(1);
IN1=1,IN2=0,IN3=1,IN4=0;
delay_ms(1);
IN1=0,IN2=0,IN3=1,IN4=0;
delay_ms(1);
IN1=0,IN2=1,IN3=1,IN4=0;
delay_ms(1);
IN1=0,IN2=1,IN3=0,IN4=0;
delay_ms(1);
IN1=0,IN2=1,IN3=0,IN4=1;
delay_ms(1);
IN1=0,IN2=0,IN3=0,IN4=1;
delay_ms(1);
IN1=1,IN2=0,IN3=0,IN4=1;
delay_ms(1);
}
u16 nCurrentMotorStepCount=0;
void SetMotor(unsigned char InputData)
{
if(InputData&0x01)
{
IN4=1;
}
else
{
IN4=0;
}
if(InputData&0x02)
{
IN2=1;
}
else
{
IN2=0;
}
if(InputData&0x04)
{
IN3=1;
}
else
{
IN3=0;
}
if(InputData&0x08)
{
IN1=1;
}
else
{
IN1=0;
}
}
// unsigned char PhaseCW[8]={0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08};//顺时针旋转相序表
// unsigned char PhaseCCW[8]={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};//逆时针旋转相序表
//void TIM3_IRQHandler(void)
//{
// if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//是更新中断
// {
// TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIM3更新中断标志
//
// nCurrentMotorStepCount++;
//
// if(nCurrentMotorStepCount <= MOTOR_STEP_COUNT)
// {
// SetMotor(PhaseCW[nCurrentMotorStepCount%8]);
// //SetMotor(PhaseCCW[nCurrentMotorStepCount%8]);
// }
//
// if(nCurrentMotorStepCount >= MOTOR_STEP_COUNT)
// {
// TIM_Cmd(TIM3, DISABLE); //关闭TIM3
//
// ENAZERO; //只有转的时候使能,否则持续供电,芯片和电机过热。
// ENBZERO ;
// nCurrentMotorStepCount = 0;
// }
// }
//}
//
#include "L298N.h"
#include "hbpwmdsq.h"
#include "sys.h"
int main ()
{
// USART1_Init(115200);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init();
SystemInit();
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA,ENABLE);//使能,开启GPIOC的外设时钟
Static_init();
Motor_en_init(1800,71); //1.8ms,一拍
while(1)
{
TIM_SetCompare1(TIM3,900);
TIM_SetCompare2(TIM3,900);
}
}