mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mehrer Byts ausgeben mit UART


Autor: Matthias Junker (xc866)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich möchte über die UART mehrere Byts ausgeben. Das funktioniert im
Moment nur mit einem Byte.
Ich möchte CNTRL, CNTRH, RC2L, und RC2H ausgeben. Das Funktionier im
Moment nur mit dem ersten Byte.
Ich benutze einen XC 866 und die Sprache ist Assembler.

Code:

;-------------------------Reaktionszeitmessung-------------------------- 
----------------------------

#include <xc866.inc>

;-------------------------User
Register-------------------------------------------------------------
CNTRL equ r2     ;Counter Low Register zuweisen
CNTRH equ r3     ;Counter High Register zuweisen

;----------------------------Flag
Adressen----------------------------------------------------------
SEND_TXT_FLAG equ 020h
;----------------------------Interups----------------------------------- 
----------------------------
 JMP Start
 ORG 002Bh
 JMP THL2
 ORG 100h

;----------------------------Ports
initialisieren---------------------------------------------------
START:  MOV PORT_PAGE,#00h
    MOV P3_DIR,#00000100b  ; P3.1 reset Taster Input    P3.2 LED Output
      MOV P1_DIR,#00000010b  ; P1.0 Taster Input T2EX enable
    MOV  PORT_PAGE,#001H
    MOV  P1_PUDEN,#00000000b       ;ENABLING PULLUP
    MOV  P1_PUDSEL,#00000000B
    MOV PORT_PAGE,#02h
    MOV P1_ALTSEL0,#00000000b  ; ALT2 einstellen für T2EX
    MOV P1_ALTSEL1,#00000011b  ; ALT2 einstellen für T2EX
       MOV PORT_PAGE,#000H      ; wichtig ohne das läuft nichts




;----------------------------Serielle Schnittstelle
einrichten---------------------------------------
    MOV BG,#10101110b     ;174d Baudrate 9600 BAUD
    MOV  SCON,#01010000b    ;Modus1 und recieive einschalten
        MOV BCON,#00000001b    ;bd generator einschalten
        MOV FDCON,#00000000b  ;Fractional Divider Control Register

;----------------------------Timer 2 Capture
Unit----------------------------------------------------
      MOV T2CON,#00001101b  ;CP/RL2=1      EXEN2=1
    MOV T2MOD,#10111000b  ;T2PRE = 100 Prescaler =16 PREN=1 EDGESEL=1
T2RHEN=1 T2REGS=1

;-----------------------------Initialisiere
Interupps------------------------------------------------
     Setb ET2
     Setb EA
     CLR TI
;-----------------------------Programm---------------------------------- 
-----------------------------
Hauptprogramm:
           NOP
           NOP
           NOP
        NOP
           NOP
        JMP Hauptprogramm

;-----------------------------Timer2
Interuppt--------------------------------------------------------
THL2:        CLR A               ; Akku löschen
        MOV A,T2CON             ; T2CON in Akku verschieben
        XRL A,#01000000b         ; 6.Bit wechseln "das ist EXF2 Bit"
        CJNE A,#00001101b,INC_CNT     ; Ist der Interuppt durch TF2
ausgelöst, gehe zu INC-CNT
        call SEND_TIME           ; jump send Time

INC_CNT:    INC CNTRL        ; R0 um 1 inkerementieren
       MOV A,CNTRL        ; R0 in Akku laden
       JNZ IRQ_T2_end      ; Wenn Akku = 0 eine Zeile weiter springen
       INC CNTRH        ; INC R1
       CLR TF2          ; Akku löschen
       RETI

;SEND_END:  CLR TI
;      RET

SEND_TIME:  CLR TI
      CLR A
        MOV A,CNTRL
      MOV SBUF,A
      ;CLR TI
      NOP
      NOP
      NOP
      NOP
      NOP
      CLR TI
      MOV A,CNTRH
      MOV SBUF,A
      CLR EXF2
      RETI





IRQ_T2_end: Clr TF2
      RETI

;----------------------------------------------------------------------- 
------------------------------


END

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den call von Sendtime mit einem RETI zu beenden ist doch bestimmt keine
Absicht? und danach soll es in INC_CNT weitergehen?

Autor: Matthias Junker (xc866)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Ablauf sollte eigentlich so sein das auf einen Knopfdruck alle 4
Bytes ausgegeben werden. Danach kann eigentlich der uP geresetet
werden.

Autor: Matthias Junker (xc866)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke ich vergesse irgendwas zu reseten nach einem Byte ich habe in
den Unterlagen nichts gefunden.

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Programmkomentare kannst du weglassen , das ist so als wenn du
nichts hinschreibst. Kommentare sollen den Programmfluss erklären nicht
die einzelne Anweisung.
Wenn ich das richtig erfasse macht dein Hauptprogramm nichts,wozu die
nops?
Du hast einen Timerinterrupt und wenn der aufgerufen wird sendest du
irgendwas raus, richtig?
Wie oft kommt dieser Interrupt? wenn es unter 1ms liegt hast du einen
schweren Denkfehler.
RETI ist doch ein Rücksprung mit Freigabe des Interrupts?
Willst du wirklich das mitten in der Interruptprozedur der Interrupt
wieder freigegeben wird?
Ich sehe auch nicht so richtig wo du sendest, das dürfte daran liegen
das ich den XC nicht kenne und du keine Komentare gemacht hast.
Ich kann in den Befehlsstrukturen nichts entdecken was mehrere Bytes
sendet. Das einzige was läuft ist alles hinter interrupt? und da gehst
du ohne schleifen die man für mehrere Bytes erwarten würde raus.

