Forum: Mikrocontroller und Digitale Elektronik Software TX 1 bit Pause einbauen, C


von kalle (Gast)


Lesenswert?

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?

von Falk B. (falk)


Lesenswert?

@ 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

von Stefan E. (sternst)


Lesenswert?

@ 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.

von Peter D. (peda)


Lesenswert?

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

von kalle (Gast)


Lesenswert?

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 ;-)

von kalle (Gast)


Lesenswert?

Das Problem liegt wahrscheinlich wirklich an anderer Stelle. Nach 17 
Bitzeiten wird nichts mehr gesendet, wenn ich 4 *

sputchar('G');

versuche.

von Stefan E. (sternst)


Lesenswert?

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).

von kalle (Gast)


Lesenswert?

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).

von Stefan E. (sternst)


Lesenswert?

kalle wrote:

> Die Daten sind nicht invertiert, lediglich die Ausgabe (es ist kein
> MAX232 oder so dran).

Achso, dann ignoriere meinen vorigen Post einfach. ;-)

von kalle (Gast)


Lesenswert?

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.

von kalle (Gast)


Lesenswert?

Ursache: Spannungsversorgung   oc:

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.