Forum: Mikrocontroller und Digitale Elektronik UART: bit 7 in UDR macht sich selbstständig!?


von jupp (Gast)


Lesenswert?

hi,


ich arbeite eben zum ersten mal mit der uart schnittstelle (mega644).
habe ein kleines testprog das kontinuierlich ein zeichen sendet (unten).
ich schreibe also ein byte in UDR0.

wenn in dem byte bit7 nicht gesetzt ist, macht sich das selbstständig, 
zb:


ich sende 8 mal: UDR0 = 0x01;
ich empfange: \x01\x81\x81\x01\x01\x01\x01\x81


ist bit7 gesetzt, kein problem:

UDR0 = 0x80;
\x80\x80\x80\x80\x80\x80\x80\x80\x80


was passiert da nur?
ja, ich habe "17.10.1 UDRn – USART I/O Data Register n" durchgelesen, da 
steht nix was auf dieses verhalten schliessen lässt...!?

der takt (1000000UL) sollte stimmen, alles default:
CKSEL = 0010, SUT = 10, CKDIV8 = 0

cfg beim empfänger sollte auch stimmen:
Serial<id=0xb53550, open=True>(port='COM1', baudrate=9600, bytesize=8, 
parity='N', stopbits=1, timeout=None, xonxoff=0, rtscts=0, dsrdtr=0)


jemand ne idee? danke schonmal!







#define F_CPU       1000000UL

#include <avr/io.h>
#include <util/delay.h>

#define BAUD_RATE          9600UL

int main(void) {

  OSCCAL = 0x9b;

  UBRR0H=(uint8_t)((F_CPU / (16 * BAUD_RATE)) - 1)>>8;
  UBRR0L=(uint8_t)(F_CPU / (16 * BAUD_RATE)) - 1;

  UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);    // async, 8N1
  UCSR0B = (1<<TXEN0);

  while(1){
    loop_until_bit_is_set(UCSR0A, UDRE0);
    UDR0 = 0x01;
    _delay_ms(100);
  }
}

von Stefan B. (stefan) Benutzerseite


Lesenswert?

jupp wrote:

> wenn in dem byte bit7 nicht gesetzt ist, macht sich das selbstständig,
> zb:

Hört sich nach ungenauer Baudrate an.

> der takt (1000000UL) sollte stimmen, alles default:
> CKSEL = 0010, SUT = 10, CKDIV8 = 0

Und das bestärkt den Verdacht. Interne RC-Oszillator? Wenn ja, 
wiederhole alles mit externem Quarz und melde dich wieder, wenn der 
Fehler bestehen bleibt.

von jupp (Gast)


Lesenswert?

ist das wirklich derartig ungenau?
im datenblatt steht, dass der interne osc nach calibrieren genau genug 
ist.

da ich anfänger bin habe ich eigentlich keine lust jetzt die sache noch 
zu verkomplizieren...
brigt es was den osc vom stk 500 zu nutzen?


danke!

von spess53 (Gast)


Lesenswert?

Hi

>brigt es was den osc vom stk 500 zu nutzen

Ja,aber nur mit Quarz.

MfG Spess

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Hast du kalibriert?
Osc. vom STK500 müsste statt externem Quarz auch gehen.

von jupp (Gast)


Lesenswert?

ja, ich habe calibriert:

in avr: cal. for frequency (8Mhz, ist doch richtig auch wenn CKDIV8 = 
0), read cal byte, im prog dann:

OSCCAL = 0x9b;


stk 500 ist dann eine externe clock, fuse also folgendermaßen:

CKSEL3..0 = 0000?

richtig?


ich habe jetzt noch in nem anderen thread gelesen, dass folgendes bei 
niedriger clock sinnvoll wäre:

UCSR0A = (1<<U2X0);
UBRR0H = (uint8_t) ((F_CPU / (8 * baudrate)) - 1)>>8;
UBRR0L = (uint8_t) (F_CPU / (8 * baudrate)) - 1;

im datenblatt steht aber das gegenteil!?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

jupp wrote:

> ja, ich habe calibriert:
> OSCCAL = 0x9b;

Wie bist du auf den Wert gekommen? Hoffentlich nicht gemäß STK500 
Handbuch 5.3.4.2 bis 5.3.4.4.

> stk 500 ist dann eine externe clock, fuse also folgendermaßen:
> CKSEL3..0 = 0000?
> richtig?

