我可以使用逻辑运算符进行十六进制比较吗?

时间:2019-04-10 08:14:25

标签: c embedded

我需要将PORTC设置为通过一堆if语句修改的临时变量,但是分配给PORTC的位序列在最后都为零,因此我假设if语句中的所有表达式均未求值为true时,我测试位序列是否小于或等于十六进制。

#include <avr/io.h>

unsigned char GetBit(unsigned char x, unsigned char k) {
    return ((x & (0x01 << k)) != 0);
}

unsigned char SetBit(unsigned char x, unsigned char k, unsigned char b) {
    return (b ? x | (0x01 << k) : x & ~(0x01 << k));
}


int main(void)
{
    /* Replace with your application code */
    DDRA = 0x00; PORTA = 0x0F; 
    DDRC = 0xFF; PORTC = 0x00;
    unsigned char tmpa = 0x00;
    unsigned char tmpc = 0x00;

    tmpa = tmpa | PORTA;
    tmpc = tmpc | PORTC;

    while (1)
    {
        if (tmpa <= 0x02) //less than or equal to 2
        {
            SetBit(tmpc, 5, 1);
            SetBit(tmpc, 6, 1);
        }
        if (tmpa <= 0x04) //less than or equal to 4 
        {
            SetBit(tmpc, 4, 1);
            SetBit(tmpc, 6, 1);
        }
        if (tmpa <= 0x06) //less than or equal to 6
        SetBit(tmpc, 3, 1);
        if (tmpa <= 0x09) //less than or equal to 9
        SetBit(tmpc,2,1);
        if (tmpa <= 0x0C)
        SetBit(tmpc,1,1); //less than or equal to 12
        if (tmpa <= 0x0F)
        SetBit(tmpc,0,1); //less than or equal to 15

        PORTC = PORTC | tmpc; ////////PORTC ends up being all zeros
        asm("break");
    }
}


3 个答案:

答案 0 :(得分:3)

问题是SetBit的返回值被丢弃了。 尝试按以下方式更改对此函数的调用:

    SetBit(tmpc,0,1); //less than or equal to 15

    tmpc = SetBit(tmpc,0,1); //less than or equal to 15

答案 1 :(得分:2)

您可以对十六进制值完全使用逻辑运算符。表示形式是二进制,十六进制还是十进制都没有区别。对于您的编译器,它是8位值。

关于您的示例: tmpa为0x0F,因此只有在条件经过验证的情况下才最后执行。在此行,tmpc等于0x00(初始化后)。通过SetBit(tmpc,0,1))时,条件的值为真(b = 1),函数将返回x | (0x01 << k,在这种情况下,该值等于0x01。 tmpc最后等于0x00(其初始值),因为您没有将其分配给SetBit函数的返回值! 试试这个:

if (tmpa <= 0x0F)
    tmpc = SetBit(tmpc,0,1); //less than or equal to 15

答案 2 :(得分:2)

是的,您可以使用逻辑运算符,但是此代码不必要地缓慢且复杂。您不需要分支或比较,只需要一个具有16个值的查找表即可。

const uint8_t VAL [0x10] =
{
  [0x00] = 1u<<5 | 1u<<6,
  [0x01] = 1u<<5 | 1u<<6,
  [0x02] = 1u<<5 | 1u<<6,
  [0x03] = 1u<<4 | 1u<<6,
  [0x04] = 1u<<4 | 1u<<6,
  // ... up to 0x0F
};

tmpc = VAL[tmpa & 0xF];