Вопрос по #ifndef
- Войдите на сайт для отправки комментариев
Сб, 22/04/2017 - 09:20
Мучаю библиотеку NRF24L01+ и вот в этом коде возник вопрос:
// BYTE type definition #ifndef API_H #define API_H //**************************************************** // SPI(nRF24L01) commands #define READ_REG 0x00 // Define read command to register #define WRITE_REG 0x20 // Define write command to register #define RD_RX_PLOAD 0x61 // Define RX payload register address #define WR_TX_PLOAD 0xA0 // Define TX payload register address #define FLUSH_TX 0xE1 // Define flush TX register command #define FLUSH_RX 0xE2 // Define flush RX register command #define REUSE_TX_PL 0xE3 // Define reuse TX payload register command #define NOP 0xFF // Define No Operation, might be used to read status register //*************************************************** #define RX_DR 0x40 #define TX_DS 0x20 #define MAX_RT 0x10 //*************************************************** // SPI(nRF24L01) registers(addresses) #define CONFIG 0x00 // 'Config' register address #define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address #define EN_RXADDR 0x02 // 'Enabled RX addresses' register address #define SETUP_AW 0x03 // 'Setup address width' register address #define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address #define RF_CH 0x05 // 'RF channel' register address #define RF_SETUP 0x06 // 'RF setup' register address #define STATUS 0x07 // 'Status' register address #define OBSERVE_TX 0x08 // 'Observe TX' register address #define CD 0x09 // 'Carrier Detect' register address #define RX_ADDR_P0 0x0A // 'RX address pipe0' register address #define RX_ADDR_P1 0x0B // 'RX address pipe1' register address #define RX_ADDR_P2 0x0C // 'RX address pipe2' register address #define RX_ADDR_P3 0x0D // 'RX address pipe3' register address #define RX_ADDR_P4 0x0E // 'RX address pipe4' register address #define RX_ADDR_P5 0x0F // 'RX address pipe5' register address #define TX_ADDR 0x10 // 'TX address' register address #define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address #define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address #define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address #define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address #define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address #define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address #define FIFO_STATUS 0x17 // 'FIFO Status Register' register address //************************************************ #endif
Откуда директива #ifndef "знает", включено ли последующее определение или нет?
Если бы директива "знала", то она тем самым бы была не нужна.
Знать или не знать должден препроцессор при обработке директив - что ему попадалось при обработке, а что - нет.
В данном слвчае смысл трех имеющихся директив: вкючаем, если впервые, иначе - выбрасываем. Т.е. они служат для того, чтобы фрагмент кода, сколько бы раз он ни встречался, вы выходной результат попал строго в единственном экземпляре.
Понятно, этим занимается препроцессор ...
Еще вопрос - файл определений:
И далее в основном файле библиотеки идет:
Имя SPI_DIR определяет регистр направления передачи, но нафига значение этого регистра вычислять как сумму и затем применять к нему побитную операцию?
SPI_DIR - это некоторая комбинация флагов. И вычисляется она вполне стандартным способом.
А зачем нужен каждый из этих флагов, наверняка указано в дэйташите.
SPI_DIR - это некоторая комбинация флагов. И вычисляется она вполне стандартным способом.
А зачем нужен каждый из этих флагов, наверняка указано в дэйташите.
Просто непонятно, к чему такие сложности, когда всего-то навсего нужно настроить направление передачи порта ... сразу бы написали SPI_DIR = 0x0F
Просто непонятно, к чему такие сложности, когда всего-то навсего нужно настроить направление передачи порта ... сразу бы написали SPI_DIR = 0x0F
А что такое 0x0F?
Ну, это я в уме :) прикинул результат вычисления SPI_DIR
Результат = 0xof;
Видите ли, ulis считается, что так: SPI_DIR = ( CE + SCK + CSN + MOSI); писать понятнее. У меня, правда, есть некоторые сомнения на этот счет. Да, конечно, сходу непонятно, что такое 0x0F, но это при желании можно выяснить, заглянув в дэйташит. А вот для понимания CE + SCK + CSN + MOSI одного дэйташита недостаточно - придется загоянуть еще и в заголовочный файл.
Но есть и другой момент. Может оказаться, что у другого процессора (контроллера, библиотеки) интересующие нас биты расположены в другом порядке. Тогде комбинация ( CE + SCK + CSN + MOSI) может уже оказаться не равной 0x0F. Т.е. символическая константа сохранится, а численная - будет другой.
Но есть и другой момент. Может оказаться, что у другого процессора (контроллера, библиотеки) интересующие нас биты расположены в другом порядке. Тогде комбинация ( CE + SCK + CSN + MOSI) может уже оказаться не равной 0x0F. Т.е. символическая константа сохранится, а численная - будет другой.
Ну, наверно польза есть, значит, для другого процессора, просто поменять значения CE, SCK, CSN, MOSI? Как все запущено!