|
//ICC-AVR application builder : 09-05-2006 8:59:17
// Target : M16
// Crystal: 4.0000Mhz
/*
RX程序流程:
没有新字符输入,头指针和尾指针相同
有新字符输入,中断处理,头指针加一,取UDR到RX-BUFER
之后RECEIVE程序中对尾指针加一,准备接收下一个字符,同时返回当前字符
TX程序流程:
TRANS接收到RX的输入字符,头指针加一,将数据存入发送缓冲区,打开UDRIE寄存器空中断,进入中断程序。
尾指针加一,之后发送字符,直到头尾指针相同,即发送完毕,关闭UDRIE中断寄存器。
*/
#include <iom16v.h>
#include <macros.h>
/* UART Buffer Defines */
#define UART_RX_BUFFER_SIZE 128 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1 )
#define UART_TX_BUFFER_SIZE 128 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1 )
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
#error RX buffer size is not a power of 2
#endif
/* Static Variables */
static unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
static volatile unsigned char UART_RxHead;
static volatile unsigned char UART_RxTail;
static unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
static volatile unsigned char UART_TxHead;
static volatile unsigned char UART_TxTail;
static volatile unsigned char CHECK=0;
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}
//UART0 initialize
// desired baud rate: 9600
// actual: baud rate:2404 (0.2%)
// char size: 5 bits
// parity: Disabled
void uart0_init(void)
{
unsigned char x;
x=0;
UART_RxTail = x;
UART_RxHead = x;
UART_TxTail = x;
UART_TxHead = x;
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
UBRRL = 0x19; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = (1<<RXCIE)|(1<<TXEN)|(1<<RXEN);//|(1<<TXCIE)
}
unsigned char DataInReceiveBuffer( void )
{
return ( UART_TxHead != UART_TxTail );
/* return 0 (FALSE) if the TX complete */
}
#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
{
//uart has received a character in UDR
unsigned char data;
unsigned char tmphead;
data = UDR; /* read the received data */
/* calculate buffer index */
tmphead = ( UART_RxHead + 1 ) & UART_RX_BUFFER_MASK;
UART_RxHead = tmphead; /* store new index */
if ( tmphead == UART_RxTail )
{
/* ERROR! Receive buffer overflow */
/*仿真中没有出现这种情况*/
}
UART_RxBuf[tmphead] = data; /* store received data in buffer */
}
#pragma interrupt_handler uart0_tx_isr:14
void uart0_tx_isr(void)
{
//character has been transmitted
unsigned char tmptail;
CHECK++;
/* check if all data is transmitted */
if ( DataInReceiveBuffer( ))//UART_TxHead != UART_TxTail
{
/* calculate buffer index */
tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;
UART_TxTail = tmptail; /* store new index */
UDR = UART_TxBuf[tmptail]; /* start transmition */
}
else
{
UCSRB &= ~(1<<UDRIE); /* disable UDRE interrupt */
}
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
uart0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
/* Read and write functions */
unsigned char ReceiveByte( void )
{
unsigned char tmptail;
while ( UART_RxHead == UART_RxTail ) /* wait for incomming data */
;
tmptail = ( UART_RxTail + 1 ) & UART_RX_BUFFER_MASK;/* calculate buffer index */
UART_RxTail = tmptail; /* store new index */
return UART_RxBuf[tmptail]; /* return data */
}
void TransmitByte( unsigned char data )
{
unsigned char tmphead;
/* calculate buffer index */
tmphead = ( UART_TxHead + 1 ) & UART_TX_BUFFER_MASK;
/* wait for free space in buffer */
while ( tmphead == UART_TxTail )
;
UART_TxBuf[tmphead] = data; /* store data in buffer */
UART_TxHead = tmphead; /* store new index */
UCSRB |= (1<<UDRIE); /* enable UDRE interrupt */
}
void main(void)
{
init_devices();
while ( 1 ) /* forever */
{
TransmitByte( ReceiveByte() ); /* echo the received character */
}
} |
|