|
Сложная автозамена через #define |
|
|
|
Dec 9 2015, 08:59
|

Местный
  
Группа: Участник
Сообщений: 240
Регистрация: 14-04-10
Из: Россия, г.Челябинск
Пользователь №: 56 634

|
Пример: сейчас Код // Запись значений по указателям *pTIMER7_PERIOD = 0x0000FFFF; *pTIMER7_WIDTH = 0x00007FFF; Как сделать такую запись через всего 1 дефайн? Т.к. текст TIMER7 есть во всех именах регистров, то, наверно, их можно заменить одним дефайном? Код #define BKLT_TIMER TIMER7
*pBKLT_TIMER_PERIOD = 0x0000FFFF; *pBKLT_TIMER_WIDTH = 0x00007FFF; и т.д. Что нужно дополнительно сделать, чтобы такая замена работала?
|
|
|
|
|
Dec 9 2015, 11:33
|
Профессионал
    
Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528

|
Цитата(kolobochishe @ Dec 9 2015, 15:59)  и т.д. Что нужно дополнительно сделать, чтобы такая замена работала? Так не получится, потому что pBKLT_TIMER_WIDTH для препроцессора уже одна неделимая лексема и всё что он может с ней сделать разве что заменить целиком. Удобнее подход, когда набор из четырёх регистров таймера описывается как структура. Тогда TIMER7 можно описать как указатель на такую структуру, а к регистрам обращаться как TIMER7->PERIOD. Где-то так, по примеру CMSIS для кортексов и без учёта особенностей компилятора. Код #define __IO volatile typedef struct{ __IO uint16_t CONFIG; __IO uint32_t COUNTER; __IO uint32_t PERIOD; __IO uint32_t WIDTH; }Timer_TypeDef; #define TIMER0 ((Timer_TypeDef*)0xFFC01600) ... #define TIMER7 (TIMER0+7)
#define BKLT_TIMER TIMER7 BKLT_TIMER->PERIOD = 0x0000FFFF; BKLT_TIMER->WIDTH = 0x00007FFF;
--------------------
Russia est omnis divisa in partes octo.
|
|
|
|
|
Dec 15 2015, 12:48
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(kolobochishe @ Dec 9 2015, 14:59)  *pBKLT_TIMER_PERIOD = 0x0000FFFF; *pBKLT_TIMER_WIDTH = 0x00007FFF;[/code] и т.д. Что нужно дополнительно сделать, чтобы такая замена работала? #define concatABC_(a, b, c) a##b##c #define concatABC(a, b, c) concatABC_(a, b, c) #define TIMER TIMER7 *concatABC(p, TIMER, _PERIOD) = 0x0000FFFF;
|
|
|
|
|
Dec 16 2015, 15:42
|

Местный
  
Группа: Участник
Сообщений: 240
Регистрация: 14-04-10
Из: Россия, г.Челябинск
Пользователь №: 56 634

|
Цитата(SSerge @ Dec 9 2015, 17:33)  ... Удобнее подход, когда набор из четырёх регистров таймера описывается как структура. Тогда TIMER7 можно описать как указатель на такую структуру, а к регистрам обращаться как TIMER7->PERIOD. ... Было такое желание, но мне не хочется создавать лишние структуры. Хоть на нынешнем контроллере можно и истратить лишние байты, но все же, по-моему, лучше экономить память. Вдруг завтра на Attiny что-то придется делать Цитата(jcxz @ Dec 15 2015, 18:48)  #define concatABC_(a, b, c) a##b##c #define concatABC(a, b, c) concatABC_(a, b, c)
#define TIMER TIMER7 *concatABC(p, TIMER, _PERIOD) = 0x0000FFFF; Спасибо  правда непонятно как это работает...
Сообщение отредактировал kolobochishe - Dec 16 2015, 16:02
|
|
|
|
|
Dec 18 2015, 08:16
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(kolobochishe @ Dec 16 2015, 21:42)  Спасибо  правда непонятно как это работает... А что именно непонятно? Как я понял: у Вас есть записи типа *pTIMER7_PERIOD = 0x0000FFFF; и Вы хотите, чтобы конкретный таймер можно было задать где в заголовке дефайном, типа #define MY_TIMER TIMER7и чтобы, при необходимости, можно было в одном месте поменять номер таймера не редактируя весь исходник. Это можно сделать макросами как я описал: #define MY_TIMER TIMER7 ... *concatABC(p, MY_TIMER, _PERIOD) = 0x0000FFFF;Если Вы хотели нечто другое, то формулируйте вопрос яснее.
|
|
|
|
|
Dec 18 2015, 10:28
|

Местный
  
Группа: Участник
Сообщений: 240
Регистрация: 14-04-10
Из: Россия, г.Челябинск
Пользователь №: 56 634

|
Цитата(jcxz @ Dec 18 2015, 13:16)  А что именно непонятно? ... Непонятно как эта двухуровневая конструкция работает  Так то понятно, я это и хотел, но простая конкатенация с одним уровнем не работает. Компилятор сразу подставляет MY_TYMER вместо TIMER7 Цитата(barabek @ Dec 18 2015, 10:32)  Добавлю. Поля структуры это регистры периферии (на сленге : поля замапены на регистры). Если вы какие-то поля (читай - регистры) не используете по прямому назначению, то как вы их еще можете использовать? Бывают регистры, которые в таймере добавляют какой-то функционал. Например статус, маска прерываний. А мне нужен просто ШИМ выход для подсветки, без всяких статусов. Но это уже неважно. Я понял что никакой переменной-структуры не создается, а определение структуры нужно лишь для задания смещений относительно первого регистра конкретного таймера. Если они все расположены друг за другом (вроде других вариантов пока не встречал), то хороший метод
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|