Побитовые операции в кодировании C

Я пытаюсь научиться писать драйверы для контактов GPIO в STM32F4 Discovery. Я просматривал учебники и наткнулся на эту строку:

static void hal_gpio_configure_pin_mode (GPIO_TypeDef *GPIOx, uint16_t pin_no, uint32_t mode)
{
    GPIOx->MODER |= (mode << (2* pin_no));
}

Я относительно новичок во встроенных системах и не знаю, что делает GPIOX->MODER |= (mode << (2* pin_no));. Кроме того, я не знаю, почему pin_no 16-битный, а режим 32-битный. Я знаю, что ‹‹ — это побитовый оператор сдвига влево. Но я все еще не понимаю полного контекста.

Кто-нибудь может все это объяснить?


person Aditya Rajguru    schedule 18.10.2017    source источник
comment
Нет причин, по которым pin_no и mode должны иметь один и тот же тип. Их значения не используются вместе, как это происходит в таких операциях, как сложение или умножение. Скорее, pin_no — это просто индекс, используемый (с 2) для вычисления того, насколько нужно сдвинуть значение (mode). Количество битов для сдвига просто должно быть числом; он не обязательно должен быть того же типа, что и перемещаемая вещь. Таким образом, в то время как такие операторы, как + и *, требуют, чтобы их операнды были преобразованы в один и тот же тип, оператор << может иметь разные типы слева и справа.   -  person Eric Postpischil    schedule 19.10.2017
comment
Посмотрите регистр модера в разделе gpio документации на чип. Вы увидите, что это просто установка пары битов в этом регистре.   -  person old_timer    schedule 19.10.2017
comment
Google: c как работают побитовые операторы. Или почитайте книгу.   -  person Lundin    schedule 19.10.2017


Ответы (1)


Пытаюсь объяснить строку GPIOx->MODER |= (mode << (2* pin_no));:

  • GPIOx — указатель на структуру
  • GPIOx->MODER обращается к члену MODER внутри этой структуры
  • x |= y — это сокращение от x = x | y, что означает «выполнить логическое ИЛИ x и y и записать результат обратно в x».
  • mode << (2* pin_no) означает сдвиг влево содержимого переменной mode на два pin_no бита.

Следовательно, строка означает «взять содержимое GPIOx->MODER, побитовое ИЛИ с содержимым mode, сдвинутым влево.

person Georg P.    schedule 18.10.2017
comment
Я бы добавил к этому, что скорее всего режим для каждого вывода кодируется двумя битами и может иметь 4 разных значения. И эта функция предполагает, что режим изначально установлен на 00. - person Eugene Sh.; 19.10.2017
comment
да, подходит для пост-сброса в зависимости от состояния сброса, но перед звонком следует маскировать. - person old_timer; 19.10.2017