Keil uVision (компилятор C51), что означает унарный оператор "!"?

Я программирую с Keil uVision 4.

У меня есть такой код:

sbit X = P3 ^ 3; // X is third bit of P3 register

...

    while (1) {
      X = !X; // X equals not X ?!

      if (X == 0)
        printf("0");
      else
        printf("1");
    }

Я могу контролировать `P3^3 Общий входной контакт, потому что на этом контакте у меня есть ИК-датчик (импульсный инфракрасный датчик). Это дает мне 1 в этой строке, когда он мигает, 0, когда он спит.

когда P3^3 подтянут к 1, выход (как и ожидалось) 10101010101010..

Когда он все еще равен 0, вывод равен (как и ожидалось) 0000000000000..

Поведение, которое я получаю, это то, что я описал выше, учитывая, что sbit X устанавливается / не устанавливается PIR.

Итак, вопрос в том, что означает оператор ! в компиляторе Keil C51?

2 ответа

Решение

В Keil C51, чтобы процитировать руководство:

Тип sbit определяет бит в регистре специальной функции (SFR)

Таким образом, вы не объявляете переменную X и не читаете ее один раз перед циклом, а определяете ссылку на P3.3 и читаете ее состояние на каждой итерации цикла. То есть X является ссылкой на аппаратный регистр выводов ввода / вывода, а не переменной.

Несмотря на внешность sbit это не просто typedef псевдоним и ^ не является побитовым оператором XOR. Скорее он определяет ссылку на битовый адресуемый регистр. Назначение X записывает в аппаратный регистр - в этом случае поведение определяется аппаратными средствами, а не языком. Я полагаю, что способность изменять значение X, когда оно слишком высокое, внешне присуща аппаратному обеспечению GPIO, а не странному поведению ! оператор. Проверьте аппаратную документацию на поведение выводов ввода / вывода, но я снова предполагаю, что вытягивание этого высокого уровня делает вывод выводным

Чтобы получить поведение (я полагаю), вы ожидаете, что кодируете его так:

sbit p = P3 ^ 3; // p is third bit of P3 register


...
int X = p ; // get p's current value

while (1) {
  X = !X; // X equals not X ?!

  if (X == 0)
    printf("0");
  else
    printf("1");
}

Предположительно это означает то же самое, что и в стандартном C. !x оценивает 1 если x==0или 0 иначе. Результат имеет тип int,

Если вы ищете побитовое дополнение, которое инвертирует все биты, вы хотите ~ оператор.

ОБНОВИТЬ:

Это больше, чем это; см . ответ Клиффорда.

Другие вопросы по тегам