PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] PIC und RS232 einmal mehr



20.05.2005, 22:38
Hallo

Ich möchte vom PC via RS232 bytes zum PIC 16F627 senden.
Ich habe die Beispiele bei sprut.de etc studiert, aber es klappt irgendwie nicht.

Kann mir jemand sagen, was bei dem unten angeführten code nicht stimmt. An PORTB pin 0 ist eine LED und wenn Daten an RS232 ankommen, dann sollte diese LED angehen. Es klappt aber nicht.

Ich bin um jegliche Hilfe dankbar!
Grüsse
Sami

;************************************************* ************
MAIN
;************************************************* ************

;-----------------------------------------------------------------------------
INITUSART
;-----------------------------------------------------------------------------
BSF STATUS,RP0 ; switch to Bank1
MOVLW 0x20 ; sender: RS232
MOVWF TXSTA ;
BCF STATUS,RP0 ; switch to Bank 0
MOVLW 0x90 ; receiver: RS232
MOVWF RCSTA ;

;-----------------------------------------------------------------------------
SETBAUD
;-----------------------------------------------------------------------------
BSF STATUS,RP0 ; Bank1
MOVLW 15 ; Set Baud rate 19,2 kBPS bei 20 MHz
MOVWF SPBRG
BCF TXSTA, BRGH ; BRGH=0
BCF STATUS,RP0 ; Bank 0


;-----------------------------------------------------------------------------
CLRPORTS
;-----------------------------------------------------------------------------
clrf PORTA
clrf PORTB


;-----------------------------------------------------------------------------
RECDATA1
;-----------------------------------------------------------------------------
btfss PIR1,RCIF ; sind Daten da ?
goto RECDATA1 ; nein, noch keine Daten da
;movfw RCREG ; RS232-Register auslesen
;movwf CHAR ; und in den Speicher nach 'Zeichen' schreiben


;-----------------------------------------------------------------------------
SETB0ON ; set pin 0 on PortB to 1
;-----------------------------------------------------------------------------
bsf STATUS, RP0 ; switch to bank1
bcf TRISB ^ 0x80, 0 ; set on port B pin 0 as output
bcf STATUS, RP0 ; switch back to bank0
movlw b'00000001' ; set bit 0 high in work reg
movwf PORTB ; move work reg to PORTB
;-----------------------------------------------------------------------------
LOOP ; long loop, this allows to see an LED
;-----------------------------------------------------------------------------
count1 equ 15h
count2 equ 16h
L1 decfsz count1,1
goto L1
decfsz count2,1
goto L1

end
[/code]

21.05.2005, 09:28
Ohne jetzt deinen Code genauer anzusehen:

1. Dein Programm fängt (einfach) bei Adresse 0x0000 an. Das ist schlecht, da auf 0x0000 der Resetvector und auf 0x004 der Interruptvector liegt. Der Programmspeicher beginnt bei 0x0005 (Datasheet seite 13)

Besser:
org 0x00
goto MAIN ; Nach Reset mit MAIN beginnen
:
:
org 0x05
MAIN
:
:

2. Was macht dein Programm nach Ende der Schleife? Es läuft ins leere! Das 'end' ist nur eine Derektive für den Assembler. Das hat auf dein Programm keinen Einfluss. Wenn count2 runtergezählt ist, wird das 'goto L1' übersprungen. Was aber nach 'goto L1' im Programmspeicher steht ist völlig ungewiss!

Also: Zum Testen deine LOOP komplett entfernen und durch

LOOP goto LOOP ; Endloosschleife

ersetzen. Hier loopt der Prozessor bis Power OFF. Zum Testen ist das besser. Später würde ich dann den USART aber über Interrupts verwenden.

Chief Brady

21.05.2005, 10:43
Danke!
Ich habe die 2 Sachen korrigiert.
Ich benutzte dieses Program nur zum testen, ob und wie ich Daten via RS232 vom PC an den PIC schicken kann.
Trotzdem läuft das Program nicht.
1) wenn es startet leuchtete von Anfang an LED3 (PortB pin2)
2) ich sende Daten an RS232 aber die kann ich am PIC nicht abfangen, d.h. LED0, PortB pin0, leuchtet nie auf.

Danke für Eure Hilfe.
Gruss
Sam

21.05.2005, 11:26
Was bei deinem Init-USART noch fehlt ist


