加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
user_main.c 13.27 KB
一键复制 编辑 原始数据 按行查看 历史
xiaguangbo 提交于 2020-06-22 12:15 . update user_main.c.
///类型
enum motor_state_t
{
motor_stop_state_v,
motor_accelerate_state_v,
motor_speed_max_state_v,
motor_decelerate_state_v
};
struct motor_spta_t
{
int32_t total_step_v; //设定运行总脉冲数。负数就往复位方向移动
uint32_t step_counter_v; //已经运行的脉冲数
uint16_t speed_v; //当前速度
uint16_t speed_max_v; //用户设定的最大速度
uint32_t speed_max_threshold_v; //最大速度阈值,值越大,速度就能分的越精细,相当于速度百分比。用户设定的最大速度小于等于这个值
enum motor_state_t state_v; //运行状态
bool enable_interrupt_counter_v; //定时器中断计数的开关
uint16_t accelerate_decelerate_action_threshold_v; //加减速一次的频率阈值,当中断次数达到这个值后就会加减速一次
uint16_t accelerate_decelerate_interrupt_counter_v; //加减速时的定时器中断次数计数
uint32_t accelerate_decelerate_counter_v; //加减速次数计数
uint32_t accelerate_decelerate_step_v; //加减速阶段的脉冲数
uint32_t speed_accumulator_v; //速度累加器
//以下为非必需
GPIO_PinState reset_direction_io_level_v; //复位方向的方向电平
int32_t absolute_position_step_v; //绝对位置,以步数为单位
GPIO_TypeDef *step_gpio_array_v, *direction_gpio_array_v; //IO组,脉冲、方向
uint16_t step_gpio_v, direction_gpio_v; //IO号,脉冲、方向
TIM_HandleTypeDef *power_timer_p; //电力定时器
uint8_t power_channel_v; //电力通道
uint16_t power_run_v, power_hold_v; //运行功率,保持功率
// uint8_t motor_id_v; //用于查询
// bool limit_flag; //触发复位开关
// float motor_1mm_setp_v; //电机走1mm所需的步数
// GPIO_TypeDef *reset_limit_gpio_array_v; //IO组,复位限位
// uint16_t reset_limit_gpio_v;//IO号,复位限位
// GPIO_PinState reset_limit_io_level_v; //复位限位开关被触碰的电平
};
#define curve_s_table_total_v 200 //s曲线参数个数
//初始化电机参数
void motor_arg_init(struct motor_spta_t *motor_pa, GPIO_TypeDef *step_gpio_array_va, uint16_t step_gpio_va, GPIO_TypeDef *direction_gpio_array_va, uint16_t direction_gpio_va, GPIO_PinState reset_direction_io_level_va, TIM_HandleTypeDef *power_timer_pa, uint8_t power_channel_va, uint16_t power_run_va, uint16_t power_hold_va)
{
motor_pa->step_gpio_array_v = step_gpio_array_va;
motor_pa->step_gpio_v = step_gpio_va;
motor_pa->direction_gpio_array_v = direction_gpio_array_va;
motor_pa->direction_gpio_v = direction_gpio_va;
motor_pa->reset_direction_io_level_v = reset_direction_io_level_va;
motor_pa->power_timer_p = power_timer_pa;
motor_pa->power_channel_v = power_channel_va;
motor_pa->power_run_v = power_run_va;
motor_pa->power_hold_v = power_hold_va;
motor_pa->speed_max_threshold_v = 0xffff;
motor_pa->absolute_position_step_v = 0;
}
//设定数值,并启动电机
void motor_move(struct motor_spta_t *motor_pa, int32_t total_step_va, uint16_t speed_max_va, uint16_t accelerate_decelerate_action_threshold_va)
{
if (total_step_va == 0)
return;
motor_pa->total_step_v = total_step_va;
motor_pa->step_counter_v = 0;
motor_pa->speed_v = 0;
motor_pa->speed_max_v = speed_max_va > motor_pa->speed_max_threshold_v ? motor_pa->speed_max_threshold_v : speed_max_va;
motor_pa->enable_interrupt_counter_v = true;
motor_pa->accelerate_decelerate_interrupt_counter_v = 0;
motor_pa->accelerate_decelerate_counter_v = 0;
motor_pa->accelerate_decelerate_step_v = 0;
motor_pa->accelerate_decelerate_action_threshold_v = accelerate_decelerate_action_threshold_va;
motor_pa->speed_accumulator_v = 0;
if (motor_pa->total_step_v > 0)
{
if (motor_pa->reset_direction_io_level_v == GPIO_PIN_SET)
HAL_GPIO_WritePin(motor_pa->direction_gpio_array_v, motor_pa->direction_gpio_v, GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(motor_pa->direction_gpio_array_v, motor_pa->direction_gpio_v, GPIO_PIN_SET);
}
else
HAL_GPIO_WritePin(motor_pa->direction_gpio_array_v, motor_pa->direction_gpio_v, motor_pa->reset_direction_io_level_v);
__HAL_TIM_SET_COMPARE(motor_pa->power_timer_p, motor_pa->power_channel_v, motor_pa->power_run_v); //加大功率
motor_pa->state_v = motor_accelerate_state_v; //加速
}
//加减速控制。在中断里运行
void motor_spta_algorithm(struct motor_spta_t *motor_pa)
{
if (motor_pa->state_v == motor_stop_state_v)
return;
bool carry_v = false;
//拉低脉冲信号
HAL_GPIO_WritePin(motor_pa->step_gpio_array_v, motor_pa->step_gpio_v, GPIO_PIN_RESET);
motor_pa->speed_accumulator_v += motor_pa->speed_v; //叠加速度
if (motor_pa->speed_accumulator_v >= motor_pa->speed_max_threshold_v) //阈值,如果当前速度达到阈值,发送脉冲的速度就达到最快了,这个阈值就是算法的最大速度
{
carry_v = true;
motor_pa->speed_accumulator_v -= motor_pa->speed_max_threshold_v;
}
if (carry_v == true) //判断是否溢出
{
motor_pa->step_counter_v++;
//拉高脉冲
HAL_GPIO_WritePin(motor_pa->step_gpio_array_v, motor_pa->step_gpio_v, GPIO_PIN_SET);
if (motor_pa->total_step_v > 0)
motor_pa->absolute_position_step_v++;
else
motor_pa->absolute_position_step_v--;
}
//根据电机的状态进行工作
switch (motor_pa->state_v)
{
case motor_accelerate_state_v:
//记录加速的步数
if (carry_v == true)
motor_pa->accelerate_decelerate_step_v++;
if (motor_pa->enable_interrupt_counter_v)
{
motor_pa->accelerate_decelerate_interrupt_counter_v++;
if (motor_pa->accelerate_decelerate_interrupt_counter_v >= motor_pa->accelerate_decelerate_action_threshold_v)
{
motor_pa->accelerate_decelerate_interrupt_counter_v = 0;
motor_pa->accelerate_decelerate_counter_v++; //计录加速的次数
motor_pa->speed_v = curve_s_table_v[motor_pa->accelerate_decelerate_counter_v] * motor_pa->speed_max_v; //计算当前速度
//如果加速次数达到最高次数,就停止加速,并让速度等于最大速度,再切换状态
if (motor_pa->accelerate_decelerate_counter_v >= curve_s_table_total_v)
{
motor_pa->enable_interrupt_counter_v = false;
motor_pa->speed_v = motor_pa->speed_max_v;
motor_pa->state_v = motor_speed_max_state_v;
}
}
}
//如果总步数大于1步
if ((uint32_t)fabs(motor_pa->total_step_v) > 1)
{
if (motor_pa->step_counter_v >= (uint32_t)fabs(motor_pa->total_step_v) / 2) //如果已走步数大于最大步数的一半
{
//加速时中断计数被断,所以要调整,最后一次加速多长时间,减速的第一次的速度就维持多长时间
motor_pa->accelerate_decelerate_interrupt_counter_v = motor_pa->accelerate_decelerate_action_threshold_v - motor_pa->accelerate_decelerate_interrupt_counter_v;
motor_pa->state_v = motor_decelerate_state_v;
}
}
else if (motor_pa->step_counter_v > 0) //只有1步就至少走1步
motor_pa->state_v = motor_decelerate_state_v;
break;
case motor_speed_max_state_v:
if ((uint32_t)fabs(motor_pa->total_step_v) - motor_pa->step_counter_v == motor_pa->accelerate_decelerate_step_v)
{
motor_pa->enable_interrupt_counter_v = true;
//进入减速状态就要切换为减速状态时的最大速度
motor_pa->accelerate_decelerate_counter_v--;
motor_pa->speed_v = curve_s_table_v[motor_pa->accelerate_decelerate_counter_v] * motor_pa->speed_max_v; //计算当前速度
motor_pa->state_v = motor_decelerate_state_v;
}
break;
case motor_decelerate_state_v:
if (motor_pa->enable_interrupt_counter_v)
{
motor_pa->accelerate_decelerate_interrupt_counter_v++;
if (motor_pa->accelerate_decelerate_interrupt_counter_v >= motor_pa->accelerate_decelerate_action_threshold_v) //如果中断次数达到设定次数
{
motor_pa->accelerate_decelerate_interrupt_counter_v = 0;
motor_pa->accelerate_decelerate_counter_v--;
motor_pa->speed_v = curve_s_table_v[motor_pa->accelerate_decelerate_counter_v] * motor_pa->speed_max_v; //计算当前速度
}
if (motor_pa->speed_v <= 100)
motor_pa->enable_interrupt_counter_v = false;
}
if (motor_pa->step_counter_v >= (uint32_t)fabs(motor_pa->total_step_v))
{
//设定电机状态
motor_pa->state_v = motor_stop_state_v;
__HAL_TIM_SET_COMPARE(motor_pa->power_timer_p, motor_pa->power_channel_v, motor_pa->power_hold_v); //降低功率
}
break;
default:
break;
}
}
//运行示例
int main()
{
tim2_init();
tim4_init();
HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);
curve_s_init(curve_s_table_v, curve_s_table_total_v, 7);
motor_arg_init(&motor1_v, GPIOA, GPIO_PIN_6, GPIOA, GPIO_PIN_7, GPIO_PIN_SET, &htim4, TIM_CHANNEL_2, 3, 3);
while(1)
motor_move(&motor1_v, 3200, 35000, 100);
}
void tim_call_back(TIM_HandleTypeDef *htim)
{
if (htim == &htim2)
{
motor_spta_algorithm(&motor1_v);
}
}
///内容几乎不更改的函数
//s曲线y值生成
void curve_s_init(float *buff_pa, uint16_t count_va, uint8_t pan_right_va)
{
for (uint16_t i = 0; i < count_va; i++)
{
buff_pa[i] = 1.0 / (1.0 + exp(((float)pan_right_va * 2 / count_va * -i) + pan_right_va));
}
}
void tim2_init(void)
{
/* USER CODE BEGIN TIM2_Init 0 */
/* USER CODE END TIM2_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM2_Init 1 */
/* USER CODE END TIM2_Init 1 */
htim2.Instance = TIM2;
htim2.Init.Prescaler = 72 - 1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 20 - 1;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM2_Init 2 */
/* USER CODE END TIM2_Init 2 */
}
void tim4_init(void)
{
/* USER CODE BEGIN TIM4_Init 0 */
/* USER CODE END TIM4_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM4_Init 1 */
/* USER CODE END TIM4_Init 1 */
htim4.Instance = TIM4;
htim4.Init.Prescaler = 72 - 1;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 20 - 1;
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM4_Init 2 */
/* USER CODE END TIM4_Init 2 */
HAL_TIM_MspPostInit(&htim4);
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化