#include #include #include #include "oulib.h" // Provided by oulib (but not a standard export) extern int uart_send(char c, FILE *fp); /////// // GLOBAL STRUCTURES #define BUF_SIZE 30 volatile char buffer[BUF_SIZE]; volatile uint8_t front; // Oldest character volatile uint8_t back; // Next hole to place character /////// // Interrupt handler ISR(USART_RXC_vect) { char c; // Get the character out of the hardware buffer c = UDR; // Insert the charcter into the buffer only if it is not full if((back-front)%BUF_SIZE < BUF_SIZE-1) { // Store the new character in the buffer buffer[back] = c; // Increment charcter counter back = (back+1)%BUF_SIZE; }; }; // Enable/disable the serial port interrupt. // This is accomplished by setting or clearing the // bit in UCSRB that corresponds to the serial port // receive completion interrupt. // // These functions are declared "inline": the compiler // in this case does not generate the assembly code to // perform a subroutine call. Instead, the contents of // the inline function are substituted directly into the // calling function. This may mean that there are multiple // copies of this code in the end, but it does mean that // it executes fast. // inline void serial_receive_enable(void) { UCSRB |= _BV(RXCIE); // Enable serial receive interrupt } inline void serial_receive_disable(void) { UCSRB &= ~_BV(RXCIE); // Disable serial receive interrupt } // int get_next_character(void) // // Return = next character in the buffer. If there isn't one, then // we wait // int get_next_character(FILE *fp) { int c; // Wait for a character in the buffer while(front == back) {}; // Get the character c = buffer[front]; front = (front + 1)%BUF_SIZE; return(c); }; // my_void ioinit(void) // // Initialize PD0/PD1 as a serial device // void my_ioinit(void) // p.136 { UCSRB = (1<>8); UBRRL = (unsigned char) baud; // Use defaults for UCSRC, 8N1, p.153 fdevopen(uart_send, get_next_character); } // uint8_t my_kbhit(void) // // Return = 1 if a character is in the buffer // = 0 if no characters in the buffer uint8_t my_kbhit(void) { return(front != back); }; // void flash_led(unsigned int i) // // Flash B0 for msec // void flash_led(unsigned int i) { PORTB |= 1; delay_ms(i); PORTB &= ~1; delay_ms(i); } int main (void) { int c; long int val; // Initialize global structures front = 0; back = 0; // Initialize I/O DDRB = 0xFF; PORTB = 0; // Wakeup procedure flash_led(250); flash_led(250); flash_led(250); // Initialize serial port my_ioinit(); // Enable interrupts // Serial port enable serial_receive_enable(); // Global interrupt enable sei(); // Say hello... printf("hello world...\n\r"); // Loop forever for(;;) { #if 0 // Eat all of the characters in the buffer while(my_kbhit()) { c = getchar(); // Echo the character putchar(c); }; #endif if(scanf("%ld", &val) == 1) { printf("VAL:#%ld#\n\r", val); }else{ printf("oops:%c\n\r", getchar()); }; // Toggle LSB of PORTB on every cycle just to show that // we are still alive PORTB ^= 2; // "Something else": sleep for 5 sec delay_ms(5000); } };