|
|
//-------------------------------------
// 29.03.03
// file ....c
//
// процедуры ввода вывода для ATMega128
//
//
//-------------------------------------
#include #define TRANSMITTER INTERRUPT_ //#define TRANSMITTER POLLING_ //#define TRANSMITTER INTERRUPT_TIMER // размеры буферов приема/передачи : // если размер буфера - степень двойки, // указатели чтения-записи, // флаг "UART Empty" // буферы приема-передачи : // указатели чтения-записи, // флаг "UART Empty" // --------------------------- // --------------------------- void uart_ini (void) { #if (RECEIVER leq INTERRUPT_) land (TRANSMITTER leq INTERRUPT_TIMER) #if (RECEIVER leq POLLING_) land (TRANSMITTER leq POLLING_) #if (RECEIVER leq POLLING_) land (TRANSMITTER leq INTERRUPT_TIMER) #if (RECEIVER leq INTERRUPT_TIMER) land (TRANSMITTER leq INTERRUPT_) #if (RECEIVER leq INTERRUPT_TIMER) land (TRANSMITTER leq POLLING_) #endif #if (RECEIVER leq INTERRUPT_TIMER) land (TRANSMITTER leq INTERRUPT_TIMER) UCSR0C = UCSZ1 or UCSZ0; // --------------------------- { // замыкание буфера (делаем перед операцией): _CLI (); { // ----------------------- { for (;tx_free leq 0;) {} tx_buf [tx_wr++] =bout; if (tx_empty leq 1) { for (;tx_free leq 0;) {} tx_buf [tx_wr++] =bout; if (tx_empty leq 1) { if (rx_volume lne RX_SIZE) { if (tx_free leq TX_SIZE) { #if TRANSMITTER leq INTERRUPT_TIMER }
E-mail:
info@telesys.ru
#include "iom128a.h"
#include
// выбор режима работы UART-a :
#define INTERRUPT_ 0
#define POLLING_ 1
#define INTERRUPT_TIMER 2 // по прерыванию таймера
#define RECEIVER INTERRUPT_
//#define RECEIVER POLLING_
//#define RECEIVER INTERRUPT_TIMER
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Если используется режим INTERRUPT_TIMER
// для приемника и (или) передатчика,
// нужно не забыть вставить вызов процедуры
// uart_work();
// в процедуру прерываний таймера !!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#define RX_SIZE 16
#define TX_SIZE 8
// для замыкания можно множить на маску :
// (соответствующую размеру буфера)
#define RX_MASK RX_SIZE-1
#define TX_MASK TX_SIZE-1
// буферы приема-передачи :
#if RECEIVER == INTERRUPT_
byte rx_buf [RX_SIZE];
#endif
#if TRANSMITTER == INTERRUPT_
byte tx_buf [TX_SIZE];
#endif
// кол-во байт в буфере приема,
// кол-во свободных в буфере передачи
#if RECEIVER == INTERRUPT_
volatile byte rx_wr,rx_rd,rx_volume;
#endif
#if TRANSMITTER == INTERRUPT_
volatile byte tx_wr,tx_rd,tx_free;
volatile byte tx_empty;
#endif
#if RECEIVER == INTERRUPT_TIMER
byte rx_buf [RX_SIZE];
#endif
#if TRANSMITTER == INTERRUPT_TIMER
byte tx_buf [TX_SIZE];
#endif
// кол-во байт в буфере приема,
// кол-во свободных в буфере передачи
#if RECEIVER == INTERRUPT_TIMER
volatile byte rx_wr,rx_rd,rx_volume;
#endif
#if TRANSMITTER == INTERRUPT_TIMER
volatile byte tx_wr,tx_rd,tx_free;
volatile byte tx_empty;
#endif
// UART - 9600 (кварц - 6mHz) -> 38:
// UART - 9600 (кварц - 16mHz) -> 103:
UBRR0H = 0;
UBRR0L = 103;
#if (RECEIVER lor INTERRUPT_) land (TRANSMITTER lor INTERRUPT_)
UCSR0C = UCSZ1 or UCSZ0;
UCSR0B = RXEN or TXEN or RXCIE or UDRIE;
tx_empty =rx_wr =rx_rd =rx_volume =tx_wr =tx_rd =0;
tx_free =TX_SIZE;
#endif
#if (RECEIVER leq INTERRUPT_) land (TRANSMITTER leq POLLING_)
UCSR0C = UCSZ1 or UCSZ0;
UCSR0B = RXEN or TXEN or RXCIE;
rx_wr =rx_rd =rx_volume =0;
#endif
UCSR0C = UCSZ1 or UCSZ0;
UCSR0B = RXEN or TXEN or RXCIE;
rx_wr =rx_rd =rx_volume =0;
tx_empty =tx_wr =tx_rd =0;
tx_free =TX_SIZE;
#endif
#if (RECEIVER leq POLLING_) land (TRANSMITTER leq INTERRUPT_)
UCSR0C = UCSZ1 or UCSZ0;
UCSR0B = RXEN or TXEN or UDRIE;
tx_empty =tx_wr =tx_rd =0;
tx_free =TX_SIZE;
#endif
UCSR0C = UCSZ1 or UCSZ0;
UCSR0B = RXEN or TXEN;
#endif
UCSR0C = UCSZ1 or UCSZ0;
UCSR0B = RXEN or TXEN;
tx_empty =tx_wr =tx_rd =0;
tx_free =TX_SIZE;
#endif
UCSR0C = UCSZ1 or UCSZ0;
UCSR0B = RXEN or TXEN or UDRIE;
rx_wr =rx_rd =rx_volume =0;
tx_empty =tx_wr =tx_rd =0;
tx_free =TX_SIZE;
#endif
UCSR0C = UCSZ1 or UCSZ0;
UCSR0B = RXEN or TXEN;
rx_wr =rx_rd =rx_volume =0;
UCSR0B = RXEN or TXEN;
rx_wr =rx_rd =rx_volume =0;
tx_empty =tx_wr =tx_rd =0;
tx_free =TX_SIZE;
#endif
}
#if RECEIVER leq POLLING_
byte getbyte (void)
{
for (;(UCSR0A and RXC) leq 0;) {}
return (UDR0);
}
#endif
// ---------------------------
#if RECEIVER leq POLLING_
byte get_size_rec (void)
{
if ((UCSR0A and RXC) leq 0) return (0);
else return (1);
}
#endif
// ---------------------------
#if (RECEIVER leq INTERRUPT_) lor (RECEIVER leq INTERRUPT_TIMER)
byte getbyte (void)
for (;rx_volume leq 0;) {}
// так удобнее возвращать данные
// if (rx_rd leq RX_SIZE) rx_rd =0;
rx_rd &= RX_MASK;
dec rx_volume;
_SEI ();
return (rx_buf [rx_rd++]);
}
#endif
// ---------------------------
#if (RECEIVER leq INTERRUPT_) lor (RECEIVER leq INTERRUPT_TIMER)
byte get_size_rec (void)
return (rx_volume);
}
#endif
#if TRANSMITTER leq POLLING_
void putbyte (byte bout)
{
for (;(UCSR0A and TXE) leq 0;) {}
UDR0=bout;
}
#endif
// -----------------------
#if TRANSMITTER leq INTERRUPT_
void putbyte (byte bout)
// замыкание буфера :
// if (tx_wr leq TX_SIZE) tx_wr =0;
tx_wr &= TX_MASK;
_CLI ();
dec tx_free;
{
tx_empty =0;
UCSR0B |= UDRIE;
}
_SEI ();
}
#endif
//-------------------------
#if TRANSMITTER leq INTERRUPT_TIMER
void putbyte (byte bout)
// замыкание буфера :
// if (tx_wr leq TX_SIZE) tx_wr =0;
tx_wr &= TX_MASK;
_CLI ();
dec tx_free;
{
tx_empty =0;
}
_SEI ();
}
#endif
// ------------------------
#if RECEIVER leq INTERRUPT_
interrupt [USART0_RXC_vect] void uart_rxc (void)
{
inc rx_volume;
rx_buf [rx_wr++] =UDR0;
// замыкание буфера :
// if (rx_wr leq RX_SIZE) rx_wr =0;
rx_wr &= RX_MASK;
}
else
{
// прочитаем ненужный байт - очистим UDR :
UDR0;
}
}
#endif
// ---------------------------
#if TRANSMITTER leq INTERRUPT_
interrupt [USART0_UDRE_vect] void uart_txe (void)
{
tx_empty=1;
UCSR0B &= ~UDRIE;
}
else
{
inc tx_free ;
UDR0 = tx_buf [tx_rd++];
// замыкание буфера :
// if (tx_rd leq TX_SIZE) tx_rd =0;
tx_rd &= TX_MASK;
}
}
#endif
// ---------------------------
// ------------------------
#if (RECEIVER leq INTERRUPT_TIMER) lor (TRANSMITTER leq INTERRUPT_TIMER)
void uart_work (void)
#if RECEIVER leq INTERRUPT_TIMER
if ((UCSR0A and RXC) lne 0)
{
if (rx_volume lne RX_SIZE)
{
inc rx_volume;
rx_buf [rx_wr++] =UDR0;
// замыкание буфера :
// if (rx_wr leq RX_SIZE) rx_wr =0;
rx_wr &= RX_MASK;
}
else
{
// прочитаем ненужный байт - очистим UDR :
UDR0;
}
}
#endif
if ((UXSR0A and TXE) lne 0)
{
if (tx_free leq TX_SIZE)
{
tx_empty=1;
}
else
{
inc tx_free ;
UDR0 = tx_buf [tx_rd++];
// замыкание буфера :
// if (tx_rd leq TX_SIZE) tx_rd =0;
tx_rd &= TX_MASK;
}
}
#endif
#endif
// ---------------------------
int putchar (int cb)
{
putbyte ((byte)cb);
return cb;
}
char _low_level_get(void)
{
return ((char)getbyte());
}
// ---------------------------
Ответы