2013-06-18 4 views
3

Я программирования с Keil uVision 4.Keil uVision (компилятор C51), что означает унарный оператор «!»?

У меня есть некоторый код, как это:

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 общий входной контакт, потому что на этом выводе я уже получил PIR (импульсный инфракрасный датчик). Это дает мне 1 на этой линии, когда она мигает, 0 когда она спит.

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

Когда он по-прежнему 0, выход (не ожидается) 0000000000000..

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

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

+0

В документации указано, что 'sbit' не может быть объявлен внутри функции, поэтому я также предполагаю, что этот фрагмент кода удален? Нельзя указывать, что с помощью elipsis ('...') – Clifford

+0

Чтобы быть ясным, было бы полезно описать вывод «ожидаемый», когда ввод будет низким, так как при анализе я думаю, что он корректно ведет себя * (т.е. в кодировке), учитывая аппаратное обеспечение и семантику расширения языка 'sbit'. – Clifford

+0

Да, область действия глобальная. Я ожидаю почти того же выхода, что и у меня, когда линия была высокой. Прати, я думал, что '!' Является тем же самым '~'. –

ответ

4

В Keil C51, процитировать manual:

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

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

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

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

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"); 
} 
+0

Жаль, что я не знаю, на P3^3 у меня есть PIR (импульсный инфракрасный датчик). Это дает мне 1 на этой линии, когда она мигает, 0 когда она спит. Поведение, которое я обнаруживаю, это то, что я описал выше, учитывая, что 'sbit X' установлен/не установлен PIR. –

+1

@FilippoLauria: Я имел в виду аппаратное обеспечение MCU GPIO, а не оборудование, которое вы подключили к булавке. Я считаю, что на 8051 порт настроен как ввод, записывая в него нуль, что позволяет его утверждать извне. Вы пишете 1 на контакт, чтобы установить его как вход, после этого вы должны только его прочитать - вы пишете в нем выражение «X =! X», поэтому вы переключаете его между входом и выходом в цикле while , Как я уже сказал, проверьте документацию для своего MCU. – Clifford

0

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

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

UPDATE:

Там больше, чем это; см. Clifford's answer.

+0

Я думаю, что c51 является расширением стандарта C. Если вы правильно сказали, почему компилятор не дает мне ошибку (или предупреждение), когда я пытаюсь назначить 'int'' sbit'? –

+0

@ Филиппо Лаурия: Я не знаю; вполне возможно, я ошибаюсь. Я знаком с C, а не с Keil C51. Получаете ли вы предупреждение, когда вы явно присваиваете значение 'int'' sbit'? –

+0

Я пробовал '(int x = 1; sbit y = P3^3; ... y = x;)' никаких предупреждений не срабатывает. Возможно, это похоже на то, как вы сказали, и по какой-то причине мне неизвестно, поведение, на мой взгляд, странно. –

Смежные вопросы