Могу ли я использовать логические операторы для шестнадцатеричного сравнения? - PullRequest
0 голосов
/ 10 апреля 2019

Мне нужно установить 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 ]

3 голосов
/ 10 апреля 2019

Проблема в том, что возвращаемое значение SetBit отбрасывается. Попробуйте изменить вызовы этой функции следующим образом:

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

до

    tmpc = SetBit(tmpc,0,1); //less than or equal to 15
2 голосов
/ 10 апреля 2019

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

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