Arduino UNO 5x7 LED矩阵乒乓球游戏Y轴弹跳异常求助
Arduino UNO 5x7 LED矩阵乒乓球游戏Y轴弹跳异常排查求助
我正在做基于Arduino UNO的5x7 LED矩阵乒乓球游戏课程项目,X轴弹跳功能正常,但Y轴存在异常:当ballPosY的值为B0111111时,switch语句无法识别该值,导致ballDirY无法切换方向。我试过替换switch为if、交换case顺序、用延迟替代异步逻辑、用十进制或0b前缀表示二进制值等方法,都没解决。LED矩阵对应行能收到信号,说明ballPosY确实等于B0111111,但方向切换逻辑失效,求帮忙排查。
问题代码
long prevMoveTime = millis(), currentMoveTime; // Variables for asynchronous drawBall method. int ballPosX = B00100, ballPosY = B1110111; // X & Y positions of the ball with their initial values. bool ballDirX = true, ballDirY = true; // Direction on the ball (true = left/up, false = right/down). void setup() { for (int i = 0; i <= 13; i++) { pinMode(i, OUTPUT); } PORTB = ballPosX; PORTD = ballPosY; } void drawBall() { currentMoveTime = millis(); switch (ballPosX) { case B10000: ballDirX = true; break; case B00001: ballDirX = false; break; } switch (ballPosY) { case B0111111: ballDirY = true; break; case B1111110: ballDirY = false; break; } if (currentMoveTime - prevMoveTime > 1000) { if (ballDirX) { ballPosX >>= 1; } else { ballPosX <<= 1; } PORTB = ballPosX; if (ballDirY) { ballPosY >>= 1; ballPosY |= B1000000; } else { ballPosY <<= 1; ballPosY |= B0000001; } PORTD = ballPosY; prevMoveTime = currentMoveTime; } } void loop() { drawBall(); }
问题根源
ballPosY被定义为int类型,Arduino的int是16位有符号整数。当执行右移操作时,有符号数会保留符号位,导致ballPosY的高位被填充1,最终存储的是16位数值(比如你预期的B0111111实际可能是0xFFBF,对应十进制-65),和case中B0111111(十进制63)的8位无符号值不相等,因此switch无法匹配。
修复方案
- 修改变量类型:将
ballPosX和ballPosY改为byte类型(8位无符号整数),避免符号位扩展干扰。 - 保持原有逻辑不变,仅调整变量类型即可解决匹配问题。
修改后的代码
long prevMoveTime = millis(), currentMoveTime; byte ballPosX = B00100, ballPosY = B1110111; bool ballDirX = true, ballDirY = true; void setup() { for (int i = 0; i <= 13; i++) { pinMode(i, OUTPUT); } PORTB = ballPosX; PORTD = ballPosY; } void drawBall() { currentMoveTime = millis(); switch (ballPosX) { case B10000: ballDirX = true; break; case B00001: ballDirX = false; break; } switch (ballPosY) { case B0111111: ballDirY = true; break; case B1111110: ballDirY = false; break; } if (currentMoveTime - prevMoveTime > 1000) { if (ballDirX) { ballPosX >>= 1; } else { ballPosX <<= 1; } PORTB = ballPosX; if (ballDirY) { ballPosY >>= 1; ballPosY |= B1000000; } else { ballPosY <<= 1; ballPosY |= B0000001; } PORTD = ballPosY; prevMoveTime = currentMoveTime; } } void loop() { drawBall(); }
内容的提问来源于stack exchange,提问作者TheKillerAxe
相关产品推荐
相关产品推荐

