-         

Ergebnis 1 bis 10 von 10

Thema: verzweiflung bei 16F870 mit PortA

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    19.12.2004
    Beiträge
    7

    verzweiflung bei 16F870 mit PortA

    Anzeige

    Hallo zusammen,
    Ich will einfacherweise den PortA als digitale Eingänge und den PortB als Ausgänge verwenden.
    Wenn ich auf PortA Pin1 5V anlege (High-Signal) sollte dann die erste LED leuchten usw...
    Sollte PortA komplett auf LOW sein, sollen alle LED's leuchten.
    Nur es will nicht funktionieren. Schaut euch bitte mal den Code an:
    Vllt kann mir jemand weiterhelfen. Danke!
    mfG. Michael



    list p=16f870

    #include <P16f870.INC>

    ; Programmablauf: Wenn kein PIN an Port A high ist, dann alle LEDs einschalten. Wenn ein PIN an Port A high ist, dann das entsprechende LED einschalten

    Init

    bsf STATUS, RP0 ; auf Bank 1 umschalten
    movlw B'11111111' ; PortA alle output
    movwf TRISA
    MOVLW 0x06
    MOVWF ADCON1
    bcf STATUS, RP0 ; auf Bank 0 zurückschalten
    clrf PORTA

    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

    int
    nop
    clrf PORTB
    nop
    movfw PORTA
    btfsc STATUS, Z ; Taste gedrückt?
    goto main1 ; keine Taste gedrückt
    goto main2
    main2
    movlw B'11111111'
    movwf PORTB
    goto int
    main1
    movwf PORTB ; Tastencode zu LEDs
    goto int

    end

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    13.08.2005
    Beiträge
    195
    hallo

    es wäre einfacher zu helfen, wenn du genau beschreibst, was funktioniert und was nicht.

    aber generell kann man sagen:
    • du brauchst vor dem init ein "ORG 0x00". das legt fest, wo das programm überhaupt im pic geschrieben werden soll. und bei 0x00 (hexadezimal für 0 ;-) fängt der prozessor immer an die befehle abzuarbeiten.
    • man sollte auch immer noch "ORG 0x04" einfügen. das ist die adresse zu dem der prozessor springt, sobald ein interrupt ausgeführt wird. ist jetzt bei deinem programm nicht vorgesehen, aber du machst das zeug ja auch nicht exziplit aus, also lieber mal noch direkt darunter ein retfie (damit springt er dann wieder dahin zurück, wo er zum interrupt gerufen wurde.)
    • dann würde ich auch noch ganz am anfang, um sicher zu sein, dass man überhaupt auf der bank 1 ist bcf STATUS,RP1 bsf STATUS,RP0 machen. sonst kann es ja sein, dass man auf der bank 4 landet, wenn in STATUS, RP1 auch eine 1 ist.
      du brauchst auch nicht für jede änderung von TRISX auf die bank eins zu springen, und dann wieder auf die bank 0.

    also würde ich das ungefähr so machen:

    Code:
    	list p=16f870 
    	#include <P16f870.INC> 
    	__config _LVP_OFF & _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _CPD_OFF & _BODEN_OFF & _DEBUG_OFF
    
    						;Programmablauf: Wenn kein PIN an Port A high ist, dann alle LEDs einschalten. Wenn ein PIN an Port A high ist, dann das entsprechende LED einschalten 
    	ORG		 0x00
    	NOP					;manche pics machen da irgendwie zicken, deswegen kommt da immer ein nop rein.
    	goto	Init
    	
    	ORG 	0x04		;ein interrupt?
    	retfie				;dann zurück!
    	
    	
    Init
    	
    	bsf 	STATUS, RP0 ; auf Bank 1 umschalten 
    	bcf		STATUS, RP1 ; auf Bank 1 umschalten
    	
    	MOVLW 0x06			; 
    	MOVWF ADCON1 		;macht den ad-wandler aus, d.h. alle ein/ausgänge ist digital
    	
    	movlw 	0xFF		; ist bisschen schneller und kürzer. B'11111111' geht aber auch!; PortA alle input 
    	movwf 	TRISA 
    	
    	clrf	TRISB		; ist bisschen schneller und kürzer. movlw D'0'; movwf TRISB, geht auch! PORTB alle als output
    	
    	bcf 	STATUS, RP0 ; auf Bank 0 umschalten 
    
    	clrf	PORTA
    	clrf	PORTB
    	
    int 
    	;nop 				;wenn du das so lässt, macht er ein nur 2-3 befehle davor die leds an, (zeile 48)
    	;clrf 	PORTB 		;und dann machst du sie für 8-10 befehle wieder aus -> sie schauen evtl. so aus, 
    	;nop 				;als ob sie gar nicht an währen. 
    	
    	movfw 	PORTA 		;der Inhalt von PORTA wird in W geschoben
    	btfsc 	STATUS, Z 	;überspringe den nächsten befehl, wenn Z = 0  ->  wenn W != 0 -> wenn PORTA = 0
    	goto 	main1 		; W = 0
    	;goto 	main2 		;braucht man eigentlich nicht, weil ja direkt darunter schon main2 steht;
    
    main2 
    	movwf 	PORTB ; Tastencode zu LEDs 
    	goto 	int 
    
    main1 
    	movlw 	B'11111111' 
    	movwf 	PORTB 
    	goto 	int 
    	
    	end

    das meiste habe ich schon im code kommentiert. nach meiner logik, hast du main1 und main2 vertauscht. da kann ich mich aber auch irren. das ist für mich immer rel. kompliziert, diese btfss sachen.

    ich weiß zwar nicht wie das bei dir und deiner programmierumgebung ist, aber ich gebe da immer noch das config word mit an. das musst du aber evtl. noch deinen gegebenheiten anpassen. ich weiß ja nicht was für einen oszillator du verwendest.

    ich hoffe meine ganzen behauptungen stimmen,..

    edit: natürlich auch noch ein herzliches willkommen im forum!

    SEIDL.

  3. #3
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    66
    Beiträge
    10.970
    Hallo!

    Es ist unmöglich ohne Schaltplan der Hardware oder zumindest Beschreibung, wie die Tasten und LEDs angeschlossen sind, sagen, ob der Code richtig funktioniert.

    MfG

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    19.12.2004
    Beiträge
    7
    hmmmm... so funktionierts leider nicht. Danke trotzdem.
    Es scheint, als würde der PIC abstürzen und neu starten, wenn ich nen Eingang betätige.

    Nun anders:
    Meine Problematik besteht darin, dass ich PortA(Eingänge) nicht einlesen und gleichzeitig 1:1 an PortB(Ausgänge) weitergeben kann.
    Die LED's leuchten dann wie sie wollen oder eben garnicht... Wahrscheinlich ist es so wie der PIC gerade meint...

    Aufbau:

    Ich beschalte einen PIC16F870 auf PortA (digitale Eingänge oder umgeschaltete Analogeingänge) mit Tastern, so wie in dem Bild:


    und die Ausgänge auf PortB so:

    genauso wie die LED D1.

    Wie muss ich dann mein Programm schreiben, dass ich den Signalzustand von PortA einlesen und direkt an PortB weitergeben kann?

    Sorry dass ich so einfache Sachen frage. Ich hab schon so viele Seiten im Internet durchwühlt und nichts dergleichen gefunden...

    mfG. Michael

  5. #5
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    66
    Beiträge
    10.970
    Laut deinen Schaltplänen ist dein Hauptprogramm in zwei Zeilen realisierbar, da das Ausgangssignal am Pin von PORTB immer einem Eingangssignal am entsprechendem Pin von PORTA gleich seien sollte.
    Dafür braucht man immer nur endlos eigelesener Wert vom PORTA ins PORTB schreiben (kopieren), ohne irgendwas prüfen zu müssen:

    movfw PORTA (bzw. movf PORTA,0 oder movf PORTA,W)
    movwf PORTB

    Sonst sollte noch, wie der Benedikt.Seidl schon geschrieben hat, die Konfiguration des PICs mit __config Direktive festgelegt werden.

    MfG

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    19.12.2004
    Beiträge
    7
    Es funktioniert jetzt.
    Code:
    Code:
    list p=16f870
       #include <P16f870.INC>
       __config _LVP_OFF & _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _CPD_OFF & _BODEN_OFF & _DEBUG_OFF
                     ;Programmablauf: Wenn kein PIN an Port A high ist, dann alle LEDs einschalten. Wenn ein PIN an Port A high ist, dann das entsprechende LED einschalten
       ORG       0x00
       NOP               ;manche pics machen da irgendwie zicken, deswegen kommt da immer ein nop rein.
       goto    Init
       ORG     0x04      ;ein interrupt?
       retfie            ;dann zurück!
    Init
       bsf     STATUS, RP0 ; auf Bank 1 umschalten
       bcf     STATUS, RP1 ; auf Bank 1 umschalten
       MOVLW   0x06         ;
       MOVWF   ADCON1       ;macht den ad-wandler aus, d.h. alle ein/ausgänge ist digital
       movlw   B'11111111'      ;ich habs so gemacht, weil das für mich im Moment noch übersichtlicher und klarer ist
       movwf   TRISA
       movlw   B'00000000' 
       movwf   TRISA
       bcf     STATUS, RP0 ; auf Bank 0 umschalten
       clrf    PORTA
       clrf    PORTB
               
    schleife   
       movfw   PORTA       ;der Inhalt von PORTA wird in W geschoben
       movwf   PORTB
       goto    schleife
       end
    Nur: Ohne Schleife reagiert der PIC ziemlich langsam auf die Eingange. Ich weiß zwar nicht warum, aber mit Schleife gehts jetzt super.
    Danke nochmal

    mfG. Michael

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.12.2005
    Ort
    Euskirchen-Großbüllesheim
    Alter
    67
    Beiträge
    2.063
    Hallo,
    vermutlich hat der PIC16F870 an Port A Analog- und / oder Comparator-Eingänge.
    Dann müssen die Eingänge von Port A zuerst von Analog- auf TTL-Eingänge initialisiert werden.
    MfG Karl-Heinz
    HobbyElektronik hier klicken ....

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    19.12.2004
    Beiträge
    7
    Ja genau, wahrscheinlich.
    So haben wir es gelöst:
    Code:
    MOVWF   ADCON1       ;macht den ad-wandler aus, d.h. alle ein/ausgänge ist digital
    Steht übrigens oben schon im Code drin

    mfG. Michael

  9. #9
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    66
    Beiträge
    10.970
    Hallo!

    @ Black_Arrow

    Ich habe gedacht, dass "Wenn kein PIN an Port A high ist, dann alle LEDs ausschalten".

    Um bei Port B alle pins als Ausgänge haben, muss in deinem Code B´00000000´ in TRISB und nicht TRISA geschrieben werden.

    MfG

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    19.12.2004
    Beiträge
    7
    Hi!
    Achja... sorry, das habe ich im Code schon abgeändert.
    Tut mir leid, dass ich das nicht mehr gepostet hab.

    Danke trotzdem.

    mfG. Michael

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •