// INTERRUPT-DRIVEN serial code //used as an example in the serial communication doc. #include #include //timeout values for each task #define t1 100 #define t2 1000 //I like these definitions #define begin { #define end } //the subroutines void task1(void); //test for button press void task2(void); //increment note to be played void gets_int(void); //starts getting a string from serial line void puts_int(void); //starts a send to serial line void initialize(void); //all the usual mcu stuff unsigned int time1, time2 ; //task scheduling timeout counters unsigned long time; unsigned int v; //RXC ISR variables unsigned char r_index; //current string index unsigned char r_buffer[16]; //input string unsigned char r_ready; //flag for receive done unsigned char r_char; //current character //TX empth ISR variables unsigned char t_index; //current string index unsigned char t_buffer[16]; //output string unsigned char t_ready; //flag for transmit done unsigned char t_char; //current character //********************************************************** //timer 0 overflow ISR interrupt [TIM0_COMP] void timer0_overflow(void) begin time++; //Decrement the three times if they are not already zero if (time1>0) --time1; if (time2>0) --time2; end //********************************************************** //UART character-ready ISR interrupt [USART_RXC] void uart_rec(void) begin r_char=UDR; //get a char UDR=r_char; //then print it //build the input string if (r_char != '\r') r_buffer[r_index++]=r_char; else begin putchar('\n'); //use putchar to avoid overwrite r_buffer[r_index]=0x00; //zero terminate r_ready=1; //signal cmd processor UCSRB.7=0; //stop rec ISR end end /**********************************************************/ //UART xmit-empty ISR interrupt [USART_DRE] void uart_send(void) begin t_char = t_buffer[++t_index]; if (t_char == 0) begin UCSRB.5=0; //kill isr t_ready=1; //transmit done end else UDR = t_char ; //send the char end /**********************************************************/ //********************************************************** //Entry point and task scheduler loop void main(void) begin initialize(); //main task scheduler loop -- never exits! while(1) begin if (time1==0) task1(); if (time2==0) task2(); end end //********************************************************** //Task 1 input a string and print it void task1(void) begin time1=t1; //reset the task timer //print ad get another serial string if (r_ready ) begin sscanf(r_buffer,"%d",&v); gets_int(); end end //********************************************************** //Task 2 print the system time void task2(void) begin time2=t2; //reset the task timer sprintf(t_buffer,"%ld %d\n\r",time,v) ; puts_int(); end //********************************************************** // -- non-blocking keyboard check initializes ISR-driven // receive. This routine merely sets up the ISR, which then //does all the work of getting a command. void gets_int(void) begin r_ready=0; r_index=0; UCSRB.7=1; end //********************************************************** // -- nonblocking print: initializes ISR-driven // transmit. This routine merely sets up the ISR, then //send one character, The ISR does all the work. void puts_int(void) begin t_ready=0; t_index=0; if (t_buffer[0]>0) begin putchar(t_buffer[0]); UCSRB.5=1; end end //********************************************************** //Set it all up void initialize(void) begin //serial setop for debugging using printf, etc. UCSRB = 0x18 ; UBRRL = 103 ; putsf("\r\nStarting...\r\n"); //set up timer 0 OCR0=249; //1 mSec TIMSK=2; //turn on timer 0 cmp-match ISR TCCR0=0b00001011; //prescalar to 64 and Clr-on-match //init the task timers time1=t1; time2=t2; r_ready=0; t_ready=1; //crank up the ISRs #asm sei #endasm gets_int(); end