movlw 0x07 ; Comparator aus und auf
movwf CMCON ; Digital IO


Und du solltest den TX auf 'Ausgang' und RX auf Eingang setzen


bsf STATUS, RP0 ; switch to bank1
movlw b'00000010' ; RB1 = IN, sonst alles OUT
movwf TRISA ; /
bcf STATUS, RP0 ; switch to bank0


Dafür kann in SETB0ON dann das


bsf STATUS, RP0 ; switch to bank1
bcf TRISB ^ 0x80, 0 ; set on port B pin 0 as output
bcf STATUS, RP0 ; switch back to bank0


entfallen.

21.05.2005, 11:43
Das Program sieht nun folgendermassen aus:



list p=16f627
#include "p16f627.inc"

CHAR equ 0X22

__CONFIG _BODEN_ON & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_ON & _XT_OSC

ERRORLEVEL -302
org 0x00
goto MAIN
org 0x04

org 0x05
;************************************************* ************
MAIN
;************************************************* ************

;-----------------------------------------------------------------------------
INITUSART
;-----------------------------------------------------------------------------
BSF STATUS,RP0 ; switch to Bank1
MOVLW 0x20 ; sender: RS232
MOVWF TXSTA ;
BCF STATUS,RP0 ; switch to Bank 0
MOVLW 0x90 ; receiver: RS232
MOVWF RCSTA ;
movlw 0x07 ; Comparator aus und auf
movwf CMCON ; Digital IO

bsf STATUS, RP0 ; switch to bank1
movlw b'00000010' ; RB1 = IN, sonst alles OUT
movwf TRISA ; /
bcf STATUS, RP0 ; switch to bank0

;-----------------------------------------------------------------------------
SETBAUD
;-----------------------------------------------------------------------------
BSF STATUS,RP0 ; Bank1
MOVLW 15 ; Set Baud rate 19,2 kBPS bei 20 MHz
MOVWF SPBRG
BCF TXSTA, BRGH ; BRGH=0
BCF STATUS,RP0 ; Bank 0

;-----------------------------------------------------------------------------
CLRPORTS
;-----------------------------------------------------------------------------
clrf PORTA
clrf PORTB

;-----------------------------------------------------------------------------
RECDATA1
;-----------------------------------------------------------------------------
btfss PIR1,RCIF ; sind Daten da ?
goto RECDATA1 ; nein, noch keine Daten da
;movfw RCREG ; RS232-Register auslesen
;movwf CHAR ; und in den Speicher nach 'Zeichen' schreiben

;-----------------------------------------------------------------------------
SETB0ON ; set pin 0 on PortB to 1
;-----------------------------------------------------------------------------
; bsf STATUS, RP0 ; switch to bank1
; bcf TRISB ^ 0x80, 0 ; set on port B pin 0 as output
; bcf STATUS, RP0 ; switch back to bank0
movlw b'00000001' ; set bit 0 high in work reg
movwf PORTB ; move work reg to PORTB

;-----------------------------------------------------------------------------
LOOP ; long loop, this allows to see an LED
;-----------------------------------------------------------------------------
count1 equ 15h
count2 equ 16h
L1 decfsz count1,1
goto L1
decfsz count2,1
goto L1
goto LOOP ; just for testing
end


Beim Start leuchtet sofort LED3, portb pin2, auf. LED1, portb pin 0, leuchtet nicht auf, wenn ich Daten via rs232 schicke.

Was ist hier falsch?

Vielen Dank für HIlfe.
Gruss
Sam

21.05.2005, 11:59
Natürlich: PORTB Pin2 ist doch TX. Wenn nichts gesendet wird, ist TX HI, also leuchtet deine LED.

Was mir noch aufgefallen ist: Du solltest bei der PORT-Initialisierung die Internen Pullup-Widerstände einschalten, wenn du LED's dran hast (sofern du keine externen Pull-UP's hast).

SETBANK 1
bcf OPTION,RBPU ; Weak Pull-Up's ON
SETBANK 0

Auch solltest du die LED nicht mit

movlw b'00000001' ; set bit 0 high in work reg
movwf PORTB ; move work reg to PORTB

sondern eher

bsf PORTB,0

einschalten. Dann werden die anderen Pin's nicht berührt.

PS: SETBANK ist bei mir ein Macro zum Bankumschalten

21.05.2005, 12:03
Und nochwas: Betriebst du den PIC tatsächlich mit 20MHz?

