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
Den call von Sendtime mit einem RETI zu beenden ist doch bestimmt keine Absicht? und danach soll es in INC_CNT weitergehen?
Der Ablauf sollte eigentlich so sein das auf einen Knopfdruck alle 4 Bytes ausgegeben werden. Danach kann eigentlich der uP geresetet werden.
Ich denke ich vergesse irgendwas zu reseten nach einem Byte ich habe in den Unterlagen nichts gefunden.
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.
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.
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...
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:
1 | ... |
2 | init: |
3 | setb ti |
4 | ... |
5 | sendbyte: |
6 | jnb ti, $ |
7 | clr ti |
8 | mov sbuf, a |
9 | ret |
10 | ... |
Peter
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
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
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
Hallo Da hast du recht das sieht wirklich schöner aus. Habe es jetzt so gemacht. Danke
Ich hatte ja oben schon die Funktion sendbyte geschrieben, hat aber wohl keinen interessiert. Peter
Hallo Interessiert schon aber mit jnb funktioniert das doch nicht? oder? Gruss
Pedas Methode ist eleganter...(den Code habe ich mir jetzt erst angeguckt...) Ich hab deine ja einfach nur verkürzt...
"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
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
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.