PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Uart



tobi.robotz
14.04.2010, 17:12
HI. Mache grade das AVR-Toturial auf www.mikrocontroller.net
und bin gerade beim Punkt UART. Jetzt habe ich das erste Programm fertig, dass "Test!" an den Computer sendet.
http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART
Ich habe schon mühevoll auf Windwos 7 hyperterminal installiert erst über DLL-Dateinen und EXE von einem XP-Rechner gezogen und in die Systemordner von Windows 7 kopiert. Dann nochmal eine Hyperterminal-Version aus dem Internet geladen. Habe jetzt 2mal hyperterminal installiert. Das hyperterminal funktioniert an sich. Man kann es starten und alles einstellen etc. Es ergibt sich auch eine Verbindung zur COM-1 (RS232)-Schnittstelle. Aber ich empfange nichts.
Woran könnte das liegen?
Gibt es eigentlich eine Suchfunktion für das Forum?

tobi.robotz
14.04.2010, 17:17
Achso ich verwende einen AT-MEGA 16 und das Pollin-Evalationsboard. Ich hätte auch einen AT-Mega 8 da. Aber das würde doch normalerweise keinen Unterschied machen.

Falls doch. Kann ich dann den MEGA 16 im Sockel lassen? Ich möchte ihn nicht zu oft aus dem Sockel nehmen. Da mir sonst Pins abbrechen.

PicNick
14.04.2010, 18:29
eine herzergreifende möglichkeit (u.A) ist es, beim Verbindungskabel PC<>µC einfach mal RX u. TX auszukreuzen

"suchen" gibt's in der Menüzeile oben.

schau auch mal da
http://www.rn-wissen.de/index.php/Terminals
rein

tobi.robotz
14.04.2010, 18:49
Wie kreuze ich RX u. TX aus? Ich verwende kein Null-Modem-Kabel bei dem 2 Adern gekreuzt sind. Sondern ein normales Sub-D-Verlängerungskabel. Falls du das meinst.

Ahja Suchen ist der 3. Menüpunkt. Danke.

veit
14.04.2010, 19:05
uart ist immer das gleiche:
rx-tx vertauscht
baudrate falsch.

verbinde an deinem seriellen kabel rx und tx. wenn du zeichen sendest müssen die zurückkommen. dann geht schonmal dein terminal

tobi.robotz
14.04.2010, 19:15
Achso diese zwei Fehler werden immer gemacht.
Naja aber rx-tx vertauscht...verstehe ich so dass der Pin rx am µC nicht auf tx an der Rechner-Schnittstelle geht und tx nicht auf rx an der Rechnerschnittstelle. Wenn dem so ist kann das bei mir eigentlich nicht der Fall sein. Ich verwende ein fertiges evalationsboard und keinen eigenen Aufbau und den Stecker verkehrt anschließen geht nicht. Oder verstehe ich das falsch? Die Baudrate habe ich 9600 gewählt. Ganz nach
http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART

veit
14.04.2010, 19:35
nicht argumentieren sondern einfach mal machen. glaub mir ES MACHEN ALLE MAL FALSCH

also pins kurzschließen - senden - kucken

PicNick
15.04.2010, 08:44
Beim PC auch sicher "Handshake OFF" einstellen, ist auch beliebt.

Auskreuzen:
Am PC sollte der Uart-Stecker ein Buchse sein
Ist am Eva-Board auch eine Buchse, MUSS ausgekreuzt werden (==> Null-modem-kabel)

tobi.robotz
15.04.2010, 10:53
Ah ok. Ich muss aber nicht auskreuzen am PC ist ein männlicher Stecker und am Kabel auf der PC-Seite somit eine Buchse am Board Buchse und am anderen Ende Stecker. Passt also.
Wie stelle ich Handshake aus?
Ich hab rx und tx mit einem Jumper gebrückt. Im Terminal gebe ich jetzt etwas ein. Wenn ich Enter drücke bleibt alles genauso nur der Cursor springt auf den Anfang der Zeile. Funktioniert mein Terminal?

PicNick
15.04.2010, 11:27
Am PC sollte der Uart-Stecker ein Buchse sein
Ist am Eva-Board auch eine Buchse, MUSS ausgekreuzt werden (==> Null-modem-kabel)

Is natürlich genau umgekehrt:
Am PC COM-Port ist ein Stecker
Ist am EVA-Board auch ein Stecker---> Null-Modem, ausgekreuzt.
sonst ---> Verlängerung

Terminal scheint zu funktionieren

Enter --> Zeilenanfang, sonst nix, das ist ok.

(Erst die kombination <CR><LF> erzeugt eine neue Zeile).

tobi.robotz
15.04.2010, 11:36
Ja ich hab auch mit dem Jumper noch ein bisschen experimentiert. Herausgenommen, Textdateien gesendet mit und ohne Jumper, etc. Ohne Jumper kann man nicht mal was eingeben. Beim Board habe ich einen Jumper an die falsche stelle gesetzt. Jetzt funktioniert die Übertragung. Aber ich bekomme anstatt "Test!", "0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R".
Woran könnte das liegen?

