Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: битовая арифметика
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
ЧипХрум
Програмирую на AVRStudio под atmega32 , делаю сигналку себе на авто.
Програмирую на си.
1.Испытываю затруднение по обращению к биту порта в условии.
к примеру

if ((бит порта)==1)
или
if ((бит порта)==0)

Если я правильно понимаю к порту на ввод информации лучше всего
обращаться через регистр PIN , поправте если я не прав.


2.Так же имею вопрос как обратиться правильно к биту переменной
типа unsigned char или unsigned int в том же условии
MrYuran
Цитата(ЧипХрум @ Jun 3 2008, 10:01) *
Если я правильно понимаю к порту на ввод информации лучше всего
обращаться через регистр PIN

Мало того, это единственно возможный способ считать информацию с порта
Цитата
2.Так же имею вопрос как обратиться правильно к биту переменной

Ну, есть куча способов. Самый простой (для меня) - наложение маски.
То есть:
#define BIT5 0x20 // определили маску 5-го бита

PIN & BIT5 - будет равно BIT5, если соответственный бит в PIN включен, либо 0, если выключен.

Ну а также есть способы для работы через битовые команды, но я лично их не люблю.
Палыч
Если транслятор WinAVR - воспользуйтесь макросами из sfr_defs.h :

bit_is_set
bit_is_clear и др.

Если другой - взять эти макросы или найти аналогичные
bloodden
if( (PINB&BIT5) != 0) делаем, если бит установлен
Это, так сказать, итог под постом MrYuran

Можно через заднее место если в CodeVision пишите: if(PINB.5)
Но это работает ТОЛЬКО в это компиляторе.
ЧипХрум
Спасибо за разьяснение !!! beer.gif
ЧипХрум
Спасибо за разьяснение !!! beer.gif
ЧипХрум
Появилась траблемма , помогайте я не справляюсь !!!

#define BIT3 0x08

if ((PINC&BIT3) == 1) //
{

Sirena();

}

А вот выражение .
При установке 3 го бита в порте PINC в 1 цу выражение не реагирует .
А вот в этом выражении все впорядке

#define BIT0 0x01

if ((PINC&BIT0) == 0)
{

Sirena();

}

Почему так и чего не хватает в первом выражении.
vitko
Цитата(ЧипХрум @ Jun 4 2008, 13:36) *
Появилась траблемма , помогайте я не справляюсь !!!

#define BIT3 0x08

if ((PINC&BIT3) == 1) //
{
Sirena();
}

А вот выражение .
При установке 3 го бита в порте PINC в 1 цу выражение не реагирует .
Почему так и чего не хватает в первом выражении.


а по вашему, результат операции (PINC & 0x08) может быть равен 0x01 ?
rezident
При использовании в условиях битовых операций с наложением маски я вам крайне рекомендую использовать только сравнение с нулем, либо с одной и тех масок, что вы накладываете. Не используйте сравнение с каким либо другим числом, чтобы не попасть впросак. Причину ошибки вам указал vitko.
PINC&BIT3 преобразуется препроцессором в выражение PINC&0x08. Это выражение может принимать значение либо 0x08, либо 0x00. 0x01 оно никогда равно не будет.
Lepeksiy
В таких ситуациях проще писать без сравнения, в стиле
Код
#define BIT3 0x08

if (PINC & BIT3)
{ // если бит == 1
}
else
{ // если бит == 0
}
rezident
Цитата(Lepeksiy @ Jun 5 2008, 16:22) *
В таких ситуациях проще писать без сравнения, в стиле
Отнюдь. Явное сравнение гораздо нагляднее и доступнее для восприятия.
bloodden
Какой МК? Если мега, то смотрите на порту Ц jitag есть. так вот он если включен, то порты не работают.
Stanislav_S
Для наглядности можно так:
#define MASK 0x01
if(PINX>>N&MASK==MASK)
{
bla;
}
else
{
bla;
}
Lepeksiy
Цитата(rezident)
Отнюдь. Явное сравнение гораздо нагляднее и доступнее для восприятия.

Мне как раз вариант без сравнения кажется более наглядным. Дело вкуса и привычек.
Явное сравнение более наглядно, если речь идет об арифметических операциях. А проверка бита является булевой по своей сути.
rezident
Цитата(Lepeksiy @ Jun 5 2008, 18:25) *
Мне как раз вариант без сравнения кажется более наглядным. Дело вкуса и привычек.
Явное сравнение более наглядно, если речь идет об арифметических операциях. А проверка бита является булевой по своей сути.
При проверке условия на уровне ассемблерных инструкций идет сравнение значения выражения с нулем и только потом уже на уровне ЯВУ присваивается абстракция в виде true/false. Кстати, значения true/false могут отличаться от 1/0. Так что прошу от вас обоснования, почему нельзя в условии явно с нулем сравнивать?
Lepeksiy
Цитата
При проверке условия на уровне ассемблерных инструкций идет сравнение значения выражения с нулем

Какое это имеет значение? Мы тут наглядность на си рассматриваем, а не ассемблер.
А в таких случаях, как в примере выше, avr-gcc (при включенной оптимизации) использует SBIC или SBIS.
Цитата
Так что прошу от вас обоснования, почему нельзя в условии явно с нулем сравнивать?

