Forum: Mikrocontroller und Digitale Elektronik Problem mit UART PIC 16F627


von Eric J. (f3-john)


Lesenswert?

list p=16f627

  #define __16F627
  #include <P16f627.INC>

    ERRORLEVEL      -302    ;SUPPRESS BANK SELECTION MESSAGES

;**************************************************************
; Configuration festlegen
;
;Power on Timer, kein Watchdog, HS-Oscillator, kein Brown out, kein
LV-programming, MCLR, externer Oszillator
    __CONFIG        _PWRTE_ON & _WDT_OFF & _HS_OSC & _BODEN_OFF &
_LVP_OFF & _MCLRE_ON & _ER_OSC_CLKOUT

;**************************************************************
;Registerzuordnung
Eingang    equ 0x22

  org 0x000
  goto  init

;**************************************************************
;Initialisierung

init
  bsf    STATUS,RP0    ;Bankumschaltung
  movlw  b'11110000'
  movwf  TRISA      ;PortA Eingänge
  movlw  b'00000000'
  movwf  TRISB      ;PortB Ausgänge
    BSF     TRISB,1           ; RX-RS232 für USART-Modul
    BSF     TRISB,2           ; TX-RS232 für USART-Modul
  bcf    status,rp0    ;Bankumschaltung
  BSF     CMCON, CM0     ;Komperatoreingänge auf Digital schalten
    BSF     CMCON, CM1
    BSF     CMCON, CM2

; USART initialisieren
    BSF      STATUS,RP0        ; Bank1
    MOVLW    0x24              ; Sender: RS232
    MOVWF    TXSTA             ;
    BCF      STATUS,RP0        ; Bank 0
    MOVLW    0x90              ; Empfänger: RS232
    MOVWF    RCSTA             ;

; USART Baudrate einstellen
    BSF      STATUS,RP0        ; Bank1
    MOVLW    D'23'             ; Set Baud rate 14.7456 Mhz bei 38400
Baud
    MOVWF    SPBRG
    BSF      TXSTA, BRGH       ; BRGH=1
    BCF      STATUS,RP0        ; Bank 0

;**************************************************************
;Programm

RS232in
  btfss  PIR1,RCIF
  goto  RS232in    ; Interrupt kam von wo anders
  movfw  RCREG    ; RS232-Register auslesen
  movwf  Eingang

RS232out
  btfss  PIR1,TXIF  ; ist Sender leer ?
  goto  RS232out  ; nein, noch nicht leer
  movfw  Eingang
  movwf  TXREG    ; und in den RS232-Sender schreiben
  goto  RS232in




END


Leider funktioniert dieses Programm nicht:(
Es soll nur die Daten vom NMEA protokoll vom GPS einlesen und gleich 
wieder rausschicken.

Leider kommt am Ausgang nur datenmüll an, obwohl ab und zu auch mal ne 
zeile korrekt ausgegeben wird.
Habe dann mal zu test eine "3" senden lassen immer wenn ein Byte 
emfpangen wird und das hat wunderbar funktioniert auch in dem Rythmus 
wie ie daten vom NMEA reinkommen.

Ich habe schon alles versucht aber nichts hilft.
hoffe Ihr könnt mir helfen.

von Ottmar K. (wil1)


Lesenswert?

Hallo
bcf    status,rp0    ;Bankumschaltung

Richtig : STATUS,RP0

mfg Ottmar

von W.S. (Gast)


Lesenswert?

Eric John schrieb:
> Leider funktioniert dieses Programm nicht

Dein Code ist lausig. Abgesehen von formalen Dingen scheinst du der 
Ansicht zu sein, daß man Rx und Tx immer und jederzeit benutzen kann, 
ohne drauf zu achten, ob der Tx auch frei ist, wenn am Rx grad was 
passendes eingetroffen ist. Mein Rat: Zwischenpufferung.

Hier ist mal ein kruder Auszug aus einer meiner Quellen. Syntax ist ein 
bissel anders als bei deinem Assembler, aber du wirst es schon 
verstehen:

; Interrupt-Routine
; =================

          ORG      4

Interrupt:
          MOVWF    RetteW         ; W retten
          SWAPF    Status,W       ; Flags in W holen
          CLRF     Status
          MOVWF    RetteFlags     ; Flags retten
          MOVF     FSR,W
          MOVWF    RetteFSR

          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:       SKIP     ADIF
          GOTO     i3
           ... usw.


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


;===== Kaltstart =================================================

Start:   MOVLW  ValPortA
         MOVWF  PortA
         MOVLW  ValPortB
         MOVWF  PortB
         MOVLW  ValPortC
         MOVWF  PortC
         MOVLW  ValPortD
         MOVWF  PortD
         MOVLW  ValPortE
         MOVWF  PortE
         CLRF   tx_ip
         CLRF   tx_op
         CLRF   rx_ip
         CLRF   rx_op
         CLRF   AbFlags
         CLRF   ModFlags
         CLRF   AdcMap
         CLRF   Protokoll
         CLRF   Amplix
         CLRF   SloMoCount

         BSF    RP0        ; Bank 1
         MOVLW  B'01000000'
         MOVWF  OptionReg
         MOVLW  ValTrisA
         MOVWF  TrisA
         MOVLW  ValTrisB
         MOVWF  TrisB
         MOVLW  ValTrisC
         MOVWF  TrisC
         MOVLW  ValTrisD
         MOVWF  TrisD
         MOVLW  ValTrisE
         MOVWF  TrisE
         MOVLW  B'00100010'
         MOVWF  ADCON1     ; 5 Kanäle AN0..4 analog, left justified
         MOVLW  20
         MOVWF  SPBRG
         MOVLW  B'00100110'
         MOVWF  TXSTA

         BCF    RP0        ; wieder Bank 0
         MOVLW  B'10110000'
         MOVWF  RCSTA

         MOVLW  B'00000101' ;Timer 1, Pre=1:1, intern
         MOVWF  T1CON

         BSF    RP0
         BSF    RCIE
         BSF    TXIE
         BSF    INTE
         BSF    PEIE
         BCF    RP0
         ...usw.


W.S.

von Eric J. (f3-john)


Lesenswert?

Hallo W.S. Danke für deine Antwort.

Das Senden funktioniert bei mir ja, aber auch beim Einlesen habe ich 
keinen Puffer oder wartezeit.

Ist mir ehrlich gar nicht aufgefallen:(
Hoffe das es daran liegt.

Was meine Formale schreibweise angeht wie z.b.
status,rp0   Richtig : STATUS,RP0


Wozu gibt es denn Compiler?^^
sicherlich nicht schön aber die funktion bleibt die selbe.


Werde aber mal das programm umschreiben:

RS232in
  btfss  PIR1,RCIF
  goto  RS232in    ; Interrupt kam von wo anders
  movfw  RCREG    ; RS232-Register auslesen
  movwf  Eingang

RS232out
  btfss  PIR1,TXIF  ; ist Sender leer ?
  goto  RS232out  ; nein, noch nicht leer
  movfw  Eingang
  movwf  TXREG    ; und in den RS232-Sender schreiben

leer
   btfsc  PIR1,RCIF
   goto leer
   btfsc  PIR1,TXIF
   goto leer
   goto  RS232in


Das sollte doch genügen damit er genug zeit hat zum senden und 
empfangen?

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.