Как работает эта простая строка кода C?

Мне нужны 9-битные данные UART на Arduino Uno, поэтому мне нужно выполнить некоторую ручную настройку Arduino UART. По сути, я не понимаю эту строку примера кода (из таблицы данных), она предназначена для включения выводов UART Tx и Rx на Arduino, что делается на простом и понятном машинном языке, просто означает загрузку немедленного значения в UCSR0B (регистр управления и состояния USART B) таким образом, что бит RXE (разрешение приема) и бит TXE (разрешение передачи) имеют высокий уровень. Другими словами, загрузите 00011000 в USCR0B.

Вот пример кода C из таблицы данных:

USCR0B = (1 << RXE) | (1 << TXE);

person Nathan Darker    schedule 10.09.2015    source источник
comment
Очень длинный путь, чтобы задать очень простой вопрос. Обратите внимание на это руководство со страниц справки SO: Этот сайт предназначен для получения ответов. Это не дискуссионный форум. Там нет болтовни.   -  person kaylum    schedule 10.09.2015
comment
Есть отличный ответ, так что небольшая подсказка: более новые версии avr libc включают макрос _BV (битовое значение), который скрывает смещение, в результате чего код, по мнению некоторых, лучше читается: USCR0B = _BV(RXE) | _BV(TXE)   -  person    schedule 10.09.2015
comment
1 << n — это де-факто стандартный способ маскирования одного бита.   -  person Lundin    schedule 10.09.2015
comment
@Lundin Вот почему я написал, что некоторые подумают :) Он заменяет технические детали семантикой ... в конце концов, использовать его или нет - дело личного вкуса.   -  person    schedule 10.09.2015
comment
@FelixPalmen Приглашать малоизвестные макросы для выполнения простых вещей — это не личный вкус, это повсеместно плохая практика. Предположим, что программисты на C знают язык C и не знают какой-то доморощенный макроязык. Этот макрос _BV предлагает помощь Я встроенный программист C, который не знает о байтах и ​​битах. Решение этой проблемы — учиться, а не изобретать макросы.   -  person Lundin    schedule 10.09.2015
comment
@Lundin, этот макрос не является ни неясным, ни доморощенным, он предоставляется avr libc по какой-то причине, и это улучшает семантическую выразительность кода - вы КОГДА-ЛИБО об этом здесь? Использование макросов с битовыми операциями также является довольно распространенной практикой. Вы НЕ ДОЛЖНЫ использовать его, если он вам не нравится, но, пожалуйста, перестаньте считать свое мнение единственно верным в мире.   -  person    schedule 10.09.2015
comment
@FelixPalmen Это доморощенное пиво Atmel, и для его использования нет веских причин. Библиотеки MCU C, как известно, неясны и нестандартны. Известно, что производители полупроводников плохо умеют программировать на C. Вы можете быть абсолютно уверены, что вы не найдете такого макроса ни в одной другой библиотеке MCU C, но вы можете быть уверены, что найдете там какую-то другую малоизвестную нестандартную функцию, которую вы можете использовать/отказаться. Ключ к здравомыслию и переносимости при работе с микроконтроллерами состоит в том, чтобы собрать как можно меньше нестандартного C, нестандартного де-факто дерьма и придерживаться чистого стандартного кода.   -  person Lundin    schedule 10.09.2015


Ответы (1)


RXE и TXE — это битовые индексы, поэтому (1<<RXE) | (1<<TXE) — это маска, где биты TXE и RXE равны 1 (а все остальные биты равны 0).

Например. Мне не известны фактические значения RXE и TXE, но предположим, что TXE — это бит 3, а RXE — это бит 4, тогда соответствующие определения файла заголовка могут выглядеть примерно так:

#define TXE 3  // TX Enable = bit 3
#define RXE 4  // RX Enable = bit 4

и расчет маски будет работать так:

            1<<TXE  = 00001000 = 0x08
            1<<RXE  = 00010000 = 0x10
(1<<RXE) | (1<<TXE) = 00011000 - 0x18
person Paul R    schedule 10.09.2015