Я читал какой-то код для использования на arduino ATMEGA328P и не могу понять, что делает эта строка кода.
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
Я знаю, что ASSR — это асинхронный регистр состояния, а EXCLK — это биты AS2 в этом регистре. Я почти уверен, что _BV() используется для установки этого бита, поправьте меня, если я ошибаюсь. Чего я не знаю, так это того, что на самом деле делает этот код? Похоже, что этот код использует побитовые операции для сравнения регистра ASSR с одним битом ( ~(_BV(EXCLK) | _BV(AS2))
), а затем устанавливает этот регистр в один бит, единицу или ноль. Для меня это не имеет никакого смысла, так как этот регистр имеет размер 7 бит и его нельзя сравнить с одним битом. Любая помощь приветствуется, спасибо.
Соответствующая документация:
У меня мало опыта в Arduino, но похоже, что эта строка очищает биты EXCLK и AS2.
Из контекста BV() должен дать вам битовый вес.
AS2 - это бит 5 (считая справа, начиная с 0) в регистре, затем _BV(AS2)
должно возвращаться 32 (
). По той же логике _BV(EXCLK)
должно возвращаться 64, так как EXCLK — это бит 6.
так что в двоичном виде у нас есть
_BV(AS2) = 00100000
и_BV(EXCLK) = 01000000
Когда мы или эти значения получаем 01100000
инвертирует ~
значения, поэтому мы получаем 10011111
Затем &=
сохраняет все биты, равные 1, в предыдущем результате без изменений и устанавливает оставшиеся биты (5 и 6) в 0.
_BV
макрос, выполняющий сдвиг влево. EXCLK
и AS2
являются битовыми позициями в их регистре. Таким образом, код выполняет операцию ИЛИ между битовыми значениями, инвертирует все это (все 8 бит) и объединяет их с регистром. Короче говоря, он очищает эти биты.
Кейт
Бруно Феррейра
_BV()
его также можно рассматривать как сдвиг вправо (на самом деле именно так он и определяется).