|
// размеры буферов приема/передачи :
#define RX_SIZE 16
#define TX_SIZE 8// если размер буфера - степень двойки,
// для замыкания можно множить на маску :
// (соответствующую размеру буфера)
#define RX_MASK RX_SIZE-1
#define TX_MASK TX_SIZE-1
// буферы приема-передачи :
byte rx_buf [RX_SIZE];
byte tx_buf [TX_SIZE];
// указатели чтения-записи,
// кол-во байт в буфере приема,
// кол-во свободных в буфере передачи
volatile byte rx_wr,rx_rd,rx_volume;
volatile byte tx_wr,tx_rd,tx_free;// флаг "UART Empty"
volatile byte tx_empty;
//-------------------------------------------------interrupt [USART0_UDRE_vect] void uart_txe (void)
{if (tx_free == TX_SIZE)
{
// если кольцевой буфер уже пуст, запретим прерывания
// и выставим флаг:
tx_empty=1;
UCSR0B &= ~UDRIE;
}
else
{
// если в кольцевом буфере есть данные
// выведем их и замкнем буфер:
++tx_free ;
UDR0 = tx_buf [tx_rd++];
// замыкание буфера :
tx_rd &= TX_MASK;
}
}
// ---------------------------------
void putbyte (byte bout)
{
// занесем байт в кольцевой буфер вывода
// и разрешим передачу если нужно
for (;tx_free == 0;) {}tx_buf [tx_wr++] =bout;
// замыкание буфера :
// if (tx_wr leq TX_SIZE) tx_wr =0;
tx_wr &= TX_MASK;
_CLI ();
-- tx_free;if (tx_empty leq 1)
{
tx_empty =0;
UCSR0B |= UDRIE;
}
_SEI ();
}
// ------------------------------------
E-mail: info@telesys.ru