Hallo, ich habe eine frage wenn ich jetzt an den PIC über rs232 2 bytes hintereinander sende werden die hardwaremäßig gepuffert ? und wenn ja wie lese ich das zweite byte aus ? oder muss ich einfach zweimal hintereinader das RCREG auslesen und in zwei verschiednen ram registern speichern ? RS232in btfss PIR1,RCIF ; sind Daten da ? goto RS232in ; nein, noch keine Daten da movfw RCREG ; RS232-Register auslesen movwf Zeichen ; und in den Speicher nach 'Zeichen' schreiben movfw RCREG movwf Zeichen2 könnte das so klappen ?? wenn nur ein zeichzen gesendet wird müssten dann ja in Zeichen2 nur nullen stehen also 0x00 , oder habe ich da jetzt einen denkfehler und mein programm würde an der stelle hängen bleiben ? kanns gerade leiter nicht testen, deswegen frage ich hier mal die spezialisten ;-) PS: Was ich noch vergass , der pic läuft mit 20mhz und es ist eine baud von 9600 eingestellt ... was mir aber gerade durch den kopf ging sollte ich dann für die folgenden zeichen nicht lieber eine schleife machen die halt nur x mal das PIR1 register abfragt ob daten da sind ? es werden maximal 4 bytes direkt hintereinader gesendet mfg
Marcel Klug schrieb: > oder muss ich einfach zweimal hintereinader das RCREG auslesen und in > zwei verschiednen ram registern speichern ? Genau so. Allerdings solltest du vor jeder Leseoperation das Interuptflag RCIF abfragen. Wenn nur ein Zeichen empfangen wurde, wird es nach dem ersten Auslesen zurückgesetzt, bei zwei Bytes nach dem zweiten Auslesen. Was passiert, wenn du zweimal RCREG ausliest, obwohl nur ein Byte drin steht, kann ich dir jetzt nicht beantworten.
Mach am beste den I/O-Verkehr per Interrupt und Ringpuffern: Auszug aus der Interrupt-Routine: .... SKIP RCIF GOTO i1 ; Byte von SIO wurde empfangen BCF RCIF MOVF RCSTA,W ; Test auf Rx Fehler ANDLW B'00000110' SKIP NZ GOTO i_rxb BCF CREN NOP BSF CREN GOTO i1 i_rxb: MOVF rx_ip,W ; Zeichen in den ANDLW 7 ; Empfangs-Ringpuffer ADDLW RxBuf ; schreiben MOVWF FSR MOVF RCREG,W MOVWF Indirect INCF rx_ip,W ANDLW 7 MOVWF rx_ip i1: SKIP TXIF GOTO i2 ; SIO Sender kann nächstes Byte vertragen ; (TXIF kann man nicht löschen! - nur mit TXIE=0 verbieten) MOVF tx_ip,W XORWF tx_op,W SKIP Z GOTO i_send_next BSF RP0 ; Bank 1 BCF TXIE ; wenn es nix zu tun gibt, löschen wir TXIE BCF RP0 GOTO i2 i_send_next: MOVF tx_op,W ADDLW TxBuf MOVWF FSR MOVF Indirect,W MOVWF TXREG INCF tx_op,W ANDLW 63 MOVWF tx_op i2: .... Und hier die UP, die vom normalen Programm aufgerufen werden: ; V.24 In/Out-Funktionen ; Test, ob empfangene Zeichen verfügbar sind. ; ZERO, wenn nix anliegt CharAvail: MOVF rx_ip,W XORWF rx_op,W RETURN ; liefert empfangenes Zeichen GetChar: MOVF rx_ip,W XORWF rx_op,W SKIP NZ GOTO GetChar ; wartet auf Zeichen!! MOVF rx_op,W ADDLW RxBuf MOVWF FSR INCF rx_op,W ANDLW 7 MOVWF rx_op MOVF Indirect,W RETURN ; sendet Zeichen PutChar: BCF GIE MOVWF PHudl ; Zeichen retten __put1: INCF tx_ip,W XORWF tx_op,W ANDLW 63 SKIP Z GOTO __put2 BSF RP0 ; Puffer ist voll, also warten BSF TXIE BCF RP0 BSF GIE GOTO __put1 __put2: BCF GIE MOVF tx_ip,W ANDLW 63 ADDLW TxBuf MOVWF FSR MOVF PHudl,W MOVWF Indirect INCF tx_ip,W ANDLW 63 MOVWF tx_ip BSF RP0 BSF TXIE BCF RP0 MOVF PHudl,W ; Zeichen zurück nach W BSF GIE RETURN So, das sollte ausreichen. W.S.
Wie wärs, wenn man sich im Datenblatt die Funktionsweise des USART Receivers durchliest? Sie befindet sich im Kapitel 10.2.2.
Marcel Klug schrieb: > wenn ich jetzt an den PIC über rs232 2 bytes > hintereinander sende werden die hardwaremäßig gepuffert ? Nö der 16f876a hat nur ein Schieberegister für den Empfang und ein Datenregister. Er kann also maximal 1 Byte gerade Empfangen während das vorherige von der Software weiterverarbeitet wird. Marcel Klug schrieb: > wenn nur ein zeichzen gesendet wird müssten dann ja in Zeichen2 nur > nullen stehen also 0x00 , oder habe ich da jetzt einen denkfehler Du liest 2 hintereinander das Datenregister aus also 2 denselben Wert. Marcel Klug schrieb: > es werden maximal 4 bytes direkt hintereinader gesendet Da ist eine Interruptroutine mit Ringpuffer und eine Statemachine für den Empfang nicht verkehrt. Gruß Anja
@ Anja okay aber im Datenblatt steht dass das RCREG ein doppelter puffer ist. Würde ich so verstehen dass das RCREG 2 bytes speichern kann. Weiter steht noch im Datenblatt wenn das 3. byte kommt und das stop bit angekomment ist und dabei der RCREG noch nicht leer ist , dass das 3 byte verloren ist und das OERR bit gesetzt wird. dieses OERR bit kann nur gelöscht werden indem man die UART resetet (CREN) So da ich ja weiß das maximal 4 bytes nacheinander ohne pause kommen werde ich das einfach so machen : RS232in btfss PIR1,RCIF ; sind Daten da ? goto RS232in ; nein, noch keine Daten da movfw RCREG ; RS232-Register auslesen movwf Zeichen ; und in den Speicher nach 'Zeichen' schreiben MOVLW 20 ; 20 ins Arbeitsregister laden MOVWF 0x20 ; die 20 wird in die Speicherzelle 0x20 kopiert byte2 ; eine Einsprungmarke btfss PIR1,RCIF ; sind Daten da ? goto byte2_no ; nein, noch keine Daten da movfw RCREG ; RS232-Register auslesen movwf Zeichen2 ; und in den Speicher nach 'Zeichen' schreiben goto byte_3 byte2_no DECFSZ 0x20,1 ;der Wert in der Sp.Zelle 20h wird um 1 verringert GOTO byte2 ; Sprung zur Marke LOOP goto Main ; hier geht das eigtl. Programm weiter byte_3 MOVLW 20 ; 20 ins Arbeitsregister laden MOVWF 0x20 ; die 20 wird in die Speicherzelle 0x20 kopiert byte3 ; eine Einsprungmarke btfss PIR1,RCIF ; sind Daten da ? goto byte3_n ; nein, noch keine Daten da movfw RCREG ; RS232-Register auslesen movwf Zeichen3 ; und in den Speicher nach 'Zeichen' schreiben goto byte_4 byte3_no DECFSZ 0x20,1 ;der Wert in der Sp.Zelle 20h wird um 1 verringert GOTO byte3 ; Sprung zur Marke LOOP GOTO Main byte_4 ..... da schreibe ich jetzt mal nicht weiter ^^ so müsste das ja klappen und dauert bei einem PIC tackt von 20mhz ja eigentlich auch nicht lange Mit Freundlichen Grüßen
Marcel BesondersKlug schrieb: > So da ich ja weiß das maximal 4 bytes nacheinander ohne pause kommen > werde ich das einfach so machen : Hmm.. wozu fragst du eigentlich nach Rat? W.S.
@ W.S. entschuldige da habe ich mich falsch ausgedrückt ! eigentlich wollte ich wissen ob man das so machen kann ...
Hi, falls es jemanden interessiert, ich habe mal selbst ein bisschen überelegt und gelesen und habe mir jetzt auch dank eurer tollen hilfe hier im forum eine kleine Interrupt routine gebastelt. ;RS232-Empfänger-Interrupt? btfss PIR1,RCIF goto intEnde ; Interrupt kam von wo anders movfw RCREG ; RS232-Register auslesen movwf temp goto Ringpuffer ; und in den Speicher nach 'Zeichen' schreiben Ringpuffer_fertig bsf DatenSindDa,0 ; Kennzeichen für gültige Daten setzen bcf PIR1,RCIF ; interrupt-Flag löschen goto intEnde Ringpuffer movlw 5 subwf puffer_zähler, w btfsc STATUS,Z goto Zeichen_0 movlw 4 subwf puffer_zähler, w btfsc STATUS,Z goto Zeichen_1 movlw 3 subwf puffer_zähler, w btfsc STATUS,Z goto Zeichen_2 movlw 2 subwf puffer_zähler, w btfsc STATUS,Z goto Zeichen_3 movlw 1 subwf puffer_zähler, w btfsc STATUS,Z goto Zeichen_4 Zeichen_0 movfw temp movwf Zeichen0 decf puffer_zähler, 1 goto Ringpuffer_fertig Zeichen_1 movfw temp movwf Zeichen1 decf puffer_zähler, 1 goto Ringpuffer_fertig Zeichen_2 movfw temp movwf Zeichen2 decf puffer_zähler, 1 goto Ringpuffer_fertig Zeichen_3 movfw temp movwf Zeichen3 decf puffer_zähler, 1 goto Ringpuffer_fertig Zeichen_4 movfw temp movwf Zeichen4 movlw 5 movwf puffer_zähler goto Ringpuffer_fertig intEnde ; geretteten Status wieder zurückschreiben swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie Bei der Init meines pics lade ich natürlich 5 in den puffer_zähler. Jetzt will ich noch die DTR line an RB0 anschliesen (natürlich über MAX232) und RB0 auch auf Interrupt stellen und wenn jetzt die RB0 High geht soll die 5 in den puffer_zähler laden. Ich weiß das ist umständlich aber der Puffer funktioniert so schon mal für mich ganz gut. Im Hauptprogramm frage ich jetzt einfach immer DatenSindDa ab wenn das bit gesetzt ist gebe ich dem pic noch ein paar ms zeit damit der empänger interrupt in ruhe weiter arbeiten kann und ich alle empfangenen zeichen sicher um puffer habe und dann geht mein eigentliches programm weiter.
Hm bis auf das Call besser ist als goto und du in der schleife den ISR nicht deaktivierst ist es ok. z.b. wie im Anhang. edit: http://grautier.com/temp/fifo.txt
okay mit dem goto habe ich gedacht mache ich es lieber so weil er ja sonst nachdem er zeichen0 geschrieben hat mit einem call befehl wieder in den puffer_zähler zurück springt und unnötig weitere befehle ausführt ... das war mein gedanlke ! Was meinst du mit ich deaktiviere die ISR nicht ?? mfg
Was ich noch wissen wollte in MPLAB bekomme ich beim kompelieren diesen fehler Register in operand not in bank 0. Ensure that bank bits are correct. wo er ja uach recht hat ADCON1 ist in BANK 1 und ich schalte ja auch vorher mit bsf STATUS, RP0 in Bank1 ich hänge mal mein programm an was ich bis jetzt habe ... Trozdem baut er die Hex und sie läuft auch
Marcel Klug schrieb: > Was ich noch wissen wollte in MPLAB bekomme ich beim kompelieren diese > fehler > Register in operand not in bank 0. Ensure that bank bits are correct. Das ist keine Fehlermeldung (error) sondern nur ein Hinweis (message). Leider eine unglückliche Lösung die schon bei vielen Leuten für Verwirrung gesorgt hat.
aaahh okay danke aber kannst du mir erklären warum das so ist ? muss ja irgendwie an mir liegen , denn wenn ich von sprut ein programm nehme zeigt er mir es nicht an ... mfg
Hy, ich habe die antwort auf meiner Frage selbst gefunden ! Ich muss einfach am anfang meines Assemblercodes das hier eintragen ERRORLEVEL -302 ;remove message about using proper bank hatte ich auch hatte es aber deaktiviert ;ERRORLEVEL -302 ;remove message about using proper bank mfg sunny
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.