所以我的任务是使用面包板,4个开关,3个LED和一个Arduino制作一个2位加法器。问题在于加法器做了两件冲突的事情(至少在我的代码中),首先是它只打开一个灯(001)打开一个开关,但它还需要计算10+之类的东西00,这只表示一个开关将打开,使得(如我的代码所述)它将最终打开对应于两者的灯而不是仅中间的(010),反之亦然(001)。我知道它与if语句的第一位有关,这里是代码:
int A0Pin = 12;
int A1Pin = 11;
int B0Pin = 10;
int B1Pin = 9;
int LED0Pin = 6;
int LED1Pin = 5;
int LED2Pin = 4;
void setup()
{
pinMode(A0Pin, INPUT);
pinMode(A1Pin, INPUT);
pinMode(B0Pin, INPUT);
pinMode(B1Pin, INPUT);
pinMode(LED0Pin, OUTPUT);
pinMode(LED1Pin, OUTPUT);
pinMode(LED2Pin, OUTPUT);
}
void loop()
{
int b1Value = digitalRead(A0Pin);
int b2Value = digitalRead(A1Pin);
int b3Value = digitalRead(B0Pin);
int b4Value = digitalRead(B1Pin);
digitalWrite(LED0Pin, LOW);
digitalWrite(LED1Pin, LOW);
digitalWrite(LED2Pin, LOW);
if (b1Value == HIGH)
{
digitalWrite(LED0Pin,HIGH);
digitalWrite(LED1Pin,LOW);
digitalWrite(LED2Pin,LOW);
}
if (b2Value == HIGH)
{
digitalWrite(LED0Pin,HIGH);
digitalWrite(LED1Pin,LOW);
digitalWrite(LED2Pin,LOW);
}
if (b3Value == HIGH)
{
digitalWrite(LED0Pin,HIGH);
digitalWrite(LED1Pin,LOW);
digitalWrite(LED2Pin,LOW);
}
if (b4Value == HIGH)
{
digitalWrite(LED0Pin,HIGH);
digitalWrite(LED1Pin,LOW);
digitalWrite(LED2Pin,LOW);
}
if(b1Value == HIGH && b3Value == HIGH )
{
digitalWrite(LED0Pin,LOW);
digitalWrite(LED1Pin,HIGH);
digitalWrite(LED2Pin,LOW);
}
if(b2Value == HIGH && b4Value == HIGH )
{
digitalWrite(LED0Pin,LOW);
digitalWrite(LED1Pin,LOW);
digitalWrite(LED2Pin,HIGH);
}
if(b2Value == HIGH && b3Value == LOW && b4Value == LOW)
{
digitalWrite(LED0Pin,LOW);
digitalWrite(LED1Pin,HIGH);
digitalWrite(LED2Pin,LOW);
}
if(b1Value == LOW && b2Value == LOW && b4Value == HIGH)
{
digitalWrite(LED0Pin,LOW);
digitalWrite(LED1Pin,HIGH);
digitalWrite(LED2Pin,LOW);
}
if(b1Value == HIGH && b2Value == HIGH)
{
digitalWrite(LED0Pin,HIGH);
digitalWrite(LED1Pin,HIGH);
digitalWrite(LED2Pin,LOW);
}
if(b3Value == HIGH && b4Value == HIGH)
{
digitalWrite(LED0Pin,LOW);
digitalWrite(LED1Pin,HIGH);
digitalWrite(LED2Pin,LOW);
}
if(b1Value == HIGH && b2Value == HIGH && b4Value == HIGH)
{
digitalWrite(LED0Pin,LOW);
digitalWrite(LED1Pin,LOW);
digitalWrite(LED2Pin,HIGH);
}
if(b2Value == HIGH && b4Value == HIGH && b2Value == HIGH)
{
digitalWrite(LED0Pin,LOW);
digitalWrite(LED1Pin,LOW);
digitalWrite(LED2Pin,HIGH);
}
if(b1Value == HIGH && b2Value == HIGH && b3Value == HIGH)
{
digitalWrite(LED0Pin,HIGH);
digitalWrite(LED1Pin,LOW);
digitalWrite(LED2Pin,HIGH);
}
if(b3Value == HIGH && b4Value == HIGH && b1Value == HIGH)
{
digitalWrite(LED0Pin,HIGH);
digitalWrite(LED1Pin,LOW);
digitalWrite(LED2Pin,HIGH);
}
if(b1Value == HIGH && b2Value ==
HIGH && b3Value == HIGH && b4Value == HIGH)
{
digitalWrite(LED0Pin,LOW);
digitalWrite(LED1Pin,HIGH);
digitalWrite(LED2Pin,HIGH);
}
delay(10);
}
请原谅缺乏优化(可以在我弄清楚灯光问题之后),任何有关优化的帮助也会非常感激,但是现在我只需要帮助制作它以便像01+这样的东西00不要因为只有一个开关打开而感到困惑,导致两个灯都打开或只打开一个,但不正确。我是在Tinkercad上做的:
电路图:
01 + 01 = 010
第一次开启(01 + 00 = 001)
只是第二次开启,但被误解为10 + 00 = 010(反之亦然)
答案 0 :(得分:2)
嗯,首先:有比你选择的更好的方法。但是,这个答案将坚持你的方法并解释你的代码失败的原因。
据我所知,你的方法背后的想法是:
1)覆盖没有输入为高电平的情况(即通过转动所有LED启动)。 1例。
2)覆盖恰好1输入高的情况。 4例。
3)覆盖恰好2个输入高的情况。 6例。
4)覆盖正好3个输入高的情况。 4例。
5)覆盖所有4个输入都很高的情况。 1例。
该方法将起作用,因为步骤5优先于步骤4,步骤4优先于步骤3,依此类推。也就是说,即使您在例如步骤4,它将在步骤5中更正(如果所有输入均为高电平)。
你的代码出了什么问题?
问题是您没有涵盖所有情况。例如,您永远不会将b1
和b4
都视为高。
此外你还有一个拼写错误:
if(b2Value == HIGH && b4Value == HIGH && b2Value == HIGH)
^^^ ^^^
此外,您的代码永远不会像在此处一样检查LOW:
if(b2Value == HIGH && b3Value == LOW && b4Value == LOW)
LOW值由if语句的优先级隐式处理。
总的来说,你必须有初始化加上15个if语句。
所以你的代码应该是:
// Handle 1 case with no input high
digitalWrite(LED0Pin, LOW);
digitalWrite(LED1Pin, LOW);
digitalWrite(LED2Pin, LOW);
// Handle 4 cases with exactly 1 input being high
if (b1Value == HIGH)
{
...
}
else if (b2Value == HIGH)
{
...
}
else if (b3Value == HIGH)
{
...
}
else if (b4Value == HIGH)
{
...
}
// Handle 6 cases with exactly 2 input being high
if(b1Value == HIGH && b2Value == HIGH )
{
...
}
else if(b1Value == HIGH && b3Value == HIGH )
{
...
}
else if(b1Value == HIGH && b4Value == HIGH)
{
...
}
else if(b2Value == HIGH && b3Value == HIGH)
{
...
}
else if(b2Value == HIGH && b4Value == HIGH)
{
...
}
else if(b3Value == HIGH && b4Value == HIGH)
{
...
}
// Handle 4 cases with exactly 3 input being high
if(b1Value == HIGH && b2Value == HIGH && b3Value == HIGH)
{
...
}
else if(b1Value == HIGH && b2Value == HIGH && b4Value == HIGH)
{
...
}
else if(b1Value == HIGH && b3Value == HIGH && b4Value == HIGH)
{
...
}
else if(b2Value == HIGH && b3Value == HIGH && b4Value == HIGH)
{
...
}
// Handle 1 cases with exactly 4 input being high
if(b1Value == HIGH && b2Value == HIGH && b3Value == HIGH && b4Value == HIGH)
{
...
}
以上解释了为什么您的代码无法正常工作以及如何修复它。
但是你可以看到这种方法非常容易出错(即很容易错过一个案例)。除此之外,它还有糟糕的表现。所以我建议采用更简单的方法。
int temp = 2 * digitalRead(A1Pin) +
digitalRead(A0Pin) +
2 * digitalRead(B1Pin) +
digitalRead(B0Pin);
output0 = (temp & 1) == 1;
output1 = (temp & 2) == 2;
output2 = (temp & 4) == 4;
答案 1 :(得分:1)
这些引脚标记得很好:A1Pin
,A0Pin
等。变量名称应遵循相同的惯例:a1Value
,a0Value
等。这将使if
语句更易于理解。
然后你需要系统地了解if
陈述。有4个输入,有16种可能的组合,每个都需要if
语句。每个if
语句都应检查每个输入值。
所以前两个if
语句是
if (a1Value == LOW && a0Value == LOW && b1Value == LOW && b0Value == LOW)
{
digitalWrite(LED0Pin,LOW); // 0 + 0 = 0
digitalWrite(LED1Pin,LOW);
digitalWrite(LED2Pin,LOW);
}
else if a1Value == LOW && a0Value == LOW && b1Value == LOW && b0Value == HIGH)
{
digitalWrite(LED0Pin,HIGH); // 0 + 1 = 1
digitalWrite(LED1Pin,LOW);
digitalWrite(LED2Pin,LOW);
}
和最后一个if
语句是
else if (a1Value == HIGH && a0Value == HIGH && b1Value == HIGH && b0Value == HIGH)
{
digitalWrite(LED0Pin,LOW); // 3 + 3 = 6
digitalWrite(LED1Pin,HIGH);
digitalWrite(LED2Pin,HIGH);
}
还有13个要去。
现在当然还有其他方法可以做到这一点,但我想我会帮助你完成你的开始。
让代码正常工作后,您可以将其发布到code review,然后就如何优化代码提供各种建议。
答案 2 :(得分:1)
根据Yunnosch评论这是他的意思,你可以预先计算加法的价值,然后将其显示给LED,这大大简化了代码 下面的代码应该起作用 - 或者至少作为指导 我在一个例子中评论了你理解逻辑,希望它有所帮助
注意:因为我不在Arduino的前面这个代码没有经过测试 - 但它确实编译了
int A0Pin = 12;
int A1Pin = 11;
int B0Pin = 10;
int B1Pin = 9;
int LED0Pin = 6;
int LED1Pin = 5;
int LED2Pin = 4;
void setup()
{
pinMode(A0Pin, INPUT);
pinMode(A1Pin, INPUT);
pinMode(B0Pin, INPUT);
pinMode(B1Pin, INPUT);
pinMode(LED0Pin, OUTPUT);
pinMode(LED1Pin, OUTPUT);
pinMode(LED2Pin, OUTPUT);
}
void loop()
{
int b1Value = digitalRead(A0Pin);
int b2Value = digitalRead(A1Pin);
int b3Value = digitalRead(B0Pin);
int b4Value = digitalRead(B1Pin);
// b1 is set to represent 1 and b2 will represent 2 same with b3 and b4 pair
// lets assume b1 = 1 b2 = 0 the number is 1
// b3 is set to 1 and b4 is set to 1
// input : b2|b1 + b4|b3
// 0| 1 1| 1
// sum = 1*1 + 0*2 + 1*1 + 1*2 = 4 - which is represented in binary as b100
int sum = (b1Value * 1) + (b2Value * 2) + (b3Value * 1) + (b4Value * 2);
if (sum & 0x1) //binary rep b001 - following the example will result in 0
digitalWrite(LED0Pin, HIGH);
else
digitalWrite(LED0Pin, LOW);
if (sum & 0x2) //binary rep b010 - following the example will result in 0
digitalWrite(LED1Pin, HIGH);
else
digitalWrite(LED1Pin, LOW);
if (sum & 0x4) //binary rep b100 - following the example will result in 1
digitalWrite(LED2Pin, HIGH);
else
digitalWrite(LED2Pin, LOW);
delay(10);
}
答案 3 :(得分:1)
这取决于您是否负责模拟完整加法器或模拟完整加法器。如果您正在仿真一个,您可以使用这些引脚(至少对于大多数变体)分配给AVR端口的事实。
void loop() {
int a = (PORTB >> 3) & 3; // take the two 'A' bits from the input port and make a number between 0 and 3
int b = (PORTB >> 1) & 3; // likewise for 'B'
PORTD = ( a + b ) << 4; // add them together and shift to light the LEDs
}
如果我没有7482并希望效仿,那么我该怎么做。
如果目标是通过组合逻辑来演示如何创建完整加法器,那么使用半加法器逻辑sum = a xor b
和carry = a and b
以及全加法逻辑sum = ( a xor b ) xor c
来创建它。
carry = ( a and b ) or ( c and ( a xor b ) )
。
void loop() {
// input a as two separate bits
bool a0 = digitalRead(A0Pin);
bool a1 = digitalRead(A1Pin);
// input b as two separate bits
bool b0 = digitalRead(B0Pin);
bool b1 = digitalRead(B1Pin);
// half adder for digit 0 of output sum and carry
bool s0 = a0 ^ b0;
bool c0 = a0 & b0;
// full adder for digit 1 of output sum and carry
bool s1 = (a1 ^ b1) ^ c0;
bool c1 = (a1 & b1) | (c0 & (a1 ^ b1));
digitalWrite(LED0Pin, s0);
digitalWrite(LED1Pin, s1);
digitalWrite(LED2Pin, c1); // digit2 of output will be carry from digit 1
}
这里的不同之处在于它显示了工作,并告诉教师您已经理解了加法器的用途,而不仅仅是将真值表转换为一组if语句。对于两位加法器,您可能会使用它,但是您不想手动写出所有可能的输入和输出,例如,一个8位加法器。