Uart Fehler bei Attiny2313

Persönliche Seite #1624152
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
Gast #1624207
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.
Gast #1624219
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
#1624571
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
Persönliche Seite #1624579
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....

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