Wenn du externe clock auf dem STK500 einstellst, ja. Aber oben hat Spess 
empfohlen vom STK500 den externen Quarz zu nehmen. Auswahl über Jumper 
XTAL1 und OSCSEL. Ich habe kein STK500 und weiss nicht wie genau die 
externe Clock vom STK500 ist.

> ich habe jetzt noch in nem anderen thread gelesen, dass folgendes bei
> niedriger clock sinnvoll wäre:
>
> UCSR0A = (1<<U2X0);
> UBRR0H = (uint8_t) ((F_CPU / (8 * baudrate)) - 1)>>8;
> UBRR0L = (uint8_t) (F_CPU / (8 * baudrate)) - 1;
>
> im datenblatt steht aber das gegenteil!?

Rechne es aus. Im Datenblatt (17.11 Examples of Baud Rate Setting) meine 
ich eine Tendenz zu erkennen, dass UCSR0A = (1<<U2X0); eher Vorteile 
hat. Aber gerade bei 9600 Baud @ 1 MHz ist -7,0% Baudratenfehler (kein 
UCSR0A = (1<<U2X0)) gegen 0,2% (UCSR0A = (1<<U2X0)) enorm! Es ist hier 
also auf jeden Fall ratsam. Das würde ich sogar vor der Umstellung der 
Taktrate einmal testen.

von spess53 (Gast)


Lesenswert?

Hi

>Ich habe kein STK500 und weiss nicht wie genau die externe Clock vom >STK500 ist.

Ich habe das mal vor einiger Zeit nachgemessen. Den vom Controller des 
STK generierten Takt kann man vergessen.

MfG Spess

von Urs (Gast)


Lesenswert?

Tip: <util/setbaud.h> verwenden, das benutzt auch den Prescaler, wenn es 
damit bessere Ergebnisse gibt.

Kleiner Fallstrick noch: Beim Mega644 ist das zwar nicht der Fall, aber 
einige andere AVRs (Mega8 z.B.) haben für UBRR*H und UCSR*C die gleiche 
Adresse, die Unterscheidung folgt über das Bit URSEL, das beim Zugriff 
auf UCSR*C gesetzt sein muss, sonst passiert Baudsalat.

von jupp (Gast)


Lesenswert?

>> ja, ich habe calibriert:
>> OSCCAL = 0x9b;

>Wie bist du auf den Wert gekommen? Hoffentlich nicht gemäß STK500
>Handbuch 5.3.4.2 bis 5.3.4.4.

im avr studio auf der advanced im abschnitt "oscillator calibration 
byte" read cal byte geclickt. habe das irgendwo gelesen. das scheint 
aber nur das register auszulesen. macht also wenig sinn!?
wie macht man das also?



>>Ich habe kein STK500 und weiss nicht wie genau die externe Clock vom >>STK500 
ist.

>Ich habe das mal vor einiger Zeit nachgemessen. Den vom Controller des
>STK generierten Takt kann man vergessen.

dann werde ich wohl nicht drumrumkommen einen quarz zu benutzen. scheint 
ja recht idiotensicher zu sein mit dem stk500. (um die elkos muss ich 
mich da ja nicht kümmern, sind schon auf dem board?)


danke euch!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Habe ich mir gedacht. Damit kalibierst du IMHO die Software Clock des 
STK500, nicht die des eingesteckten AVRs.

Den eingesteckten AVR könntest du kalibrieren, in dem du darauf einen 
Zeitgeber programmierst und dessen Ausgabe mit einer bekannten, genauen 
Zeitquelle vergleichst. Die Abweichung ist dann ein Maß für das 
Kalibrierbyte. Das ist so grundlegend für einen µC, dass es eine 
application note von Atmel dazu geben müsste.

von jupp (Gast)


Lesenswert?

ich habe mich vorgestern das erste mal ernsthaft mit einem atmega 
datenblatt auseinander gesetzt und ich muss sagen, das ist wirklich sehr 
gut geschrieben. habe eigentlich alles auf anhieb geblickt.

aber...

>Das ist so grundlegend für einen µC, dass es eine
>application note von Atmel dazu geben müsste.

genau...
da wird man irgenwie allein gelassen.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Hehe, so habe ich das nicht gemeint. SUCHEN solltest du ;-)

AVR053 - Calibration of the internal RC oscillator
http://www.atmel.com/dyn/resources/prod_documents/doc2555.pdf

von jupp (Gast)


Lesenswert?

scherzkeks

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.