You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于28BYJ-48电机驱动代码中位运算(0x99>>j)&(0x80>>i)的疑问

28BYJ-48电机驱动代码的位运算解析与改写问题排查

问题背景

研究位运算后找到一段能驱动28BYJ-48 5V电机的Python代码(唯一可用的Python驱动代码),但自行改写的代码无法运行,存在两个困惑:

  • 代码中(0x99>>j)&(0x08>>i)的位运算逻辑,曾误以为>>是左移位,理解存疑;
  • 改写后的分步代码为何无法生效。
    已查阅位运算资料和讲解视频,仍搞不懂十六进制值的移位运算,也不清楚自写代码失效原因,请求解答。

有效代码

import RPi.GPIO as GPIO
from time import sleep

#configuring pins and motors
motorPin = (18,23,24,25)     #GPIO pin in BCM mode refer to map
rolePerMinute =13
stepsPerRevolution = 2048
stepSpeed = (60/rolePerMinute)/stepsPerRevolution


#setup the pins to the motor
def setup():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)

    for i in motorPin:
        GPIO.setup(i, GPIO.OUT)

def rotary1():
    n =1
    while n < 10000:
        for j in range(4):
            for i in range(4):
                GPIO.output(motorPin[i],0x99>>j & (0x08>>i))
            sleep(stepSpeed)
            n +=1

自行改写的代码

import RPi.GPIO as GPIO
from time import sleep

#configuring pins and motors
motorPin = (18,23,24,25)     #GPIO pin in BCM mode refer to map
rolePerMinute =13
stepsPerRevolution = 2048
stepSpeed = (60/rolePerMinute)/stepsPerRevolution


#setup the pins to the motor
def setup():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)

    for i in motorPin:
        GPIO.setup(i, GPIO.OUT)

def rotary():
    n = 1
    while n < 10000:

        GPIO.output(18,0x99>>1 & (0x08>>1))
        sleep(stepSpeed)
        GPIO.output(23,0x99>>2 & (0x08>>2))
        sleep(stepSpeed)
        GPIO.output(24,0x99>>3 & (0x08>>3))
        sleep(stepSpeed)
        GPIO.output(25,0x99>>4 & (0x08>>4))
        sleep(stepSpeed)
        n+= 1

一、位运算逻辑解析

首先明确:>>是右移位运算符,左移位是<<。右移位会把二进制数的每一位向右移动指定位数,左侧补0,右侧超出的位直接丢弃。

先把代码里的十六进制转成二进制,方便理解:

  • 0x99 = 二进制10011001(8位)
  • 0x08 = 二进制00001000(8位)

代码里的双层循环:

  • 外层j从0到3:控制0x99的右移位数,对应步进电机的每一步驱动状态
  • 内层i从0到3:控制0x08的右移位数,对应四个GPIO引脚的电平设置

按位与&运算的规则是:对应位都为1时结果为1,否则为0。非零值在GPIO输出中代表高电平,0代表低电平。

举几个具体例子:

  • 当j=0、i=0:0x99>>0 = 10011001,0x08>>0 = 00001000,按位与结果为00001000(非零)→ 对应引脚输出高电平
  • 当j=0、i=1:0x08>>1 = 00000100,和10011001按位与结果为00000000→ 对应引脚输出低电平
  • 当j=1:0x99>>1 = 01001100,再和不同i移位后的0x08做与运算,就能生成下一步的四个引脚电平组合

这段逻辑的本质是用0x99的二进制位序列,生成28BYJ-48需要的四相步进驱动时序——单极四相步进电机需要四个绕组按特定顺序通断电,才能完成步进动作。


二、改写代码失效的原因

你的代码和原代码的核心逻辑完全不符,问题集中在三点:

  1. 驱动时序错误:原代码是先一次性设置完四个引脚的电平(内层i循环),再等待stepSpeed完成一步;而你是设置一个引脚就延迟一次,相当于每个引脚的电平变化不同步,完全不符合步进电机的驱动要求——步进电机需要四个绕组的电平同步切换(或按固定时序同时更新),才能带动转子转动。
  2. 移位参数错误:原代码中j和i的取值范围都是0-3,但你用了1-4,移位后的二进制值完全偏离原有的驱动序列。比如0x99>>4是00001001,0x08>>4是00000001,按位与的结果和原代码的驱动电平完全不匹配。
  3. 循环逻辑错误:原代码中每完成4步(j循环一次),n才加1;而你的代码每次while循环只做了一轮四个引脚的逐个输出就加1,步进的步数和时序完全混乱,电机无法识别正确的驱动信号。

如果要改写,必须保留原代码的时序逻辑:先同步设置四个引脚的电平,再进行延迟。比如可以把四个引脚的电平提前计算好,再批量设置,或者用循环完成四个引脚的电平设置后再sleep。

内容的提问来源于stack exchange,提问作者Michael Silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 14:45:34