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

 
 
> шаблон и регистр IO AVR
megajohn
сообщение Jun 22 2012, 08:13
Сообщение #1


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

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



Как правильно в шаблоне определить и использовать регистр (к примеру UDR0 ) ?
кроме как передавать типы и значения в шаблоны не приходилось и как только не химичил c __io (аля volatile) ничего путного не выходило


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 3)
scifi
сообщение Jun 22 2012, 08:28
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



ИМХО, нужно шаблону передать тип, у которого есть (статические) методы "записать регистр", "прочитать регистр".
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Jun 22 2012, 09:43
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Код
template<volatile unsigned char* __io Reg>
struct Test
{
  void f() { *Reg = 0; }
};

Test<&PORTA> t;
t.f();


Правда учти, что некоторые регистры - __ext_io

Еще можно специализации использовать:
Код
template<int No>
struct USART;

#define defUART(N)
template<> struct USART<N> { \
    INLINE static void enableReadyToSendInt(bool v) { PUTBIT(UCSR##N##B, UDRIE##N, v); } \
    INLINE static void enableReceivedInt(bool v) { PUTBIT(UCSR##N##B, RXCIE##N, v); } \
    INLINE static void enableSendInt(bool v) { PUTBIT(UCSR##N##B, TXCIE##N, v); } \
    INLINE static void enableSend(bool v) { PUTBIT(UCSR##N##B, TXEN##N, v); } \
    INLINE static void clearSendIntFlag() { UCSR##N##A = BIT(TXC##N); } \
    INLINE static byte read() { return UDR##N; } \
    INLINE static void write(byte v) { UDR##N = v; } \
    INLINE static void clearInputBuffer() { read(); read(); read(); } \
    INLINE static bool isFrameError() { return TESTBIT(UCSR##N##A, FE##N); } \
};

#if defined ATMEGA128

enum {Usart0, Usart1};

defUART(0)
defUART(1)

#elif defined ATMEGA1280

enum {Usart0, Usart1, Usart2, Usart3};

defUART(0)
defUART(1)
defUART(2)
defUART(3)

....


А затем USART<x> можно передавать как аргумент шаблона. Имхо это лучше передачи регистров - семантика регистров сильно процессорно-зависима, а USART<x> скрывает детали процессора.
Go to the top of the page
 
+Quote Post
neiver
сообщение Jun 22 2012, 10:16
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Я обычно использую такую класс-обёртку:
Код
#define IO_REG_WRAPPER(REG_NAME, CLASS_NAME, DATA_TYPE) \
    struct CLASS_NAME\
    {\
        typedef DATA_TYPE DataT;\
        static DataT Get(){return REG_NAME;}\
        static void Set(DataT value){REG_NAME = value;}\
        static void Or(DataT value){REG_NAME |= value;}\
        static void And(DataT value){REG_NAME &= value;}\
        static void Xor(DataT value){REG_NAME ^= value;}\
        static void AndOr(DataT andMask, DataT orMask){REG_NAME = (REG_NAME & andMask) | orMask;}\
        template<int Bit>\
        static bool BitIsSet(){return REG_NAME & (1 << Bit);}\
        template<int Bit>\
        static bool BitIsClear(){return !(REG_NAME & (1 << Bit));}\
    }

Использовать его так:
Код
IO_REG_WRAPPER(UDR0, Udr0, uint8_t);

template<class Udr>
class Usart
{
....
};
...
Usart<Udr0> usart;

Работает со всеми компиляторами независимо от того, как именно объявлен регистр (как дефайт, или еще что).
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 3rd August 2025 - 20:40
Рейтинг@Mail.ru


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