UART liefert Mist...

Gast #135889
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!
Gast #135890
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
Gast #135891
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
Gast #135892
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 :)
Gast #135893
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?
Gast #135895
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
Gast #135896
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!
Angehängte Dateien:
Gast #135899
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren