我正在为一个学校项目用C编写一个微型(ATmega 328 p)。事情是我试图代表这个真值表(A,B和C只是输入,更具体的按钮)和XOR是LED上的输出,还有其他3个LED,但他们正在做一个不同的门,现在他们工作正常。
我有这个特定的部分问题,因为异或不工作,它应该是关闭时,2按钮按下,但不是。它只是关闭时,所有的按钮都没有按下:
if ( ((BTS & _BV(BT1)) ^ (BTS & _BV(BT2))) || ((BTS & _BV(BT2)) ^ (BTS & _BV(BT3)))) //EXOR
{
LEDS |= _BV(LED2); //Set 1 on LED2
}
else
{
LEDS &= ~_BV(LED2); //Set 0 on LED2
}
我把完整的代码放在这里只是为了参考。
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#define delay 500
//--Tags
//-Inputs
#define BTS PINB
#define BT1 PINB0
#define BT2 PINB1
#define BT3 PINB2
//-Outputs
#define LEDS PORTD
#define LED0 PORTD2
#define LED1 PORTD3
#define LED2 PORTD4
#define LED3 PORTD5
void init_ports(void);
int main(void)
{
init_ports();
while (1)
{
//Output 1
if ((BTS & _BV(BT1)) && (BTS & _BV(BT2)) && (BTS & _BV(BT3))) // AND
{
LEDS |= _BV(LED0); //Set 1 on LED0
}
else
{
LEDS &= ~ _BV(LED0); //Set 0 on LED0
}
//Output 2
if ((BTS & _BV(BT1)) || (BTS & _BV(BT2)) || (BTS & _BV(BT3))) // OR
{
LEDS |= _BV(LED1); //Set 1 on LED1
}
else
{
LEDS &= ~ _BV(LED1); //Set 0 on LED1
}
//Output 3
if ( ((BTS & _BV(BT1)) ^ (BTS & _BV(BT2))) || ((BTS & _BV(BT2)) ^ (BTS & _BV(BT3)))) //EXOR
{
LEDS |= _BV(LED2); //Set 1 on LED2
}
else
{
LEDS &= ~_BV(LED2); //Set 0 on LED2
}
//Output 4
if (!((BTS & _BV(BT1)) && (BTS & _BV(BT2)) && (BTS & _BV(BT3)))) // NOR
{
LEDS |= _BV(LED3); //Set 1 on LED3
}
else
{
LEDS &= ~_BV(LED3); //Set 0 on LED3
}
}
}
void init_ports (void)
{
//--Inputs
DDRB &= ~(_BV(BT1) | _BV(BT2) | _BV(BT3));
//-PULL-UP
PORTB &= ~(_BV(BT1) | _BV(BT2) | _BV(BT3));
//--Outputs
DDRD |= (_BV(LED0) | _BV(LED1) | _BV(LED2) | _BV(LED3));
//-Off
PORTD &= ~(_BV(LED0) | _BV(LED1) | _BV(LED2) | _BV(LED3));
}
有什么可能的想法吗?YOU!!:D
我试着用这个布尔表达式y = A 'B'C + A 'BC' + AB 'C' + ABC
5条答案
按热度按时间flseospp1#
你的标题谈到了三个变量的XOR,
然而,你的真值表:
是不是一个三变量XOR。对于三变量XOR,第6行和第7行的结果应该为零。
真值表表示“B exclusive-or C or A”,如:
uxhixvfz2#
编写一些代码,使用您的布尔表达式构造一个真值表,并将其与赋值中给出的表进行比较。它们匹配吗?如果没有,仔细考虑你得到的真值表,并构造一个匹配的布尔表达式。你也可以在谷歌上搜索卡诺图,它可以帮助你从真值表中构造一个表达式。
ctehm74n3#
注意
这里的 XOR 操作是按位的(不是逻辑的)。
由于两个操作数中都有
bitwise AND
,因此除了左边的位#BT1和右边的位#BT2之外,它们中的每一个都重置了所有位。左侧的位#BT2和右侧的位#BT1为0。这意味着,
^
在这里的工作方式与按位OR完全相同,如果在两个操作数中都设置了这些位,则会产生两个位都设置的结果。可能你想把操作数转换成一些预定义的值。
例如,您可以使用三元运算符
((((BTS & _BV(BT1)) ? 1 : 0) ^ (BTS & _BV(BT2)) ? 1 : 0))
或者你可以通过简单的比较来实现同样的效果:
((((BTS & _BV(BT1)) != 0) ^ ((BTS & _BV(BT2)) != 0))
inb24sb24#
通常我会要求初学者在代码中使用 * 更少 * 的变量。在这种情况下,使用三个中间值可以压缩代码,以便读者可以看到正在发生的事情。
这是一个奇怪的真值表的3路异或。以下内容可能对您有所帮助:
即使是宏标识符,使用前导下划线也是一个坏主意。用不同的东西。
编辑:
如上所述,你在这个问题中提出的真值表很奇怪。
下面进一步压缩代码,以强调您在问题中使用的逻辑运算。用几个
#define
宏代替象形文字代码:编辑2:
在这个问题引起的尖刻批评中,NAND被错误地贴上NOR的标签,到目前为止,还没有引起注意。这就是太多代码的干扰。
下面的代码减少了,读者可以很快满足自己,一切都是有序的。奇真值表的问题仍然没有解决。
8fq7wneg5#
正如支持乌克兰所写的那样,真值表是为了
无论如何,设A、B和C为输入值(0000_0ABC)的位2、1和0
其中0xF6是EXOR列的位掩码(顶行是位0,底行是位7)。