serieller TX mit delay in Software (AVR, UART)

Gast #6606915
Lesenswert?

Für's schnelle Debuggen ohne Debugger.
Der Vorteil: braucht keinen Timer oder Interrupts.
Der Nachteil: hat keinen Timer.

Kann man das noch schicker schreiben, so dass die Wartezeit samt 
Schleifendurchlauf und Vergleich näher an der tatsächlichen Bitzeit dran 
ist (so dass 1/BAUDRATE-CONST genutzt werden kann)?
CONST könnte noch mit F_CPU angepasst werden.

Ich hatte zuvor Schieben mit variablem i drin (d&(1<<i)), so sind's 
schonmal 32 Byte weniger (neues Timing noch nicht getestet, Takt 1MHz):
1
    uint16_t d = 0b1000000000 | (c<<1);  // stop, data LSB first, start
2
    for(uint8_t i=0; i<10; i++){
3
        if( d & 1 )
4
            PORT |= (1<<PIN);
5
        else
6
            PORT &= ~(1<<PIN);
7
        d>>=1;
8
        _delay_us(70/*104*/);
9
    }
Gast #6606944
Lesenswert?

floh boing schrieb:
> Kannst du auch was Sinnvolles beitragen,

Ich verstehe auch nicht, was du uns mit diesem Thread großartiges 
mitteilen willst. Da ist seit Erfindung der Mikroprozessoren nichts 
neues oder interessantes dran.

Du solltest Interrupts sperren, die versauen dir sonst das Timing.
Gast #6606959
Lesenswert?

Hallo,

ganz solide. Die 70µs sind gewürfelt?

Du könntest das genauso auch mit dem d laufen lassen und auf i 
verzichten, zumindest wenn c uint8 ist. Ist aber kaum besser.
1
uint16_t d = 0b1000000000 | (c<<1);  // stop, data LSB first, start
2

3
    while(d) {
4
        if(d&1) {PORT |=  (1<<PIN);}
5
        else    {PORT &= ~(1<<PIN);}
6
        d>>=1;
7
        _delay_us(70);
8
    }
Gast #6607136
Lesenswert?

Textausgaben untersuchen ist auch eine Variante des Debugging. Lange 
Zeit ging es gar nicht anders. Ich kam in meiner Jugendzeit noch 
zwangsweise zu diesem unerquicklichen Genuss.

Eproms mit Kippschaltern zu programmieren ist auch aus der Mode gekommen 
:-)

Kennt ihr noch die Computerzeitschriften mit Spielen zum Abschreiben? 
Also wo man seitenweise Hex-Zahlen abtippen musste.

Wenn das Programmieren heute noch so mühsam wäre, würden alle nur noch 
vor dem Fernseher sitzen. Den Stress tut sich heute niemand mehr an.
#6607198
Lesenswert?

Hier meine Version:
1
void sputchar(unsigned char c)
2
{
3
  c = ~c;                                       // complement to send 0 = stop bit(s)
4
  STXD_oe = 1;                                  // output
5
  STXD = MARK;                                  // start bit
6
  for (uint8_t i = 9 + STOP_BITS; i; i--)       // start + data + stop bits
7
  {
8
    _delay_us(1e6 / BAUD);                      // bit duration
9
    if (c & 1)
10
      STXD = MARK;
11
    else
12
      STXD = !MARK;                             // = Space
13
    c >>= 1;                                    // next bits or stop bit(s)
14
  }
15
}
Angehängte Dateien:
Gast #6607229
Lesenswert?

Stefan ⛄ F. schrieb:
> Du solltest Interrupts sperren, die versauen dir sonst das Timing.

Guter Hinweis.

A. S. schrieb:
> ganz solide. Die 70µs sind gewürfelt?
>
> Du könntest das genauso auch mit dem d laufen lassen und auf i
> verzichten, zumindest wenn c uint8 ist. Ist aber kaum besser.

Ja, ausprobiert. Darin steckt aber auch die Abweichung des internen RCs 
bei meinem AVR.
Danke für's Feedback.

Peter D. schrieb:
> Hier meine Version:

Danke Peter, die hatte ich gestern in 
Beitrag "Re: ATtiny44 -Software Uart - nur senden" ff. gefunden, und 
wollte gerade den Link posten.
Im Beitrag von Schorsch werden auch die offenbar 9 Takte für Schleife 
und Ausgabe berücksichtigt.

Falk B. schrieb:
>
.
Das habe ich mir gedacht.


Thema erledigt. Danke!
Gast #6607284
Lesenswert?

Martin schrieb:
> Wer Interrupts nicht sperren möchte nimmt:

Da darin ein Delay steckt sind die Nebenwirkungen ev. drastisch, da dann 
der Interrupt nicht mehr annähernd Real Time ist, jedenfalls manchmal - 
das ganze ist eben ein Weg aus der Computersteinzeit. Zuletzt habe ich 
das gesehen bei ZX80 und C64.

Georg
Gast #6607306
Lesenswert?

Bei einem Steuergerät in einem Verteilzentrum hatten die das mal clever 
mit der Power-LED kombiniert (war offenbar anfangs nicht eingeplant 
gewesen).

Man konnte ein USB-UART Adapterkabel anstelle der Power-LED anstecken. 
Dieses hatte einen Taster, der die beiden Pins miteinander verband. 
Dadurch konnte man Debug Ausgaben auf eben diesem LED-Pin aktivieren.

Mein Motorrad hat etwas ähnliches. Da baumelt aus dem Steuergerät ein 
kleiner zweipoliger Stecker, an den man ein Diagnosegerät anschließen 
kann. Wer dieses Gerät nicht hat, kann dort einfach eine Drahtbrücke 
einsetzen. Dann gibt das Gerät hilfreiche Morsecodes auf der gelben 
Kontroll-Leuchte aus. Und diese Codes sind in der Betriebsanleitung alle 
dokumentiert (was leider nicht mehr selbstverständlich ist).

Klar hat so eine Soft-UART Seiteneffekte. Sie kann trotzdem in 
bestimmten Anwendungsfällen äußerst nützlich sein.
Gast #6612332
Lesenswert?

Peters Algorithmus hat mindestens zwei Vorteile:

- es gibt keine (überflüssige) Wartezeit am Ende
- es muss nur ein Byte geschoben werden, denn das Stopbit gibt es 
"kostenlos" beim Schieben (durch die Invertierung)
Gast #6612404
Lesenswert?

floh boing schrieb:
> Peters Algorithmus hat mindestens zwei Vorteile:
>
> - es gibt keine (überflüssige) Wartezeit am Ende
> - es muss nur ein Byte geschoben werden, denn das Stopbit gibt es
> "kostenlos" beim Schieben (durch die Invertierung)

a) die Wartezeit am Ende ist nicht überflüssig. Das weiß Peter auch. 
Darum versteckt er das im Schleifenzähler. Rechne mal nach.

b) Dafür braucht er einen Schleifenzähler.

(c) Es gibt 2 verschiedene Stellen, in denen die Leitung gesetzt wird.

Peters Code ist (wieder mal) sehr pfiffig und kaum zu toppen. Bei der 
Aufgabe sind die Möglichkeiten aber auch überschaubar ... und sinnlos. 
Das Problem bleibt das Delay: Damit ist kein Interrupt erlaubt und und 
Rechenzeit spielt keine Rolle.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren