增加读取寄存器状态和控制步进电机功能

This commit is contained in:
yankun
2026-02-06 17:12:14 +08:00
parent eaa1427f9f
commit 04936f22cf
4 changed files with 868 additions and 384 deletions

136
Core/Inc/machine.h Normal file
View File

@@ -0,0 +1,136 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : machine.h
* @brief : LK540 Machine Stepper Motor Control Header
* 步进电机控制模块头文件
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
******************************************************************************
*/
/* USER CODE END Header */
#ifndef __MACHINE_H
#define __MACHINE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Exported types ------------------------------------------------------------*/
/**
* @brief 步进电机方向枚举
*/
typedef enum
{
MOTOR_DIR_CWW = 0, /* 向左移动 (Counter Clockwise) */
MOTOR_DIR_CW = 1 /* 向右移动 (Clockwise) */
} Motor_DirectionTypeDef;
/* Exported constants --------------------------------------------------------*/
/* 电机参数定义 */
#define MOTOR_PULSE_PER_MM 5.33f /* 每毫米脉冲数 */
#define MOTOR_ORIGIN_DISTANCE 215.0f /* 原点距离 (mm) */
#define MOTOR_MATERIAL1_DISTANCE 192.4f /* 1#料距离 (mm) */
#define MOTOR_MATERIAL2_DISTANCE 65.4f /* 2#料距离 (mm) */
#define MOTOR_MATERIAL3_DISTANCE 61.6f /* 3#料距离 (mm) */
#define MOTOR_MATERIAL4_DISTANCE 188.6f /* 4#料距离 (mm) */
/* GPIO引脚定义 */
#define MOTOR_ORIGIN_PIN_PORT GPIOB
#define MOTOR_ORIGIN_PIN GPIO_PIN_3
#define MOTOR_LIMIT_PIN_PORT GPIOG
#define MOTOR_LIMIT_PIN GPIO_PIN_15
#define MOTOR_DIR_PIN_PORT GPIOD
#define MOTOR_DIR_PIN GPIO_PIN_7
#define MOTOR_STEP_PIN_PORT GPIOG
#define MOTOR_STEP_PIN GPIO_PIN_9
/* Exported macro ------------------------------------------------------------*/
/* Exported functions prototypes ---------------------------------------------*/
/**
* @brief 检测步进电机是否在原点
* @retval 1: 在原点, 0: 不在原点
*/
uint8_t Machine_IsAtOrigin(void);
/**
* @brief 检测步进电机是否在临界点(限位传感器)
* @retval 1: 在临界点, 0: 不在临界点
*/
uint8_t Machine_IsAtLimit(void);
/**
* @brief 设置步进电机方向
* @param dir: 方向 (MOTOR_DIR_CWW: 向左, MOTOR_DIR_CW: 向右)
* @retval None
*/
void Machine_SetDirection(Motor_DirectionTypeDef dir);
/**
* @brief 步进电机移动一步
* @note 产生一个脉冲信号电机移动一步1/5.33 mm
* @retval None
*/
void Machine_Step(void);
/**
* @brief 步进电机移动到原点
* @note 一直向左移动直到检测到原点传感器PB3为0
* 如果检测到限位传感器PG15为0则停止并返回错误
* @retval 0: 成功到达原点, 1: 到达限位点(错误)
*/
uint8_t Machine_MoveToOrigin(void);
/**
* @brief 步进电机从原点移动到中心点
* @note 中心点就是原点位置215.0mm处)
* 如果已经在原点,则不需要移动
* @retval 0: 成功, 1: 失败
*/
uint8_t Machine_MoveToCenter(void);
/**
* @brief 步进电机从中心点移动到1#料位置
* @note 从原点215.0mm向左移动22.6mm到达1#料192.4mm
* @retval 0: 成功, 1: 失败(到达限位点)
*/
uint8_t Machine_MoveToMaterial1(void);
/**
* @brief 步进电机从中心点移动到2#料位置
* @note 从原点215.0mm向左移动149.6mm到达2#料65.4mm
* @retval 0: 成功, 1: 失败(到达限位点)
*/
uint8_t Machine_MoveToMaterial2(void);
/**
* @brief 步进电机从中心点移动到3#料位置
* @note 从原点215.0mm向右移动153.4mm到达3#料61.6mm
* @retval 0: 成功, 1: 失败(到达限位点)
*/
uint8_t Machine_MoveToMaterial3(void);
/**
* @brief 步进电机从中心点移动到4#料位置
* @note 从原点215.0mm向右移动26.4mm到达4#料188.6mm
* @retval 0: 成功, 1: 失败(到达限位点)
*/
uint8_t Machine_MoveToMaterial4(void);
#ifdef __cplusplus
}
#endif
#endif /* __MACHINE_H */

View File

@@ -31,7 +31,7 @@ extern "C" {
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
#include "machine.h"
/* USER CODE END Includes */ /* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/ /* Exported types ------------------------------------------------------------*/

332
Core/Src/machine.c Normal file
View File

@@ -0,0 +1,332 @@
/* 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 */

View File

@@ -97,6 +97,22 @@ int main(void)
MX_GPIO_Init(); MX_GPIO_Init();
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */
/* 上电后步进电机初始化:从任何位置移动到原点 */
/* Power-on initialization: Move stepper motor to origin from any position */
if (Machine_MoveToOrigin() == 0)
{
/* 成功到达原点,移动到中心点(中心点就是原点位置) */
/* Successfully reached origin, move to center (center is the origin position) */
Machine_MoveToCenter();
}
else
{
/* 移动到原点失败,可能是到达限位点或超时 */
/* Failed to move to origin, may have reached limit or timeout */
/* 这里可以添加错误处理例如LED闪烁或蜂鸣器报警 */
/* Error handling can be added here, such as LED blinking or buzzer alarm */
}
/* USER CODE END 2 */ /* USER CODE END 2 */
/* Init scheduler */ /* Init scheduler */