bsp_motor.h

#ifndef __BSP_MOTOR_H
#define __BSP_MOTOR_H

#include "main.h"
#include "tim.h"		

#define	FORM_LEN				11000																			//速度表空间大小
#define TIM_FREQ					(SystemCoreClock / ((TIM3 -> PSC) + 1))	//频率ft值
#define STEP_ANGLE  		1.8f																			//步进电机的步距角 单位:度
#define FSPR						(360.0f / 1.8f)														//步进电机的一圈所需脉冲数
#define MICRO_STEP			1																				//细分器细分数
#define SPR							(FSPR * MICRO_STEP)												//细分后一圈所需脉冲数
#define CONVER(speed)		(float)(speed * SPR / 60.0f)							//根据电机转速(r / min) , 计算电机步速(step / s)
#define MIN_SPEED				(float)(TIM_FREQ / 65535)									//最低频率 / 速度
#define MOTOR_ENABLE		1
#define MOTOR_DISABLE		0
#define MOTOR_CW				0
#define MOTOR_CCW				1

typedef struct{
		__IO uint8_t state;							//状态
		__IO uint16_t compare;					//比较值
		__IO uint32_t location;					//位置
}motorState_Typedef;

typedef struct{
		__IO int32_t	vStart;						//初始速度
		__IO int32_t	vUniform;					//目标速度
		__IO int32_t  accelTotalStep;		//加速度总步数
		__IO int32_t  decLocation;			//开始减速的位置
		__IO int32_t  totalStep;				//完整曲线总步数
		__IO int32_t  incAccelTotalStep;//加加速度步数
		__IO int32_t  decAccelTotalStep;//减加速度步数
		__IO float	Form[FORM_LEN];			//S加减速 速度表
}motorSpeed_Typedef;

typedef enum{
		STOP = 0,												//停止状态
		ACCEL,													//加速状态
		UNIFORM,												//匀速状态
		DECEL,													//减速状态
}motorStateEnum_Typedef;

/**
  * @brief  电机使能/失能
  * @param  参数
  * @retval 无
	*	@note 	无
  */
__STATIC_INLINE void Motor_Turn(uint8_t flag)
{
		if(flag)
		{
				HAL_GPIO_WritePin(MOTOR_EN_GPIO_Port , MOTOR_EN_Pin , GPIO_PIN_RESET);
		}else{
				HAL_GPIO_WritePin(MOTOR_EN_GPIO_Port , MOTOR_EN_Pin , GPIO_PIN_SET);
		}
}

/**
  * @brief  电机顺/逆时针旋转
	* @param  参数一:方向,0为顺时针旋转 , 1为逆时针旋转
  * @retval 无
	*	@note 	无
  */
__STATIC_INLINE void Motor_Dir(uint8_t dir)
{
		if(dir)
		{
				HAL_GPIO_WritePin(MOTOR_DIR_GPIO_Port , MOTOR_DIR_Pin , GPIO_PIN_SET);
		}else{
				HAL_GPIO_WritePin(MOTOR_DIR_GPIO_Port , MOTOR_DIR_Pin , GPIO_PIN_RESET);
		}
}


extern motorSpeed_Typedef motorSpeed;
extern motorState_Typedef motorState;

bool Stepper_Move_S(int16_t end_speed , float acc_tim , int32_t step);

#endif

bsp_motor.c

#include "bsp_motor.h"

motorSpeed_Typedef motorSpeed = {0};
motorState_Typedef motorState = {0};

bool Generate_Speed_Table(int32_t vUniform , float accel_tim)
{
		float vMiddle = 0.0f;						//中间点速度
		float k = 0.0f;									//加加速度
		float ti = 0.0f;								//时间间隔 dt
		float sumT = 0.0f;							//时间累加量
		float deltaV = 0.0f;						//速度的增量dv
		float temp = 0.0f;							//中间变量
	
		motorSpeed.vUniform = CONVER(vUniform);
	
		accel_tim /= 2.0f;																				//加加速段的时间(加速度斜率>0的时间)
		vMiddle = motorSpeed.vUniform / 2.0f;											//计算中点的速度
		k = fabsf((2.0f * vMiddle) / (accel_tim * accel_tim));		//根据中点速度计算加加速度
		motorSpeed.incAccelTotalStep = (int32_t)((k * accel_tim * accel_tim * accel_tim) / 6.0f);																   //加加速度需要的步数
		accel_tim *= 2.0f;
		motorSpeed.decAccelTotalStep = (int32_t)(((k * accel_tim * accel_tim * accel_tim) / 6.0f) - motorSpeed.incAccelTotalStep); //减加速度需要的步数
		accel_tim /= 2.0f;
		/* 计算共需要的步数 , 并校验内存大小 , 申请内存空间存放速度表*/
		motorSpeed.accelTotalStep = motorSpeed.decAccelTotalStep + motorSpeed.incAccelTotalStep;																	 //加速需要的步数
		if(motorSpeed.accelTotalStep % 2 != 0)
		{
				motorSpeed.accelTotalStep += 1;
		}                                                                                                     
		if(FORM_LEN < motorSpeed.accelTotalStep)
		{
				printf("FORM_LEN 缓存长度不足\r\n , 请将 FORM_LEN修改为%d\r\n" , motorSpeed.accelTotalStep);
				return false;
		}
		
		ti = pow(6.0f * 1.0f / k , 1.0f / 3.0f);
		sumT += ti;
		deltaV = 0.5f * k * sumT * sumT;
		motorSpeed.Form[0] = deltaV;
		
		if(motorSpeed.Form[0] <= MIN_SPEED)
		{
				motorSpeed.Form[0] = MIN_SPEED;
		}
		for(int i = 1 ; i < motorSpeed.accelTotalStep ; i ++)
		{
				ti = 1.0f / motorSpeed.Form[i - 1];
				if(i < motorSpeed.incAccelTotalStep)
				{
						sumT += ti;
						deltaV = 0.5f *	k * sumT * sumT;
						motorSpeed.Form[i] = deltaV;
						if(i == motorSpeed.incAccelTotalStep - 1)
						{
								sumT = fabsf(sumT - accel_tim);
						}
				}else{
						sumT += ti;
						temp = fabsf(accel_tim - sumT);
						deltaV = 0.5f * k * temp * temp;
						motorSpeed.Form[i] = motorSpeed.vUniform - deltaV;
				}
		}
		return true;
}

