#include #include #pragma interrupt_handler iTxd:11 typedef struct { int head; int tail; int nchar; int size; }IODESC; volatile IODESC txdesc; char txbuff[32]; void InitUart(int baud) { UCR = 0x18; /* enable uart rec and xmit */ UBRR = baud; txdesc.head = 0; txdesc.tail = 0; txdesc.nchar = 0; txdesc.size = 32; } void Disable(void) /* disable interrupts */ { SREG &= ~0x80; } void Enable(void) /* enable interrupts */ { SREG |= 0x80; } void EnableTxIRQ(void) { UCR |= 0x20; /* enable transmit data register empty interrupt */ } void DisableTxIRQ(void) { UCR &= ~0x20; /* disable transmit data register empty interrupt */ } void iTxd(void) /* interrupt handler for uart */ { UDR = txbuff[txdesc.tail++]; /* get character from buffer */ if(--txdesc.nchar == 0) /* one less character to send */ DisableTxIRQ(); /* stop transmitting data */ if(txdesc.tail == txdesc.size) txdesc.tail = 0; /* wrap tail pointer */ } void LED_On(int i) { PORTB = ~BIT(i); /* low output to turn LED on */ } void PutC(int i) { while(txdesc.nchar == txdesc.size); /* pend on buffer full */ Disable(); /* Disable interrupts */ txbuff[txdesc.head++] = (char)i; /* put data into buffer */ if(txdesc.head == txdesc.size) txdesc.head = 0; /* wrap head pointer */ if(txdesc.nchar == 0) /* first char in buff? */ EnableTxIRQ(); /* start transmit interrupt */ txdesc.nchar++; Enable(); /* enable interrupts */ } main() { int i,j; InitUart(25); DDRB = 0xFF; /* output */ PORTB = 0xFF; /* all off */ j=0; while(1) { LED_On(j); if(++j == 8) j = 0; for(i=' ';i<'z';++i) { PutC(i); } PutC('\r'); PutC('\n'); while((PIND & 0x80) == 0); /* stop if button 7 is pushed */ } return 0; }