0xff что это
Перейти к содержимому

0xff что это

  • автор:

Что такое 0xFF и почему он сдвинут в 24 раза?

Вот шестнадцатеричное значение 0x12345678, записанное как двоичное и помеченное некоторыми битовыми позициями:

. а вот 0x000000FF:

Таким образом, побитовое И выбирает только нижние 8 бит исходного значения:

. и сдвиг влево на 24 бита перемещает его из нижних 8 бит в верх:

. что составляет 0x78000000 в шестнадцатеричном формате.

Остальные части работают с оставшимися 8-битными частями ввода:

Таким образом, общий эффект состоит в том, чтобы рассматривать 32-битное значение ldata как последовательность из четырех 8-битных байтов и изменять их порядок в обратном порядке.

Такой код обычно используется для обмена между форматами с прямым порядком байтов и прямым порядком байтов. Есть также небольшой трюк, который преобразует слово в известном формате (скажем, с прямым порядком байтов) в любой порядок следования байтов на текущей машине, и наоборот. Это будет примерно так:

Это работает (при условии, что я не напортачил), потому что независимо от того, как на самом деле хранятся байты, сдвиг влево гарантированно смещается в сторону более значимых битов. Преобразование в char * позволяет вам получить доступ к байтам в том порядке, в котором они фактически хранятся в памяти. Используя этот трюк, вам не нужно определять порядок байтов машины для чтения / записи материала в известном формате. По общему признанию, вы также можете просто использовать стандартные функции (hton и т. Д.): P

(Примечание: вы должны быть немного осторожны и использовать символ перед переключением, иначе он просто переполнится по всей вашей обуви. Кроме того, + = не единственный вариант, | =, вероятно, будет иметь больше смысла, но может быть менее понятным, если ты к этому не привык я не уверен)

Вам нужно рассматривать 0x000000FF как битовую маску, т.е. где оно равно 1, будет взято значение ldata , а где оно будет равно 0 — 0.

Чтобы понять битовую маску, вам нужно преобразовать ее в двоичную форму, с шестнадцатеричным кодом это очень просто, каждое шестнадцатеричное число состоит из 4 двоичных цифр, то есть:

Шестнадцатеричный 0 = двоичный 0000 шестнадцатеричный 1 = двоичный 0001 и так далее.

Теперь к сдвигам: обратите внимание, что сдвиг берет некоторые данные из источника, ровно 8 бит, и перемещает их в другое место в месте назначения.

Теперь обратите внимание, что есть | , т.е. операция ИЛИ для всех операций И ​​с битовой маской, то есть нули останутся нулями, и в случае, если будет ‘1’, результат будет содержать единицу.

Надеюсь, это поможет 🙂

Скажем, данные — это 32-битное число, представленное как 0x12345678 (каждое число — 4 бита в шестнадцатеричном формате).

Data & 0x000000FF означает сохранение только последних 8 бит (называемых битовой маской) = 0x00000078

AVR GCC :: УПРАВЛЕНИЕ ПОРТАМИ МИКРОКОНТРОЛЛЕРА

Порты микроконтроллера — это устройства ввода/вывода, позволяющие микроконтроллеру передавать или принимать данные. Стандартный порт микроконтроллера AVR имеет восемь разрядов данных, которые могут передаваться или приниматься параллельно. Каждому разряду (или биту) соответствует вывод (ножка) микроконтроллера. Ножки микроконтроллера также называют пинами. Для обозначения портов используются латинские буквы А, В, С и т.д. Количество портов ввода/вывода варьируется в зависимости от модели микроконтроллера.

Любой порт микроконтроллера можно сконфигурировать как вход или как выход. Для того чтобы это сделать, следует записать в соответствующий порту регистр DDRx необходимое значение. Кроме того, как вход или выход можно сконфигурировать отдельно любой вывод (пин) порта. В любом случае, хотите вы сконфигурировать весь порт или отдельный вывод, вам необходимо будет работать с ригистрами DDRx.

DDRx — регистр направления передачи данных. Этот регистр определяет, является тот или иной вывод порта входом или выходом. Если некоторый разряд регистра DDRx содержит логическую единицу, то соответствующий вывод порта сконфигурирован как выход, в противном случае — как вход. Буква x в данном случае должна обозначать имя порта, с которым вы работаете. Таким образом, для порта A это будет регистр DDRA, для порта B — регистр DDRB и т. д.

Используя AVR GCC, записать в необходимый регистр то или иное значение можно одним из следующих способов.

Для всего порта сразу.

Все выводы порта D будут сконфигурированы как выходы.

0xff — шестнадцатиричное представление числа ff, где 0x является префиксом, используемым для записи шестнадцатиричных чисел. В десятичном представлении это будет число 255, а в двоичном виде оно будет выглядеть как 11111111. То есть во всех битах регистра DDRD будут записаны логические единицы.

В AVR GCC для представления двоичных чисел используется префикс 0b. Таким образом, число 11111111 должно представляться в программе как 0b11111111. Мы можем записать предыдущую команду в более читабельном виде.

