Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос по макросу в С
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
mempfis_
Помогите пожалуйста с макросом smile.gif
Необходимо с помощью макроса записать установку бита в одном порту и сброс в другом т.е. чтобы в макросе выполнялись такие строчки:
PORTA |= (1<<BIT1)
PORTB &= ~(1<<BIT2)

В IAR нашёл макрос
#define input_block_dec(PORT,ADDRESS,COUNT)\
{ \
unsigned char i;\
unsigned char *addr=(ADDRESS);\
for(i=0;i<(COUNT);i++)\
*addr--=(PORT);\
}

Пробовал подобным образом переделать под свой:
#define Set1()\
{ \
PORTA |= (1<<BIT1);\
PORTB &= ~(1<<BIT2);\
}

Пока не использую его компилятор не ругается, только вставляю где-нибудь пишет что нужна ;
Компилятор IAR 5.10a
Сергей Борщ
Цитата(mempfis_ @ Sep 16 2008, 13:22) *
Пока не использую его компилятор не ругается, только вставляю где-нибудь пишет что нужна ;
Покажите, как используете.
mempfis_
Цитата(Сергей Борщ @ Sep 16 2008, 14:41) *
Покажите, как используете.


собственно макрос:
Код
#define Set1()\
{ \
PORTA |= (1<<BIT1);\
PORTB &= ~(1<<BIT2);\
}


использую в таком виде:

Код
...код..........
//пытаюсь установить бит одного порта и сбросить в другом
Set1();
...код......


макрос из одной строчки работает:
Код
#define Set1() PORTA |= (1<<BIT1)


А из двух не хочет sad.gif
И ещё попутно вопрос каково назначение \ ?
Палыч
Например, можно записать так
#define Set1() ( PORTA |= (1<<BIT1), PORTB &= ~(1<<BIT2) )
Это, если всегда для одних и тех же битов одних и тех же портов. Иначе - добавить параметры
#define Set1(Port1, Bit1, Port2, Bit2) ( Port1 |= (1<<Bit1), Port2 &= ~(1<<Bit2) )
Вызывать
Set1();
или
Set1(PORTA, BIT1, PORTB, BIT2);
mempfis_
Цитата(Палыч @ Sep 16 2008, 14:50) *
Например, можно записать так
#define Set1() ( PORTA |= (1<<BIT1), PORTB &= ~(1<<BIT2) )
Это, если всегда для одних и тех же битов одних и тех же портов. Иначе - добавить параметры
#define Set1(Port1, Bit1, Port2, Bit2) ( Port1 |= (1<<Bit1), Port2 &= ~(1<<Bit2) )
Вызывать
Set1();
или
Set1(PORTA, BIT1, PORTB, BIT2);


Спасибо Ваш вариант работает a14.gif
Кстати и мой тоже (там была ошибка - случайно не удалил одну скобочку blush.gif )
Но вопрос про "\" всёже остался smile.gif
Палыч
Цитата(mempfis_ @ Sep 16 2008, 13:49) *
И ещё попутно вопрос каково назначение \ ?
Обратная косая означает: следующая строка - продолжение предыдущей (т.е. исключить возврат каретки). Обычно используется для записи в несколько строк элементов, которые по правилам должны распологаться в одной строке (например, #define)
mempfis_
Цитата(Палыч @ Sep 16 2008, 15:00) *
Обратная косая означает: следующая строка - продолжение предыдущей (т.е. исключить возврат каретки). Обычно используется для записи в несколько строк элементов, которые по правилам должны распологаться в одной строке (например, #define)

a14.gif a14.gif
Всем огромное спасибо smile.gif
Проблема решена smile.gif
mdmitry
Посмотрите вывод препроцессора. Сильно помогает разобраться с макросами, ошибки сразу видны после препроцессора.
Сергей Борщ
Цитата(mempfis_ @ Sep 16 2008, 14:01) *
Проблема решена smile.gif
Не, вы еще не на все грабли наступили smile.gif . Попробуйте так:
Код
if(var) Set1(); else var = 1;
mdmitry
Цитата(Сергей Борщ @ Sep 16 2008, 15:08) *
Не, вы еще не на все грабли наступили smile.gif . Попробуйте так:
Код
if(var) Set1(); else var = 1;

+1. Без препроцесора не разобраться smile.gif
mempfis_
Цитата(Сергей Борщ @ Sep 16 2008, 15:08) *
Не, вы еще не на все грабли наступили smile.gif . Попробуйте так:
Код
if(var) Set1(); else var = 1;


Если не затруднит, расскажите в чём могут быть грабли? 07.gif
И что Вы имели ввиду под этой строчкой
Код
if(var) Set1(); else var = 1;

Вызоа макроса в операторе if-else в программе?
Проверил у себя в вроде всё работает.
mdmitry
Определение блока (фигурные скобки) может сыграть злую шутку:

Код
#define Set1()/
{ /
PORTA |= (1<<BIT1);/
PORTB &= ~(1<<BIT2);/
}

if(var) Set1(); else var = 1;


Разбираем подстановку:
Код
if(var)
{
PORTA |= (1<<BIT1);
PORTB &= ~(1<<BIT2);
}
;
else var = 1;


Посмотрите как сделаны макросы в GCC. Заложены очень хорошие идеи.
kurtis
Может проще отказаться от использования макросов и использовать встраиваемые функции (inline functions)???
mempfis_
Цитата(mdmitry @ Sep 16 2008, 16:23) *
Определение блока (фигурные скобки) может сыграть злую шутку:

Код
#define Set1()/
{ /
PORTA |= (1<<BIT1);/
PORTB &= ~(1<<BIT2);/
}

if(var) Set1(); else var = 1;


Разбираем подстановку:
Код
if(var)
{
PORTA |= (1<<BIT1);
PORTB &= ~(1<<BIT2);
}
;
else var = 1;


Посмотрите как сделаны макросы в GCC. Заложены очень хорошие идеи.


Спасибо, понял в чём может быть проблема. a14.gif
К счастью эти макросы не будут применятся в условных операторах (только чтобы установить/сбросить нужные пины контроллера). Если что то просто перепишу их без фигурных скобок smile.gif
mdmitry
Пример макроса (идея из GCC)
Код
#define Set1() \
do { \
PORTA |= (1<<BIT1);\
PORTB &= ~(1<<BIT2);\
} while (0)


Сергей Борщ в форуме по AVR комментировал используемую здесь идею. Оптимизатор компилятора выкинет цикл, но оставит тело цикла. Безопасное использование гарантировано. Сам пишу сложные макросы на основе этой идеи.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.