/**
  * @brief  速度决策
  * @param  pScurve:S曲线结构体指针
  * @retval 无
	*	@note 	在中断中使用,每进一次中断,决策一次
  */
void Speed_Decision(void)
{
		static uint8_t i = 0;
		static uint32_t index = 0;
		i ++;
		if(i == 2)
		{
				i = 0;
				switch(motorState.state)
				{
						case ACCEL:
												if(motorState.location >= (motorSpeed.accelTotalStep - 1))
												{
														motorState.state = UNIFORM;
														index -= 1;
														break;
												}
												motorState.compare = (uint16_t)(TIM_FREQ / motorSpeed.Form[index] / 2.0f);
												index ++;
						break;
						case DECEL:
												if(motorState.location >= (motorSpeed.totalStep - 1))
												{
														HAL_TIM_OC_Stop_IT(&htim3 , TIM_CHANNEL_1);
														Motor_Turn(MOTOR_DISABLE);
														memset((void*)motorSpeed.Form , 0 , sizeof(float) * FORM_LEN);
														index = 0;
														motorState.state = STOP;
														break;
												}
												motorState.compare = (uint16_t)(TIM_FREQ / motorSpeed.Form[index] / 2.0f);
												index --;
						break;
						case UNIFORM:
												if(motorState.location >= motorSpeed.decLocation)
												{
														motorState.state = DECEL;
												}
						break;		
				}
				motorState.location ++;
		}
		uint32_t tim_count = __HAL_TIM_GET_COUNTER(&htim3);
		uint16_t tmp = tim_count + motorState.compare;
		__HAL_TIM_SET_COMPARE(&htim3 , TIM_CHANNEL_1 , tmp);
}

/**
  * @brief  步进电机S曲线加减速
  * @param  axis:想要控制的轴编号
  * @param  start_speed:启动速度,单位:转/分钟
	* @param  end_speed:目标速度,单位:转/分钟
	* @param  acc_time:加速时间,单位:秒
	* @param  step:运动步数,单位:步(需考虑细分)
  * @retval true:正常
  * @retval false:参数设置错误或速度表空间不足
	*	@note   无
  */
bool Stepper_Move_S(int16_t end_speed , float acc_time , int32_t step)
{
		if(motorState.state != STOP)
		{
				return false;
		}
		if(Generate_Speed_Table(end_speed , acc_time) != true)
		{
				return false;
		}
		if(step < 0)
		{
				step = -step;
				Motor_Dir(MOTOR_CCW);
		}else{
				Motor_Dir(MOTOR_CW);
		}
		
		if(step >= motorSpeed.accelTotalStep * 2)
		{
				motorSpeed.totalStep = step;
				motorSpeed.decLocation = motorSpeed.totalStep - motorSpeed.accelTotalStep;
		}else{
				printf("加减速参数设置错误! \r\n");
				return false;
		}
		memset(&motorState , 0 , sizeof(motorState));
		
		motorState.state = ACCEL;
		motorState.location = 0;
		motorState.compare = (uint16_t)(TIM_FREQ / motorSpeed.Form[0]);
		
		__HAL_TIM_SET_COUNTER(&htim3 , 0);
		__HAL_TIM_SET_COMPARE(&htim3 , TIM_CHANNEL_1 , motorState.compare / 2.0f);
		Motor_Turn(MOTOR_ENABLE);
		HAL_TIM_OC_Start_IT(&htim3 , TIM_CHANNEL_1);
		return true;
}

/**
  * @brief	比较输出中断回调函数
  * @param	NULL;
  * @retval	NULL;
  */

void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
		if(htim -> Instance == TIM3)
		{
				__HAL_TIM_SetCounter(&htim3 , 0);
				Speed_Decision();
		}
}

posted on 2025-10-17 15:22  电子Π  阅读(17)  评论(0)    收藏  举报