#!/usr/bin/env python # -*- coding: utf-8 -*- """ # @Time : 2026/1/4 15:06 # @Author : reenrr # @File : stepper_motor_test.py # @Desc : 线条厂控制步进电机 """ import time from periphery import GPIO import sys sys.setswitchinterval(0.000001) # 减小线程切换间隔 # -------------- # 硬件参数配置(必须与你的设备匹配!) # -------------- # 1. 脉冲(PUL)引脚配置 → GPIO32 PUL_Pin = 32 # 2. 方向(DIR)引脚配置 → GPIO33 DIR_Pin = 33 # 3. LCDA257C驱动器核心参数(关键!与拨码/软件设置一致) PULSES_PER_ROUND = 400 # 每圈脉冲数(按驱动器细分拨码调整) PULSE_FREQUENCY = 5000 # 初始测试频率(建议从500开始逐步调高) # 4. LCDA257C时序参数(遵循手册要求,不可低于最小值) MIN_DIR_DELAY_US = 10 # DIR提前PUL的最小延迟(>8us) PULSE_LOW_MIN_US = 2 # 脉冲低电平最小宽度(≥2us) PULSE_HIGH_MIN_US = 2 # 脉冲高电平最小宽度(≥2us) # 5. 方向电平定义(可根据实际测试调整) CLOCKWISE_LEVEL = True # 顺时针→DIR高电平 COUNTER_CLOCKWISE_LEVEL = False # 逆时针→DIR低电平 def init_stepper() -> tuple[GPIO, GPIO]: """初始化PUL和DIR引脚(输出模式,适配LCDA257C)""" try: # 初始化脉冲引脚(输出模式) pul_gpio = GPIO(PUL_Pin, "out") # 初始化方向引脚(输出模式) dir_gpio = GPIO(DIR_Pin, "out") # 初始状态:脉冲低电平,方向低电平(驱动器空闲状态) pul_gpio.write(False) dir_gpio.write(False) print(f"✅ PUL引脚初始化完成:{PUL_Pin}引脚") print(f"✅ DIR引脚初始化完成:{DIR_Pin}引脚") return pul_gpio, dir_gpio except FileNotFoundError: raise RuntimeError(f"GPIO芯片不存在!检查 {PUL_Pin} 是否存在(命令:ls /dev/gpiochip*)") except PermissionError: raise RuntimeError("GPIO权限不足!请用 sudo 运行程序(sudo python test.py)") except Exception as e: raise RuntimeError(f"GPIO初始化失败:{str(e)}") from e def rotate(pul_gpio: GPIO, dir_gpio: GPIO, rounds: float, direction: str = "clockwise", test_freq: int = PULSE_FREQUENCY): """ 控制LCDA257C驱动器旋转(优化版脉冲发送,解决频率不生效问题) :param pul_gpio: PUL引脚GPIO对象 :param dir_gpio: DIR引脚GPIO对象 :param rounds: 旋转圈数(正数,可小数) :param direction: 方向(clockwise/counterclockwise) :param test_freq: 本次旋转使用的脉冲频率(覆盖全局默认值) """ # 1. 参数合法性校验 if rounds <= 0: print("❌ 圈数必须为正数!") return if test_freq < 100: print("❌ 频率过低(≥100Hz),请调整test_freq参数!") return # 2. 设置旋转方向(严格遵循DIR提前时序) if direction == "clockwise": dir_gpio.write(CLOCKWISE_LEVEL) print(f"\n=== 顺时针旋转 {rounds} 圈(目标频率:{test_freq}Hz)===") elif direction == "counterclockwise": dir_gpio.write(COUNTER_CLOCKWISE_LEVEL) print(f"\n=== 逆时针旋转 {rounds} 圈(目标频率:{test_freq}Hz)===") else: print("❌ 方向参数错误!仅支持 clockwise/counterclockwise") return # DIR电平设置后,延迟≥8us(满足LCDA257C时序要求) time.sleep(MIN_DIR_DELAY_US / 1_000_000) # 3. 计算脉冲参数(确保高低电平≥最小宽度) total_pulses = int(rounds * PULSES_PER_ROUND) pulse_period = 1.0 / test_freq # 脉冲周期(秒) # 确保高低电平宽度不低于驱动器要求(避免脉冲识别失败) high_period = max(pulse_period / 2, PULSE_HIGH_MIN_US / 1_000_000) low_period = max(pulse_period / 2, PULSE_LOW_MIN_US / 1_000_000) # 打印参数(便于调试) print(f"总脉冲数:{total_pulses} | 理论高电平:{high_period * 1e6:.1f}us | 理论低电平:{low_period * 1e6:.1f}us") # 4. 优化版脉冲发送(解决Python高频延时不准问题) start_total = time.perf_counter() # 高精度计时(统计实际频率) for _ in range(total_pulses): # 高电平(直接sleep,避免while循环的调度延迟) pul_gpio.write(True) time.sleep(high_period) # 低电平 pul_gpio.write(False) time.sleep(low_period) end_total = time.perf_counter() # 5. 计算实际频率(验证是否达到目标) actual_duration = end_total - start_total actual_freq = total_pulses / actual_duration if actual_duration > 0 else 0 print(f"✅ 旋转完成 | 实际频率:{actual_freq:.0f}Hz | 耗时:{actual_duration:.2f}秒") def motor_test_demo(): """电机测试示例(逐步提升频率,验证转速变化)""" pul_gpio = None dir_gpio = None try: # 初始化引脚 pul_gpio, dir_gpio = init_stepper() print("\n=== 步进电机频率测试程序启动 ===") while True: print(f"\n===== 测试频率:{PULSE_FREQUENCY}Hz =====") # 远离电机方向 顺时针 rotate(pul_gpio, dir_gpio, rounds=10.0, direction="clockwise") time.sleep(5) # # 靠近电机方向 逆时针 rotate(pul_gpio, dir_gpio, rounds=10.0, direction="counterclockwise") time.sleep(5) # except Exception as e: print(f"\n❌ 程序异常:{str(e)}") finally: # 安全释放GPIO资源(必须执行,避免引脚电平残留) if pul_gpio: pul_gpio.write(False) pul_gpio.close() print("\n✅ PUL引脚已关闭(低电平)") if dir_gpio: dir_gpio.write(False) dir_gpio.close() print("✅ DIR引脚已关闭(低电平)") print("✅ 程序退出完成") if __name__ == '__main__': # 运行测试demo(必须sudo执行) motor_test_demo()