Forum: Mikrocontroller und Digitale Elektronik Uart Fehler bei Attiny2313


von Tim H. (hotty) Benutzerseite


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)
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
#define F_CPU 4915200UL
5
#include <util/delay.h> 
6
7
#define BAUD        38400UL
8
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)
9
10
uint8_t counter = 0;
11
uint8_t rx[4];
12
uint8_t status = 0;
13
14
15
ISR(USART_RX_vect)
16
{
17
    while ( !( UCSRA & (1<<UDRE)) )
18
        ;
19
20
  rx[counter] = UDR;
21
  counter++;
22
  if(counter > 3){ //alle 4 Bytes sind da
23
      OCR0A =  rx[1];  //red
24
      OCR1AL = rx[2];//green
25
      OCR1BL = rx[3]; //blue
26
      counter = 0;
27
  }
28
}
29
30
void uart_init(void)
31
{
32
    UBRRH = (unsigned char) (UBRR_BAUD>>8);
33
    UBRRL = (unsigned char) (UBRR_BAUD & 0x0ff);
34
35
    UCSRB = (1<<RXCIE)|(1<<RXEN);
36
37
    UCSRC = (1 << UCSZ0) | (1 << UCSZ1);
38
}
39
40
41
int main(void)
42
{
43
    DDRB = (1 << PB4 ) | (1 << PB3 ) | (1 << PB2 ); 
44
45
  
46
    TCCR0A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
47
    TCCR0B = (1<<CS10);
48
49
    TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
50
    TCCR1B = (1<<CS10);
51
    TIMSK &= ~0x3c;
52
53
    OCR0A = 200;  //red
54
    OCR1AL = 0xff;//green
55
    OCR1BL = 127; //blue
56
57
    uart_init();
58
59
    sei();
60
61
  while( 1 )
62
    ;  
63
}

Hoffe auf helfende Antworten :)
Danke schonmal

Tim

von isr (Gast)


Lesenswert?

in der isr eine while Schleife???

von Tim H. (hotty) Benutzerseite


Lesenswert?

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

von isr (Gast)


Lesenswert?

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

von Tim H. (hotty) Benutzerseite


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

von isr (Gast)


Lesenswert?

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

von Tim H. (hotty) Benutzerseite


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.

von isr (Gast)


Lesenswert?

wenn du die Standardbeschaltung laut DB hast, dann schafft der 120kbaud

von Tim H. (hotty) Benutzerseite


Lesenswert?

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

von isr (Gast)


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.

von Tim H. (hotty) Benutzerseite


Lesenswert?

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

von spess53 (Gast)


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

von Tim H. (hotty) Benutzerseite


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

von avr (Gast)


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

von Tim H. (hotty) Benutzerseite


Lesenswert?

Danke ... ich test mal 76800

von spess53 (Gast)


Lesenswert?

Hi

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

Aber Masse hast du auch verbunden?

MfG Spess

von Tim H. (hotty) Benutzerseite


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 ?

von Tim H. (hotty) Benutzerseite


Lesenswert?

Hat da wer ne Idee?

von TestX .. (xaos)


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

von Tim H. (hotty) Benutzerseite


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

von Tim H. (hotty) Benutzerseite


Lesenswert?

Kann man das nun so rechnen?

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.