Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: шаблон и регистр IO AVR
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
megajohn
Как правильно в шаблоне определить и использовать регистр (к примеру UDR0 ) ?
кроме как передавать типы и значения в шаблоны не приходилось и как только не химичил c __io (аля volatile) ничего путного не выходило
scifi
ИМХО, нужно шаблону передать тип, у которого есть (статические) методы "записать регистр", "прочитать регистр".
Непомнящий Евгений
Код
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> скрывает детали процессора.
neiver
Я обычно использую такую класс-обёртку:
Код
#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;

Работает со всеми компиляторами независимо от того, как именно объявлен регистр (как дефайт, или еще что).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.