mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Uart Fehler bei Attiny2313


Autor: Tim H. (hotty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin gerade dabei (erstmal eine) RGB LED über den PC mit dem Uart zu 
steuern. Geplant sind letztendlich 20 Attiny2313 und 20 RGB Leds 
(SuperFlux). Bei jedem AVR sollen dann die RX Leitungen mit dem 
PC-Verbunden werden (sozusagen: Low-Budget-Bus-System).
Damit man hier auch recht schnell die Farben updaten kann, bruach ich 
schon eine Baudrate von mehr als 50k.

Zu meinem Problem: Ich habe nun einen AVR aufgebaut, mit MAX232 und PC. 
Allerdings funktioniert die ganze Schaltung nur bis 38400 Baud 
zuverlässig. Bei 57600 gibt es im Bereich zwischen 60 und 150 (als Byte) 
Probleme (zur Erklärung: es werden 4 Byte übertragen: Adresse, R, G, B). 
Ich verwende sogar einen Baudratenquarz mit 4,9152Mhz. Mein Ziel sind 
eigenlich 115,2kBaud.

Hier mein Code: (daran wirds liegen, denn der Terminal überträgt alles 
richtig. Interessant auch: die 115.2kBaud gehen realtiv Fehlerfrei mit 
8Mhz internem Quarz, aber nicht genau genug -> ca. 5% Fehler)
#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 4915200UL
#include <util/delay.h> 

#define BAUD        38400UL
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)

uint8_t counter = 0;
uint8_t rx[4];
uint8_t status = 0;


ISR(USART_RX_vect)
{
    while ( !( UCSRA & (1<<UDRE)) )
        ;

  rx[counter] = UDR;
  counter++;
  if(counter > 3){ //alle 4 Bytes sind da
      OCR0A =  rx[1];  //red
      OCR1AL = rx[2];//green
      OCR1BL = rx[3]; //blue
      counter = 0;
  }
}

void uart_init(void)
{
    UBRRH = (unsigned char) (UBRR_BAUD>>8);
    UBRRL = (unsigned char) (UBRR_BAUD & 0x0ff);

    UCSRB = (1<<RXCIE)|(1<<RXEN);

    UCSRC = (1 << UCSZ0) | (1 << UCSZ1);
}


int main(void)
{
    DDRB = (1 << PB4 ) | (1 << PB3 ) | (1 << PB2 ); 

  
    TCCR0A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
    TCCR0B = (1<<CS10);

    TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
    TCCR1B = (1<<CS10);
    TIMSK &= ~0x3c;

    OCR0A = 200;  //red
    OCR1AL = 0xff;//green
    OCR1BL = 127; //blue

    uart_init();

    sei();

  while( 1 )
    ;  
}

Hoffe auf helfende Antworten :)
Danke schonmal

Tim

Autor: isr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
in der isr eine while Schleife???

Autor: Tim H. (hotty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hab ich aus dem Tutorial übernommen. Das wartet ja bis alles da ist 
von dem Byte, oder muss das da etwas raus?

Autor: isr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn die ISR "zuschlägt", weisst du doch schon, dass alles da ist

Autor: Tim H. (hotty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal.

Es läuft schon etwas besser ohne den while-Teil (vielleicht Einbildung). 
Aber es gibt immer noch viele Fehler. Vielleicht liegt es an der 
UART-Konfiguration?

Tim

Autor: isr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
counter und rx muss volatile sein. Die Konfig hab ich mir jetzt noch 
nicht angeschaut. wo ist eigentlich die Timer ISR?

Autor: Tim H. (hotty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das volatile hat nichts gebracht.

Vielleicht liegt es doch auf der Hardwareseite:
Ich habe einen Max3232 (den Max232 hatte ich nicht mehr da) auf 5V mit 
100nF Kerkos. Müssen da ELKOs hin? Den Max232 hatte ich schon auf 115.2k 
mit 100nF Kerkos laufen.

Autor: isr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn du die Standardbeschaltung laut DB hast, dann schafft der 120kbaud

Autor: Tim H. (hotty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja ich hab auch im DB geschaut. Da steht halt nur was von wegen 0.1uf 
... also passt das ja wohl.

Autor: isr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sieht der Rest des Codes aus. Ich sehe eine init zum Timer, aber 
keine Timer ISR. Evtl ist die so groß, dass der UART_RX Interrupt 
"aufgehalten" wird und Zeichen verliert bei hoher Geschwindigkeit.

Autor: Tim H. (hotty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist der ganze Code... Die Timer nehm ich ja nur für PWM

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Du solltest dir mal ein Protokoll überlegen. In der derzeitigen Form 
erholt sich deine Übertragung nach einem Fehler bis zum nächsten 
Neustart nicht mehr.

Mf Spess

Autor: Tim H. (hotty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das stimmt schon... ich wollte eigentlich ein recht günstiges System 
nehmen: ich will nur die RX aller Slaves mit dem TX vom Master 
verbinden.

Achso: mein Fehler ist nie, dass ein Byte mal fehlt. Sondern immer: 
anstatt z.b. einer 0x60 wird eine 0xFF üebrtragen ...

Autor: avr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du mußt auch aufpassen. Dein Quarz mit 4,9152 MHz ist nicht
automatisch für alle Baudraten geeignet.

Gut: 9600, 19200, 38400 und 76800

aber: 28800 Fehler 1,6%
      57600 Fehler - 3%

und deine 115200 Fehler 6,7%

Also Beachten oder Quarz tauschen.

avr

Autor: Tim H. (hotty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke ... ich test mal 76800

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>ich will nur die RX aller Slaves mit dem TX vom Master
>verbinden.

Aber Masse hast du auch verbunden?

MfG Spess

Autor: Tim H. (hotty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja Masse wird auch verbunden. Momentan hab ich ja nur einen AVR dran.

bei den 76800 kommt übrigens der Fehler auf meinem PC, dass die Baudrate 
nicht unterstützt wird...? Wie kann ich die trotzdem verwenden ?

Autor: Tim H. (hotty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat da wer ne Idee?

Autor: Andi ... (xaos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim H. schrieb:
> Hier mein Code: (daran wirds liegen, denn der Terminal überträgt alles
> richtig. Interessant auch: die 115.2kBaud gehen realtiv Fehlerfrei mit
> 8Mhz internem Quarz, aber nicht genau genug -> ca. 5% Fehler)

uart mit internem rc oszillator... nein das geht mal garnicht..nur 
glückssache wenn das läuft....besorg dir einen richtigen quartz dann 
läufts auch

Autor: Tim H. (hotty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab ja den 4.9152 MHz ... wenn ich da 38.4k Baud drauf mache:

Könnte ich doch auf folgende Akualisierungsrate kommen:

Zeit / Bit = 1/38400
pro Befehl 40 Bits = 1/38400 * 40
an 20 Slaves =

Macht = 1/0.0208s = 48 Hz

Kommt das hin? Die Rechenzeit beim PC ist ja recht schnell... dann gehts 
maximal auf 47Hz runter.
Aber das hört sich ja ganz gut an, wenn das passt... Damit lässt sich 
sicher nen Stroboskop machen... Und es soll einen Befehl für alle 
aufeinmal geben. Also würden dann noch höhere Raten möglich sein....

Autor: Tim H. (hotty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann man das nun so rechnen?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.