PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit UART



Mule
06.10.2005, 16:06
hallo,
ich fang gerade an mit dem UART ein bisschen herumzuprobieren:


#include <avr/io.h>

#define F_CPU 16000000
#define BAUD 9600
#define UBRR_BAUD ((F_CPU/(16*BAUD))-1)



void senden(void) {

UBRRH = (unsigned char) (UBRR_BAUD>>8);
UBRRL = (unsigned char) UBRR_BAUD;
UCSRB |= (1<<TXEN);
UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

while (!(UCSRA & (1<<UDRE)));
UDR = 'a' ;
}


int main (void) {

senden ();

}

Ich benütze Terminal v1.9 von Bray. Wenn ich den Code aber ausführt zeigt das 'C0 00 C0' bzw 'ein großes R mit so einem Apostroph, dann <0>, dann wieder das R'.

Wo kann da der Fehler liegen? Hab ich da was an der Konfiguration vom Terminal falsch gemacht oder liegt es am Code?

Danke,
Chris.

ceekay
06.10.2005, 16:19
hallo,

Was für einen Controller verwendest du?

Hast du die Fuses richtig eingestellt? auf externen oszillator?

Welche Einstellungen hast du im Terminal Programm für die Verbindung eingestellt.

Wenn man nur Müll empfängt liegt es häufig an der Baudrate.

gruß ceekay

SprinterSB
06.10.2005, 16:59
...oder auf crystal oscillator oder ceramic oscillator.

Bist du sicher, daß dein Host UBRR_BAUD richtig auswertet? Du musst mit 32 Bits rechnen, sonst stimmt das Ergebnis nicht.

Nach senden() verschwindest du im Nirvana (soft reset).

Mule
06.10.2005, 17:37
@SprinterSB: um senden() war eine Endlosschleife. Ich hatte auch noch eine zweite Funktion zum auswerten von meinen Entfernungsmesser. Nachdem das mit mit dem senden() aber nicht so funktioniert hat, habe ich alles überflüssige gelöscht. Das ist doch egal, was nach senden() passiert, oder sollte man das nicht machen?

Ich hab jetzt UBRR_BAUD per Hand eingegeben (ich hab jetzt 7,3...Mhz um einen genauen UBRR-Wert zu erhalten). Dann funktioniert es!
Bin mir also sicher, dass das UBRR_BAUD nicht richtig ausgewertet wird. Werde das korrigieren.

Danke erstmal

SprinterSB
06.10.2005, 18:34
Schreib einfach "16l" anstatt "16", und der Nenner wird mit 32b gerechnet.

Mule
07.10.2005, 12:28
Danke, hab das gemacht und es funktioniert.
Jetzt hab ich doch noch ein Problem: Ich hab den Messwert in der Variable 'uin16_t Wert' gespeichert. Wie kan ich diesen Wert jetzt am besten übertragen?

SprinterSB
07.10.2005, 15:58
Das kommt drauf an, was du unter 'besser' verstehst ;-)

Übertragung in deinem Lieblingsformat. Gebräuchlich sind zB
- Binärübertragung oder BCD
-- little endian: low-byte(s)/nibbles zuerst
-- big endian: high-byte(s)/nibbles zuerst

- ASCII-Übertragung
-- als Dezimal- Binär, Hex- Oktalzahl, ...

Zur Darstellung ist ASCII nicht schlecht, erfordert allerdings mehr Arbeit auf dem µC zur Umwandlung, vor allem wenns keine ganzen Zahlen mehr sind. Der PC kann das eigentlich besser auswerten wenn's binär ankommt, weil er intern ja auch diese Darstellung nutzt und nicht zurückwandeln muss. Zudem braucht ASCII mehr Bandbreite bei der Übertragung. Um 16 bit zu übertragen hast du binär mit 2 Bytes, in ASCII brauchst du bis zu 5.

Binär schliesst allerdings eine Soft-Flusskontrolle aus.

Am einfachsten ist die Umwandlung nach Hex:

#include <avr/pgmspace.h>

extern void send (char);

static const prog_char hexdigits[] = "0123456789abcdef";

#define HEXDIGIT(i) \
((char) pgm_read_byte (hexdigits[(i)&0xf]))

foo()
{
send ('0');
send ('x');
send (HEXDIGIT (x>>12));
send (HEXDIGIT (x>>8));
send (HEXDIGIT (x>>4));
send (HEXDIGIT (x));
}
oder so.