void CMOTOR_MFCDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
#define MOTOR_LEAD 40 /* 电机模组导程,单位0.1mm */
#define STEP_PER_CIRCLE 200 /* 细分为1时,电机走一圈需要的步数 */
#define MOTOR_DRIVER_SUBDIVISION 32 /*电机驱动器细分*/
#define TIM_CLK 8000000 /* 定时器时钟频率 */
typedef enum
{
MOTOR_STOP = 0,
MOTOR_ACCELERATE,
MOTOR_UNIFORM,
MOTOR_DECELERATE
}motor_run_state_typedef;
UINT distance = 300;
UINT speed = 100;
UCHAR accel_time = 10;
static UINT g_steps_total; /* 电机总共需要运行的步数 */
static UINT g_steps_done; /* 电机已经运行的步数 */
static UINT g_steps_accelerate; /* 电机总加速运行的步数 */
static UINT g_step_timer_pulse_num; /* 电机运行一步需要定时器的脉冲数 */
static UINT g_first_step_timer_pulse_num; /* 电机运行的第一步需要定时器的脉冲数c0 */
static UINT g_step_timer_pulse_num_min; /* 电机运行一步需要定时器的脉冲数的最小值 */
static UINT speed_step_per_second;
static UINT time_sum;
static motor_run_state_typedef motor_run_state;
static double acceleration;
g_steps_total = distance * STEP_PER_CIRCLE * MOTOR_DRIVER_SUBDIVISION / MOTOR_LEAD;
if (1 == g_steps_total)
{
g_step_timer_pulse_num = 1000;
motor_run_state = MOTOR_DECELERATE;
}
else if (0 != g_steps_total)
{
g_step_timer_pulse_num_min = TIM_CLK * MOTOR_LEAD * 1.0 / speed / STEP_PER_CIRCLE / MOTOR_DRIVER_SUBDIVISION;
acceleration = speed / accel_time * 10;
g_step_timer_pulse_num = TIM_CLK * 1.0 * sqrt(2 * MOTOR_LEAD * 1.0 / STEP_PER_CIRCLE / MOTOR_DRIVER_SUBDIVISION / acceleration); /* 计算c0 */
g_first_step_timer_pulse_num = g_step_timer_pulse_num;
motor_run_state = MOTOR_ACCELERATE;
}
time_sum = 0;
g_steps_done = 0;
g_steps_accelerate = 0;
m_pDc->MoveTo(0, m_rect.bottom / 2);
while (1)
{
g_steps_done++;
if (g_steps_done >= g_steps_total) /* 运行完成 */
{
return;
}
switch (motor_run_state)
{
case MOTOR_ACCELERATE:
if (g_steps_done * 2 > g_steps_total)
{
g_steps_accelerate--;
g_step_timer_pulse_num = g_first_step_timer_pulse_num * (sqrt(g_steps_accelerate*1.0 + 1) - sqrt(g_steps_accelerate*1.0));
motor_run_state = MOTOR_DECELERATE;
}
else if (g_steps_done * 2 == g_steps_total)
{
g_step_timer_pulse_num = g_first_step_timer_pulse_num * (sqrt(g_steps_accelerate*1.0 + 1) - sqrt(g_steps_accelerate*1.0));
motor_run_state = MOTOR_DECELERATE;
}
else
{
g_steps_accelerate++;
g_step_timer_pulse_num = g_first_step_timer_pulse_num * (sqrt(g_steps_accelerate*1.0 + 1) - sqrt(g_steps_accelerate*1.0));
if (g_step_timer_pulse_num <= g_step_timer_pulse_num_min)
{
g_step_timer_pulse_num = g_step_timer_pulse_num_min;
motor_run_state = MOTOR_UNIFORM;
}
else
{
motor_run_state = MOTOR_ACCELERATE;
}
}
break;
case MOTOR_UNIFORM:
if (g_steps_total - g_steps_done <= g_steps_accelerate)
{
g_steps_accelerate--;
g_step_timer_pulse_num = g_first_step_timer_pulse_num * (sqrt(g_steps_accelerate*1.0 + 1) - sqrt(g_steps_accelerate*1.0));
motor_run_state = MOTOR_DECELERATE;
}
break;
case MOTOR_DECELERATE:
g_steps_accelerate--;
g_step_timer_pulse_num = g_first_step_timer_pulse_num * (sqrt(g_steps_accelerate*1.0 + 1) - sqrt(g_steps_accelerate*1.0));
break;
}
if (g_step_timer_pulse_num >= 0xffff)
{
g_step_timer_pulse_num = 0xffff;
}
if (g_step_timer_pulse_num == 0)
{
g_step_timer_pulse_num = 1; /* 此条语句仅为调试使用,看程序是否会执行到这里 */
return; /* ERROR */
}
speed_step_per_second = TIM_CLK / g_step_timer_pulse_num;
time_sum += g_step_timer_pulse_num;
m_pDc->LineTo(time_sum * 0.00001, m_rect.bottom / 2 - speed_step_per_second*0.01);
}
}
总结:
1、
2、将距离修改为30,UINT distance = 30;
3、
4、
5、
6、
7、
8、