Hallo,
Ich habe ein Problem und zwar empfangen der Daten über die Serielle
Schnittstelle, UART mit µController. Senden von Mikrokontroller zu PC
klappt aber nicht andersherum. Ich hoffe der Assemblercode ist
verständlich:
--------------------------------------------------------
CPU 8051
INCLUDE REG_8252.INC ;
INCLUDE HWS52_02.LIB ;allgemeine Hilfsprogramme
;INCLUDE HWSADDA.LIB ;AD/DA Wandler Hilfsprogramme
ORG 0
Ljmp start
org 23h
mov sp,#2Fh; Specialfunktion Register auf die Adresse..
start:
ioinit: anl pcon,#01111111b ;Bit SMOD=0 bei 9600 Baud
mov th1,#253 ;Reloadwert ins Timer-HByte
mov tl1,#253 ;Anfangswert Timer
anl tmod,#00001111b ;8-Bit-Timer1 mit Reload
orl tmod,#00100000b ;
setb tr1 ;Start Timer1
mov scon,#01010000b ;8-Bit-UART, Empfang zulassen
clr es ;kein serieller Interrupt
clr et1 ;kein Timer-Interupt
loop:
JNB RI,EMIT_IT ; testen ob es empfang gibt
CLR RI ; für nächsten empfang den Bit löschen
MOV A,SBUF ; Lese Data von Uart
MOV SBUF,A ; schreibe nach Uart
LJMP END_IT
EMIT_IT:
CLR TI
END_IT:
mov P2, A ; Daten an Port 2 (LED)
sjmp loop
------------------------------------------------
kann mir jemand sagen was ich falsch gemacht habe. Hab schon alles
mögliche versucht aber der Port gibt immer das gleiche aus(Binär:
00001101)
Ich hoffe ihr könnt mir weiterhelfen...
MfG
Alex
Daten empfängt man für Gewöhnlich mit einem Interrupt und nicht in einer
Endlosschleife.
Außerdem solltest du den Code nochmal formatieren und der Übersicht
halber Groß- und Kleinschreibung zumindest konsequent machen.
Was bringt dir 'start:' ? Da passiert ja nun wahrlich nichts ...
Was ich selbst mal machte, und zwar zog ich mir den SDCC-Compiler für µC
8051 aus dem Netz. Freeware. Darin enthalten, sind serielle
Standardroutinen in C, mit richtigen FIFO-Speichern, interruptgesteuert
bzw. voll automatisch.
Daraus, aus dem C-Code, erstellte ich dann die entsprechenden
Assemblerroutinen für einen 8051. Es ist stellenweise etwas kniffelig,
aber es geht ausgezeichnet.
Zusätzlich braucht man noch Funktionen Putchar und Getchar, um Zeichen
ins Sende-FIFO zu stellen bzw. aus dem Empfangs-FIFO heraus zu holen.
Die entsprechenden C-Funktionen waren im SDCC auch drin.
Man muß da nur den C-Code auf Assembler umportieren. Und wenn man schon
mal den C-Code hat, und etwas logisch denken kann, da sollte das gehen.
Egal für welchen µC, es muß kein 8051 sein.
Was macht der globale Interupt IE ?? Vergessen ?
> MOV A,SBUF ; Lese Data von Uart> MOV SBUF,A ; schreibe nach Uart
Was soll das? Ringelpietz mit anfassen.
Nach mov a,sbuf hast du doch das empfange im Akku.
Also arbeite damit weiter.
Hi
Kenne zwar den 8051 nicht, aber dem Hinweis auf den Interrupt zufolge
müsste es genauso wie beim Atmega8 funktinieren. Ich nehme da gern einen
Buffer und zwei Variablen als Zeiger. Eine, die auf die Stelle zeigt, wo
das neuempfangene Byte eingetragen wird und eine, die auf die zu lesende
Speicherzelle zeigt. Sozusagen Schreib- und Lesezeiger. Sind die beiden
Unterschiedlich, dann ist ein Zeichen im Buffer und kann von dem
Hauptprogramm bearbeitet werden.
Ablauf ist wie folgt:
Am anfang sind beide Variablen gleichzusetzen. Kommt ein Zeichen in der
ISR an, wird dieses an die Stelle geschrieben, wo der Bufer anfängt und
der hinzu addierte Schreibzeiger zeigt. Anschließend wird der Wert im
Schreibzeiger um 1 erhöht, die Buffergrenze abgefragt und eventuell
dieser Zeiger wieder auf 0 gesetzt. So erhält man einen Ringbuffer. Im
Hauptprogramm wird nun der unterschied zwischen Lese- und Schreibzeiger
festgestellt und eine Bearbeitungsroutine angesprochen. Auch hier wird
der Lesezeiger wie der Schreibzeiger hochgezählt, auf Buffergrenze
geprüft und evtl. wieder auf 0 gesetzt. So eilt der Lese- dem
Schreibzeiger nach. Nun ist es auch egal, wie dein Programm grad
ausgelastet ist, für die Abarbeitung der Zeichen findet der Controller
irgendwann immer die Zeit. Und du brauchst dir nur zu merken: ankommende
Zeichen schreibt die ISR in den Bufer, bearbeitet wird durch
Hauptprogramm bei unterschiedlichen Werten in den Zeigern.
Gruß oldmax
Lehrmann Michael schrieb:> Was bringt dir 'start:' ? Da passiert ja nun wahrlich nichts ...
Doch der Sprung LJMP Sprung... allerdings sollte der Befehl 2 Zeilen
oben stehen.
Komme trotz der Vorschläge und Kritisierungen nicht weiter :(
Habe auch mit Interrupt probiert, geht auch nicht.
Die Ratschläge gehen nicht an das Problem...
Wenigstens eine Beispielhafte INITIALISIERUNG um einen Seriellen Empfang
zu gewährleisten! Vllt. hab ich da was vergessen?!
Danke!