21.05.2005, 13:22
Ich habe externe Widerstände, ich betreibe das Ganez auf dem Vellemen K8048.
Das mit den 20 MHZ habe ich nicht verstanden.

Der Code sieht nun folgendermassen aus.
Warum geht denn LED1, pin 0 on PortB, nicht auf high, wenn ich Daten via RS232 sende?



;
; Handler for RS232 communication
; ------------------------------
;
;
;-------------------------------------------------------------------------------------------------

list p=16f627
#include "p16f627.inc"

CHAR equ 0X22

__CONFIG _BODEN_ON & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_ON & _XT_OSC

ERRORLEVEL -302
org 0x00
goto MAIN
org 0x04

org 0x05
;************************************************* ************
MAIN
;************************************************* ************

;-----------------------------------------------------------------------------
INITUSART
;-----------------------------------------------------------------------------
BSF STATUS,RP0 ; switch to Bank1
MOVLW 0x20 ; sender: RS232
MOVWF TXSTA ;
BCF STATUS,RP0 ; switch to Bank 0
MOVLW 0x90 ; receiver: RS232
MOVWF RCSTA ;
movlw 0x07 ; Comparator aus und auf
movwf CMCON ; Digital IO

bsf STATUS, RP0 ; switch to bank1
movlw b'00000010' ; RB1 = IN, sonst alles OUT
movwf TRISA ; /
bcf STATUS, RP0 ; switch to bank0

;-----------------------------------------------------------------------------
SETBAUD
;-----------------------------------------------------------------------------
BSF STATUS,RP0 ; Bank1
MOVLW 15 ; Set Baud rate 19,2 kBPS bei 20 MHz
MOVWF SPBRG
BCF TXSTA, BRGH ; BRGH=0
BCF STATUS,RP0 ; Bank 0

;-----------------------------------------------------------------------------
CLRPORTS
;-----------------------------------------------------------------------------
clrf PORTA
clrf PORTB

;-----------------------------------------------------------------------------
RECDATA1
;-----------------------------------------------------------------------------
btfss PIR1,RCIF ; sind Daten da ?
goto RECDATA1 ; nein, noch keine Daten da
;movfw RCREG ; RS232-Register auslesen
;movwf CHAR ; und in den Speicher nach 'Zeichen' schreiben

;-----------------------------------------------------------------------------
SETB0ON ; set pin 0 on PortB to high
;-----------------------------------------------------------------------------
; bsf STATUS, RP0 ; switch to bank1
; bcf TRISB ^ 0x80, 0 ; set on port B pin 0 as output
; bcf STATUS, RP0 ; switch back to bank0
bsf PORTB,0 ; set bit 0 on PortB to high

;-----------------------------------------------------------------------------
LOOP ; long loop, this allows to see an LED
;-----------------------------------------------------------------------------
count1 equ 15h
count2 equ 16h
L1 decfsz count1,1
goto L1
decfsz count2,1
goto L1
goto LOOP ; just for testing
end

21.05.2005, 13:34
> Das mit den 20 MHZ habe ich nicht verstanden.

Wiel du das Baudrate-Register für fosz=20 MHz setzt:

> BSF STATUS,RP0 ; Bank1
> MOVLW 15 ; Set Baud rate 19,2 kBPS bei 20 MHz
> MOVWF SPBRG

Ich kann mich im Moment leider nicht intensiever mit deinem Code beschäftigen, aber ich könnte heute abend Code posten, der funktioniert (ist bei mir im Einsatz ;-)

21.05.2005, 13:40
Ich kann die Daten vom PC auch mit 9600 schicken. Das mit den 20 MHZ habe ich von sprut Beispielen.

Das wäre super, wenn Du mir code posten kannst, der läuft.

Vielen vielen Dank, Gruss
Sami - sami@hassanein.ch

iClou
21.05.2005, 15:58
Ich habe das Experimentier Kit K8048 von Velleman, http://www.velleman.be.

Frage:
Kann ich via diese RS232 Schnittstelle vom Kit überhaupt den PIC via USART ansprechen?
Wenn nein, wo kann ich eine möglichst einfach Schaltung nachschlagen?

--
Dank, Grüsse
Sam

art-hightech
21.05.2005, 17:53
Das mit den 20 MHZ habe ich von sprut Beispielen

