Писал когда-то что-то такое: #ifndef USCIA_H__
#define USCIA_H__
#include <io.h>
#ifndef USCIB_H__
enum usci_module_t { USCI0, USCI1 };
#endif
template <usci_module_t const module>
class uscia_t
{
public:
class usca_ctl0_t /* USCI Ax Control Register 0 */
{
public:
uint8_t operator=(uint8_t value) { module ? UCA1CTL0 = value : UCA0CTL0 = value; return value; }
uint8_t operator|=(uint8_t value) { module ? UCA1CTL0 |= value : UCA0CTL0 |= value; return value; }
uint8_t operator&=(uint8_t value) { module ? UCA1CTL0 &= value : UCA0CTL0 &= value; return value; }
operator uint8_t() { return module ? UCA1CTL0 : UCA0CTL0; }
} static CTL0;
class usca_ctl1_t /* UCI Ax Control Register 1 */
{
public:
uint8_t operator=(uint8_t value) { module ? UCA1CTL1 = value : UCA0CTL1 = value; return value; }
uint8_t operator|=(uint8_t value) { module ? UCA1CTL1 |= value : UCA0CTL1 |= value; return value; }
uint8_t operator&=(uint8_t value) { module ? UCA1CTL1 &= value : UCA0CTL1 &= value; return value; }
operator uint8_t() { return module ? UCA1CTL1 : UCA0CTL1; }
} static CTL1;
.....
class usca_rxbuf_t /* UCI Ax Receive Buffer */
{
public:
operator uint8_t() { return module ? UCA1RXBUF : UCA0RXBUF; }
} static RXBUF;
class usca_txbuf_t /* UCI Ax Transmit Buffer */
{
public:
uint8_t operator=(uint8_t value) { module ? UCA1TXBUF = value : UCA0TXBUF = value; return value; }
uint8_t operator|=(uint8_t value) { module ? UCA1TXBUF |= value : UCA0TXBUF |= value; return value; }
uint8_t operator&=(uint8_t value) { module ? UCA1TXBUF &= value : UCA0TXBUF &= value; return value; }
operator uint8_t() { return module ? UCA1TXBUF : UCA0TXBUF; }
} static TXBUF;
.....
// flags
class rxifg_t
{
public:
operator uint8_t() { return module ? UCA1RXIFG : UCA0RXIFG; }
} static RXIFG;
class rxie_t
{
public:
operator uint8_t() { return module ? UCA1RXIE : UCA0RXIE; }
} static RXIE;
.....
class rxd_bit
{
public:
operator uint8_t() { return module ? (1 << 7) : (1 << 5); }
} static RXD_BIT;
class mosi_bit
{
public:
operator uint8_t() { return TXD_BIT; }
} static MOSI_BIT;
class miso_bit
{
public:
operator uint8_t() { return RXD_BIT; }
} static MISO_BIT;
class clk_ste_port
{
public:
operator uint8_t volatile *() const { return module ? &P5IN : &P3IN; }
} static CLK_STE_PORT;
};
#endif // USCIA_H__
#ifndef UART_H__
#define UART_H__
#include <stdint.h>
#include <io.h>
#include "../common/usciA.h"
#include <scmRTOS.h>
#ifndef INLINE
#define INLINE __attribute__((__always_inline__))
#endif
template <usci_module_t module>
class uart_t
{
typedef uscia_t<module> UCA;
.....
};
template <usci_module_t module>
void uart_t<module>::init(uint32_t const divider)
{
UCA::CTL1 |= (1 * UCSWRST);
UCA::CTL1 = 0
|(0 * UCRXEIE)|(0 * UCBRKIE)|(0 * UCTXADDR)
|(1 * UCSWRST)
|(1 * UCSSEL1)|(0 * UCSSEL0)
;
UCA::CTL0 = (0 * UCPEN)|(0 * UCMSB)|(0 * UC7BIT)|(0 * UCSPB)|(0 * UCMODE1)|(0 * UCMODE0)|(0 * UCSYNC);
UCA::BR0 = (divider / 16) & 0xFF;
UCA::BR1 = (divider / 16) >> 8;
UCA::MCTL = ((divider - (divider / 16) * 16) * UCBRF0)
|(0 * UCBRS0)|(1 * UCOS16);
UCA::CTL1 &= ~(1 * UCSWRST);
P3SEL |= UCA::RXD_BIT | UCA::TXD_BIT;
UCA::IFG |= UCA::TXIFG;
UCA::IE |= UCA::RXIE;
}
static uart_t<USCI1> UART __attribute__((unused));