/* Sende- und Empfangsroutinen mit Interrupt */ /* Pufferung in zirkularem Buffer */ #define CLOCKMHZ 12 #if CLOCKMHZ==11 #define TIMER2400 0xF4 #define TIMER4800 0xFA #define TIMER9600 0xFD #endif #if CLOCKMHZ==12 #define TIMER2400 0xF3 #define TIMER4800 0xF9 #define TIMER9600 0xFD #endif #if CLOCKMHZ==16 #define TIMER2400 0xEF #define TIMER4800 0xF7 #define TIMER9600 0xFC #endif void serial(void); void serial0_init(void); char txs (void); /* SendeStatus */ char rxs (void); /* EmpfangsStatus */ char putchar (char c); /* Senden eines Zeichens */ char _getkey(void); /* Empfang eines Zeichens */ void debuglocal(void); /* verwendete Hardware-Ressourcen 8051x SERIAL0 TIMER0 stellt Baudrate ein */ #include /* nicht erforderlich, würde mit 51 auch laufen */ #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 serial0_init(void) { /* serielle Schnittstelle 0 */ /* 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 */ /* Timer 1 */ /* TMOD */ TMOD &= 0x0F; /* T1 auf Modus 2, Reload */ TMOD |= 0x20; TH1 = 0xf3; /* Reload-Wert für 2400 Baud */ /* TCON */ TR1 = 1; /* T1 einschalten */ /* Interrupts */ ES0 = 1; /* Serieller Interrupt ein */ /* Interrupt von Timer 1 wird nicht benötigt */ } 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); }