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!
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
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
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 :)
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?
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
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
@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!
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
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.
Na sicher geht das, TX mit RX zu verbinden. Dann passiert auch exakt das von Dir vorhergesagte, sofern die Hardware nicht kaputt ist.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.