PicNick
15.04.2010, 11:57
Das klingt nach Baudrate. (Oder µC Taktfrequenz --> check fuses)

Wenn das Teminal mehr Zeichen (als gesendet) zeigt, ist die µC Baudrate zu niedrig. (oder der Quartz, s.o)

Mich wundert aber etas das gleichförmige 0R0R.....
das wiederum könnte am µC Programm liegen, das in wirklichkeit schrott statt des Textes schickt.

tobi.robotz
15.04.2010, 15:07
Die fuses sind so http://www.mikrocontroller.net/images/atmega8-nachher.png

Einen Fehler im Programm kann ich auch nahezu ausschließen weil ich den kompletten Syntax schon aus dem avr-Toturial kopiert und geflasht habe.
Dabei kam auch 0Ò0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R 0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R
0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R0R 0R0R0R0R0R0R0R0R0R0R0R0R0R0R0
heraus.

Ich habe es auch schon mit einem AT-mega8 anstatt des ATMEGA16 probiert. Mach keinen unterschied.

PicNick
15.04.2010, 15:30
Mach mal dein Programm mal ohne Loop, d.h. schick' nur einmal den Text und dann nix mehr.
Und zeig möglichst genau, was das Teminal dann bringt.
Die Baudrate stimmt dann, wenn genausoviele Zeichen gezeigt werden, wie geschickt wurden. Schwierigkeit: das Terminalprogramm zeigt eventuelle binär "00" nicht her. Aber vielleicht kommen wir der Sache trotzdem näher.

Zweite Möglichkeit: du schickst immer nur EIN bestimmtes Zeichen und dann pause und dann wieder.
Gut sind da ein-bit-zeichen, z.B. "@" also 0x40. Je nachdem, was dann das Terminal zeigt, kann man ableiten, was es mit der Baudrate auf sich hat.


Nach wie vor sorge ich mich wegen der Dauer-R's

tobi.robotz
16.04.2010, 18:42
Hallo.

Beim Programm ohne loop kommt nichts an. Sende ich ein Zeichen z.B. "T" ohne loop kommt auch nichts an. Sende ich das zeichen'@' mit anschließender verzögerung und dann rjmp loop kommt þ~~~~~~
hmmmn. Aber immerhin kenn ich mich schon ein bisschen besser aus. Vielleicht krieg ich es ja noch hin.

tobi.robotz
16.04.2010, 18:45
Achso es kommt immer nur ein ~ und dann die Pause. Die Baudrate müsste somit stimmen.

PicNick
16.04.2010, 19:16
naja, eine Tilde "~" ist hex 0x7E 01111110

Dass die Baudrate stimmt, kann man da nicht ableiten, wenn du eigentlich
"@" schickst, also 0 0000 00101 . Das schaut ja schom fast verkehrt polarisiert aus

01111110 "~"
00000010 "@"


Schau dir bitte (mir zuliebe) in deinem Programm nochmal insbes.
.equ F_CPU = 4000000
.equ UBRR_VAL = ((F_CPU+BAUD*8 )/(BAUD*16)-1)
ZEICHENGENAU an.

bei den nullen bei der CPU hab ich mich schon mal vertan und lange gesucht

tobi.robotz
17.04.2010, 00:56
.equ F_CPU = 16000000
.equ UBRR_VAL = ((F_CPU+BAUD*8 )/(BAUD*16)-1)
So sieht das bei meinem Programm aus. Ich habe ein 16MHz-Quarz.
Ich habe immer noch das 0R0R...-Problem.

tobi.robotz
17.04.2010, 00:58
.include "m8def.inc"

.def temp = r16 ; Register für kleinere Arbeiten
.def zeichen = r17 ; in diesem Register wird das Zeichen an die
; Ausgabefunktion übergeben

.equ F_CPU = 16000000 ; Systemtakt in Hz
.equ BAUD = 9600 ; Baudrate

; Berechnungen
.equ UBRR_VAL = ((F_CPU+BAUD*8 )/(BAUD*16)-1) ; clever runden
.equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille

.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler
.error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif

; Stackpointer initialisieren

ldi temp, HIGH(RAMEND)
out SPH, temp
ldi temp, LOW(RAMEND)
out SPL, temp

; Baudrate einstellen

ldi temp, HIGH(UBRR_VAL)
out UBRRH, temp
ldi temp, LOW(UBRR_VAL)
out UBRRL, temp

; Frame-Format: 8 Bit

ldi temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
out UCSRC, temp

sbi UCSRB,TXEN ; TX aktivieren

