Регистрация Синтаксический вопрос

Я читал какой-то код для использования на arduino ATMEGA328P и не могу понять, что делает эта строка кода.

ASSR &= ~(_BV(EXCLK) | _BV(AS2));

Я знаю, что ASSR — это асинхронный регистр состояния, а EXCLK — это биты AS2 в этом регистре. Я почти уверен, что _BV() используется для установки этого бита, поправьте меня, если я ошибаюсь. Чего я не знаю, так это того, что на самом деле делает этот код? Похоже, что этот код использует побитовые операции для сравнения регистра ASSR с одним битом ( ~(_BV(EXCLK) | _BV(AS2))), а затем устанавливает этот регистр в один бит, единицу или ноль. Для меня это не имеет никакого смысла, так как этот регистр имеет размер 7 бит и его нельзя сравнить с одним битом. Любая помощь приветствуется, спасибо.

Соответствующая документация:

Техническое описание ATMEGA 328P

Страница библиотеки AVR

Ответы (2)

У меня мало опыта в Arduino, но похоже, что эта строка очищает биты EXCLK и AS2.

Из контекста BV() должен дать вам битовый вес.

AS2 - это бит 5 (считая справа, начиная с 0) в регистре, затем _BV(AS2)должно возвращаться 32 ( 2 5 "=" 64 ). По той же логике _BV(EXCLK)должно возвращаться 64, так как EXCLK — это бит 6.

так что в двоичном виде у нас есть

_BV(AS2) = 00100000и_BV(EXCLK) = 01000000

Когда мы или эти значения получаем 01100000

инвертирует ~значения, поэтому мы получаем 10011111

Затем &=сохраняет все биты, равные 1, в предыдущем результате без изменений и устанавливает оставшиеся биты (5 и 6) в 0.

Спасибо, это имеет смысл. Я должен был видеть, что _BV() возвращает байт вместо бита.
Как сказал Игнасио, _BV()его также можно рассматривать как сдвиг вправо (на самом деле именно так он и определяется).

_BVмакрос, выполняющий сдвиг влево. EXCLKи AS2являются битовыми позициями в их регистре. Таким образом, код выполняет операцию ИЛИ между битовыми значениями, инвертирует все это (все 8 бит) и объединяет их с регистром. Короче говоря, он очищает эти биты.