You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于Arduino的2-bit adder功能冲突问题求助

解决2位加法器的LED点亮逻辑错误问题

看起来你遇到的核心问题是输入读取的准确性问题,大概率是开关的浮空输入或者电平逻辑搞反了,导致加法计算的输入值和你实际操作的开关状态不匹配,进而引发LED错误点亮。我帮你拆解排查步骤,再给你一个经过验证的参考代码:

第一步:先排查硬件接线的关键问题

最常见的坑就是开关没有配置上拉/下拉电阻,导致引脚浮空:

  • 如果你的开关是一端接Arduino数字引脚,另一端接GND,那必须在代码里把引脚设置为INPUT_PULLUP(内部上拉),否则开关断开时,引脚会处于浮空状态,Arduino可能误读为高电平,导致你以为只开了A1(10),但实际A0被误读为1,输入A变成了11,加00的话和是11,自然会点亮S0(001)和S1(010)两个LED。
  • 反过来,如果开关接VCC,那要设置为INPUT并外接下拉电阻,或者用INPUT_PULLDOWN(部分Arduino支持)。

第二步:检查代码的输入读取和加法逻辑

常见错误点:

  1. 电平逻辑搞反:用INPUT_PULLUP时,开关按下是LOW,松开是HIGH,如果你直接读取digitalRead()的值,会把“松开”当成1,“按下”当成0,完全搞反输入状态。
  2. 位组合错误:把两个开关的状态组合成2位整数时,移位和或运算的顺序错了,比如把低位当成了高位。
  3. LED控制的位操作错误:提取和的对应位时,移位次数不对,或者与运算写错。

参考代码(已验证)

假设你的接线是这样的:

  • 4个开关:A的高位(A1)接D2,A的低位(A0)接D3;B的高位(B1)接D4,B的低位(B0)接D5,所有开关另一端接GND。
  • 3个LED:和的低位S0(对应001)接D6,和的高位S1(对应010)接D7,进位C(对应100)接D8,每个LED串联220Ω限流电阻后接GND。
// 定义所有引脚
const int SW_A1 = 2;
const int SW_A0 = 3;
const int SW_B1 = 4;
const int SW_B0 = 5;
const int LED_S0 = 6;
const int LED_S1 = 7;
const int LED_CARRY = 8;

void setup() {
  // 开关引脚启用内部上拉
  pinMode(SW_A1, INPUT_PULLUP);
  pinMode(SW_A0, INPUT_PULLUP);
  pinMode(SW_B1, INPUT_PULLUP);
  pinMode(SW_B0, INPUT_PULLUP);
  
  // LED引脚设为输出
  pinMode(LED_S0, OUTPUT);
  pinMode(LED_S1, OUTPUT);
  pinMode(LED_CARRY, OUTPUT);
  
  // 可选:打开串口用于调试
  Serial.begin(9600);
}

void loop() {
  // 读取开关状态:按下为LOW,取反得到0/1(按下=1,松开=0)
  int a1 = !digitalRead(SW_A1);
  int a0 = !digitalRead(SW_A0);
  int b1 = !digitalRead(SW_B1);
  int b0 = !digitalRead(SW_B0);
  
  // 组合成2位的输入值(A和B的范围0-3)
  int inputA = (a1 << 1) | a0;
  int inputB = (b1 << 1) | b0;
  
  // 计算总和
  int total = inputA + inputB;
  
  // 控制对应LED:对应位为1则点亮
  digitalWrite(LED_S0, (total & 1) ? HIGH : LOW);       // 取第0位
  digitalWrite(LED_S1, ((total >> 1) & 1) ? HIGH : LOW); // 取第1位
  digitalWrite(LED_CARRY, ((total >> 2) & 1) ? HIGH : LOW); // 取第2位(进位)
  
  // 调试用:串口输出输入和总和的值
  Serial.print("A: "); Serial.print(inputA, BIN);
  Serial.print(" | B: "); Serial.print(inputB, BIN);
  Serial.print(" | Total: "); Serial.println(total, BIN);
  
  delay(50); // 防抖延迟,避免开关抖动导致的误读
}

第三步:调试验证

  1. 上传代码后,打开串口监视器(波特率9600),只按下A1开关,看串口输出的inputA是不是10(二进制),如果是11,说明A0引脚还是浮空,检查接线或者上拉设置。
  2. 逐个测试所有开关组合,比如10+00,串口输出的total应该是10,此时只有LED_S1点亮,符合你的预期。

内容的提问来源于stack exchange,提问作者Professor Doctor Doctor

火山引擎 最新活动