226 lines
10 KiB
C
226 lines
10 KiB
C
/*******************************************************************************
|
||
* @file stepper_s.1.c
|
||
* @Author: MQjehovah mail:MQjehovah@hotmail.com
|
||
* @version 1.0.0
|
||
* @date 2018-02-28 14:15:45
|
||
* @brief 加速曲线是根据时间来离散的,所以每个阶段由时间来分割,及时间累积达到某个值。总的加速时间值由用户指定
|
||
******************************************************************************
|
||
* @attention
|
||
*******************************************************************************/
|
||
/* Includes ------------------------------------------------------------------*/
|
||
#include "stepper.h"
|
||
/* Definition ----------------------------------------------------------------*/
|
||
STEPPER motor;
|
||
STEPPER *pmotor = &motor;
|
||
/* Functions -----------------------------------------------------------------*/
|
||
/*******************************************************************************
|
||
* @brief 步进电机GPIO口初始化
|
||
* @param None
|
||
* @retval None
|
||
* @Note 用户自己实现
|
||
*******************************************************************************/
|
||
void Motor_GPIO_Init(void)
|
||
{
|
||
// GPIO_InitTypeDef GPIO_InitStructure;
|
||
// RCC_APB2PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
|
||
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||
// GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||
// GPIO_ResetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4);
|
||
}
|
||
|
||
#if ADV_TIM_ENABLE
|
||
/*******************************************************************************
|
||
* @brief 高级定时器驱动S型电机驱动
|
||
* @param None
|
||
* @retval None
|
||
* @Note 使用高级定时器1,使用TIM_RepetitionCounter参数跳过细分中断
|
||
减少中断的次数
|
||
*******************************************************************************/
|
||
void Initial_PWM_Motor1(void)
|
||
{
|
||
TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
|
||
NVIC_InitTypeDef NVIC_InitStructure;
|
||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||
|
||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
|
||
Motor_GPIO_Init();
|
||
TIM_DeInit(TIM1);
|
||
//中断NVIC设置:允许中断,设置优先级
|
||
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PWM1_PreemptionPriority;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = PWM1_SubPriority;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
TIM_BaseInitStructure.TIM_Period = 1000;
|
||
TIM_BaseInitStructure.TIM_Prescaler = 5;
|
||
TIM_BaseInitStructure.TIM_ClockDivision = 0;
|
||
TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||
TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
|
||
TIM_TimeBaseInit(TIM1, &TIM_BaseInitStructure);
|
||
|
||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM2模式
|
||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //信号输出到对应的输出引脚
|
||
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //互补信号输出到对应的输出引脚
|
||
TIM_OCInitStructure.TIM_Pulse = 50; //脉冲宽度
|
||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //互补输出高电平有效
|
||
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互补输出高电平有效
|
||
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //输出空闲状态为1
|
||
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; //互补输出空闲状态为0
|
||
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //OC1通道初始化
|
||
|
||
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
|
||
TIM_ARRPreloadConfig(TIM1, ENABLE);
|
||
|
||
//清中断,以免一启用中断后立即产生中断
|
||
TIM_ClearFlag(TIM1, TIM_FLAG_Update);
|
||
//使能TIM1中断源
|
||
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
|
||
TIM_Cmd(TIM1, DISABLE);
|
||
TIM_CtrlPWMOutputs(TIM1, ENABLE); //使能PWM输出
|
||
}
|
||
#endif
|
||
|
||
/*******************************************************************************
|
||
* @brief 电机驱动定时器初始化
|
||
* @param None
|
||
* @retval None
|
||
* @Note 使用定时器TIM2,输出PWM,每次脉冲进入中断
|
||
*******************************************************************************/
|
||
void Motor_PWM_Init(void)
|
||
{
|
||
TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
|
||
NVIC_InitTypeDef NVIC_InitStructure;
|
||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||
|
||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
|
||
Motor_GPIO_Init();
|
||
TIM_DeInit(TIM2);
|
||
//中断NVIC设置:允许中断,设置优先级
|
||
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //更新事件 TIM2_IRQHandler
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //抢占优先级3
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级1
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //允许中断
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
TIM_BaseInitStructure.TIM_Period = 1000;
|
||
TIM_BaseInitStructure.TIM_Prescaler = 5;
|
||
TIM_BaseInitStructure.TIM_ClockDivision = 0;
|
||
TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||
TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
|
||
TIM_TimeBaseInit(TIM2, &TIM_BaseInitStructure);
|
||
|
||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM2模式
|
||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //信号输出到对应的输出引脚
|
||
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //互补信号输出到对应的输出引脚
|
||
TIM_OCInitStructure.TIM_Pulse = 500; //脉冲宽度
|
||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //互补输出高电平有效
|
||
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互补输出高电平有效
|
||
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //输出空闲状态为1
|
||
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; //互补输出空闲状态为0
|
||
TIM_OC1Init(TIM2, &TIM_OCInitStructure); //OC1通道初始化
|
||
|
||
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
|
||
TIM_ARRPreloadConfig(TIM2, ENABLE);
|
||
//清中断,以免一启用中断后立即产生中断
|
||
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
|
||
//使能TIM1中断源
|
||
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
|
||
TIM_Cmd(TIM2, DISABLE);
|
||
//TIM_CtrlPWMOutputs(TIM2,ENABLE); //使能PWM输出
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* @brief 计算S型曲线表
|
||
* @param None
|
||
* @retval None
|
||
* @Note None
|
||
*******************************************************************************/
|
||
void Calculate_S_Table(void)
|
||
{
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* @brief 电机初始化函数
|
||
* @param None
|
||
* @retval None
|
||
* @Note None
|
||
*******************************************************************************/
|
||
void MOTOR_Init(void)
|
||
{
|
||
Motor_PWM_Init(); //初始化电机驱动PWM
|
||
/* 初始化电机参数 */
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* @brief 定时器2中断函数
|
||
* @param None
|
||
* @retval None
|
||
* @Note None
|
||
*******************************************************************************/
|
||
void TIM2_IRQHandler(void)
|
||
{
|
||
TIM2->SR = (u16)~TIM_FLAG_Update;
|
||
if (1 == pmotor->en)
|
||
{
|
||
//位置计算
|
||
if (pmotor->dir_pos == pmotor->dir)
|
||
{
|
||
pmotor->current_puase++;
|
||
}
|
||
else
|
||
{
|
||
pmotor->current_puase--;
|
||
}
|
||
pmotor->current_step = pmotor->current_puase / pmotor->div;
|
||
|
||
pmotor->passed_puase++; //总脉冲个数
|
||
pmotor->f_puase++; //以该频率脉冲输出的脉冲个数
|
||
|
||
|
||
|
||
|
||
//对称反转???
|
||
// if (pmotor->RevetDot == pmotor->PulsesHaven)
|
||
// {
|
||
// pmotor->pulsecount = pmotor->Step_Table[pmotor->CurrentIndex];
|
||
// }
|
||
if (pmotor->f_puase >= pmotor->table_step[pmotor->f_index]) //一个频率的步数走完
|
||
{
|
||
if (pmotor->passed_puase <= pmotor->start_step) //如果是起步阶段
|
||
{
|
||
if (pmotor->f_index < pmotor->start_f - 1)
|
||
{
|
||
pmotor->f_index++; //进入下一个频率阶段
|
||
pmotor->f_puase = 0;
|
||
if (pmotor->f_index >= pmotor->start_f) //启动阶段的步数没有走完,禁止进入下一阶段的频率
|
||
pmotor->f_index = pmotor->start_f;
|
||
}
|
||
}
|
||
if (pmotor->target_puase - pmotor->passed_puase <= pmotor->stop_step) //停止阶段
|
||
{
|
||
// if (pmotor->f_index < pmotor->StartTableLength - 1)
|
||
// {
|
||
// pmotor->f_index = pmotor->StartTableLength + pmotor->StopTableLength - pmotor->CurrentIndex;
|
||
// }
|
||
// pmotor->f_index++;
|
||
// pmotor->f_puase = 0;
|
||
// if (pmotor->f_index >= pmotor->StartTableLength + pmotor->StopTableLength)
|
||
// pmotor->CurrentIndex = pmotor->StartTableLength + pmotor->StopTableLength - 1;
|
||
}
|
||
pmotor->TIMx->ARR = pmotor->table_time[pmotor->f_index]; //设置周期
|
||
pmotor->TIMx->CCR1 = (pmotor->table_time[pmotor->f_index]) >> 1; //设置占空比
|
||
}
|
||
//旋转预定脉冲数,停止,running=0,可以进行下一次旋转
|
||
if (pmotor->passed_puase >= pmotor->target_puase && pmotor->passed_puase > 3)
|
||
{
|
||
pmotor->en = 0;
|
||
pmotor->running = 0;
|
||
pmotor->f_index = 0;
|
||
TIM_Cmd(pmotor->TIMx, DISABLE); //DISABLE
|
||
}
|
||
}
|
||
}
|
||
|
||
/*********************************END OF FILE**********************************/
|