реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Использование макросов с аргументами в Си
MaxiMuz
сообщение Nov 28 2013, 07:32
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 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) в макрос подставляется символ , который при обединение с остальным текстом сам является библиотечным макросом. Т.е. до каких пор происходит раскрытие макроса ?
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Nov 28 2013, 13:15
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Бегло посмотрел. Вроде все нормально.
Макросы тупо подставляют параметры как текст не вычисляя их значение.
Если вы вместо параметра впишите текст и не будет синтаксических ошибок, то все пучком.
Go to the top of the page
 
+Quote Post
SSerge
сообщение Nov 29 2013, 06:54
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Цитата(MaxiMuz @ Nov 28 2013, 14:32) *
Т.е. до каких пор происходит раскрытие макроса ?

До упора sm.gif
После обработки макро разбор продолжается от начала текста, получившегося в результате макроподстановки.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Nov 29 2013, 11:48
Сообщение #4


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Не совсем понятен смысл таких макросов.
Если абстрагироваться, то нужно и от пинов, и от портов, и от уровней.
А это - всем известные макросы Аскольда Волкова или их подобие в виде шаблонов с++ (были пара тем)


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Nov 29 2013, 12:12
Сообщение #5


неотягощённый злом
******

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



Цитата(MrYuran @ Nov 29 2013, 15:48) *
+1


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение Nov 29 2013, 12:29
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Nov 29 2013, 12:52
Сообщение #7


неотягощённый злом
******

Группа: Свой
Сообщений: 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)


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Nov 29 2013, 18:19
Сообщение #8


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Я обычно так делаю
Код
#define LCD_WR1_pin 4
static inline void LCD_wr1(const char value)
{
  GPIOB->BSRR = 1 << (LCD_WR1_pin + value?0:16);
}

Никаких макро и никаких неясных абстракций. Все конкретно.
Go to the top of the page
 
+Quote Post
winipuh
сообщение Dec 1 2013, 15:37
Сообщение #9


Частый гость
**

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



Цитата(_Pasha @ Nov 29 2013, 22:19) *
Код
#define LCD_WR1_pin 4
static inline void LCD_wr1(const char value)
{
  GPIOB->BSRR = 1 << (LCD_WR1_pin + value?0:16);
}

Всего два вопроса:
  1. А зачем у аргумента функции квалификатор const? Тут же параметр не по ссылке передается, а по значению. blink.gif
  2. 1 << (LCD_WR1_pin + value ? 0 : 16); <— Вы тут часом скобочки не забыли? sm.gif
    Я о том, что приоритет операции "+" выше, чем у тернарной операции "?:"
    Надо бы так: 1 << (LCD_WR1_pin + (value ? 0 : 16));
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 2 2013, 05:39
Сообщение #10


неотягощённый злом
******

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



Цитата(winipuh @ Dec 1 2013, 19:37) *
Ну и если ещё продолжить придираться, то аргумент функции размером меньше int на ARM архитектуре менее оптимален. Так что char'у тут не место....


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 2 2013, 06:29
Сообщение #11


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Скобочки - запросто мог потерять.
Цитата(demiurg_spb @ Dec 2 2013, 08:39) *
Ну и если ещё продолжить придираться, то аргумент функции размером меньше int на ARM архитектуре менее оптимален. Так что char'у тут не место....


Если нужны вычисления на этапе выполнения, то для чего вообще эти инлайны? Это несерьезно. В конце концов, bit band существует.
Go to the top of the page
 
+Quote Post
winipuh
сообщение Dec 2 2013, 08:24
Сообщение #12


Частый гость
**

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



Я не придраться sad.gif
Просто уже и раньше кое-где встречал наподобие
Код
void func(const int x)
{
     ....
}

Например, в исходниках scmRTOS. Теперь вот и у Паши (уважаемого, надо сказать, человека sm.gif).
Вот я и спрашиваю... Вдруг в этом есть какой-то глубокий смысл, а я и не в курсе... laughing.gif
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 2 2013, 08:36
Сообщение #13


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(winipuh @ Dec 2 2013, 11:24) *
Вот я и спрашиваю... Вдруг в этом есть какой-то глубокий смысл, а я и не в курсе... laughing.gif

Ну, вдруг кто-то (или сам автор) задаст в value переменную. А компилятор - бац - нельзя! rolleyes.gif
Go to the top of the page
 
+Quote Post
winipuh
сообщение Dec 2 2013, 09:50
Сообщение #14


Частый гость
**

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



Цитата(ViKo @ Dec 2 2013, 12:36) *
Ну, вдруг кто-то (или сам автор) задаст в value переменную. А компилятор - бац - нельзя! rolleyes.gif

Шутить изволите? sm.gif
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 2 2013, 10:13
Сообщение #15


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(winipuh @ Dec 2 2013, 12:50) *
Шутить изволите? sm.gif

По-моему, в книге Шилдта описан этот прием. Для библиотечных функций.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 09:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01476 секунд с 7
ELECTRONIX ©2004-2016