目录
一、硬件原理图接口
二、软件实现
/* motor.c */
#include "motor.h"
//电机引脚和端口
#define MOTOR_PORT GPIOE
#define MOTOR_PIN_A GPIO_PIN_9
#define MOTOR_PIN_B GPIO_PIN_8
#define MOTOR_PIN_C GPIO_PIN_7
#define MOTOR_PORT_D GPIOB
#define MOTOR_PIN_D GPIO_PIN_2
typedef struct
{
volatile int goCount; /*设置电位器在本次调节中需要转动步数*/
volatile u8 RunOneStepInterval; //每走一步的间隔时间
}S_FLOWCHECK;
S_FLOWCHECK FlowCheck=
{
.goCount = 0,
.RunOneStepInterval = 40,
};
//旋转控制逻辑A-AB-B-BC-C-CD-D-DA //二相四线的控制方式
const uint8_t MotorCtrPara[] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09};
static void MOTOR_STOP()
{
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_A);
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_B);
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_C);
gpio_bit_reset(MOTOR_PORT_D, MOTOR_PIN_D);
}
void Motor_Init(void)
{
rcu_periph_clock_enable(RCU_GPIOE);
rcu_periph_clock_enable(RCU_GPIOB);
gpio_init(MOTOR_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,
MOTOR_PIN_A|MOTOR_PIN_B|MOTOR_PIN_C);
gpio_init(MOTOR_PORT_D, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, MOTOR_PIN_D);
MOTOR_STOP(); //输出全部拉低
}
static void set_motor_rotation(uint8_t gpio_valve)
{
gpio_valve &= 0x0f;
switch(gpio_valve)
{
case 0x01:
gpio_bit_set(MOTOR_PORT, MOTOR_PIN_A);
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_B);
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_C);
gpio_bit_reset(MOTOR_PORT_D, MOTOR_PIN_D);
break;
case 0x03:
gpio_bit_set(MOTOR_PORT, MOTOR_PIN_A);
gpio_bit_set(MOTOR_PORT, MOTOR_PIN_B);
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_C);
gpio_bit_reset(MOTOR_PORT_D, MOTOR_PIN_D);
break;
case 0x02:
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_A);
gpio_bit_set(MOTOR_PORT, MOTOR_PIN_B);
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_C);
gpio_bit_reset(MOTOR_PORT_D, MOTOR_PIN_D);
break;
case 0x06:
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_A);
gpio_bit_set(MOTOR_PORT, MOTOR_PIN_B);
gpio_bit_set(MOTOR_PORT, MOTOR_PIN_C);
gpio_bit_reset(MOTOR_PORT_D, MOTOR_PIN_D);
break;
case 0x04:
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_A);
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_B);
gpio_bit_set(MOTOR_PORT, MOTOR_PIN_C);
gpio_bit_reset(MOTOR_PORT_D, MOTOR_PIN_D);
break;
case 0x0c:
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_A);
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_B);
gpio_bit_set(MOTOR_PORT, MOTOR_PIN_C);
gpio_bit_set(MOTOR_PORT_D, MOTOR_PIN_D);
break;
case 0x08:
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_A);
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_B);
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_C);
gpio_bit_set(MOTOR_PORT_D, MOTOR_PIN_D);
break;
case 0x09:
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_B);
gpio_bit_reset(MOTOR_PORT, MOTOR_PIN_C);
gpio_bit_set(MOTOR_PORT, MOTOR_PIN_A);
gpio_bit_set(MOTOR_PORT_D, MOTOR_PIN_D);
break;
default:
break;
}
}
/******************************************************************
* @brief 步进电机控制,需要在1ms定时器中断中一直调用
*******************************************************************/
void Motor_TickInc(void) //1ms进入一次
{
static signed char positive_tick=0; //正向转
static signed char negative_tick=7; //反向转
uint8_t mOdr = 0x00;
if(FlowCheck.goCount == 0)
{
MOTOR_STOP();
return;
}
if(FlowCheck.RunOneStepInterval > 0) //40ms没到直接返回
{
FlowCheck.RunOneStepInterval--;
return;
}
//已经到达40ms
if(FlowCheck.goCount > 0) //正转
{
mOdr|=MotorCtrPara[positive_tick];
positive_tick++;
if(positive_tick > 7) //磁极转完一圈
{
positive_tick =0;
FlowCheck.goCount--;
FlowCheck.RunOneStepInterval = 40; //8个磁极全部走完,40ms间隔重新赋值
}
}
else //反转
{
mOdr|=MotorCtrPara[negative_tick];
negative_tick--;
if(negative_tick < 0) //磁极转完一圈
{
negative_tick = 7;
FlowCheck.goCount++;
FlowCheck.RunOneStepInterval = 40;
}
}
set_motor_rotation(mOdr);
}