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

 
 
> Вопрос по макросу в С, Сброс/установка битов в двух разных портах
mempfis_
сообщение Sep 16 2008, 10:22
Сообщение #1


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

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Помогите пожалуйста с макросом 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
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 14)
Сергей Борщ
сообщение Sep 16 2008, 10:41
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Sep 16 2008, 10:49
Сообщение #3


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

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(Сергей Борщ @ Sep 16 2008, 14:41) *
Покажите, как используете.


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


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

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


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


А из двух не хочет sad.gif
И ещё попутно вопрос каково назначение \ ?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Sep 16 2008, 10:50
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Например, можно записать так
#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);
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Sep 16 2008, 11:00
Сообщение #5


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

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(Палыч @ 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
Go to the top of the page
 
+Quote Post
Палыч
сообщение Sep 16 2008, 11:00
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(mempfis_ @ Sep 16 2008, 13:49) *
И ещё попутно вопрос каково назначение \ ?
Обратная косая означает: следующая строка - продолжение предыдущей (т.е. исключить возврат каретки). Обычно используется для записи в несколько строк элементов, которые по правилам должны распологаться в одной строке (например, #define)
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Sep 16 2008, 11:01
Сообщение #7


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

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(Палыч @ Sep 16 2008, 15:00) *
Обратная косая означает: следующая строка - продолжение предыдущей (т.е. исключить возврат каретки). Обычно используется для записи в несколько строк элементов, которые по правилам должны распологаться в одной строке (например, #define)

a14.gif a14.gif
Всем огромное спасибо smile.gif
Проблема решена smile.gif
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Sep 16 2008, 11:03
Сообщение #8


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Посмотрите вывод препроцессора. Сильно помогает разобраться с макросами, ошибки сразу видны после препроцессора.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 16 2008, 11:08
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Sep 16 2008, 11:19
Сообщение #10


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



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

+1. Без препроцесора не разобраться smile.gif


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Sep 16 2008, 11:37
Сообщение #11


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

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



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


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

Вызоа макроса в операторе if-else в программе?
Проверил у себя в вроде всё работает.
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Sep 16 2008, 12:23
Сообщение #12


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Определение блока (фигурные скобки) может сыграть злую шутку:

Код
#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. Заложены очень хорошие идеи.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
kurtis
сообщение Sep 16 2008, 12:27
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Может проще отказаться от использования макросов и использовать встраиваемые функции (inline functions)???
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Sep 16 2008, 12:33
Сообщение #14


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

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(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
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Sep 16 2008, 12:42
Сообщение #15


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Пример макроса (идея из GCC)
Код
#define Set1() \
do { \
PORTA |= (1<<BIT1);\
PORTB &= ~(1<<BIT2);\
} while (0)


Сергей Борщ в форуме по AVR комментировал используемую здесь идею. Оптимизатор компилятора выкинет цикл, но оставит тело цикла. Безопасное использование гарантировано. Сам пишу сложные макросы на основе этой идеи.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 26th July 2025 - 06:46
Рейтинг@Mail.ru


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