Хотя такая запись и выглядит более наглядной, при конфигурировании портов принято использовать шестнадцатиричное представление чисел.

Для того чтобы сконфигурировать все выводы порта D как входы, следует записать во все биты регистра DDRD логические нули.

В регистр DDRD можно записать и другие числа. Например:

0xb3 — шестнадцатиричное представление числа 179. В двоичном виде оно будет выглядеть как 10110011. То есть часть выводов порта D будет сконфигурирована как выходы, а часть — как входы.

PD0 — 1 (выход)
PD1 — 1 (выход)
PD2 — 0 (вход)
PD3 — 0 (вход)
PD4 — 1 (выход)
PD5 — 1 (выход)
PD6 — 0 (вход)
PD7 — 1 (выход)

Каждый бит регистров DDRx может быть установлен отдельно. Например, чтобы сконфигурировать отдельно вывод PD2 как выход, нам необходимо в соответствующий бит регистра DDRD записать 1. Для этого применяют следующую конструкцию.

1 — осуществляет сдвиг единички влево на 2 бита, то есть справа добавляются два нулевых бита и получается 100, а знак «|», стоящий перед знаком присваивания » 100%»>

Чтобы сконфигурировать отдельно вывод PD2 как вход, нам необходимо в соответствующий бит регистра DDRD записать 0. Для этого применяют следующую конструкцию.

В данном случае результат сдвига единицы на две позиции влево инвертируется с помощью операции побитного инвертирования, обозначаемой значком «

При инверсии мы получаем вместо нулей единички, а вместо единичек — нули. Эта логическая операция иначе называется операцией НЕ (английское название NOT).

Таким образом, при побитном инвертировании 00000100 мы получаем 11111011. (Подробнее о работе с числами в микроконтроллере см. во врезке ниже.)

Получившееся число с помощью операции побитного логического умножения & умножается на число, хранящееся в регистре DDRD, и результат записывается в регистр DDRD.

При логическом умножении 0*0=0, 0*1=0, 1*1=1 . Операцию логического умножения иначе называют операцией И (английское название AND).

То есть сдвинутая нами влево на две позиции единичка превращается при инвертировании в ноль и умножается на соответствующий бит, хранящийся в регистре DDRD. При умножении на ноль мы получаем ноль. Таким образом, бит PD2 становится равным нулю.

Кроме логических операций И, ИЛИ, НЕ существует также операция «исключающее ИЛИ» (английское название XOR). Она обозначается значком ^.

При исключающем ИЛИ значение бита, к которому «прибавляется» единичка, изменяется на противоположное.

Например, 110011 ^ 11010 = 101001.


Следует добавить, что работа с числами в 8-битном микроконтроллере проходит с использованием 8-битных регистров. Перед вычислениями аргумент помещается в один из специальных регистров, с которыми напрямую может работать арифметико-логическое устройство (АЛУ). Например, перед выполнением команды DDRD &=

