MaxiMuz 0 28 ноября, 2013 Опубликовано 28 ноября, 2013 · Жалоба Для удобства работы с портами ввода/вывода (на STM32 в Keil) написал небольшой хидер, приведу его часть : #define SbitP(Port,Nbit) GPIO##Port->BSRR=GPIO_BSRR_BS##Nbit #define RbitP(Port,Nbit) GPIO##Port->BSRR=GPIO_BSRR_BR##Nbit #define SmbitP(Port,mask) GPIO##Port->BSRR=(mask) #define RmbitP(Port,mask) GPIO##Port->BSRR=(mask)<<16 в программе использую следующие варианты включения макросов: #define LCD_dataShift 1 void LCD_wrAdr (u8 Adr) { SmbitP(A,((Adr&0x0f)<<LCD_dataShift)); // выставляем на шину адрес RbitP(A,7); // вкл. на запись адреса A0=0 SbitP(A,5); // вкл.строба записи delay(2000);// Задержка ~ 100нс RbitP(A,5); // снимаем строб записи RmbitP(A,(0x0f<<LCD_dataShift)); // Сброс битов шины DBх delay(5000);// Задержка ~ 200нс } У меня вопрос: на сколько корректно такое применение макросов ? т.к. в случае с RbitP(A,7) в макрос подставляется символ , который при обединение с остальным текстом сам является библиотечным макросом. Т.е. до каких пор происходит раскрытие макроса ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tarbal 4 28 ноября, 2013 Опубликовано 28 ноября, 2013 · Жалоба Бегло посмотрел. Вроде все нормально. Макросы тупо подставляют параметры как текст не вычисляя их значение. Если вы вместо параметра впишите текст и не будет синтаксических ошибок, то все пучком. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба Т.е. до каких пор происходит раскрытие макроса ? До упора :) После обработки макро разбор продолжается от начала текста, получившегося в результате макроподстановки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 17 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба Не совсем понятен смысл таких макросов. Если абстрагироваться, то нужно и от пинов, и от портов, и от уровней. А это - всем известные макросы Аскольда Волкова или их подобие в виде шаблонов с++ (были пара тем) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба +1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaxiMuz 0 29 ноября, 2013 Опубликовано 29 ноября, 2013 (изменено) · Жалоба Не совсем понятен смысл таких макросов. Если абстрагироваться, то нужно и от пинов, и от портов, и от уровней. а смысл - вместо записи GPIOA->BSRR=GPIO_BSRR_BS2 писать SbitP(A,2) помоему так нагляднее , и букф меньше. Вот по поводу абстрагирования от пинов, добавим еще пару макросов для именования выводов #define LCD_A0 7 и #define LCD_WR1 5 : #define LCD_A0 7 // Выбор: Адрес A0=L/ Данные A0=H #define LCD_WR1 5 // Запись в модуль: H-активный уровень #define LCD_dataShift 1 void LCD_wrAdr (u8 Adr) { SmbitP(A,((Adr&0x0f)<<LCD_dataShift)); // выставляем на шину адрес RbitP(A,LCD_A0); // вкл. на запись адреса A0=0 SbitP(A,LCD_WR1); // вкл.строба записи delay(2000);// Задержка ~ 100нс RbitP(A,LCD_WR1); // снимаем строб записи RmbitP(A,(0x0f<<LCD_dataShift)); // Сброс битов шины DBх delay(5000);// Задержка ~ 200нс } В этом случае получается что перед тем как раскрыть макрос, нужно вместо букв параметра подставить то что означают эти буквы. Как в таком случае поведет себя предпроцессор , корректна ли такая запись с точки зрения стандарта написания макросов ? Изменено 29 ноября, 2013 пользователем MaxiMuz Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба Вы не до конца поняли намёк про макросы Аскольда Волкова. Не поленитесь - погуглите да изучите. Потом будете себя укорять за то, что слишком поздно услышали об этих "сакральных" знаниях. По теме: то, что вы изобразили в последнем примере работать не будет. Требуется допиливание макросов. Вот так: #define _RbitP(Port,Nbit) GPIO##Port->BSRR=GPIO_BSRR_BR##Nbit #define RbitP(Port,Nbit) _RbitP(Port,Nbit) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 29 ноября, 2013 Опубликовано 29 ноября, 2013 · Жалоба Я обычно так делаю #define LCD_WR1_pin 4 static inline void LCD_wr1(const char value) { GPIOB->BSRR = 1 << (LCD_WR1_pin + value?0:16); } Никаких макро и никаких неясных абстракций. Все конкретно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
winipuh 0 1 декабря, 2013 Опубликовано 1 декабря, 2013 · Жалоба #define LCD_WR1_pin 4 static inline void LCD_wr1(const char value) { GPIOB->BSRR = 1 << (LCD_WR1_pin + value?0:16); } Всего два вопроса: А зачем у аргумента функции квалификатор const? Тут же параметр не по ссылке передается, а по значению. :blink: 1 << (LCD_WR1_pin + value ? 0 : 16); <— Вы тут часом скобочки не забыли? :) Я о том, что приоритет операции "+" выше, чем у тернарной операции "?:" Надо бы так: 1 << (LCD_WR1_pin + (value ? 0 : 16)); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 2 декабря, 2013 Опубликовано 2 декабря, 2013 · Жалоба Ну и если ещё продолжить придираться, то аргумент функции размером меньше int на ARM архитектуре менее оптимален. Так что char'у тут не место.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 2 декабря, 2013 Опубликовано 2 декабря, 2013 · Жалоба Скобочки - запросто мог потерять. Ну и если ещё продолжить придираться, то аргумент функции размером меньше int на ARM архитектуре менее оптимален. Так что char'у тут не место.... Если нужны вычисления на этапе выполнения, то для чего вообще эти инлайны? Это несерьезно. В конце концов, bit band существует. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
winipuh 0 2 декабря, 2013 Опубликовано 2 декабря, 2013 · Жалоба Я не придраться :( Просто уже и раньше кое-где встречал наподобие void func(const int x) { .... } Например, в исходниках scmRTOS. Теперь вот и у Паши (уважаемого, надо сказать, человека :)). Вот я и спрашиваю... Вдруг в этом есть какой-то глубокий смысл, а я и не в курсе... :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 2 декабря, 2013 Опубликовано 2 декабря, 2013 · Жалоба Вот я и спрашиваю... Вдруг в этом есть какой-то глубокий смысл, а я и не в курсе... :laughing: Ну, вдруг кто-то (или сам автор) задаст в value переменную. А компилятор - бац - нельзя! :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
winipuh 0 2 декабря, 2013 Опубликовано 2 декабря, 2013 · Жалоба Ну, вдруг кто-то (или сам автор) задаст в value переменную. А компилятор - бац - нельзя! :rolleyes: Шутить изволите? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 2 декабря, 2013 Опубликовано 2 декабря, 2013 · Жалоба Шутить изволите? :) По-моему, в книге Шилдта описан этот прием. Для библиотечных функций. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться