Forum: Mikrocontroller und Digitale Elektronik RS-232, empfangen der Daten am µC, Assembler


von AlexTGM (Gast)


Lesenswert?

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

von AlexTGM (Gast)


Lesenswert?

Kein Kenner da?

von AlexTGM (Gast)


Lesenswert?

also doch keiner, schade :(

von Lehrmann M. (ubimbo)


Lesenswert?

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 ...

von Wilhelm F. (Gast)


Lesenswert?

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.

von 8051 (Gast)


Lesenswert?

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.

von oldmax (Gast)


Lesenswert?

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

von AlexTGM (Gast)


Lesenswert?

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!

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
Noch kein Account? Hier anmelden.