|
Использование макросов с аргументами в Си |
|
|
|
Nov 28 2013, 07:32
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Для удобства работы с портами ввода/вывода (на 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) в макрос подставляется символ , который при обединение с остальным текстом сам является библиотечным макросом. Т.е. до каких пор происходит раскрытие макроса ?
|
|
|
|
|
Nov 29 2013, 12:29
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(MrYuran @ Nov 29 2013, 14:48)  Не совсем понятен смысл таких макросов. Если абстрагироваться, то нужно и от пинов, и от портов, и от уровней. а смысл - вместо записи 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нс } В этом случае получается что перед тем как раскрыть макрос, нужно вместо букв параметра подставить то что означают эти буквы. Как в таком случае поведет себя предпроцессор , корректна ли такая запись с точки зрения стандарта написания макросов ?
Сообщение отредактировал MaxiMuz - Nov 29 2013, 12:30
|
|
|
|
|
Nov 29 2013, 12:52
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(MaxiMuz @ Nov 29 2013, 16:29)  Вы не до конца поняли намёк про макросы Аскольда Волкова. Не поленитесь - погуглите да изучите. Потом будете себя укорять за то, что слишком поздно услышали об этих "сакральных" знаниях. По теме: то, что вы изобразили в последнем примере работать не будет. Требуется допиливание макросов. Вот так: Код #define _RbitP(Port,Nbit) GPIO##Port->BSRR=GPIO_BSRR_BR##Nbit #define RbitP(Port,Nbit) _RbitP(Port,Nbit)
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Dec 2 2013, 08:24
|

Частый гость
 
Группа: Участник
Сообщений: 127
Регистрация: 31-10-12
Пользователь №: 74 189

|
Я не придраться  Просто уже и раньше кое-где встречал наподобие Код void func(const int x) { .... } Например, в исходниках scmRTOS. Теперь вот и у Паши (уважаемого, надо сказать, человека  ). Вот я и спрашиваю... Вдруг в этом есть какой-то глубокий смысл, а я и не в курсе...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|