Files
freertos-STM32F103ZET6/Core/Src/machine.c

333 lines
9.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : machine.c
* @brief : LK540 Machine Stepper Motor Control Implementation
* 步进电机控制模块实现
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "machine.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* 步进脉冲时序参数(微秒) */
#define STEP_PULSE_HIGH_TIME_US 10 /* 脉冲高电平时间 */
#define STEP_PULSE_LOW_TIME_US 10 /* 脉冲低电平时间 */
/* 移动相关参数 */
#define MAX_STEPS_TO_ORIGIN 50000 /* 移动到原点的最大步数(防止无限循环) */
#define STEP_DELAY_US 100 /* 每步之间的延时(微秒) */
/* 各料位相对于原点的距离mm */
#define DISTANCE_TO_MATERIAL1 22.6f /* 215.0 - 192.4 = 22.6mm (向左) */
#define DISTANCE_TO_MATERIAL2 149.6f /* 215.0 - 65.4 = 149.6mm (向左) */
#define DISTANCE_TO_MATERIAL3 153.4f /* 215.0 - 61.6 = 153.4mm (向右) */
#define DISTANCE_TO_MATERIAL4 26.4f /* 215.0 - 188.6 = 26.4mm (向右) */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
static void DelayUs(uint32_t us);
static uint32_t Machine_MmToSteps(float mm);
static uint8_t Machine_MoveSteps(Motor_DirectionTypeDef dir, uint32_t steps);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/**
* @brief 微秒级延时函数
* @param us: 延时时间(微秒)
* @note 基于系统时钟的简单延时72MHz系统时钟下
* 考虑循环开销使用约60个周期/微秒
* @retval None
*/
static void DelayUs(uint32_t us)
{
uint32_t i;
/* 72MHz时钟考虑循环开销约60个周期/微秒 */
for (i = 0; i < us * 60; i++)
{
__NOP();
}
}
/**
* @brief 将毫米距离转换为步数
* @param mm: 距离(毫米)
* @retval 步数
*/
static uint32_t Machine_MmToSteps(float mm)
{
/* 每毫米5.33个脉冲,向上取整 */
return (uint32_t)(mm * MOTOR_PULSE_PER_MM + 0.5f);
}
/**
* @brief 步进电机移动指定步数
* @param dir: 移动方向
* @param steps: 移动步数
* @retval 0: 成功, 1: 失败(到达限位点)
*/
static uint8_t Machine_MoveSteps(Motor_DirectionTypeDef dir, uint32_t steps)
{
uint32_t i;
/* 设置方向 */
Machine_SetDirection(dir);
DelayUs(STEP_DELAY_US);
/* 移动指定步数 */
for (i = 0; i < steps; i++)
{
/* 检查限位传感器 */
if (Machine_IsAtLimit())
{
return 1; /* 到达限位点,返回错误 */
}
/* 移动一步 */
Machine_Step();
DelayUs(STEP_DELAY_US);
}
return 0; /* 成功 */
}
/* USER CODE END 0 */
/* Exported functions --------------------------------------------------------*/
/**
* @brief 检测步进电机是否在原点
* @note PB3状态为0表示检测到步进电机在原点
* @retval 1: 在原点, 0: 不在原点
*/
uint8_t Machine_IsAtOrigin(void)
{
GPIO_PinState pinState;
/* 读取PB3引脚状态 */
pinState = HAL_GPIO_ReadPin(MOTOR_ORIGIN_PIN_PORT, MOTOR_ORIGIN_PIN);
/* PB3为0表示在原点 */
return (pinState == GPIO_PIN_RESET) ? 1 : 0;
}
/**
* @brief 检测步进电机是否在临界点(限位传感器)
* @note PG15状态为0表示检测到步进电机到达临界点不能再前进了
* @retval 1: 在临界点, 0: 不在临界点
*/
uint8_t Machine_IsAtLimit(void)
{
GPIO_PinState pinState;
/* 读取PG15引脚状态 */
pinState = HAL_GPIO_ReadPin(MOTOR_LIMIT_PIN_PORT, MOTOR_LIMIT_PIN);
/* PG15为0表示在临界点 */
return (pinState == GPIO_PIN_RESET) ? 1 : 0;
}
/**
* @brief 设置步进电机方向
* @param dir: 方向
* MOTOR_DIR_CWW (0): 向左移动 (CWW - Counter Clockwise)
* MOTOR_DIR_CW (1): 向右移动 (CW - Clockwise)
* @note PD7为0表示向左1表示向右
* @retval None
*/
void Machine_SetDirection(Motor_DirectionTypeDef dir)
{
GPIO_PinState pinState;
/* 根据方向设置PD7引脚状态 */
pinState = (dir == MOTOR_DIR_CWW) ? GPIO_PIN_RESET : GPIO_PIN_SET;
/* 设置方向引脚 */
HAL_GPIO_WritePin(MOTOR_DIR_PIN_PORT, MOTOR_DIR_PIN, pinState);
}
/**
* @brief 步进电机移动一步
* @note 产生一个脉冲信号,电机移动一步
* 移动1mm需要5.33个脉冲所以一步约等于1/5.33 mm
* 脉冲时序:低->高->低
* @retval None
*/
void Machine_Step(void)
{
/* 确保步进引脚初始为低电平 */
HAL_GPIO_WritePin(MOTOR_STEP_PIN_PORT, MOTOR_STEP_PIN, GPIO_PIN_RESET);
DelayUs(STEP_PULSE_LOW_TIME_US);
/* 产生高电平脉冲 */
HAL_GPIO_WritePin(MOTOR_STEP_PIN_PORT, MOTOR_STEP_PIN, GPIO_PIN_SET);
DelayUs(STEP_PULSE_HIGH_TIME_US);
/* 恢复低电平 */
HAL_GPIO_WritePin(MOTOR_STEP_PIN_PORT, MOTOR_STEP_PIN, GPIO_PIN_RESET);
DelayUs(STEP_PULSE_LOW_TIME_US);
}
/**
* @brief 步进电机移动到原点
* @note 一直向左移动直到检测到原点传感器PB3为0
* 如果检测到限位传感器PG15为0则停止并返回错误
* @retval 0: 成功到达原点, 1: 到达限位点(错误)
*/
uint8_t Machine_MoveToOrigin(void)
{
uint32_t stepCount = 0;
/* 设置方向为向左CWW */
Machine_SetDirection(MOTOR_DIR_CWW);
DelayUs(STEP_DELAY_US);
/* 如果已经在原点,直接返回 */
if (Machine_IsAtOrigin())
{
return 0;
}
/* 一直向左移动直到检测到原点 */
while (!Machine_IsAtOrigin())
{
/* 检查限位传感器 */
if (Machine_IsAtLimit())
{
return 1; /* 到达限位点,返回错误 */
}
/* 防止无限循环 */
if (stepCount++ > MAX_STEPS_TO_ORIGIN)
{
return 1; /* 超时,返回错误 */
}
/* 移动一步 */
Machine_Step();
DelayUs(STEP_DELAY_US);
}
return 0; /* 成功到达原点 */
}
/**
* @brief 步进电机从原点移动到中心点
* @note 中心点就是原点位置215.0mm处)
* 如果已经在原点,则不需要移动
* @retval 0: 成功, 1: 失败
*/
uint8_t Machine_MoveToCenter(void)
{
/* 如果已经在原点(中心点),直接返回成功 */
if (Machine_IsAtOrigin())
{
return 0;
}
/* 否则移动到原点 */
return Machine_MoveToOrigin();
}
/**
* @brief 步进电机从中心点移动到1#料位置
* @note 从原点215.0mm向左移动22.6mm到达1#料192.4mm
* @retval 0: 成功, 1: 失败(到达限位点)
*/
uint8_t Machine_MoveToMaterial1(void)
{
uint32_t steps;
/* 计算需要的步数 */
steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL1);
/* 向左移动 */
return Machine_MoveSteps(MOTOR_DIR_CWW, steps);
}
/**
* @brief 步进电机从中心点移动到2#料位置
* @note 从原点215.0mm向左移动149.6mm到达2#料65.4mm
* @retval 0: 成功, 1: 失败(到达限位点)
*/
uint8_t Machine_MoveToMaterial2(void)
{
uint32_t steps;
/* 计算需要的步数 */
steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL2);
/* 向左移动 */
return Machine_MoveSteps(MOTOR_DIR_CWW, steps);
}
/**
* @brief 步进电机从中心点移动到3#料位置
* @note 从原点215.0mm向右移动153.4mm到达3#料61.6mm
* @retval 0: 成功, 1: 失败(到达限位点)
*/
uint8_t Machine_MoveToMaterial3(void)
{
uint32_t steps;
/* 计算需要的步数 */
steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL3);
/* 向右移动 */
return Machine_MoveSteps(MOTOR_DIR_CW, steps);
}
/**
* @brief 步进电机从中心点移动到4#料位置
* @note 从原点215.0mm向右移动26.4mm到达4#料188.6mm
* @retval 0: 成功, 1: 失败(到达限位点)
*/
uint8_t Machine_MoveToMaterial4(void)
{
uint32_t steps;
/* 计算需要的步数 */
steps = Machine_MmToSteps(DISTANCE_TO_MATERIAL4);
/* 向右移动 */
return Machine_MoveSteps(MOTOR_DIR_CW, steps);
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */