1. SGM42630电路设计
2. 产生固定数量PWM
生成固定数量的PWM个数需要创建这几个函数:
2.1 SGM23630初始化
int SGM42630_Init(void)
{
NRESET_SGM42630_H(); //1正常模式,0复
SGM42630_StepMotor_Dir_FWD();
SGM42630_StepMotor_MicroStep(8);//8细分模式
STEP_SGM42630_L();//默认低
return 0;
}
2.2 开启电机运行
void SGM42630_StepMotor_Enable(void)
{
NENABLE_SGM42630_L(); //0=使能PWM
NSLEEP_SGM42630_H(); //1休眠禁用,0使能休眠
}
2.3 关闭电机运行
void SGM42630_StepMotor_Disable(void)
{
NENABLE_SGM42630_H(); //1=失能PWM
NSLEEP_SGM42630_L(); //1休眠禁用,0使能休眠
}
2.4 电机正转
//正转
void SGM42630_StepMotor_Dir_FWD(void)
{
DIR_SGM42630_L(); //0正转,1反转
}
2.5 电机反转
//反转
void SGM42630_StepMotor_Dir_REV(void)
{
DIR_SGM42630_H(); //0正转,1反转
}
2.6 电机细分
//细分数
void SGM42630_StepMotor_MicroStep(u8 stepsSet)
{
if(stepsSet==8)
{
USMO_SGM42630_H(); //00:全速;01:1/2细分;10:1/4细分;11:1/8细分
USM1_SGM42630_H();
}
else if(stepsSet==4)
{
USMO_SGM42630_L(); //00:全速;01:1/2细分;10:1/4细分;11:1/8细分
USM1_SGM42630_H();
}
else if(stepsSet==2)
{
USMO_SGM42630_H(); //00:全速;01:1/2细分;10:1/4细分;11:1/8细分
USM1_SGM42630_L();
}
else if(stepsSet==1)
{
USMO_SGM42630_L(); //00:全速;01:1/2细分;10:1/4细分;11:1/8细分
USM1_SGM42630_L();
}
}
2.7 设置电机步数
2.7.1 输入电机步数端口(初始化)
volatile s32 iSGM42630_StepMotor_Steps=0;//iSGM42630_StepMotor_Steps==0 停止电机
u8 bSGM42630_StepMotor_DelayMode=0;
void SGM42630_StepMotor_SetMove(int steps)
{
iSGM42630_StepMotor_Steps = steps;
}
//归零
void SGM42630_StepMotor_ReturnZero(void)
{
SGM42630_StepMotor_Move(-12000);
SGM42630_StepMotor_Move(5000);//全两处差不多1250步 8细分为10000微步 到尽头会返回转
}
2.7.2 电机步数实现
void SGM42630_StepMotor_Move(int steps)
{
u32 movesteps;
bSGM42630_StepMotor_DelayMode=1;
SGM42630_StepMotor_Enable();
if(steps>0)
{
SGM42630_StepMotor_Dir_FWD();
movesteps=steps;
}
else
{
SGM42630_StepMotor_Dir_REV();
movesteps=-steps;
}
while(movesteps--)
{
//负向限位判断
if(LIMIT_UP_IN()>0 && steps<0)
{
break;
}
STEP_SGM42630_H();
delay_us(100);
STEP_SGM42630_L();
delay_us(100);
}
SGM42630_StepMotor_Disable();
bSGM42630_StepMotor_DelayMode=0;
}
8.7.3 放入循环,利用每次循环处理
这样利用全局变量bSGM42630_StepMotor_DelayMode表示状态位,为1为固定步数模式输出。为0为循环步数模式输出。
在每次循环中判断设定步数(全局变量)iSGM42630_StepMotor_Steps的值,如果为0了则需要退出执行,如果大于零,则需要在每一次循环中产生一个高低电平。
void SGM42630_StepMotor_SetMove(int steps)
{
iSGM42630_StepMotor_Steps = steps;
}
void SGM42630_StepMotor_StepsRunLoop(void)
{
static u8 state=0;
if(bSGM42630_StepMotor_DelayMode==1)return;
if(iSGM42630_StepMotor_Steps==0)
{
SGM42630_StepMotor_Disable();
state=0;
return;
}
if(iSGM42630_StepMotor_Steps>0)
{
SGM42630_StepMotor_Enable();
SGM42630_StepMotor_Dir_FWD();//正转
if(state==0)
{
STEP_SGM42630_H();
state=1;
}
else
{
STEP_SGM42630_L();
iSGM42630_StepMotor_Steps--;
state=0;
}
}
else if(iSGM42630_StepMotor_Steps<0)
{
SGM42630_StepMotor_Enable();
SGM42630_StepMotor_Dir_REV();//反转
if(state==0)
{
STEP_SGM42630_H();
state=1;
}
else if(state==1)
{
STEP_SGM42630_L();
iSGM42630_StepMotor_Steps++;
state=0;
}
}
}
2.8 控制协议
case 0x0C://调焦电机步数控制
if(recMotorCtrl_Def->motorCtrlMode == 0x10)//向前
{
pos = recMotorCtrl_Def->motorCtrlStep;
SGM42630_StepMotor_SetMove(pos);
}
else if(recMotorCtrl_Def->motorCtrlMode == 0x01)//向后
{
pos = recMotorCtrl_Def->motorCtrlStep;
SGM42630_StepMotor_SetMove(-pos);
}
2.9 代码实现
在系统快速循环中进行处理:
extern void Timer100us_loop(void);
__weak void Timer100us_loop(void)
{
}
uint32_t count_Timer100us_loop = 0;
//TIM7调用函数100us
int TIM7_PeriodCallback(TIM_HandleTypeDef *htim)
{
count_Timer100us_loop++;
Timer100us_loop();
return 0;
}
//定时器中断产生100us查询循环
void Timer100us_loop(void)
{
device_fast_loop();//设备快速LOOP
}
#include "SGM42630.h"
u32 count_runMotor = 0;
void device_fast_loop(void)
{
if(count_runMotor>=0)
{
SGM42630_StepMotor_StepsRunLoop();
count_runMotor = 0;
}
bsp_fast_loop();//
}