我知道这可能是错误的部分,但我的问题是微控制器编程特定(AVR大多)!
我使用Uart在两个AVR atmega8之间发送字节,其中字节中的每个位代表某些东西,并且在发送的每个字节中只有一个位是1
所以如果我想检查,比如说,接收字节的第5位那么我可以这样写:
short byte=UDR;
if(byte&(1<<5))
{
// do stuff for bit 5
}
那么它总是可以正常工作
但是,如果我这样写:
short byte=UDR;
if(byte==0b00100000)
OR
short byte=UDR;
if(byte==0x20)
然后它不会工作,如果我使用Switch-case而不是if-else,它也会失败我无法理解这个问题,编译器是否将其解释为符号no和第7位作为符号?还是别的什么?编译器是AVR-gnu,来自AVR studio 5
如果有人问我在接收器上也有led显示接收到的字节所以我知道收到的字节是正确的,但由于某种原因,我无法比较它的条件!仍然会有一些噪声导致比特被Uart误解,从而改变实际接收到的字节吗?
帮助!
注意每一个
这里有点像PARANORMAL
我终于解决了这个问题
我添加了8个led来表示接收到的字节,下面是我发现的:
led表示(1<<5)为0b00100000没关系,因为它是我发送的
,
在接收到0b00100000时分配发光的其他led(不包括8个)不发光!
增值的人!
我很确定收到的字节是正确的。但是if-else和切换大小写比较有问题
它不起作用,因为第二个公式改变了代码的含义,而不仅仅是掩码常量的拼写。要测试一个位,您必须对常量应用按位和(&
),而不仅仅是将值与常量进行比较:
if (byte & 0b00100000) /* note: 0b00100000 is a gcc extension */
或:
if (byte & 0x20) /* or byte & 32, or byte & (1 << 5), etc. */
C没有二进制文字的语法,你不能输入0b00100000
并让它编译。
很难理解为什么它不能用于== 0x20
的情况,因为我们不知道UDR
特定于您的平台的值。
如果UDR
设置超过1位,那么精确相等性检查当然会失败,而单位测试会成功。
您只能为每个case
使用具有精确值的switch()
,但是您当然可以在检查之前屏蔽:
switch( byte & 0x20 )
{
case 0:
break;
case 0x20:
break;
}