Forum: Mikrocontroller und Digitale Elektronik UART liefert Mist...


von Phip (Gast)


Lesenswert?

Hallo zusammen,

Ich hab' ein Problem mit dem U(S)ART meines ATmega8515. Ich bekomme
zwar was vom PC, aber das sind zum Teil bei mehreren Zeichen
verschiedene Werte für's gleiche Zeichen oder einfach irgendwas
komisches. Jedenfalls krieg' ich nix schlaues. Den Code hab' ich mehr
oder weniger vom hiesigen Tutorial übernommen, nur die Definitionsdatei
ist geändert. Eingebaut hab' ich dann noch eine Anzeige, damit ich
auch seh', was ich bekomme.

Hier ist der Code:

.include "m8515def.inc"

;Hier kommen diverse Definitionen & Co...

.org 0x00
        rjmp main

.org URXCaddr                             ; Interruptvektor für
UART-Empfang
        rjmp int_rxc

; Hauptprogramm
main:
        ldi temp, LOW(RAMEND)
        out SPL, temp
        ldi temp, HIGH(RAMEND)
        out SPH, temp

        ; Baudrate einstellen
        ldi temp, LOW(UBRRVAL)
        out UBRRL, temp
        ldi temp, HIGH(UBRRVAL)
        out UBRRH, temp

        ; Frame-Format: 8 Bit
        ldi temp, (1<<URSEL)|(3<<UCSZ0)
        out UCSRC, temp

        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren

        ldi temp, 0x0F
        out DDRA, temp

        rcall LED_Initialize
        rcall LED_Test

        sei                               ; Interrupts global
aktivieren

    loop:
      rcall LED_Out_Hex

      rcall lED_Delay_10ms
    rjmp loop                         ; Endlosschleife


; Interruptroutine: wird ausgeführt sobald ein Byte über das UART
empfangen wurde
int_rxc:
    push temp
    push r17

        in temp, UDR

        ldi r17, 0xFF

    sbis PINA, 4
    eor temp, r17

    sbis PINA, 5
    swap temp

    sbis PINA, 6
    rol temp

    sbis PINA, 7
    ror temp

    mov LED_Value_Hex, temp

        pop r17
        pop temp
reti                                    ; Interrupt beenden


Wo kann da der Fehler liegen?

Und: Kann mir vielleicht jemand erklären, was
(1<<URSEL)|(3<<UCSZ0)
heissen soll? Hab's net so mit den abgekürzten Operatoren...

Danke im Voraus!

von Jochen (Gast)


Lesenswert?

Huhu Phip,

ohne mir Deinen Code näher angeschaut zu haben Folgende Dinge:

Läuft der uC mit externem Quarz oder mit internem RC-Oszillator? Für
Komunikation über die serielle solltest du eine Quarz verwenden. Der
interne RC-Oszillator ist dafür zu ungenau.

Was das (1<<URSEL)|(3<<UCSZ0) angeht:
also in C ist das << ein Shipt Opperator. je nach dem wofür URSEL bzw
UCSZ0 steh wird die zahl die vor dem << steh x mal nach links
geschoben.

Bsp:
(1 << 3) ist binär 00000001 das ganze drei mal nach links 00001000
(0x08
)

Grüßle Jochen

von dave (Gast)


Lesenswert?

Also das wichtigste haste vergessen:
.equ UBRRVAL = ?????????????

Das Problem ist der Takt. Ich verwende auch den Internen Oszillator und
kommt halt auf die Baudrate an, wie gut der ist.

Bei 1MHz ist halt maximal 4k8 möglich und bei 8Mhz kannste noch 38k4
nehmen.


Aber nur Vermutungen... gib uns Takt, Baudrate und Formel.

dave

von Phip (Gast)


Lesenswert?

Hoppla! Das hab' ich wirklich vergessen.
Hier:

.def temp = R16
.equ CLOCK = 12000000
.equ BAUD = 9600
.equ UBRRVAL = CLOCK/(BAUD*16)-1


Ich verwende einen externen 12MHz-Quarz, der sollte also eigentlich
genau genug sein... Aber wie gesagt, alles vom hiesigen Tutorial.


@Jochen:
Vielen Dank für die Aufklärung über die Operatoren. Immerhin weiss ich
jetzt, was da drin stehen soll :)

von Jochen (Gast)


Lesenswert?

Hallo noch mal,

Die Fusebits für den Quarz hast du auch entsprechend gesetzt?