Die BAUD-Rate muss auf die Frequenz deines Microcontrollers (fosc) abgestimmt werden! Dazu muss man das Register SPBRG richtig setzen!
Es gibt eine Formel, wie sich der Wert berechnet, zu finden im PIC-Datenblatt unter USART, es wäre nicht schlecht, diesen Teil mal durchzuarbeiten!
Mit welcher Oszillatorfrequenz hast du den PIC getaktet? (Frequenz von Quarz/RC)

21.05.2005, 19:14
OK, das Kit habe ich mir mal angesehen. Die USART-Pins sind nicht herausgeführt. Eine serielle Kommunikation ist also nicht ohne weiteres möglich. Sie D-SUB-Buchse am KIT scheint nur zum Programmieren gedacht.

Die Schaltung zur Verbindung PIC <-> PC ist aber denkbar einfach. Du benötigst nur einen Pegelwandler (z. B. MAX232 von MAXIM), der die TTL-Pegel des PICs auf RS232-Nivau bringt.

Ein Schaltungsbeispiel und ein USART-Test-Programm findest du hier:

http://www.oz1bxm.dk/PIC/628uart.htm

Es ist zwar für den 16F628 gedacht, aber der unterscheidet sich ja nur in der Größe des Programmspeichers. Du musst nur im Programm in den Zeilen

LIST P=16F628, R=DEC ; Use the PIC16F628 and decimal system
#include "P16F628.INC" ; Include header file

das 16F628 durch 16F627 ersetzen. Das Programm sendet nach dem Einschalten ein "16F628 alive" und sendet danach jedes empfangene Byte zurück. Das Programm funktioniert garaniert!

Chief Brady

iClou
22.05.2005, 00:05
OK, vielen Dank für die Hilfe!!
Ich werde mir das nun mal zusammenbauen und testen.

Danke für alles!
Gruss
Sami

iClou
22.05.2005, 22:10
OK, das Kit habe ich mir mal angesehen. Die USART-Pins sind nicht herausgeführt. Eine serielle Kommunikation ist also nicht ohne weiteres möglich. Sie D-SUB-Buchse am KIT scheint nur zum Programmieren gedacht.

Die Schaltung zur Verbindung PIC <-> PC ist aber denkbar einfach. Du benötigst nur einen Pegelwandler (z. B. MAX232 von MAXIM), der die TTL-Pegel des PICs auf RS232-Nivau bringt.

Ein Schaltungsbeispiel und ein USART-Test-Programm findest du hier:

http://www.oz1bxm.dk/PIC/628uart.htm



Darf ich Dich fragen, ob Du auch gerade gute Schaltpläne für Funkmodule hast?
Danke für Deine Hilfe.
Gruss
Sam

23.05.2005, 20:55
Wieso gute Schaltpläne für Funkmodule? Du sucht dir einfach Funkmodule für deinen Zweck bzw. passend zu deinem Geldbeutel (mit oder ohne eigenem Controller). In den Datenblättern steht dann, wie diese anzuschliessen sind.

iClou
23.05.2005, 21:30
OK die Frage ist etwas doof.
Ich bin Informatiker und habe nur Basiswissen von Elektronik, deshalb suche ich eine einfach Schaltung zum anfangen. Ich brauche nur on/off von einem Sender zum Empfänger wo auch mein PIC ist.

Wenn jemand hierfür einen einfachen Schaltpläne hat, dann wäre das eine grosse Hilfe zum anfangen.

Danke für jeglichen Tipp!
Gruss
Sam

Goblin
23.05.2005, 23:19
on/off? willst du den pic an/ausschalten, bzw in sleep und aus sleep wieder raus? (interrupt)? wenn ja, dann würde ne 1-kanal-funkfernsteuerung reichen. wie soll denn die reichweite sein? und ginge nicht auch ir?

iClou
24.05.2005, 06:47
Der Sender hat nur 2 Zustände, e.g. on/off. Am Empfänger ist ein PIC und dort möchte ich diese 2 Zustände auswerten können.

Ich werde die angeführte Schaltung als Grundlage für den Empfänger nehmen.
http://www.oz1bxm.dk/PIC/628uart.htm

Nun brauche ich Hilfe, wenn ich hier noch einen Funkempfänger anschliessen möchte. Wenn mir da jemand mit der Schaltung helfen kann, dann wäre das super!

Vielen Dank.
Sam