Перейти к содержанию
    

Как собрать идентификатор из частей

Здравствуйте.

Вот столкнулся с примитивной, казалось бы, проблемой при написании своей программы на языке 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.

Подскажите, может быть, существует другой способ решить эту проблему.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не проще ли потратить 10 минут времени и эти самые define прописать один единственный раз руками. Или, по вашему мнению, лучше угрохать на эту псевдоавтоматизацию день-два?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2sergeeff

Я пытаюсь писать "правильно", чтобы готовые модули можно было повторно использовать, в т.ч. и на другой аппаратной базе с минимумом правок.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день!

Подскажите пожалуйста, как в дефайне к символу присоединить апострофы по бокам?

#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
{...}

Проблема в том, что макросы Аскольда подставляют голые символы в нужное место, а шаблоны Си++ используют типизированные константы, и мне хотелось бы с помощью макроса преобразовать Аскольдовское объявление пина в совместимое с шаблоном, поставив по краям к буковкам апострофы. Но компилятор ругается...

А вообще все это нужно чтобы я мог один раз объявив расположение ног в отдельном заголовочнике, затем использовать их и в сишных и в С++-ных частях программы, не заморачиваясь. Да и вообще для совместимости новых версий со старыми. ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подскажите пожалуйста, как в дефайне к символу присоединить апострофы по бокам... Но компилятор ругается...
Вы бы указали какой компилятор. Keil, например, Вашу конструкцию прекрасно понимает...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прошу прощения. Компилятор IAR EWAVR 4.40.

Портабельно будет так:

#define TOCHAR(C)  #C[0]

var = TOCHAR(1);

В результате var будет присвоено 49.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда получается так: (оставил преобразование только последнего символа)

#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]// таже ошибка

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#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 и Палыч за отзывчивость!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...