Forum: Mikrocontroller und Digitale Elektronik PIC 16F723 und UART Problem


von Bernd K. (bernie6666)


Lesenswert?

Hallo zusammen,

ich habe hier einen PIC16F723 und wollte per RS232 ein paar Zeichen an 
den PC sende.
Leider kommen keine Zeichen an (ich hatte es schon geschafft, dass ein 
paar kryptische Zeichen empfangen wurden).

Die Hardware ist ok und ich kann Zeichen senden und empfangen!

Der Code funktioniert auch mit einem 16F871 (auf Steckbrett getestet).

Irgendwie habe ich vermutlich den PIC falsch konfiguriert oder den UART 
falsch eingestellt.
Ich komme aber selbst nach mehrmaligen durchlesen des Datenblatts nicht 
dahinter.

Anbei der Code (von Sprut)
------------------------------------------------------------------------ 
--------------------------
;**************************************************************
;*
;* Pinbelegung
;*  ----------------------------------
;*  PORTC:   0
;*      1
;*      2
;*      3
;*      4
;*      5
;*      6 RS-232-Ausgang zum Treiber
;*      7 RS-232-Eingang vom Treiber
;*
;**************************************************************
;
; sprut (zero) Bredendiek 06/2001
;
; RS-232-ECHO:
; 16F723 empfängt RS232 Code
; danach wird der code um 1 erhöht und mit RS232 zurückgesendet
;
; Prozessortakt:  4 MHz
; RS232-Baudrate: 19 200 Baud
;
;**************************************************************
; Includedatei für den 16F84 einbinden
   list      p=16f723
   #include   <P16f723.INC>
   ERRORLEVEL   -302   ;SUPPRESS BANK SELECTION MESSAGES
;**********************************************************
; Variablennamen vergeben
w_temp         equ      0x20
status_temp      equ      0x21
Zeichen         equ      0x22
DatenSindDa      equ      0x24
   org         0
   goto      init
;**********************************************************
; Interruptroutine für RS232-Empfang
   ORG         4      ;Interrupt beginnt immer bei Adresse 4
int
   movwf      w_temp      ; status retten
   swapf      STATUS,w
   movwf      status_temp
;RS232-Empfänger-Interrupt?
   btfss      PIR1,RCIF
   goto      intEnde      ; Interrupt kam von wo anders
   movfw      RCREG      ; RS232-Register auslesen
   movwf      Zeichen      ; und in den Speicher nach 'Zeichen' 
schreiben
   bsf         DatenSindDa,0    ; Kennzeichen für gültige Daten setzen
   bcf         PIR1,RCIF   ; interrupt-Flag löschen
intEnde                  ; geretteten Status wieder zurückschreiben
   swapf      status_temp,w
   movwf      STATUS
   swapf      w_temp,f
   swapf      w_temp,w
   retfie
;**********************************************************
; Anfangsinitialisierung
init
   clrf      DatenSindDa
   bsf         STATUS, RP0   ; auf Bank 1 umschalten
   movlw      B'00000000'   ; PortB alle output
   movwf      TRISB
   bcf         STATUS, RP0   ; auf Bank 0 zurückschalten
   clrf      PORTB      ; alle LEDs ausschalten
; USART initialisieren
   BSF         STATUS,RP0   ; Bank1
   MOVLW      0x20      ; 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'12'      ; Set Baud rate 19,2 kBPS bei 4 MHz (BGRH=1)
   MOVWF      SPBRG
   BSF         TXSTA, BRGH   ; BRGH=1
   BCF         STATUS,RP0   ; Bank 0
;Interrupts vorbereiten
   BSF         STATUS,RP0   ; Bank1
   BSF         PIE1,RCIE   ; Enable receive interrupts
   BCF         STATUS,RP0   ; Bank 0
   clrf      PIR1      ; alle Interruptflags löschen
   clrf      PIR2
   BSF         INTCON,GIE   ; generell Interrupts erlauben
   BSF         INTCON,PEIE   ; Interrupts von Peripheriegeräten erlauben
;**********************************************************
; Hauptprogrammschleife
Main
   btfss      DatenSindDa, 0   ; wurde was empfangen?
   goto      Main      ; nein
RS232out
   btfss      PIR1,TXIF   ; ist Sender leer ?
   goto      RS232out   ; nein, noch nicht leer
   incf      Zeichen,w   ; um 1 erhöht nach w
   movwf      TXREG      ; und in den RS232-Sender schreiben
   clrf      DatenSindDa
   goto      Main
   end
   
------------------------------------------------------------------------ 
--------------------------

Was mache ich falsch?

MfG
Bernie6666

von TK (Gast)


Lesenswert?

Hallo,

soweit ich das noch im Hinterkopf habe, muss man bei der Init den 
RxD-Pin auf Input und den TxD-Pin auf Output stellen. Also mal den 
PORT_C konfigurieren!
Dann hast Du in der ISR einen ganz beliebten Fehler drin, der Dein 
Programm jedoch in dieser Form nicht tangiert - trotzdem musst Du 
explizit in der ISR nach dem Sichern der W-und STATUS Register die BANK 
fest auf 0 vorgeben (nur mal so zur Info). Im Datasheet müsste auch eine 
ASM-Routine für die RICHTIGE REIHENFOLGE bei der USART-Init drin stehen 
- ich glaube da ist was verkehrt gelaufen bei Dir. Dann würde ich 
grundsätzlich das w_temp und s_temp NICHT auf EQU 0x20 legen, sondern 
auf (ich glaube) 0xF0. Also in den Bereich, der für alle BANKs gilt 
(auch das ist ein beliebter Fehler!!

Gruß
TK

von Bernd K. (bernie6666)


Lesenswert?

Danke für die Tipps.

Ich weiß nicht woran es lag, aber es geht jetzt.
Habe den Code nochmal neu zusammenkopiert.
Beim Vergleichen kann ich aber keinen Unterschied feststellen.
Ich kann den Fehler also nicht nachvollziehen.

Aber egal, es geht bis auf eine Kleinigkeit.

Beim Einschalten der Spannungsversorgung sendet der PIC bereits ein 
Zeichen.


Stört nicht weiter, aber es ist halt nicht so schön.

MfG
Bernie6666

von Bernd K. (bernie6666)


Lesenswert?

Einen Fehler habe ich aber trotzdem entdeckt:

; Test: String ausgeben
    MOVFW  0x54      ; "Test" ausgeben
    MOVWF  Zeichen
    CALL  Rs232out

    MOVFW  0x65      ; "Test" ausgeben
    MOVWF  Zeichen
    CALL  Rs232out

    MOVFW  0x73      ; "Test" ausgeben
    MOVWF  Zeichen
    CALL  Rs232out

    MOVFW  0x74      ; "Test" ausgeben
    MOVWF  Zeichen
    CALL  Rs232out

    MOVFW  D'32'      ; SPACE ausgeben
    MOVWF  Zeichen
    CALL  Rs232out

    MOVFW  D'13'      ; RETURN ausgeben
    MOVWF  Zeichen
    CALL  Rs232out

Habe anstatt MOFLW aus versehen MOVFW verwendet.
Deshalb die "kryptischen" Zeichen.

MfG

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.