Да сравнивайте, кто ж вам не дает smile.gif
Я разве утверждал что нельзя?? Я писал, что вариант без явного сравнения кажется мне более наглядным.
rezident
Цитата(Lepeksiy @ Jun 5 2008, 20:27) *
Какое это имеет значение?
Большое. Стиль написания на языке ЯВУ, который приближает программу к такой же, написанной на ASM, дает наиболее эффективный код.
Цитата(Lepeksiy @ Jun 5 2008, 20:27) *
Я писал, что вариант без явного сравнения кажется мне более наглядным.
Да где же тут наглядность, если не понятно с чем сравнивать и как результат сравнения определять? laughing.gif
Сраваните сами
Код
if ((tmp&BIT0)!=0)
  var=1;
else
  var=0;

Читаем/расшифровываем выражение: если при битовой операции tmp AND BIT0 результат не равен нулю, то переменной var присвоим значение 1, иначе - значение 0.
Теперь ваш вариант
Код
if (tmp&BIT0)
  var=1;
else
  var=0;

Пытаемся расшифровать: если при битовой операции tmp AND BIT0 .... а дальше чего? В этом месте нужно помнить, что где-то по умолчанию предполагается, что 0 это false, а не 0 это true. И исходя из этого предположения выбирать действие. А если вдруг окажется что true это 0, а false совсем наоборот? laughing.gif То, что вы ни разу с таким не сталкивались, не означает что такого не бывает никогда. Эталон сравнения в вашем варианте условия зарыт где-то далеко какими-то умолчаниями и/или хедерами. Ну и где тут ваша пресловутая "наглядность"? wink.gif
vet
rezident, при чём тут true/false? в plain C и слов-то таких нет;
выражение в if () проверяется именно что на неравенство нулю, в любом случае. Выражение вида a!=b имеет свой результат - ноль или не ноль соответственно.
Лично мне выражение с опущенным !=0 также представляется более естественным (для битовых операций; сравнение чисел с нулем лучше читается в явном виде). И уж конечно, такой стиль ближе к ассемблерному - в ассемблерном коде ветвление обычно ставится сразу же после наложения битовой маски, без лишних сравнений.
zltigo
Цитата(Stanislav_S @ Jun 5 2008, 14:02) *
Для наглядности можно так:
#define MASK 0x01
if(PINX>>N&MASK==MASK)

Можете смело участвовать в конкурсе по запутыванию sad.gif. Это даже не "на любом языке можно писать, как на Accемблере", это круче.
Tiny
Я не программист, и до сих пор я считал, что на Си запись
if (tmp&BIT0)
означает в любом случае: Если выражение tmp&BIT0 равно 0, то результат if ЛОЖНОНО. В противном случае - ИСТИНО. Разве в этом плане есть разные варианты?
На PHP я попал с этим в просак. По привычке из Си, Си++ я писал подобным образом. А когда на сервере поменяли PHP4 на PHP5 моя база данных перестала работать. Пришлось повозиться пару часов, чтобы понять, что нужно писать полностью типа if(A>0). Тогда все заработало.
zltigo
Цитата(vet @ Jun 6 2008, 06:30) *
Лично мне выражение с опущенным !=0 также представляется более естественным..

Более того оно так и есть на самом деле smile.gif.
rv3dll(lex)
Цитата(ЧипХрум @ Jun 3 2008, 10:01) *
Програмирую на AVRStudio под atmega32 , делаю сигналку себе на авто.
Програмирую на си.
1.Испытываю затруднение по обращению к биту порта в условии.
к примеру

if ((бит порта)==1)
или
if ((бит порта)==0)


07.gif
да времена настали - зачем использовать для битовых операций (в сигналке почти всё будет такое) контроллер который для этого не очень предназначен??? немудрено))) что для большинства достаточно pic16 а то и pic12 или 51 где не то что делать отдельную операцию чтения а всё сравнение и переход будет одной командой ассемблера - что наиболее наглядно .

JB P2.1 METKA_1
zltigo
Цитата(Tiny @ Jun 6 2008, 07:00) *
Разве в этом плане есть разные варианты?

Никаких вариантов нет.
Выражения if( (a & MASK)!=0 ) ничего кроме трудностей чтения выражений "масло маслянное с добавлением скобок" не добавляют.


Цитата(rv3dll(lex) @ Jun 6 2008, 07:05) *
да времена настали - зачем использовать для битовых операций (в сигналке почти всё будет такое) контроллер который для этого не очень предназначен???

Контроллер "не очень предназначенный для битовых операций". "Чернила для третьего класса"
занимают отныне занимают второе место.
rezident
Ладно. Вижу что бесполезно убеждать. Обсуждаемый вопрос больше относится к культуре/стилю написания программ. Если человек легко обходится при еде руками и ложкой, то убеждать его в том, что кушать лучше с ножем и вилкой, как это принято у культурных людей, видимо не имеет смысла.
GetSmart
Потом выяснится, что культурные люди кушают только в ресторане, да ещё в костюме и при галстуке smile.gif

А дома вообще жрать нельзя smile.gif
rv3dll(lex)
есть надо руками - для этого они и нужны!!!

если бы ножом и вилкой было удобно есть - то в процессе эволюции ноготь указательного пальца правой руки превратился в нож а левой руки в вилку.

некоторые ещё считают что вилку надо держать в левой руке - бред yeah.gif надо держать её так как удобнее 08.gif

Цитата(zltigo @ Jun 6 2008, 09:16) *
занимают отныне занимают второе место.


за такие деньги можно купить rfpic и не думать о горождении радио брелка. или штуки 3 простых пиков
Stanislav_S
Цитата(zltigo @ Jun 6 2008, 10:00) *
Можете смело участвовать в конкурсе по запутыванию sad.gif. Это даже не "на любом языке можно писать, как на Accемблере", это круче.

Почему? Хотя конечно объявлять MASK через define лишнее.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.