Forum: Mikrocontroller und Digitale Elektronik UBRRH oder UCSCR Register addressieren?


von Stefan (Gast)


Lesenswert?

Hallo Leute,

hoffe jemand kann mir einen Tip geben was ich
falsch mache!
Ich möchte Daten per UART vom Mikrocontroller
zum PC schicken.

Dazu soll ich die UART Register UBRRH & UCSRC
setzen, die aber auf der selben Adresse liegen.
Laut Datenblatt ist es vom ersten Bit abhängig
welches Register adressiert wird.

Dachte ich mach das mit

cbi(UCSRC,7);
UCSCR = 0x...

sbi(UBRRH,7);
UBRRH = 0x...

Aber beim debuggen funktioniert das nicht!
Wie beschreibt man die Register????

Danke, Stefan

von Henning (Gast)


Lesenswert?

so wie ich das kenne wird im UBRR register nur die Baudrate eingestelln.
wird allso irgendwo bei dier initiallisierung gemacht

bei den etwas dickeren avr´s wurde das UBRR durch UBRRH und UBRRL
ersetzt (nun 16 bit, wie ich meine)

das einzige doppelregister, was ich da kenne ist UDR, das die zu
sendenen daten beim beschreiben an einen speicherplatz schreibt. und
beim auslesen der empfangenen daten aus einem anderen speicherplatz
liest.

was noch übrig ist ist USR, was den status der UART enthält und
UCR, was zum steuern der ganzen UART benötigt wird.

noch fragen? leider kenne ich nur die "basic line", weiss also nich,
wie´s bei den megas oder so ist.

von Henning (Gast)


Lesenswert?

...weil ich´s ehh gard hier habe:

UART_Init:

    ldi tmp1, 4000000/(9600*16)-1  ; Baudrate  9600 einstellen
;    ldi tmp1, 4000000/(19200*16)-1  ; Baudrate 19200 einstellen
  ;ldi tmp1, 4000000/(38400*16)-1 ; Baudrate 38400 einstellen geht
nicht
    out UBRR, tmp1          ; Bautrate in Register übertragen

  sbi UCR, TXEN                   ; TX aktivieren

    sbi UCR, RXEN                   ; RX (Empfang) aktivieren
    sbi UCR, RXCIE                  ; bei Empfang soll Interrupt
ausgelöst werden

    ret

ZUM SENDEN:
UART_SendByte:
  sbis USR,UDRE  ;Warten, bis UDR für das nächste Byte bereit ist
  rjmp UART_SendByte

  out UDR, prm1  ; das Byte aus prm1 Senden
ret
ZUM EMPFANGEN (per interrupt des Byte merken und später behandeln):
UART_Int_rxc:
  in UARTpuf, UDR      ; Das empfangene Byte in den UARTpuf kopieren
    reti

von Stefan (Gast)


Lesenswert?

Sorry,

hab vergessen, möchte das mit einem ATmega32 machen,
deswegen mein Problem beim 16Bit Register.

Das Baudratenregister ist UBRRH und UBRRL.
Soviel ich verstehe ist UBRRL direkt adressierbar
und UBRRH über das setzen des MSB in UCSRC Register.
UCSRC legt das Frame format fest, aber ich bring
das nicht zum laufen!

Vielleicht hat da jemand für die Mega's nen Auszug
aus nem C-Programm, wär echt dankbar!

Ciao Stefan

von Bernd Walter (Gast)


Lesenswert?

Das Umschaltbit für die Registerwahl muss in einem Vorgang
mitgeschrieben werden - also bei UBRHH Zugriff muss das bit immer
gesetzt sein.

von Stefan (Gast)


Lesenswert?

Aber es funktioniert auch nicht auf diese Weise!

// UBRRH 1XXX XXXX
// UCSRC 0XXX XXXX

// Baudrate einstellen

 UBRRH = (UBRRH | 0x80);
 UBRRL = 0x17;      // 9600 bps


 // Frame Format einstellen

 UCSRC = (UCSRC | 0x20);   // Asynchrone Übertragung - Bit 5
 UCSRC = (UCSRC | 0x10);   // Even Parity - Bit 4 setzen
 UCSRC = (UCSRC & 0xFB);  // 1 Stop Bit  - Bit 3 löschen
 UCSRC = (UCSRC | 0x03);  // 8 Datenbit  - Bit 1&2 setzen

