// **************************************************************************** // John Barclough's mega32 Usartint program example ported to mega128 by Owen Allison // uses both usart0 and usart1 // ****************************************************************************** //ICC-AVR application builder : 20/06/2006 3:57:01 PM // Target : M128 // Crystal: 4.0000Mhz #define _AVR // #define _AVR TO LET SPLINT KNOW THAT HEADERS ARE FOR ICCV7AVR #include #include #include // #include "Usart.h" // ----------------------------------------------------------------------- // ------------- UART DEFINES --------------------------- // UART0 RX #pragma interrupt_handler UART0_RX_interrupt:iv_USART0_RX // UART1 RX #pragma interrupt_handler UART1_RX_interrupt:iv_USART1_RXC // UART0 TX #pragma interrupt_handler UART0_TX_interrupt:iv_USART0_TX // UART1 TX #pragma interrupt_handler UART1_TX_interrupt:iv_USART1_TXC // DEFINES UART0 #define ENABLE_RX_INT0 UCSR0B|=BIT(RXCIE0) #define DISABLE_RX_INT0 UCSR0B&=~BIT(RXCIE0) #define ENABLE_TX_INT0 UCSR0B|=BIT(TXCIE0) #define DISABLE_TX_INT0 UCSR0B&=~BIT(TXCIE0) // DEFINES UART1 #define ENABLE_RX_INT1 UCSR1B|=BIT(RXCIE1) #define DISABLE_RX_INT1 UCSR1B&=~BIT(RXCIE1) #define ENABLE_TX_INT1 UCSR1B|=BIT(TXCIE1) #define DISABLE_TX_INT1 UCSR1B&=~BIT(TXCIE1) /* UART 0 Buffer definitions */ #define BUFFER_SIZE0 4 #define NUMBER_OF_BUFFERS0 4 /* UART 1 Buffer definitions */ #define BUFFER_SIZE1 4 #define NUMBER_OF_BUFFERS1 4 /* Global Variables UART 0 */ unsigned char Buffers0[NUMBER_OF_BUFFERS0][BUFFER_SIZE0+1]; volatile unsigned char RxBuffer0 = 0; volatile unsigned char TxBuffer0; volatile unsigned char gucFlags0 = 0; volatile unsigned char RxCount0 = 0; volatile unsigned char *RxPtr0; volatile unsigned char *TxPtr0; /* Global Variables UART 1 */ unsigned char Buffers1[NUMBER_OF_BUFFERS1][BUFFER_SIZE1+1]; volatile unsigned char RxBuffer1 = 0; volatile unsigned char TxBuffer1; volatile unsigned char gucFlags1 = 0; volatile unsigned char RxCount1 = 0; volatile unsigned char *RxPtr1; volatile unsigned char *TxPtr1; // DEFINES UART0 #define TEST_MSG_FLAG0 gucFlags0&BIT(0) #define SET_MSG_FLAG0 gucFlags0|=BIT(0) #define CLEAR_MSG_FLAG0 gucFlags0&=~BIT(0) // DEFINES UART1 #define TEST_MSG_FLAG1 gucFlags1&BIT(0) #define SET_MSG_FLAG1 gucFlags1|=BIT(0) #define CLEAR_MSG_FLAG1 gucFlags1&=~BIT(0) // ------------- END UART DEFINES ------------------------------------ //---------------------------------------------------------------------- void port_init(void) { PORTA = 0x00; DDRA = 0x00; PORTB = 0x00; DDRB = 0x00; PORTC = 0x00; //m103 output only DDRC = 0x00; PORTD = 0x00; DDRD = 0x00; PORTE = 0x00; DDRE = 0x00; PORTF = 0x00; DDRF = 0x00; PORTG = 0x00; DDRG = 0x00; } //************************************************************************************************ // ******************* CRYSTAL 3.8640MHZ ********** //UART0 initialize // desired baud rate: 2400 // actual: baud rate:2400 (0.0%) // char size: 8 bit // parity: Disabled void uart0_init(void) { UCSR0B = 0x00; //disable while setting baud rate UCSR0A = 0x00; UCSR0C = 0x06; UBRR0L = 0x5F; //set baud rate lo UBRR0H = 0x00; //set baud rate hi UCSR0B = 0xD8; } //******************************************************************************************** // ******************* CRYSTAL 3.8640MHZ ************ //UART1 initialize // desired baud rate: 2400 // actual: baud rate:2400 (0.0%) // char size: 8 bit // parity: Disabled void uart1_init(void) { UCSR1B = 0x00; //disable while setting baud rate UCSR1A = 0x00; UCSR1C = 0x06; UBRR1L = 0x5F; //set baud rate lo UBRR1H = 0x00; //set baud rate hi UCSR1B = 0xD8; } //call this routine to initialize all peripherals void init_devices(void) { //stop errant interrupts until set up CLI(); //disable all interrupts XDIV = 0x00; //xtal divider XMCRA = 0x00; //external memory port_init(); //timer0_init(); // timer1_init(); // timer2_init(); //timer3_init(); uart0_init(); uart1_init(); MCUCR = 0x00; EICRA = 0x00; //extended ext ints EICRB = 0x00; //extended ext ints EIMSK = 0x00; TIMSK = 0x00; //0x45; //timer interrupt sources ETIMSK = 0x00; //0x04; //extended timer interrupt sources SEI(); //re-enable interrupts //all peripherals are now initialized } /* ************************************************************************ *\ Function: 'SendMessage0()'. Action: 1. Set the transmit pointer to the start of the current receive buffer and increments the buffer pointer. If the last buffer has been used the pointer cycles round to the first buffer. 2. Send the first character of the message. 3. If there are more characters to send then enable the transmit interrupt. Inputs: None Ouputs: None Author: John Baraclough Date: 2005-10-06 Notes: \* ************************************************************************ */ void SendMessage0(void) { _CLI(); // Disable interrupts TxPtr0 = Buffers0[RxBuffer0++]; // Set the transmit pointer to the start of the most recent receive buffer. if(RxBuffer0 == NUMBER_OF_BUFFERS0) // Do we need to cycle around to the first buffer again? { RxBuffer0 = 0; } RxPtr0 = Buffers0[RxBuffer0]; // Set the receive pointer to the start of the next receive buffer. RxCount0 = 0; // Clear the receive counter. UDR0 = *TxPtr0++; // There must be at least one charcter in the buffer. if(*TxPtr0 != 0) // If the next character isn't NULL then enable the TX interrupt. { ENABLE_TX_INT0; } _SEI(); // Now enable the global interrupt flag. } /* ************************************************************************ *\ Function: 'SendMessage1()'. Action: 1. Set the transmit pointer to the start of the current receive buffer and increments the buffer pointer. If the last buffer has been used the pointer cycles round to the first buffer. 2. Send the first character of the message. 3. If there are more characters to send then enable the transmit interrupt. Inputs: None Ouputs: None Author: John Baraclough Date: 2005-10-06 Notes: \* ************************************************************************ */ void SendMessage1(void) { _CLI(); // Disable interrupts TxPtr1 = Buffers1[RxBuffer1++]; // Set the transmit pointer to the start of the most recent receive buffer. if(RxBuffer1 == NUMBER_OF_BUFFERS1) // Do we need to cycle around to the first buffer again? { RxBuffer1 = 0; } RxPtr1 = Buffers1[RxBuffer1]; // Set the receive pointer to the start of the next receive buffer. RxCount1 = 0; // Clear the receive counter. UDR1 = *TxPtr1++; // There must be at least one charcter in the buffer. if(*TxPtr1 != 0) // If the next character isn't NULL then enable the TX interrupt. { ENABLE_TX_INT1; } _SEI(); // Now enable the global interrupt flag. } /* ************************************************************************ *\ Function: 'UART_RX_interrupt()'. Action: 1. Places the received character in the buffer. 2. Check if if the received character is or if the buffer is full. If so then terminate the buffer and set the message flag. Inputs: None Ouputs: None Author: John Baraclough Date: 2005-10-06 Notes: \* ************************************************************************ */ void UART1_RX_interrupt(void) { unsigned char Temp1; Temp1 = UDR1; // Reading the data register clears the interrupt. *RxPtr1++ = Temp1; // Save the data in the buffer and ... RxCount1++; // ... increment the count. if((Temp1==0x0d)||(RxCount1==BUFFER_SIZE1)) // Is it a or is the buffer full? { *RxPtr1 = 0; // Terminate the message and ... SET_MSG_FLAG1; // ... tell 'main()' that the buffer is ready. } } // Notes: /* ************************************************************************ */ void UART0_RX_interrupt(void) { unsigned char Temp0; Temp0 = UDR0; // Reading the data register clears the interrupt. *RxPtr0++ = Temp0; // Save the data in the buffer and ... RxCount0++; // ... increment the count. if((Temp0==0x0d)||(RxCount0==BUFFER_SIZE0)) // Is it a or is the buffer full? { *RxPtr0 = 0; // Terminate the message and ... SET_MSG_FLAG0; // ... tell 'main()' that the buffer is ready. } } /* ************************************************************************ *\ Function: 'UART0_TX_interrupt()'. Action: 1. Send the next character and increment the pointer. 2. Check that there are more characters to go and if not disable the transmit interrupt as it is not needed until the current receive buffer is full. Inputs: None Ouputs: None Author: John Baraclough Date: 2005-10-06 Notes: \* ************************************************************************ */ void UART0_TX_interrupt(void) { UDR0 = *TxPtr0++; // Writing the data register clears the interrupt. if(*TxPtr0 == 0) // Is it the end of the message? { DISABLE_TX_INT0; // Yes, so no more to send. } } /* ************************************************************************ *\ Function: 'UART1_TX_interrupt()'. Action: 1. Send the next character and increment the pointer. 2. Check that there are more characters to go and if not disable the transmit interrupt as it is not needed until the current receive buffer is full. Inputs: None Ouputs: None Author: John Baraclough Date: 2005-10-06 Notes: \* ************************************************************************ */ void UART1_TX_interrupt(void) { UDR1 = *TxPtr1++; // Writing the data register clears the interrupt. if(*TxPtr1 == 0) // Is it the end of the message? { DISABLE_TX_INT1; // Yes, so no more to send. } } /* ************************************************************************ *\ Function: 'main()'. Action: 1. Sets up the device. 2. Monitor the message flag. If this flag goes true it is cleared and the current message sent. Inputs: None Ouputs: None Author: John Baraclough Date: 2005-10-06 Notes: \* ************************************************************************ */ // void main(void) { init_devices(); //insert your functional code here... RxPtr0 = Buffers0[RxBuffer0]; // Set the receive pointer uart0 to the start of the first receive buffer. RxPtr1 = Buffers1[RxBuffer1]; // Set the receive pointer uart1 to the start of the first receive buffer. _SEI(); // Enable interrupts. while(1) { if(TEST_MSG_FLAG0) { CLEAR_MSG_FLAG0; TxBuffer0 =5; SendMessage0(); // Send the current recieve buffer and switch buffers. } // end of 'if(TEST_MSG_FLAG0)'. if(TEST_MSG_FLAG1) { CLEAR_MSG_FLAG1; TxBuffer1 =5; SendMessage1(); // Send the current recieve buffer and switch buffers. } // end of 'if(TEST_MSG_FLAG1)'. //1 end of 'while(1)'. } }