Могу ли я использовать логические операторы для шестнадцатеричных сравнений?

#c #embedded

#c #встроенный

Вопрос:

Мне нужно установить PORTC во временную переменную, которая изменяется с помощью набора операторов if, но битовая последовательность, назначенная PORTC в самом конце, равна нулю, поэтому я предполагаю, что ни одно из выражений в операторах if не было оценено как true, где я проверяю, является ли битовая последовательность меньше илиравно шестнадцатеричному.

 #include <avr/io.h>

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

unsigned char SetBit(unsigned char x, unsigned char k, unsigned char b) {
    return (b ? x | (0x01 << k) : x amp; ~(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");
    }
}


  

Комментарии:

1. Вы путаете представление значения с самим значением. Операторы работают со значениями. Не имеет значения, представлены ли они в виде восьмеричных, десятичных или шестнадцатеричных чисел.

2. скомпилируйте код на своем компьютере и используйте отладчик

3. Я предполагаю PORTC , что это какой-то аппаратный регистр. Вы уверены, что они доступны для чтения и записи? Вы должны проверить, что вы читаете перед своей if последовательностью, и какое значение у вас есть, tmpc прежде чем записывать его.

4. Вы также можете убедиться, что ваша setbit функция возвращает правильные значения. На всякий случай я бы добавил скобки вокруг выражений слева и справа от :

5. Ваше тело не содержит вопроса, и ответ на заголовок явно «да» — ответ не решает вашу проблему. Вы задаете неправильный вопрос, вопрос X-Y; вы действительно должны спросить, почему ваши вызовы setBit() не изменяют аргумент. Шестнадцатеричное число — это просто представление в исходном коде для удобства чтения человеком, на машинном двоичном уровне это просто целое число, машина ничего не знает о шестнадцатеричном, десятичном или восьмеричном.

Ответ №1:

Проблема в том, что возвращаемое значение 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)) условие будет равно true (b = 1), и функция вернет x | (0x01 << k значение, которое в этом случае равно 0x01. tmpc равен 0x00 в конце (его начальное значение), потому что вы не присваиваете его возвращаемому значению вашей функции setBit! Попробуйте это :

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

Ответ №3:

Да, вы можете использовать логические операторы, но этот код излишне медленный и сложный. Вам не нужны ветви или сравнения, все, что вам нужно, это справочная таблица с 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 amp; 0xF];