(1 аргумент помещается во вспомогательный регистр микроконтроллера. Содержимое такого регистра будет выглядеть как 11111011 .
После этого осуществляется операция побитного умножения, что дает во втором бите регистра DDRD значение 0 .

Спасибо участникам форума Олегу (oleg) и VCOM за появление этого комментария и корректирование статьи.

После того как направление передачи данных у порта сконфигурировано, можно присвоить порту значение, которое будет храниться в соответствующем регистре PORTx .
PORTx — регистр порта, где x обозначает имя порта.

Если вывод сконфигурирован как выход, то единичка в соответствующем бите регистра PORTx формирует на выводе сигнал высокого уровня, а ноль — сигнал низкого уровня.

Если же вывод сконфигурирован как вход, то единичка в соответствующем бите регистра PORTx подключает к выводу внутренний подтягивающий pull-up резистор, который обеспечивает высокий уровень на входе при отсутствии внешнего сигнала.

Установить «1» на всех выводах порта D можно следующим образом.

А установить «0» на всех выводах порта D можно так.

К каждому биту регистров PORTx можно обращаться и по отдельности так же, как в случае с регистрами DDRx.

установит «1» (сигнал высокого уровня) на выводе PD3.

установит «0» (сигнал низкого уровня) на выводе PD4.

В AVR GCC сдвиг можно осуществлять и с помощью функции _BV() , которая выполняет поразрядный сдвиг и вставляет результат в компилируемый код.

В случае использования функции _BV() две предыдущие команды будут выглядеть следующим образом.

PORTD |= _BV(PD3); // установить «1» на линии 3 порта D

_BV(PD4); // установить «0» на линии 4 порта D

В микроконтроллерах AVR каждому параллельному порту ввода/вывода поставлен в соответствие также регистр PINx .
PINx является регистром выводов порта и в отличие от регистров DDRx и PORTx доступен только для чтения. PINx позволяет считывать входные данные порта на внутреннюю шину микроконтроллера. Об этом регистре мы поговорим чуть позже.

Теперь попробуем написать несколько простых программ для лучшего понимания принципа работы с портами микроконтроллера.

Первые наши программы будут состоять всего из нескольких строк, и в их задачу будет входить зажигание светодиода, подключенного к микроконтроллеру.

Подключить светодиод к микроконтроллеру можно различными способами.

Рисунок 1 Рисунок 2

В зависимости от способа подключения светодиод будет загораться либо от сигнала высокого уровня, подаваемого на вывод PD1 микроконтроллера, как в первом случае, либо от сигнала низкого уровня в случае подключения, изображенного на втором рисунке.

Теперь попробуем мигнуть светодиодом, подключенным так, как это изображено на левом рисунке. Для этого используем функцию задержки _delay_ms().

Функция _delay_ms() формирует задержку в зависимости от передаваемого ей аргумента, выраженного в миллисекундах (в одной секунде 1000 миллисекунд). Максимальная задержка может достигать 262.14 миллисекунд. Если пользователь передаст функции значение более 262.14, то произойдет автоматическое уменьшение разрешения до 1/10 миллисекунды, что обеспечивает задержки до 6.5535 секунд. (О формировании более длительных задержек можно прочитать в статье «Циклы в языке Си. Формирование задержки».)

Понимание значения & 0xff в Java

Узнайте, как использовать значение 0xff с побитовым оператором И в Java.

  • Автор записи

1. Обзор

0xff – это число, представленное в шестнадцатеричной системе счисления (база 16). Он состоит из двух F чисел в шестнадцатеричном формате. Как мы знаем, F в шестнадцатеричном формате эквивалентно 1111 в двоичной системе счисления. Итак, 0xff в двоичном формате-это 11111111.

В этой статье мы узнаем, как использовать значение 0xff . Кроме того, мы увидим, как представить его с помощью нескольких типов данных и как использовать его с оператором & . Наконец, мы рассмотрим некоторые преимущества, связанные с его использованием.

2. Представление 0xff С Различными Типами Данных

Java позволяет нам определять числа, интерпретируемые как шестнадцатеричные (основание 16), с помощью префикса 0x , за которым следует целочисленный литерал.

Значение 0xff эквивалентно 255 в десятичной системе без знака, -127 в десятичной системе со знаком и 11111111 в двоичной системе.

Итак, если мы определим переменную int со значением 0xff , поскольку Java представляет целые числа, используя 32 бита , значение 0xff равно 255 :

Однако, если мы определим переменную byte со значением 0xff , поскольку Java представляет байт с использованием 8 бит и поскольку байт является типом данных со знаком , значение 0xff равно -1 :

Как мы видим, когда мы определяем переменную byte со значением 0xff , нам нужно понизить ее до byte , потому что диапазон типа данных byte составляет от -128 до 127 .

3. Общее использование операции & 0xff

Оператор & выполняет побитовую операцию И . Выход побитового И равен 1, если соответствующие биты двух операндов равны 1. С другой стороны, если любой бит операндов равен 0, то результат соответствующего бита оценивается как 0.

Поскольку 0xff имеет восемь единиц в последних 8 битах , это делает его элементом идентификации для побитовой операции И . Итак, если мы применим операцию x & 0xff , она даст нам самые низкие 8 бит из x . Обратите внимание, что если число x меньше 255, оно все равно останется прежним. В противном случае это будет самый низкий 8 бит из x .

В общем случае операция & 0xff предоставляет нам простой способ извлечь наименьшие 8 бит из числа . На самом деле мы можем использовать его для извлечения любых 8 битов, которые нам нужны, потому что мы можем сдвинуть вправо любой из 8 битов, которые мы хотим сделать самыми низкими битами. Затем мы можем извлечь их, применив операцию & 0xff .

Давайте рассмотрим пример, чтобы более подробно объяснить некоторые преимущества использования & 0xff .

4. Извлечение Цветовых Координат RGB С помощью & 0xff

Предположим , что у нас есть целое число x , хранящееся в 32 битах, которое представляет цвет в системе RGBA, что означает, что оно имеет 8 бит для каждого параметра (R, G, B и A):

  • R (00010000 в двоичном формате)
  • G (00111001 в двоичном формате)
  • B (10101000 в двоичном формате)
  • A (00000111 в двоичном формате)

Так, x в двоичном формате будет представлено как 00010000 00111001 10101000 00000111 — что эквивалентно 272214023 в десятичной системе счисления.

Теперь у нас есть значение x в десятичной системе счисления, и мы хотим извлечь значение для каждого параметра.

Как мы знаем, операция >> сдвигает биты вправо. Поэтому, когда мы это делаем (10000000 00000000 >> 8), это дает нам 10000000. В результате мы можем извлечь значение каждого параметра :

5. Заключение

В этом уроке мы обсудили, как операция & 0xff эффективно делит переменную таким образом, что оставляет только значение в последних 8 битах и игнорирует остальные биты. Как мы уже видели, эта операция особенно полезна, когда мы сдвигаем переменную вправо и нам нужно извлечь сдвинутые биты.

Добавить комментарий

Ваш адрес email не будет опубликован.