/* Sende- und Empfangsroutinen mit Interrupt */ /* Pufferung in zirkularem Buffer */ #include #include /* Interrupt-Bearbeitung * --------------------- * Zirkularer Puffer 'buffer', wird von ISR_serial beschrieben und * von getch() gelesen. ba und be zeigen jeweils auf den Anfang * und auf das Ende. Auf den Index be wird geschrieben, vom Index ba * wird gelesen. Beim Schreiben wird be inkrementiert, ba bleibt konstant; * beim Lesen wird ba inkrementiert, be bleibt konstant. * wenn be==ba -> buffer leer * wenn ba!=0 : be==ba-1 -> buffer voll * ba==0 : be==BUFFER-1 -> buffer voll */ #define RXBUFFER 4 volatile char i_rxovfl=0; volatile char i_rxbuffer[RXBUFFER]; volatile char i_rxba=0; /* Index für den Beginn des zirkularen Buffers */ volatile char i_rxbe=0; /* Index für das Ende des zirkularen Buffers */ #define TXBUFFER 4 volatile char i_txempty=1; volatile char i_txbuffer[TXBUFFER]; volatile char i_txba=0; /* Index für den Beginn des zirkularen Buffers */ volatile char i_txbe=0; /* Index für das Ende des zirkularen Buffers */ void serial(void) interrupt 4 { if (TI0) { if (i_txba==i_txbe) /* wenn buffer leer keine Aussendung */ { i_txempty = 1; } else { S0BUF=i_txbuffer[i_txba++]; if (i_txba==TXBUFFER) i_txba=0; i_txempty = 0; } TI0=0; } if (RI0) { if ( (((i_rxba==0) && (i_rxbe==(RXBUFFER-1))) || (i_rxbe==(i_rxba-1)) ) ) { /* Buffer voll */ i_rxovfl=1; } else { i_rxbuffer[i_rxbe++] = S0BUF; if (i_rxbe==RXBUFFER) i_rxbe=0; } RI0=0; } } void serinit(void) { /* SCON */ SM0=0;SM1=1; /* Modus 1, 8 Bit, Timer 1 */ SM20=0; /* Multi-Controller aus */ REN0=1; /* Empfänger einschalten */ TB80=0;RB80=0; /* kein 9-tes Bit */ TI0=1; /* PCON */ PCON |= 0x80; /* Division durch 2 */ /* TMOD */ TMOD &= 0x0F; /* T1 auf Modus 2, Reload */ TMOD |= 0x20; TH1 = 0xf3; /* Reload-Wert für 2400 Baud */ /* TCON */ TR1 = 1; /* T1 einschalten */ ES0 = 1; /* Serieller Interrupt ein */ } char txs (void) /* SendeStatus */ { return ((i_txba==0) && (i_txbe==TXBUFFER-1)) || ((i_txba!=0) && (i_txbe==i_txba-1)); } char putchar (char c) /* Senden */ { if (txs()) { while (txs()); /* wenn Buffer voll, warten */ } i_txbuffer[i_txbe++] = c; if (i_txbe==TXBUFFER) i_txbe=0; if (i_txempty) TI0=1; } char rxs (void) /* EmpfangsStatus */ { return (!(i_rxba==i_rxbe)); } char _getkey(void) /* Empfang eines Zeichens */ { char c; if (rxs()==0) { while (rxs()==0) ; } ES0 = 0; /* Seriellen Interrupt ausschalten */ c = i_rxbuffer[i_rxba++]; if (i_rxba==RXBUFFER) i_rxba=0; ES0 = 1; return (c); } void main(void) { char txchar='a'; char rxchar=' '; serinit(); EAL=1; while (1) { char c = 'a'; while (1) putchar (c++); /* Senden von Zeichen */ if (txs()==0) /* voriges Zeichen wurde schon abgeholt */ { putchar(txchar); txchar++; if (txchar=='z'+1) { printf("12"); txchar='a'; } } /* Empfang von Zeichen */ if (rxs()) { rxchar = _getkey(); putchar(rxchar); } } }