Hab beim debuggen in beiden Registern immer
die selben Werte stehen! :-(

Stefan

von Bernd Walter (Gast)


Lesenswert?

Ist doch jetzt eine ganz andere Software.
UBRRH = (UBRRH | 0x80);
kann nicht funktionieren.
Du liest UBRHH und setzt URSEL, was dir das Ergebniss in UCSRC
zurückschreibt.

Dann liest du UCSRC, was dir in Wirklichkeit den Wert von UBRHH
liefert, weil seit dem letzten lesen etwas anderes passiert ist.

Warum machst du dir eigendlich überhaupt Gedanken über UBRRH?
Default ist der mit 0 gefüllt und was anderes braucht man für übliche
bps Raten eigendlich nie.
Willst du wirklich derart kleine Raten haben, daß du das tastächlich
brauchst?

Für UCSRC modifikationen machst du einfach was in der Doku steht:
uint8_t ucsrc;
ucsrc = UBRRH;
ucsrc = UCSRC;
ucsrc |= 0x02; //asyncrone Übertragung - Bit 5;
ucsrc |= 0x10; //even parity - bit 4 setzen;
...
UCSRC = ucsrc;

Wobei man für eine UART initialisierung eigendlich nicht lesen muss,
sondern einfach den Wert mit gesetztem UBSEL reinschreibt.
Was vorher war dürfte dich wohl kaum interessieren.

Hier ein Beispiel von mir, was UCSRC benutzt:
        /* setup UART */
        /* select async 8e1 */
        UCSRC = _BV(URSEL) | _BV(UPM1) | _BV(UCSZ1) | _BV(UCSZ0);
        UCSRB = _BV(TXEN) | _BV(RXEN); /* rx/tx enable */
        UBRRL = (SYSCLK / (16 * BPS_RATE)) - 1; /* Bd */

von Peter D. (peda)


Lesenswert?

Ich verstehe nicht, wo überhaupt das Problem ist ???

Im Datenblatt sind doch fix und fertige Beispiele in C und Assembler
dafür.

Z.B. für den ATMega8 stehts auf Seite 136 (USART_Init).


Peter

von Stefan (Gast)


Lesenswert?

Habs jetzt auf drei Arten versucht.

UCSRC = _BV(URSEL) | _BV(UPM1) | _BV(UCSZ1) | _BV(UCSZ0);

UBRRH = 0x00;

UCSRC = (1<<URSEL)|(1<<5)|(1<<4)|(0<<3)|(1<<1)|(1<<0);

Im Debugger von AVRStudio4 schreibt er mir die Werte immer gleichzeitig
in beider Register, also geh ich mal davon aus
das der Fehler dort liegt.
Kanns leider im Moment nicht ausprobieren, deswegen hätt ich
die Register gern im Debugger gesehen!

Danke, Stefan

von Peter D. (peda)


Lesenswert?

@Stefan,

hätste gleich gesagt, daß es um den Simulator geht, dann wäre der ganze
Salm hier überflüssig gewesen.

Du must es schon mit dem richtigen Chip machen, dann gehts auch.



Peter

von Olli (Gast)


Lesenswert?

gudnnabnd,

habe das selbe Problem wie Stefan. Kann zwar beide Register schreiben,
aber je nach dem welches ich zuletzt schreibe bleibt dieser Wert in
beiden stehn (im Simulator).

Ich hab mir dann die Werte auf der Hardware mal auf die LED's schicken
lassen, und schau an da sind se korrekt. Also iss da im Sim wohl ein
Fehler. Oder ich kriegs einfach im Sim nicht richtig hin.
:-)

Mein weiteres Problem liegt aber darin, das ich keine Zeichen auf dem
Hyperterminal empfange. Obwohl die Schnittstelle korrekt initialisiert
ist.

Hatte mal die Schnittstelle so weit, das sie Daten gesendet hat, aber
das war purer Murcks :-(

Jemand einen Tip ???

PS: Schönen Sonntag abend wünsch ich noch !!!
    Morgen iss wieder Montag :-(((

von Joerg Wunsch (Gast)


Lesenswert?

Stefan, warum postest Du das in zwei verschiedenen Foren, statt den
begonnen Thread im avr-gcc Forum fortzusetzen.  Ich empfinde das als
recht unhöflich und werde es in Zukunft vermeiden, Dir weitere
Antworten zu geben.

von Stefan (Gast)


Lesenswert?

Einfacher Grund, weils sehr dringend ist und
ich mir nicht sicher war wo es hingehört!
Hätt aber drauf hinweisen können das es auch
in diesem Forum steht, is richtig, sorry!

Im übrigen funktionierts eh noch nicht, ich
kann zwar was übertragen aber nur Mist.
Wenn die Werte wie im Simulator angezeigt
in beide Register geschrieben werden, stimmt ja
die Baudrate nicht mehr!

Stefan

von Joerg Wunsch (Gast)


Lesenswert?

> Im übrigen funktionierts eh noch nicht, ich kann zwar was übertragen
> aber nur Mist.

FAQ gelesen?

http://savannah.nongnu.org/download/avr-libc/doc/avr-libc-user-manual/FAQ.html#faq_fuses

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.