📄 uartm128.c
字号:
/* Code adapted from Atmel AVR Application Note AVR306
* Interrupt mode driver for UART.
*/
#include <iom128v.h>
#include <macros.h>
#include "uartM128.h"
/* IMPORTANT: these vector numbers are for 8515! If you use other devices
* you must change them to the different set of numbers.
*
* UART_RX_interrupt set to UART, Rx Complete
* UART_TX_interrupt set to UART Data Register Empty
*/
#pragma interrupt_handler UART0_RX_interrupt:iv_USART0_RX UART0_TX_interrupt:iv_USART0_TX
#pragma interrupt_handler UART1_RX_interrupt:iv_USART1_RX UART1_TX_interrupt:iv_USART1_TX
/* UART Buffer Defines */
#define UART0_RX_BUFFER_SIZE 128 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART0_RX_BUFFER_MASK ( UART0_RX_BUFFER_SIZE - 1 )
#define UART0_TX_BUFFER_SIZE 128 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART0_TX_BUFFER_MASK ( UART0_TX_BUFFER_SIZE - 1 )
#define UART1_RX_BUFFER_SIZE 128 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART1_RX_BUFFER_MASK ( UART1_RX_BUFFER_SIZE - 1 )
#define UART1_TX_BUFFER_SIZE 128 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART1_TX_BUFFER_MASK ( UART1_TX_BUFFER_SIZE - 1 )
#if ( UART0_RX_BUFFER_SIZE & UART0_RX_BUFFER_MASK )
#error RX0 buffer size is not a power of 2
#endif
#if ( UART1_RX_BUFFER_SIZE & UART1_RX_BUFFER_MASK )
#error RX1 buffer size is not a power of 2
#endif
/* Static Variables */
static unsigned char UART0_RxBuf[UART0_RX_BUFFER_SIZE];
static volatile unsigned char UART0_RxHead;
static volatile unsigned char UART0_RxTail;
static unsigned char UART0_TxBuf[UART0_TX_BUFFER_SIZE];
static volatile unsigned char UART0_TxHead;
static volatile unsigned char UART0_TxTail;
static unsigned char UART1_RxBuf[UART1_RX_BUFFER_SIZE];
static volatile unsigned char UART1_RxHead;
static volatile unsigned char UART1_RxTail;
static unsigned char UART1_TxBuf[UART1_TX_BUFFER_SIZE];
static volatile unsigned char UART1_TxHead;
static volatile unsigned char UART1_TxTail;
/* initialize UART */
void InitUART0( unsigned char baudrateL,unsigned char baudrateH )
{
unsigned char x;
UBRR0H = baudrateH;
UBRR0L = baudrateL; /* set the baud rate */
/* enable UART receiver and transmitter, and
receive interrupt */
UCSR0B = ( (1<<RXCIE0) | (1<<RXEN0) | (1<<TXEN0) );
x = 0; /* flush receive buffer */
UART0_RxTail = x;
UART0_RxHead = x;
UART0_TxTail = x;
UART0_TxHead = x;
}
void InitUART1( unsigned char baudrateL,unsigned char baudrateH )
{ unsigned char x;
UBRR1H = baudrateH;
UBRR1H = baudrateL;
UCSR1B = ( (1<<RXCIE1) | (1<<RXEN1) | (1<<TXEN1) );
x = 0; /* flush receive buffer */
UART1_RxTail = x;
UART1_RxHead = x;
UART1_TxTail = x;
UART1_TxHead = x;
}
/* interrupt handlers */
void UART0_RX_interrupt( void )
{
unsigned char data;
unsigned char tmphead;
data = UDR0; /* read the received data */
/* calculate buffer index */
tmphead = ( UART0_RxHead + 1 ) & UART0_RX_BUFFER_MASK;
UART0_RxHead = tmphead; /* store new index */
if ( tmphead == UART0_RxTail )
{
/* ERROR! Receive buffer overflow */
}
UART0_RxBuf[tmphead] = data; /* store received data in buffer */
}
void UART0_TX_interrupt( void )
{
unsigned char tmptail;
/* check if all data is transmitted */
if ( UART0_TxHead != UART0_TxTail )
{
/* calculate buffer index */
tmptail = ( UART0_TxTail + 1 ) & UART0_TX_BUFFER_MASK;
UART0_TxTail = tmptail; /* store new index */
UDR0 = UART0_TxBuf[tmptail]; /* start transmition */
}
else
{
UCSR0B &= ~(1<<UDRIE0); /* disable UDRE interrupt */
}
}
/* Read and write functions */
unsigned char ReceiveByte0( void )
{
unsigned char tmptail;
while ( UART0_RxHead == UART0_RxTail ) /* wait for incomming data */
;
tmptail = ( UART0_RxTail + 1 ) & UART0_RX_BUFFER_MASK;/* calculate buffer index */
UART0_RxTail = tmptail; /* store new index */
return UART0_RxBuf[tmptail]; /* return data */
}
void TransmitByte0( unsigned char data )
{
unsigned char tmphead;
/* calculate buffer index */
tmphead = ( UART0_TxHead + 1 ) & UART0_TX_BUFFER_MASK;
/* wait for free space in buffer */
while ( tmphead == UART0_TxTail )
;
UART0_TxBuf[tmphead] = data; /* store data in buffer */
UART0_TxHead = tmphead; /* store new index */
UCSR0B |= (1<<UDRIE0); /* enable UDRE interrupt */
}
unsigned char DataInReceiveBuffer0( void )
{
return ( UART0_RxHead != UART0_RxTail );
/* return 0 (FALSE) if the receive buffer is empty */
}
/* interrupt handlers1*/
void UART1_RX_interrupt( void )
{
unsigned char data;
unsigned char tmphead;
data = UDR1; /* read the received data */
/* calculate buffer index */
tmphead = ( UART1_RxHead + 1 ) & UART1_RX_BUFFER_MASK;
UART1_RxHead = tmphead; /* store new index */
if ( tmphead == UART1_RxTail )
{
/* ERROR! Receive buffer overflow */
}
UART1_RxBuf[tmphead] = data; /* store received data in buffer */
}
void UART1_TX_interrupt( void )
{
unsigned char tmptail;
/* check if all data is transmitted */
if ( UART1_TxHead != UART1_TxTail )
{
/* calculate buffer index */
tmptail = ( UART1_TxTail + 1 ) & UART1_TX_BUFFER_MASK;
UART1_TxTail = tmptail; /* store new index */
UDR1 = UART1_TxBuf[tmptail]; /* start transmition */
}
else
{
UCSR1B &= ~(1<<UDRIE1); /* disable UDRE interrupt */
}
}
/* Read and write functions */
unsigned char ReceiveByte1( void )
{
unsigned char tmptail;
while ( UART1_RxHead == UART1_RxTail ) /* wait for incomming data */
;
tmptail = ( UART1_RxTail + 1 ) & UART1_RX_BUFFER_MASK;/* calculate buffer index */
UART1_RxTail = tmptail; /* store new index */
return UART1_RxBuf[tmptail]; /* return data */
}
void TransmitByte1( unsigned char data )
{
unsigned char tmphead;
/* calculate buffer index */
tmphead = ( UART1_TxHead + 1 ) & UART1_TX_BUFFER_MASK;
/* wait for free space in buffer */
while ( tmphead == UART1_TxTail )
;
UART0_TxBuf[tmphead] = data; /* store data in buffer */
UART1_TxHead = tmphead; /* store new index */
UCSR1B |= (1<<UDRIE1); /* enable UDRE interrupt */
}
unsigned char DataInReceiveBuffer1( void )
{
return ( UART1_RxHead != UART1_RxTail );
/* return 0 (FALSE) if the receive buffer is empty */
}
/* main - a simple test program*/
void main( void )
{
InitUART0( 51,0 ); /* set the baudrate to 9600 bps using a 4MHz crystal */
InitUART1( 51,0 );
_SEI(); /* enable interrupts => enable UART interrupts */
while ( 1 ) /* forever */
{
TransmitByte0( ReceiveByte0() ); /* echo the received character */
TransmitByte0( ReceiveByte0() ); /* echo the received character */
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -