Daniel schrieb:
> Ich möchte nun ein Software-Handshake unterbringen. Wo genau muss ich
> diese Steuerzeichen unterbringen?
In möglichst tief liegenden Treiberschichten.
> Hier mal die Sende- und Empfangsroutine:
>
>
1 | > void uart_putc(unsigned char data)
|
2 | > {
|
3 | > int tmphead;
|
4 | >
|
5 | > tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
|
6 | >
|
7 | > while ( tmphead == UART_TxTail ){
|
8 | > ;/* wait for free space in buffer */
|
9 | > }
|
10 | >
|
11 | > UART_TxBuf[tmphead] = data;
|
12 | > UART_TxHead = tmphead;
|
13 | >
|
14 | > /* enable UDRE interrupt */
|
15 | > UCSR0B |= (1<<UDRIE0);
|
16 | >
|
17 | > }/* uart_putc */
|
guter Platz. Noch besser wäre es allerdings die Sendefreigabe
unmittelbar vor Ausgabe des Zeichens ins UDR Register zu prüfen. Da das
aber im Interrupt passiert, ist das nicht so simpel. Denn im Interrupt
sollte man nicht warten.
Auf der anderen Seite muss die Gegenstelle nach dem Senden eins XOFF
sowieso damit rechnen, dass noch ein paar Zeichen eintrudeln werden. Es
ist nicht spezifiziert wieviele das sein können aber wenn dein
UART_TxBuf nicht allzugross dimensioniert ist, sollte das eigentlich
kein allzugroßes Problem sein. Muss man ausprobieren.
Also: Gesendet werden darf nur dann, wenn die Gegenstelle nicht mit
einem XOFF das Senden unterbunden hat.
Also wirst du in der Empfangsroutine eine Erkennung von XOFF (und XON)
einbauen. Wird XOFF erkannt, dann wird eine static volatile globale
Variable SenderAllowsTransmission auf FALSE gesetzt. In der uart_putc
fragst du ab, ob SenderAllowsTransmission auf TRUE steht und wenn nicht,
dreht die Sendroutine ihre Runden, solange, bis sie die Freigabe über
diese Variable bekommt.
> ISR (USART0_RX_vect) {
>
> // read UART status register and UART data register
> uart_menu_rxdata = UCSR0A; // Empty the Status Register
> uart_menu_rxdata = UDR0; // Read desired data
>
> UART_RX_OFF; // Kein weiterer Empfang (nur ein
> Zeichen)
>
> uart_menu_rxflag=1; // Flag, dass etwas empfangen wurde
>
> }
> [/c]
In dieser Funktion wird das empfangene Zeichen angeschaut.
Ist es XOFF, dann wird SenderAllowsTransmission auf FALSE gesetzt, ist
es XON dann wird selbige Variable auf TRUE gesetzt. Ist es keinen von
beiden, dann wird mit dem empfangenen Zeichen verfahren wie bisher auch.
> Nun ist die Frage wo ich den Software-Handshake einbaue. Der
> Software-Handshake macht doch auch nur Sinn, wenn der Sender dauerhaft
> sendet oder?
Nö.
Ein Handshake kann immer Sinn machen, wenn die Gegenstelle zeitweise
nicht aufnahmebereit ist. Das kann viele Ursachen haben, zb. weil eine
längere Berechnung im Gange ist, und die Gegenstelle nicht aufnahmefähig
ist. Oder weil die Gegenstelle befürchtet, dass wenn du weitersendest
ihr Eingangspuffer überlaufen wird.
Hint: Das ist auch das Stichwort wann dein Programm an die Gegenstelle
ein XOFF schicken könnte. Wobei dann natürlich die paradoxe Situation
enstehen kann, dass die Gegenstelle ihrerseits bereits mittels XOFF
mitgeteilt hat, dass sie zur Zeit nicht belästigt zu werden wünscht :-).
Wenn also die Gegenstelle bereits einen XOFF geschickt hat, darfst du
ihr dann deinerseits einen XOFF schicken (denk logisch nach)