Wenn das auch der Fall ist muss Dir einer weiterhelfen der sich mit ASM
asuskennt. Da bin ich die volle Niete ;-)

Ansosnsten kann ich dir noch eine Lösung für C anbieten, aber ich denke
es ist besser hier den Fehler zu finden.

Grüßle Jochen

P.S. Hab mal Deine init-Routine durchgeschaut und bis auf das du kein
TXEN mit drin hast sieht es aus wie bei mir(ich geh mal davon aus du
willst vom uC zum PC keine Daten senden?)

Ansonsten Parameter für die Serielle sollten 8N1 sein?

von Quark (Gast)


Lesenswert?

Hallo Philipp,
verstehe ich das richtig?
Du gibst mit LED_Out_Hex den Code der gedrückten Taste aus, und
liest das Ergebnis in der Int.-Routine mit PINA wieder ein?
Quark

von AxelR. (Gast)


Lesenswert?

Hallo

muss das SREG nicht im Int. gesichert werden? seh' ich sonst immer.
Ich würde im RX int nur das Datenregister auslesen. nicht gerade nach
Temp, sondern woanders hin und nur ein bit setzen, das Zeichen
angekommen sind. In der Hauptschleife dann die anderen Abfragen. Mag
hier noch gehen, bei 9K6...
Die Bitbezeichner fürs UCSRC-Register sind im Datenblatt erklärt. Habe
ich jetzt keins von deinem mega zur Hand.
Gruß
Axel

von Phip (Gast)


Angehängte Dateien:

Lesenswert?

@Jochen

Ja, die Fusebits sollten stimmen. Zumindest geht's mit meiner
Verzögerungsroutine auf. Komisch ist allerdings, dass sich das Resultat
gar nicht wirklich verändert, wenn ich den UBRRVAL verändere...

@Quark

Ne, da siehst du was falsch. In LED_Out_Hex gebe zeige ich einfach das
Zeichen an, das sich in LED_Value_Hex befindet. Im Hex-Format
natürlich. Da es gemultiplext werden muss rufe ich die Sub auch so
häufig auf.
An PortA hab' ich einfach vier Taster, mit denen ich das Signal, das
reinkommt veändere. Ich wollte sehen, ob es vielleicht einfach
irgendwie verdreht ankommt, das ist allerdings auch nicht der Fall.

@AxelR.

Weiss nicht, ob ich da was sichern sollte... Bin eben noch relativ neu
in der MC-Programmierung.
In der Interrupt-Routine mache ich eigentlich gar nicht viel mehr. Wenn
man das mit den Tastern weglässt, dann steht da eigentlich folgendes:

; Interruptroutine: wird ausgeführt sobald ein Byte über das UART
empfangen wurde
int_rxc:

        in LED_Value_Hex, UDR

reti                                    ; Interrupt beenden


Aber auch damit funzt's net :(

Langsam hab' ich wirklich das Gefühl, dass da mit der Hardware was
nicht stimmt... Aber ich wüsste nicht was...

Hat jemand eine Ahnung, wie empfindlich der MAX232 gegenüber falschen
C-Werten ist? Ich hab' da jetzt 22uF. Als ich mir aber mal das
Datenblatt von dem angesehen hab', stand da 1uF... Könnte der evtl.
einige Bits unterschlagen oder so?

Hab' mal den gesamten Code angehängt. Ihr könnt ihn euch ja ansehen.

Danke jedenfalls schon mal!

von Jochen (Gast)


Lesenswert?

Hallo noch mal,

Allso die 22uF Cs sind in Ordnung die hab ich hier mittlerweile in drei
Schaltungen so laufen und die machen keine Problem.

Grüßle Jochen

von Phip (Gast)


Lesenswert?

Weiss da niemand mehr was? Is' schon irgendwie 'n Sch*** so... :(

von anfänger (Gast)


Lesenswert?

hab da mal ne frage zum uart eines avr (mega16). Ist es möglich, den txd
direkt mit dem rxd zu verbinden? also dann müsste ja eigentlich ein
gesendetes byte direkt im empfangspuffer zu finden sein, oder? oder
gibt es irgendwelche gründe warum das nicht funktionieren würde/könnte?


mfg, anfänger.

von Rufus T. Firefly (Gast)


Lesenswert?

Na sicher geht das, TX mit RX zu verbinden. Dann passiert auch exakt das
von Dir vorhergesagte, sofern die Hardware nicht kaputt ist.

von anfänger (Gast)


Lesenswert?

ok, danke :-)

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.