Проблема с установкой битов GPIO с использованием регистров PINSEL

#c #arm #nxp-microcontroller

#c #arm #nxp-микроконтроллер

Вопрос:

Не мог бы кто-нибудь, пожалуйста, объяснить мне, как это

 LPC_PINCON->PINSEL1 amp;= ~(0x03 << 18);
  

очищает биты 18 и 19 порта 1? Будет ли

 LPC_PINCON->PINSEL1 amp;= ~(1 << 18);
LPC_PINCON->PINSEL1 amp;= ~(1 << 19);
  

дает тот же результат?

Комментарии:

1.Да, в принципе LPC_PINCON->PINSEL1 amp;= ~(1 << 18); LPC_PINCON->PINSEL1 amp;= ~(1 << 19); , это дало бы тот же результат?», Но с большим количеством шагов, а не атомарно.

2. Они эквивалентны. В первом случае вы выравниваете 2 чистых бита, во втором вы выполняете их по отдельности, хотя эффект на устройстве может быть другим , если они не выполняются одновременно (говоря в целом).

3. Вам должно стать ясно, если вы напишете число 3 в двоичном формате на бумаге и сдвинете его влево на 18 позиций.

Ответ №1:

Ваш вопрос указывает на то, что вам нужно изучить логические и двоичные операции

Из codescope.com

 Setting a bit. Use the bitwise OR operator ( | ) to set a bit. `number |= 1 << x;` That will set a bit x .
Clearing a bit. Use the bitwise AND operator ( amp; ) to clear a bit. `number amp;= ~(1 << x);` That will clear bit x . ...
Toggling a bit. The XOR operator ( ^ ) can be used to toggle a bit. `number ^= 1 << x;`
  

То же самое применимо, если вместо 1 вы будете использовать другое число. 3 в двоичном 11 формате, и он очистит два бита.

Ответ №2:

С логической точки зрения, да, два варианта эквивалентны — использование Qalculate для указания очевидного (он может вычислять такие выражения, как ~(0x03 << 18) ):

 ~(0x03 << 18) = 1111 1111 1111 0011 1111 1111 1111 1111
~(1 << 18)    = 1111 1111 1111 1011 1111 1111 1111 1111
~(1 << 19)    = 1111 1111 1111 0111 1111 1111 1111 1111
  

Таблица истинности для логической операции and:

 A   B   Q
0   0   0
0   1   0
1   0   0
1   1   1
  

Все биты [0 ..31] в LPC_PINCON->PINSEL1 останутся неизмененными, когда побитовая and операция будет выполнена со 1 значением в битовой маске в той же позиции.

Все биты [0 ..31] в LPC_PINCON->PINSEL1 будут установлены на ноль, когда побитовая and операция будет выполнена со 0 значением в битовой маске в той же позиции.

Так что да, LPC_PINCON->PINSEL1 в конечном итоге будет содержать одно и то же значение в обоих случаях.

Но выполнение операции в два этапа приведет к изменению два или три раза подряд функциональной роли вашего pin-кода, в зависимости от значения LPC_PINCON->PINSEL1 в то время, когда вы начнете его изменять.

Это может повлиять на поведение того, что подключено к вашему pin-коду, в случае, если вы уже установили значения в соответствующих LPC_GPIOn –> FIODIR , например, или других регистрах in, настраивая любую из возможных альтернативных функций для этого конкретного pin-кода.

Это означает, что настройка режима GPIO за одну операцию, вероятно, является лучшим вариантом, и поэтому два варианта не эквивалентны с аппаратной точки зрения.