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

Группа: Свой
Сообщений: 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. Подскажите, может быть, существует другой способ решить эту проблему.
|
|
|
|
|
 |
Ответов
(1 - 11)
|
Apr 16 2010, 08:28
|
Участник

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

|
2sergeeff Я пытаюсь писать "правильно", чтобы готовые модули можно было повторно использовать, в т.ч. и на другой аппаратной базе с минимумом правок.
|
|
|
|
|
Apr 16 2010, 09:18
|
Участник

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

|
2XVR Благодарю. Про вложенные define'ы я не подумал. Действительно, работает как должно.
|
|
|
|
|
Sep 2 2010, 10:53
|

Местный
  
Группа: Свой
Сообщений: 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 {...} Проблема в том, что макросы Аскольда подставляют голые символы в нужное место, а шаблоны Си++ используют типизированные константы, и мне хотелось бы с помощью макроса преобразовать Аскольдовское объявление пина в совместимое с шаблоном, поставив по краям к буковкам апострофы. Но компилятор ругается... А вообще все это нужно чтобы я мог один раз объявив расположение ног в отдельном заголовочнике, затем использовать их и в сишных и в С++-ных частях программы, не заморачиваясь. Да и вообще для совместимости новых версий со старыми.
|
|
|
|
|
Sep 2 2010, 16:58
|

Профессионал
    
Группа: Свой
Сообщений: 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.
|
|
|
|
|
Sep 3 2010, 04:48
|

Местный
  
Группа: Свой
Сообщений: 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]// таже ошибка
|
|
|
|
|
Sep 3 2010, 07:00
|

Местный
  
Группа: Свой
Сообщений: 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 и Палыч за отзывчивость!
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|