Software UART mit delay

#1798561
Lesenswert?

hallo liebe community,

habe mir mal überlegt, ob man einen Software UART auchmit der 
Zeitverzögerung delay machen kann, wenn man die BAUDRATE gegeben hat.
Ich meine nur das senden und nicht das empfangen.


Laut meiner Logik wäre das möglich, da man ja nur eine bestimmte 
Bitfolge ausgibt!


Was meint ihr zu meiner Idee, ist sowas möglich oder bin ich da auf dem 
ganz falschen Trip?

Ich bin nämlich auf der Suche nach einem Soft-UART ohne TIMER und 
INTERRUPTS.
#1798577
Lesenswert?

@  Olaf (Gast)

>der Steinzeit und funktioniert auch nur solange keine
>anderen Interrupts im Programm laufen.

Das gilt genauso für die Timerinterruptlösung. Dort dürfen auch keine 
anderen Interrupts dazwischenfunken, sonst ist das Timing im Eimer.

MfG
Falk
#1798585
Lesenswert?

1
void sputchar( uint8_t c )
2
{
3
  c = ~c;
4
  STX_PORT &= ~(1<<STX_BIT);            // start bit
5
  for( uint8_t i = 10; i; i-- ){        // 10 bits
6
    _delay_us( 1e6 / BAUD );            // bit duration
7
    if( c & 1 )
8
      STX_PORT &= ~(1<<STX_BIT);        // data bit 0
9
    else
10
      STX_PORT |= 1<<STX_BIT;           // data bit 1 or stop bit
11
    c >>= 1;
12
  }
13
}


Peter
Persönliche Seite #1798703
Lesenswert?

Peter Dannegger schrieb:
>
1
> void sputchar( uint8_t c )
2
> {
3
>   c = ~c;
4
>   STX_PORT &= ~(1<<STX_BIT);            // start bit
5
>   for( uint8_t i = 10; i; i-- ){        // 10 bits
6
>     _delay_us( 1e6 / BAUD );            // bit duration
7
>     if( c & 1 )
8
>       STX_PORT &= ~(1<<STX_BIT);        // data bit 0
9
>     else
10
>       STX_PORT |= 1<<STX_BIT;           // data bit 1 or stop bit
11
>     c >>= 1;
12
>   }
13
> }
14
>

Hier muss man aber auch aufpassen. Die vergleiche und das 
setzen/zurücksetzen sowie schieben kostet auch noch Takte. Bei hohen 
Baudraten könnten diese ins Gewicht fallen.
#1799505
Lesenswert?

Hallo nochmal,

vielen Dank für die vielen und hilfreichen Antworten!

Die Verzögerungen durch die Setz- und Löschzyklen, sowie die für die 
Abfrage kann ich vernachlässigen, da meine Baudrate nur 2400 ist.
Und Interrupts habe ich in meinen Programm sowie nicht.

Ich will es vom verständnis so einfach wie möglich halten.


@ Peter Dannegger (peda)

Erstmal vielen Dank für den C-Code, dieser ist sehr hilfreich.
Habe aber noch ein paar Fragen zum Programm.

Ich schalte hinter den uC einen MAX 232, muss ich dann auch die Bits 
invertieren wie bei dir in Zeile 3 ( c = ~c) geschehen?

Muss die for-schleife nicht nur über 9 Bits gehen, da das Start-Bit ja 
schon vorher ausgegeben wird?

Ist im _delay_us(1e6/BAUD) das 1e6 die Prozessorrate (F_CPU)?


Was ist das STX_PORT und STX_BIT? Ist das vorher als PORTx und Pxn 
definiert worden?

Wie muss die Varible c, welche an die Funktion übergeben wird im 
Hauptprogramm definiert sein? Bitweise, ASCII-codiert oder HEX-Zahlen?


Ich hoffe ich nerve nicht durch die ganzen Fragen, aber ich bin leider 
ein Anfänger im uC Programieren.
Gast #1801911
Lesenswert?

Hallo, ich bin Anfänger und fand die Lösung mit Delay sehr interessant.

Habe es mal umgesetzt, es werden 20 Buchstaben ausgegeben:

[code]
#include <stdio.h>
#include <string.h>
#include <avr/io.h>
#include <avr/eeprom.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define baud 19200
#define sendbit 1

void sputchar( uint8_t c )
{
  c = ~c;

  PORTD &= ~(1 << sendbit);        // start bit
  for( uint8_t i = 10; i; i-- ){     // 10 bits
    _delay_us( 1e6 / baud );        // bit duration

    if( c & 1 )
      PORTD &= ~(1 << sendbit);  // data bit 0
    else
      PORTD |= 1 << sendbit;     // data bit 1 or stop bit
      c >>= 1;
  }
 }


int main (void)
{

  uint8_t zaehler;
  uint8_t i;

  zaehler=85;

  DDRD = (1 << DDD1) ;

  for (i =64 ; i < zaehler; i++) {
    _delay_ms(100);
    sputchar(i);
    _delay_ms(100);
  }
 }

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