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);
}
}
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.
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!
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!?
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.
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
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.
>> 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!
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.
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.