loop:
ldi zeichen, 'T'
rcall serout ; Unterprogramm aufrufen
ldi zeichen, 'e'
rcall serout ; Unterprogramm aufrufen
ldi zeichen, 's'
rcall serout ; ...
ldi zeichen, 't'
rcall serout
ldi zeichen, '!'
rcall serout
ldi zeichen, 10
rcall serout
ldi zeichen, 13
rcall serout
rcall sync
rjmp loop

serout:
sbis UCSRA,UDRE ; Warten bis UDR für das nächste
; Byte bereit ist
rjmp serout
out UDR, zeichen
ret ; zurück zum Hauptprogramm

; kleine Pause zum Synchronisieren des Empfängers, falls zwischenzeitlich
; das Kabel getrennt wurde

sync:
ldi r16,0
sync_1:
ldi r17,0
sync_loop:
dec r17
brne sync_loop
dec r16
brne sync_1
ret

tobi.robotz
17.04.2010, 01:01
Aus dem Toturial kopiert und nur .equ F_CPU 4000000 zu .equ F_CPU 16000000 verändert

PicNick
17.04.2010, 13:19
Seltsam, ich kann diese Art Formel so nirgends im Datasheet oder in unseren Wiki-Beispielen finden

Deine Formel:
UBRR_VAL = ((F_CPU+BAUD*8 )/(BAUD*16)-1) ; c

AVR-DataSheet PDF Formel:
UBRR = F_CPU / (16*BAUDRATE) - 1;

Versuch doch mal das, bestenfalls geht's auch nicht.

tobi.robotz
17.04.2010, 13:44
Das werde ich machen. Ich habe noch ein paar andere Dinge vor zu probieren.

Im Toturial heisst es mit dieser Formel wird gerundet.

"Beispiel: Bei einem ATMega mit 16MHz und 115200 Baud ist der Wert laut Datenblatt UBBRL=8. Rechnet man mit der Formel UBRRL=(F_CPU / (UART_BAUDRATE* 16L) - 1) ergibt sich ein Wert von 7,680555 und im UBRRL Register steht somit eine 7 statt einer 8. Die Verwendung der Formel aus dem Codebespiel ergibt 8.180555 und im UBRRL Register steht somit der richtige Wert - nämlich 8 "

PicNick
17.04.2010, 14:00
Is wahr. für deine Baudrate kommt so oder so 103 raus.

Versuch aber mal, diesen Wert direkt zu setzen

.equ UBRR_VAL = 103

tobi.robotz
20.04.2010, 14:27
Ich habe es mittlerweile schon hinbekommen. Leider habe ich den Fehler nicht gefunden. Vielen Dank für die Hilfe. Ich hatte leider die letzten Tage wenig Zeit und freue mich darauf, mich endlich mit dem USART an sich zu beschäftigen.
Der funktionierende Code sieht so aus:

.include "m8def.inc"

.def temp = r16 ; Register für kleinere Arbeiten
.def zeichen = r17 ; in diesem Register wird das Zeichen an die
; Ausgabefunktion übergeben

.equ F_CPU = 16000000 ; Systemtakt in Hz
.equ BAUD = 9600 ; Baudrate

; Berechnungen
.equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden
.equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille

.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler
.error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif

; Stackpointer initialisieren

ldi temp, HIGH(RAMEND)
out SPH, temp
ldi temp, LOW(RAMEND)
out SPL, temp

; Baudrate einstellen

ldi temp, HIGH(UBRR_VAL)
out UBRRH, temp
ldi temp, LOW(UBRR_VAL)
out UBRRL, temp

; Frame-Format: 8 Bit

ldi temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
out UCSRC, temp

sbi UCSRB,TXEN ; TX aktivieren

loop:
ldi zeichen, 'T'
rcall serout ; Unterprogramm aufrufen
ldi zeichen, 'e'
rcall serout ; Unterprogramm aufrufen
ldi zeichen, 's'
rcall serout ; ...
ldi zeichen, 't'
rcall serout
ldi zeichen, '!'
rcall serout
ldi zeichen, 10
rcall serout
ldi zeichen, 13
rcall serout
rcall sync
rjmp loop

serout:
sbis UCSRA,UDRE ; Warten bis UDR für das nächste
; Byte bereit ist
rjmp serout
out UDR, zeichen
ret ; zurück zum Hauptprogramm

; kleine Pause zum Synchronisieren des Empfängers, falls zwischenzeitlich
; das Kabel getrennt wurde

sync:
ldi r16,0
sync_1:
ldi r17,0
sync_loop:
dec r17
brne sync_loop
dec r16
brne sync_1
ret

tobi.robotz
20.04.2010, 19:19
Fehler doch noch gefunden. Ich habe erst einen ATmega16 benutzt. Hier ging es nicht weil ich mich bei der Taktfrequenz vertan habe. Den Fehler hab ich aber erst gefunden als ich den ATmega16 gegen einen ATmega8 ausgetauscht habe. Das hab ich dann korrigiert. Aber beim AVR-Studio war noch der ATmega16 ausgewählt. Somit müsste sich ein Fehler beim assemblieren ergeben haben.