-
Also, das CMCON ist der interne Comparator. hier ist es erklärt ;). Kurz gesagt, beim reset des PICs ist der Comparator auf RA0 und 1 geschalten, was echt nervend ist, wenn man versucht etwas auf den zwei Pins einzulesen.
Und "bsf STATUS,RP0" ist, dass Bank1 gewählt werden soll (lies dir dazu den Abschnitt "Memory Organisation" im Datasheet durch, dann wird verständlich ^_^).
Naja, deine Lösung funzt auch, nur wird es dann schwierig, wenn du z.B.: verschiedenste Buchstaben unterscheiden musst (wenn du, z.B.: ein Protokoll auswerten musst). Deshalb ist es immer gut, zu wissen, wie man auch "größere" Zahlen vergleichen kann.
MfG
Mobius
-
jupp vielen dank
habe viele tutorials durchgelesen aber wirklich am meisten,
um die ganzen hintergründe und register zu verstehen bringt das datenblatt auch wenn einige englische worte in den übersetzer mussten ;)
der code iss noch nicht ganz fertig weil ich am besten den code in einer bestimmten zeit öfter haben soll und noch einsignal zum ausschalten aber wird schon ;)
mfg nochmal danke oxmox
-
habe ein problem beim durchlaufen loopt sich tot ^^
was genau heißt folgendes : finde dataL nirgends und auch CBLOCK nicht ! auch imt datenblatt nicht und weiß ansich nicht was der befehl bringt
clrf heißt ja speicherzelle löschen aber habe doch nirgends eine definiert dafür ?! würds ja einfach rausnehmen, aber weil wie gesagt mein erste prog ist und ich nach beispiel arbeiten wollte lass ich das erstmal so
Code:
CBLOCK 0x20 ; Declare variable addresses starting at 0x20
dataL
ENDC
; PROVIDE A SETTLING TIME FOR START UP
; ------------------------------------
;
clrf dataL
settle decfsz dataL,F
goto settle
movf RCREG,W
movf RCREG,W
movf RCREG,W ; flush receive buffer
;
-
nein, du hast dataL ja definiert ;) Mit CBLOCK kannst du einfach und schnell Variablen definieren:
dataL org 0x20
dump org 0x21
dump1 org 0x22
ist das gleiche wie
CBLOCK 0x20
dataL
dump
dump1
ENDC
Das loop ist irgendwie blöd gelöst: Du löscht den Register, dann fängst du an aus 0 so lange 1 abzuziehen, bis es wieder 0 ist. Du erzeugst einen Überlauf und dann sollte das Ganze 255-mal durchlaufen. Am Besten schaust du den Register mit einem Watch an, während du debugst.
Mobius
-
jo vielen dank nochmal :)
nu klappts auch mit dem PIC Simulator
Code:
LIST P=16F628, R=DEC ; Use the PIC16F628 and decimal system
#include "P16F628.INC" ; Include header file
ORG 0x000 ; Program starts at 0x000
;
; --------------------------------
; SET ANALOG/DIGITAL INPUTS PORT A
; --------------------------------
;
movlw 7 ; lädt 7 in das W-Register
movwf CMCON ; 0x1F = 7
; ----------------
; INITIALIZE PORTS
; ----------------
;
movlw b'00100000' ;
movwf PIE1 ; USART Receive Interrupt Enable Bit
movlw b'00000000' ; lädt 0 in das W-Rgeister
movwf PORTA ; alle low an PORTA
movlw b'00000100' ; W-Register
movwf PORTB ; lädt in 0x06
bsf STATUS,RP0 ; im Register Status wird das RP0 bit auf 1 gesetzt
movlw 0xFE ; schreibt den wert FE in W
movwf TRISA ; bis auf RA0 alle Eingäng(high)
movlw 0xFF ; alle Eingänge RB1(RX)=Eingang
movwf TRISB
; ------------------------------------
; SET BAUD RATE TO COMMUNICATE WITH PC
; ------------------------------------
; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
;
movlw 0x19 ; 0x19=9600 bps (0x0C=19200 bps)
movwf SPBRG
movlw b'00000100' ; brgh = high (2)
movwf TXSTA ; schaltet brgh high ein
bcf STATUS,RP0 ; RAM PAGE 0
movlw b'10010000' ; schaltet seriellen port ein
movwf RCSTA
;
; ---------
; MAIN LOOP
; ---------
;
loop call receive ; wait for a char
call vergleich
goto loop
;
; -------------------------------------------
; SIGNALE VON DER RSR232 SCHNITTSTELLE EMPFANGEN
; -------------------------------------------
; This routine does not return until a character is received.
;
receive btfss PIR1,RCIF ; checkt ob im register PIR1 das RCIF bit (USART Receive Interrupt Flagbit) wenn der receive buffer voll ist geht weiter
goto receive
movf RCREG,W ; speichert das empfangende in W
return
;
; -------------------------------------------------------------
; "VERGLEICHT" DIE BEIDEN SIGNALE
; -------------------------------------------------------------
;
vergleich
sublw 1
bcf PORTA,0x0
btfss STATUS,Z ;könnte auch mit einer Speicherzelle subtrahier
return
bsf PORTA,0x0
return
END
ist echt besser so zu vergleiche so kann eigentlich jedes bit auswerten
bin mal gespant wie das in der praxis klappt...
in dem code steht ja 1 stopbit no parity ist das standart oder kann man das wo einstellen ?
und sonn watchdog timer sollte man das mit reinnehmen ?
mfg DHigh
-
@Watchdog: würde ich bei so einem kleinen Programm nicht einschalten, bringt sich einfach nicht. Ich hab es noch (fast) nie gebraucht, bzw. wenn einmal der PIC abfriert dann wird es fast sicher wegen eines Programmierfehlers sein, d.h. der Watchdog hilft nichts, wenn er den PIC resetet, es wird wieder an der gleichen Stelle absaufen. Wenn du es verwendest, dnn musst du ihn jede ~53 ms resetten (clrwdt), ansonsten läuft er über und du hast den Salat mit einem neustartenden PIC ^_^.
Ich hab ihn nur einmal gebraucht, als es um eine Applikation ging, bei der der PIC regelmäßig und ohne externe Signale aus dem Sleep geholt werden musste und ein Signal zu setzten. Da bot sich der WDT, der bei 4V und 128 Vorteiler ca. jede 2. Sekunde überlief an.
Und den USART kannst du eigentlich so einstellen, wie du möchtest, einfach den Register angucken und das Datasheet durchlesen. Aber, wenn ich mich recht entsinne, ist es fast standard, dass Stopbits verwendet werden, ich glaub, beim PIC kannst auch nur zwischen Stop- oder Startbits unterscheiden. Bin mir aber nicht so sicher...
MfG
Mobius
-
falls es jemanden interessiert habe nun folgenden code:
Code:
LIST P=16F628, R=DEC ; Use the PIC16F628 and decimal system
#include "P16F628.INC" ; Include header file
ORG 0x000 ; Program starts at 0x000
; --------------------------------
; SET ANALOG/DIGITAL INPUTS PORT A
; --------------------------------
movlw 7 ; lädt 7 in das W-Register
movwf CMCON ; 0x1F = 7
; ----------------
; INITIALIZE PORTS
; ----------------
movlw b'00100000'
movwf PIE1 ; USART Receive Interrupt Enable Bit
movlw b'00000000' ; lädt 0 in das W-Rgeister
movwf PORTA ; alle low an PORTA
movlw b'00000100' ; W-Register
movwf PORTB ; lädt in 0x06
bsf STATUS,RP0 ; im Register Status wird das RP0 bit auf 1 gesetzt
movlw 0xFC ; schreibt den wert FE in W
movwf TRISA ; bis auf RA0,RA1 alle Eingäng(high)
movlw 0xFF ; alle Eingänge RB1(RX)=Eingang
movwf TRISB
; ------------------------------------
; SET BAUD RATE TO COMMUNICATE WITH PC
; ------------------------------------
; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
movlw 0x19 ; 0x19=9600 bps (0x0C=19200 bps)
movwf SPBRG
movlw b'00000100' ; brgh = high (2)
movwf TXSTA ; schaltet brgh high ein
bcf STATUS,RP0 ; RAM PAGE 0
movlw b'10010000' ; schaltet seriellen port ein
movwf RCSTA
; ---------
; MAIN LOOP
; ---------
loop call receive
call vergleich
call vergleich2
call vergleich3
call vergleich4
goto loop
; -------------------------------------------
; SIGNALE VON DER RSR232 SCHNITTSTELLE EMPFANGEN
; -------------------------------------------
receive btfss PIR1,RCIF ; checkt ob im register PIR1 das RCIF bit (USART Receive Interrupt Flagbit) wenn der receive buffer voll ist geht weiter
goto receive
movf RCREG,0 ; speichert das Empfangende in W
movwf 0x7F ; speichert das Empfangene in Speicherzelle 7F
return
; -------------------------------------------------------------
; "VERGLEICHT" DIE BEIDEN SIGNALE
; -------------------------------------------------------------
vergleich
movf 0x7F,0 ; das aus der RS232 Empfange Byte in W schreiben
sublw 1 ; das Signal wird mit 1 subtrahiert, wenn 0 herraus kommt wird Zero Bit gesetzt
btfss STATUS,Z ; wenn Zerobit gesetzt wurde, wird nächster befehl übersprungen
return
bsf PORTA,0 ; PORTA Bit 0 wird gesetzt
return
vergleich2
movf 0x7F,0 ; das aus der RS232 Empfange Byte in W schreiben
sublw 2 ; das Signal wird mit 2 subtrahiert, wenn 0 herraus kommt wird Zero Bit gesetzt
btfss STATUS,Z ; wenn Zerobit gesetzt wurde, wird nächster befehl übersprungen
return
bsf PORTA,1 ; PORTA Bit 1 wird gesetzt
return
vergleich3
movf 0x7F,0 ; das aus der RS232 Empfange Byte in W schreiben
sublw 3 ; das Signal wird mit 3 subtrahiert, wenn 0 herraus kommt wird Zero Bit gesetzt
btfss STATUS,Z ; wenn Zerobit gesetzt wurde, wird nächster befehl übersprungen
return
bcf PORTA,0 ; PORTA Bit 0 wird gelöscht
return
vergleich4
movf 0x7F,0 ; das aus der RS232 Empfange Byte in W schreiben
sublw 4 ; das Signal wird mit 4 subtrahiert, wenn 0 herraus kommt wird Zero Bit gesetzt
btfss STATUS,Z ; wenn Zerobit gesetzt wurde, wird nächster befehl übersprungen
return
bcf PORTA,1 ; PORTA Bit 1 wird gelöscht
return
END
damit kann ich über RS232 Schnittstelle 2 Relaisschalten
einzeld an und einzeld aus
also zumindestens kalppts mit dem PIC Simulator
leider ist der PIC noch nicht angekommen
MFG vielen Dank für die Hilfe hier DHigh
-
Hallo, ich bastel nochnicht lange mit PICs rum, habe das Programm was du oben beschrieben hast jedoch getestet.
Leider klappt das Programm bei mir ganz und garnicht, weder mit Simulator und "echter" Hardware.
Habe nen 16F627 @ 10Mhz Takt
Achja, ein "Echo" auf Zeichen bekomm ich manchmal, jedoch passiert bei dem senden des Zeichens "1","2","3","4" nichts an den RA-Outputs :(
edit: Achja er meint beim vergleichen, das <btfss STATUS,Z> wohl net 1 ist obwohlich eindeutig ne 1 bzw 2 sende...
-
Eine genauere Fehlerstellung wäre hilfreich. So kann ich leider nur raten, wo der Fehler liegen kann.
Vorsicht, wenn du den 16F bei 10MHz betreibst, musst du den Register SPBRG mit einem anderen Wert initialisieren, ansonsten stimmen deine Baud-Raten nicht mehr und du erhällst bei dem Empfang der Bits nur noch nonsence (der Empfänger kommt aus dem Synchron).
Ich hab jetzt die Datenblätter nicht parat, aber hast du geschaut, in wie weit sich die 627 von den 628 unterscheiden? Vor allem musst du den Source auch anpassen, was die Include und Processor-Defines betrifft. Prüf mal den Punkt nach, wenn sie sich zu sehr unterscheiden wird das nicht wirklich laufen können.
Beim Simulator wird das Programm auch schwerlich funktionieren, den Mplab hat keinen virtuellen seriellen Port, von dem ich wüsste :). Wenn du da etwas mit der seriellen Schnittstelle simulieren willst, kommst du nciht drüber hinweg die "empfangenen" Daten direkt in den betreffenden Register (bei dir RCREG) hineinzuschreiben (einfach beim watch auf den Wert klicken) und das Bit PIR1,RCIF genauso zu setzten.
Ansonsten, dürftest du bei diesem Programm kein Echo auf der Seriellen Schnittstelle haben, das Tx-Teil ist nicht einmal aktiviert.
Läuft dein PIC eigentlich, also halt, schreib einmal ein Programm, dass dir ein Rechteckssignal auf einem Port ausgibt und mess mal mit nem Osci nach (wenn du keinen hast, ein Voltmesser, wenn du etwas anderes als 5V oder 0V misst, müsste es funktionieren).
MfG
Mobius
-
ich beutze den PIC simulator von ohsonsoft der hat Rs232 unterstützung ect.
ich hab mal rumprobiert, er empfängt daten. wenn ich vor dem Step wo subrathiert wird abfrage und z.b. nen augang dann schalte leuchtet dieser auch:
Code:
bsf PORTA,0
call DELAY_ROUTINE
bcf PORTA,0
movf 0x7F,0
sublw 0x30
btfss STATUS,Z
return
bsf PORTA,0
return
BTFSS meint wohl, das wert a- wert b nicht = 0 ist und setzt somit das Zero bit nicht (hab da wenig rumprobiert deswegen die abweichung vom orginal ( 0 => 0x30))
Das programm springt einfach wieder zurück und setzt keinen ausgang
Das Programm läuft, ja die änderungen bezüglich der Mhz unterschiede und des anderen pics habe ich auch berücksichtigt