Autor: Matthias Junker (xc866)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Das mit dem Timer Interupt funktioniert. Ich möchte eigentlich wirklich
nur diese 4 Bytes rausschreiben CNTRL, CNTRH, RC2L, und RC2H.
So wie es jetzt ist schreibt er einfach das CNTRL raus, aber sobald ich
mehrere anhänge funktioniert das nicht mehr.

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kenne mich zwar nicht mit dem o.g. Controller aus, aber das
einfachste ist doch für jedes der vier Bytes die Senderoutine zu
wiederholen (neu zuschreiben/copy&paste). Die folgende Routine wartet
einfach bis das vorhergehende Byte gesendet wurde, und sendet dann
ihrerseits. Bei 4 Bytes ist das nicht gerade viel Code mehr...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sieht so aus, als wärs ein 8051-Derivat.

Wenn Du das TI nirgends auswertest, brauchst Du es auch nicht zu
löschen.

Um nun mehrere Bytes zu senden, mußt Du aber das TI auswerten, d.h. mit
dem nächsten Byte warten, bis das vorherige Senden beendet ist:
...
init:
        setb   ti
...
sendbyte:
        jnb    ti, $
        clr    ti
        mov    sbuf, a
        ret
...


Peter

Autor: Matthias Junker (xc866)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Habe noch kleine Probleme:

TI wird doch gesetzt wenn das Byte übertragen wurde? Dann müsste ich
eingentlich nur auf das TI schauen und wenn es 1 wird muss ich das TI
zuerst löschen und dann mit dem 2 Byte beginnen.
Im Moment bin ich das nur am Simulieren, vieleicht macht hier auch der
Simulator probleme.
Ich benützt den KEIL uVision3.

Gruss

Autor: Matthias Junker (xc866)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich habe das jetzt so gemacht. Vielen Dnak für eure Hilfe.

SEND_TIME:  CLR TI
          CLR A
    MOV A,CNTRL
    MOV SBUF,A


SEND_WAIT_1:  jbc    ti, send_time_2
    jmp SEND_WAIT_1

SEND_TIME_2:   CLR A
    MOV A,CNTRH
    MOV SBUF,A

SEND_WAIT_2:  jbc    ti, send_time_3
    jmp SEND_WAIT_2

SEND_TIME_3:   CLR A
    MOV A,RC2L
    MOV SBUF,A

SEND_WAIT_3:  jbc    ti, send_time_4
    jmp SEND_WAIT_3

SEND_TIME_4:   CLR A
    MOV A,RC2H
    MOV SBUF,A
    CLR EXF2
    RETI

IRQ_T2_end: Clr TF2
      RETI

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kann man bestimmt noch schöner machen... Aber erst mal wird es
funktionieren.

Schöner:

MOV A,CNTRL
CALL SEND
MOV A,CNTRH
CALL SEND
MOV A,RC2L
CALL SEND
MOV A,RC2H
CALL SEND
RETI



Muß nicht komplett richtig sein (und damit aufd Anhieb funktionieren).
Mit 8051ern habe ich schon länger nicht mehr gearbeitet...
SEND:
    CLR TI
    MOV SBUF,A

SEND_WAIT:  jbc    ti, zurueck
    jmp SEND_WAIT

zurück:
RET

Autor: Matthias Junker (xc866)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Da hast du recht das sieht wirklich schöner aus.
Habe es jetzt so gemacht.
Danke

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte ja oben schon die Funktion sendbyte geschrieben, hat aber wohl
keinen interessiert.


Peter

Autor: Matthias Junker (xc866)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Interessiert schon aber mit jnb funktioniert das doch nicht? oder?

Gruss

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pedas Methode ist eleganter...(den Code habe ich mir jetzt erst
angeguckt...)
Ich hab deine ja einfach nur verkürzt...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"jnb bit, $" heißt springe zu sich selber ($), solange das bit nicht
gesetzt ist (Jump if not bit).
Er macht also erst mit der nächsten Zeile weiter, wenn es gesetzt ist.


Der 8051 kann springen bei gesetzt (jb) oder nicht gesetzt (jnb) oder
springen und löschen (jbc).


Im Unterschied zum PIC, der kann ja nur skippen, d.h. da muß man noch
nen extra Jump ranfügen.


Peter

Autor: Matthias Junker (xc866)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AHA

Habe erst begonnen zu programmieren. Vielen Dank.

Matthias

Autor: Matthias Junker (xc866)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich habe noch schnell eine Frage zum Timer 2 Capture Mode.
Den Prescaler habe ich auf 16 eingestellt.
fpclk ist 26,7 MHz. Das Register im Timer ist 16 BIT. Dann sollte doch
alle 0,0392s ein Interupt ausgelöst werden.
Dann hat es 8 BIT im CNTRL Register und 8 Bit im CNTRH Register.
Das heist alle 0,0392s wird das CNTRL Register um 1 Incrementiert. Das
heisst 1 Stelle im CHTRH Register sollte 10,0352s sein. Das stimmt aber
irgendwie nicht ganz?
An was könnte das liegen?

Gruss

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.