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.