Software TX 1 bit Pause einbauen, C

Gast #964323
Hallo,

ich habe hier im Forum eine kleine Routine für eine serielle 
Schnittstelle gefunden.
1
volatile uint16_t stxdata = 0;
1
void sputchar(uint8_t val){
2
  while(stxdata);
3
  stxdata = 0x200 | (val<<1);
4
}

Wird im Timerinterrupt mit Baudrate aufgerufen:
1
  if (stxdata){
2
    if (stxdata & 1)
3
    {
4
      PORTB &= ~(1<<TX);  // off
5
    }
6
    else
7
    {
8
      PORTB |= (1<<TX);  // on
9
    }
10
    stxdata >>= 1;
11
  }

Jetzt würde ich gerne noch ein Bit Pause anhängen, damit es keine 
Probleme beim Empfänger gibt. Hat jemand eine Idee?
@ kalle (Gast)

>ich habe hier im Forum eine kleine Routine für eine serielle
>Schnittstelle gefunden.

Das ist ein Soft-UART:

1
void sputchar(uint8_t val){
2
  while(stxdata);
3
  stxdata = 0x400 | (val<<1);
4
}

>Jetzt würde ich gerne noch ein Bit Pause anhängen, damit es keine
>Probleme beim Empfänger gibt. Hat jemand eine Idee?

Siehe oben.

MFG
Falk
@ Falk Brunner:

> Das ist ein Soft-UART:
>
1
> void sputchar(uint8_t val){
2
>   while(stxdata);
3
>   stxdata = 0x400 | (val<<1);
4
> }
5
>

Mit einer 0 als Stopbit?
0x200 war schon richtig.


@ kalle:

> Jetzt würde ich gerne noch ein Bit Pause anhängen, damit es keine
> Probleme beim Empfänger gibt.

Ändere das 0x200 in 0x600.
kalle wrote:

> Jetzt würde ich gerne noch ein Bit Pause anhängen, damit es keine
> Probleme beim Empfänger gibt. Hat jemand eine Idee?

Das einzige Problem, daß Du damit lösen kannst ist das, daß der 
Empfänger 2 Stopbits erwartet.

Probleme mit Baudratenfehlern (RC-Oszillator statt Quarz, kein 
Baudratenquarz bei hohen Baudraten) oder wegen fehlendem Protokoll 
lassen sich damit natürlich nicht lösen.


Peter
Gast
Hallo, das ist richtig, das Ganze ist invertiert.
Und danke, mir ist gerade aufgefallen dass ich übersehen habe, dass das 
Stop Bit ja = Ruhepegel ist. Die Invertierung hat mir einen Strich 
durchs Gehirn gemacht ;-)
kalle wrote:

> Hallo, das ist richtig, das Ganze ist invertiert.

Invertiert funktioniert aber dein Timerinterrupt nicht, weil du ja in 
stxdata eine 1 als Endemarke brauchst, und diese 1 wird dann ja als 0 
ausgegeben und vom Empfänger als neues Startbit erkannt.

1
  if (stxdata){
2
  ...
3
  }

Müsstest du ändern in (um die letzte 1 zu ignorieren):
1
  if (stxdata > 1){
2
  ...
3
  }
4
  else
5
    stxdata = 0;

Außerdem musst du in sputchar 0x200 in 0x401 ändern (oder 0x801, wenn du 
2 Stopbits möchtest).
Gast
Hi, genau das war mein Problem, ich dachte das Stopbit wäre eine 0. Kann 
man schlecht noch eine dahintersetzen ;-)
Die Daten sind nicht invertiert, lediglich die Ausgabe (es ist kein 
MAX232 oder so dran).
Gast
Danke trotzdem!

Evtl sollte man die Funktion interruptsicher machen:
1
void sputchar(uint8_t val)
2
{
3
  while(stxdata);
4
  cli();
5
  stxdata = 0x200 | (val<<1);
6
  sei();
7
}

Löst aber noch nicht mein Problem. Ich forsche weiter.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.