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

 
 
> Как собрать идентификатор из частей, в С с использованием #define
Dmitro25
сообщение Apr 16 2010, 07:07
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 4-04-07
Пользователь №: 26 770



Здравствуйте.
Вот столкнулся с примитивной, казалось бы, проблемой при написании своей программы на языке C:
Мне необходимо получить идентификатор, обозначающий номер вектора прерываний, задавая число=номеру прерывания. Причём этот номер задаётся с помощью директивы #define. Поясню с помощью кода:
Код
#define INT0N 3 // номер прерывания для линии INT0
#define INT1N 2 // номер прерывания для линии INT1

#define MAKE_VECTOR_NAME(n) INT##n##_vect
#define INT0_VECTOR MAKE_VECTOR_NAME(INT0N)  // вектор прерывание для для линии INT0
#define INT1_VECTOR MAKE_VECTOR_NAME(INT1N)  // вектор прерывание для для линии INT1
#define ENABLE_INT0 EIMSK=(EIMSK|(1<<INT1N))
#define ENABLE_INT1 EIMSK=(EIMSK|(1<<INT0N))
...
#pragma vector = INT0_VECTOR
__interrupt void int0_isr_routine(void)
{
}

#pragma vector = INT1_VECTOR
__interrupt void int1_isr_routine(void)
{
}

В начале модуля задаётся номер прерывания INT0N, затем он используется для разрешения/запрещения данного прерывания (манипуляции с EIMSK). Также хотелось бы использовать этот номер при объявлении процедуры соответствующего прерывания "#pragma vector =xxxx". Однако, при компиляции приведённого выше кода, выдаётся ошибка ""INTINT0N_vect" is undefined", то есть в макросе MAKE_VECTOR_NAME не происходит подстановка числа вместо "INT0N".
Компилятор IAR for AVR.
Подскажите, может быть, существует другой способ решить эту проблему.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 11)
sergeeff
сообщение Apr 16 2010, 07:50
Сообщение #2


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Не проще ли потратить 10 минут времени и эти самые define прописать один единственный раз руками. Или, по вашему мнению, лучше угрохать на эту псевдоавтоматизацию день-два?
Go to the top of the page
 
+Quote Post
Dmitro25
сообщение Apr 16 2010, 08:28
Сообщение #3


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 4-04-07
Пользователь №: 26 770



2sergeeff
Я пытаюсь писать "правильно", чтобы готовые модули можно было повторно использовать, в т.ч. и на другой аппаратной базе с минимумом правок.
Go to the top of the page
 
+Quote Post
XVR
сообщение Apr 16 2010, 08:45
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Код
#define MAKE_VECTOR_NAME2(n) INT##n##_vect
#define MAKE_VECTOR_NAME(n) MAKE_VECTOR_NAME2(n)
Go to the top of the page
 
+Quote Post
Dmitro25
сообщение Apr 16 2010, 09:18
Сообщение #5


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 4-04-07
Пользователь №: 26 770



2XVR
Благодарю. Про вложенные define'ы я не подумал. Действительно, работает как должно.
Go to the top of the page
 
+Quote Post
Waso
сообщение Sep 2 2010, 10:53
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 268
Регистрация: 4-11-05
Пользователь №: 10 470



Добрый день!
Подскажите пожалуйста, как в дефайне к символу присоединить апострофы по бокам?
Код
#define ioc(x)  _ioc(x,y,z)
#define _ioc(x,y,z) '##x##',y, '##z##'  

#define ChipSel1  А, 7, L
#include "ascold.h"

Pin<ioc(ChipSel1)> CS1; // Error[Pe026]: too many characters in character constant

Нужно это все чтобы скрестить известный набор макросов для дрыгания ногами ascold.h с шаблоном С++, предназначенным для той-же цели.
Код
template<char port, char bit, char activestate>
class Pin
{...}

Проблема в том, что макросы Аскольда подставляют голые символы в нужное место, а шаблоны Си++ используют типизированные константы, и мне хотелось бы с помощью макроса преобразовать Аскольдовское объявление пина в совместимое с шаблоном, поставив по краям к буковкам апострофы. Но компилятор ругается...
А вообще все это нужно чтобы я мог один раз объявив расположение ног в отдельном заголовочнике, затем использовать их и в сишных и в С++-ных частях программы, не заморачиваясь. Да и вообще для совместимости новых версий со старыми. wink.gif
Go to the top of the page
 
+Quote Post
Палыч
сообщение Sep 2 2010, 12:22
Сообщение #7


Гуру
******

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



Цитата(Waso @ Sep 2 2010, 14:53) *
Подскажите пожалуйста, как в дефайне к символу присоединить апострофы по бокам... Но компилятор ругается...
Вы бы указали какой компилятор. Keil, например, Вашу конструкцию прекрасно понимает...
Go to the top of the page
 
+Quote Post
Waso
сообщение Sep 2 2010, 14:49
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 268
Регистрация: 4-11-05
Пользователь №: 10 470



Прошу прощения. Компилятор IAR EWAVR 4.40.
Go to the top of the page
 
+Quote Post
halfdoom
сообщение Sep 2 2010, 16:58
Сообщение #9


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

Группа: Свой
Сообщений: 1 003
Регистрация: 20-01-05
Пользователь №: 2 072



Цитата(Waso @ Sep 2 2010, 18:49) *
Прошу прощения. Компилятор IAR EWAVR 4.40.

Портабельно будет так:
Код
#define TOCHAR(C)  #C[0]

var = TOCHAR(1);

В результате var будет присвоено 49.
Go to the top of the page
 
+Quote Post
Waso
сообщение Sep 3 2010, 04:48
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 268
Регистрация: 4-11-05
Пользователь №: 10 470



Тогда получается так: (оставил преобразование только последнего символа)
Код
#define TOCHAR(C)  #C[0]
#define ioc(x)  _ioc(x,y,z)
#define _ioc(x,y,z) _ioc2(x,y,z)
#define _ioc2(x,y,z)  x,y, TOCHAR(')##z##TOCHAR(') // Error[Pe529]: this operator is not allowed in a template argument expression
!Ругается теперь иначе! Добавил еще один уровень дефайнов - не помогло. Еще так:
Код
#define _ioc2(x,y,z)  x,y, #'[0]##z#'[0]// таже ошибка
Go to the top of the page
 
+Quote Post
halfdoom
сообщение Sep 3 2010, 06:06
Сообщение #11


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

Группа: Свой
Сообщений: 1 003
Регистрация: 20-01-05
Пользователь №: 2 072



Правильно будет так:
Код
#define _ioc(x,y,z)  x,y, TOCHAR(z)


Go to the top of the page
 
+Quote Post
Waso
сообщение Sep 3 2010, 07:00
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 268
Регистрация: 4-11-05
Пользователь №: 10 470



Код
#define _ioc(x,y,z)  x,y, TOCHAR(z)
- нет, всеравно ругается Error[Pe529]: this operator is not allowed in a template argument expression - ему не нравится решетка из макроса TOCHAR внутри шаблона, но как она туда попадает - непонятно, потомучто еще уровень вложенности добавил специально...

Но я уже решил проблему иначе! УРА!
Меня осенило использовать перечислимый тип в объявлении шаблона вместо char:
Код
typedef enum { L, H }  GPIO_mode_t;
typedef enum { A, B, C, D, E, F }  Portname;
template<Portname port, PORT_TYPE mask, GPIO_mode_t activestate>
class Pins
{...}
Так даже грамотнее получается, чем костыли из дефайнов громоздить.

Однако тем не менее выражаю благодарность halfdoom и Палыч за отзывчивость!
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 08:56
Рейтинг@Mail.ru


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