- Labornetzteil AliExpress         
Ergebnis 1 bis 10 von 10

Thema: Assemblerbefehl: bcf kann ich nur einmal verwenden

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied Avatar von pointhi
    Registriert seit
    18.03.2009
    Alter
    28
    Beiträge
    139

    Assemblerbefehl: bcf kann ich nur einmal verwenden

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Ich bin noch kein so erfahrener Programmierer und arbeite darum noch viel mit der Ansteuerung von LEDs in bestimten Reihenfolgen, damit ich mein Wissen über Assembler verbessere, und die Fehlerquote beim Programmieren sinkt.
    Also habe ich wieder einmal ein Programm geschrieben, dass auf eiem neuem selbstgelötetes Board als Positionsleuchtensteuerung für Modellfahrzeuge eingesetzt werden soll.
    Das erste Programm lief Fehlerlos, weil ich dabei alle ausgänge nur auf 1 setzte. Alle LEDs Leuchteten.
    Beim Zweiten Programm, wollte ich 3 LEDs einschalten, nach 250ms ausschalten, noch einmal 250ms warterten, und dann auch den dritten Led asuschalten. Dass solte sich dann nach 750ms wiederholen. Also schrieb ich dass Programm, und wollte einen neue Methode benützen. Sie war Länger, man konnte aber auch andere LEDs eingeschaltet haben. Dieses Mal schrieb ich aslo nicht in Binärwärten in dass W Register, und kopierte es an PORTA, sondern schrieb an diese Stelle

    bsf PORTA,0
    bsf PORTA,1
    bsf PORTA,2


    Ich probierte dass Programm, und ich wunderte mich, dass nur der LED leuchtete, der als letztes auf 1 gestellt wurde. Ich musste das Programm wieder auf die Alte Methode umschreiben, aber ich frage mich noch immer, warum die anderen 2 LEDs nicht geleuchtet haben. Ich habe nämlich die 5 LEDs, die noch von dem 1. Test darin steckten, nicht herausgezogen. Ich hoffe ich hab dass nicht zu kompliziert beschrieben, und ihr könnt mir helfen.



    Vielleicht hilft es, ich hab dass Programm auf den PIC 16F630 gebrannt

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    16.03.2007
    Alter
    36
    Beiträge
    58
    wenn man das ganze Programm sieht ist es leichter einen Fehler zu finden. so kann man nur raten.
    Aber die Methode mit bsf sollte funktionieren. Ich hab das auch am Anfang so gemacht.

    Gruß Carsten

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied Avatar von pointhi
    Registriert seit
    18.03.2009
    Alter
    28
    Beiträge
    139
    ES könnte etwas Dauern, aber wenn ich zeit habe, kopiere ich dass komplette Programm in dass Forum

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    30.09.2006
    Ort
    Hamburg
    Alter
    41
    Beiträge
    1.013
    hi haste die Analogen PIns auf digital geschaltet ?
    Legastheniker on Bord !

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.02.2006
    Alter
    60
    Beiträge
    114
    BSF sollte man möglichst nicht direkt mit PORTs verwenden.
    BSF ist nämlich ein "Read-Modify-Write" Befehl, d. h. es wird erst der aktuelle Wert von PortA gelesen, dann entsprechend modifiziert und dann zurückgeschrieben. Das Dumme ist, es wird nicht immer das gelesen, was man zuletzt in den Port reingeschrieben hat, sondern das, was gerade an den Pins an Spannung anliegt. Funktioniert zwar unter bestimmten Umständen trotzdem, aber sicherer ist es, ein sogenanntes Shadow-Register zu benutzen. Der gewünschte Zustand des Ports wird in dieses Schatten-Register geschrieben und kann dann auch gefahrlos mit BSF, BCF usw. geändert werden. Dann wird der gesamte Inhalt des Shadow-Registers in einem Rutsch auf den Port gelegt mit MOVF shadow,PORTA.

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    30.09.2006
    Ort
    Hamburg
    Alter
    41
    Beiträge
    1.013
    beim 16f gibs des nicht erst bei den 18ern

    OB per movf oder bsf,bcf ist wurst bei bsf,bcf ist nur der unterschid das das Reg, PORTB nach W geschrieben wird und da verändert und dann zurück zu PORTB geschrieben.

    bei Movf schiebst die 8bit nach W und von da nach PORTB also ein par takte weniger bei leds aber unwichtig und du musst immer die kompletten 8bit schreiben.

    Ansonsten würde ich noch tipen das du entweder die pins nicht auf digital geschaltet hast oder das du in der falschen bank bist.
    Legastheniker on Bord !

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied Avatar von pointhi
    Registriert seit
    18.03.2009
    Alter
    28
    Beiträge
    139
    Danke für die Hilfe. Ich hab es mir schon ein wenig angeschaut. Dass Datenblatt werde ich schon Bald reinstellen. Ich habe ein paar Probleme, es kompakt anzuzeigen.

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied Avatar von pointhi
    Registriert seit
    18.03.2009
    Alter
    28
    Beiträge
    139
    Hier ist dass versprochene Programm. Vielleicht kommt ihr damit ja weiter. Nach meinem wissen, ist der PIC 16F630 mit keinem Anologausgang ausgestadtet.

    Code:
    ******************************************************************************
    ; Dateiname:	Positionsbeleuchtung ohne Landebeleuchtung
    ; Autor:		Thomas Pointhuber	
    ; Datum:  		25.05.09
    ; Version:		1.00
    ;
    ; Letzte Änderung:	keine 
    ;			
    ;******************************************************************************
    ; Funktionsbeschreibung des Programms: 	Erstellt ein Blinklicht auf dem PORTA (0,1,2)
    ;										
    ;			RA,0		Positionsleuchte rechts
    ;			RA,1		Positionsleuchte links
    ;			RA,2		Positionsleuchte unten
    ;			RC,1		Landeleuchte Flügel
    ;			RC,2		Landeleuchte Propeller, Höhenruder, Seitenruder
    ;
    ;******************************************************************************
    	list      	p=16F630			; "list" Anweisung zur Definition des Prozessors
    	#include 	<p16f630.inc>		; Einbinden von speziellen zum Controller gehörenden Variablen über die Datei *.inc 
    
    	__CONFIG  _CP_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CPD_OFF
    ;
    ; '__CONFIG' Diese Anweisung wird benutzt, um das Configurations-Word innerhalb des *.asm Datei einzubinden.
    ; Weitere Informationen zum Configurations-Word können auch dem Datenblatt entnommen werden.
    ; Die mit einem Sternchen * markierten Optionen sind ausgewählt worden.
    ;              
    ;				CP: Code Protection bit
    ;              *		OFF = Program Memory code protection is disabled 
    ;                  		ON  = Program Memory code protection is enabled
    ;              	WDT: Watchdog Timer Enable bit
    ;                  		ON  = WDT enabled
    ;               *  		OFF = WDT disabled 
    ;               BODEN: Brown-out Detect Enable bit
    ;               * 	 	ON  = BOD enabled 
    ;                   	OFF = BOD disabled
    ;               PWRTE: Power-up Timer Enable bit
    ;                     	OFF = PWRT disabled
    ;              	*		ON  = PWRT enabled
    ;               MCLRE: GP3/MCLR pin function select
    ;                      	ON  = GP3/MCLR pin function is MCLR
    ;               *   	OFF = GP3/MCLR pin function is digital I/O
    ; 				CPD: Data Code Protection bit 
    ;               *   	OFF = Data memory code protection is disabled 
    ;                      	ON  = Data memory code protection is enabled
    ;				Oscillator Variationen:
    ;						LP_OSC   = Low power crystal on GPIO4 and GPIO5 
    ;						XT_OSC   = Crystal/resonator on GPIO4 and GPIO5 
    ;						HS_OSC   = High speed crystal/resonator on GPIO4 and GPIO5 
    ;						EC_OSC   = I/O function on GPIO4 pin, CLKIN on GPIO5 
    ;					*	INTRC_OSC_NOCLKOUT  = I/O function on GPIO4 pin, I/O function on GPIO5 
    ;						INTRC_OSC_CLKOUT  = CLKOUT function on GPIO4 pin, I/O function on GPIO5 
    ;						EXTRC_OSC_NOCLKOUT  = I/O function on GPIO4 pin, RC on GPIO5 
    ;						EXTRC_OSC_CLKOUT    = CLKOUT function on GPIO4 pin, RC on GPIO5
    ;   
    ;
    	ERRORLEVEL      -302    	; Unterdrücken BANK SELECTION MESSAGES, dazu das ; Semikolon links entfernen
    ;								; Dies unterdrückt im Compiler die Nachricht "Register in operand not in bank 0.  Ensure that bank bits are correct"	
    ;
    ;*****************************************************************************
    ; Deklaration der Variablen und Konstanten
    ;******************************************************************************
    ;	
    schleife	EQU	H'0020'							; Anzahl der "schleifen"
    help		EQU	H'0021'							; Hilfsvariable für verschiedene Aufgaben. Achtung der Inhalt wird nie gerettet!
    sekunde		EQU	H'0022'							; Variable für die Einerstelle der Zahl
    leuchten1	EQU	H'0023'							; Variable für die Tabelle LED_PORTA
    leuchten2	EQU	H'0024'							; Variable für die Tabelle LED_PORTC
    ;******************************************************************************
    
    		org		0x000							; Startadresse des PICs
    		goto	EINSTELLUNGEN
    ;******************************************************************************
    ; INTERRUPT
    		org 	0X004 							; Startadresse der ISR
    		retfie									; Beenden der ISR, zurück zum Programm
    
    ;******************************************************************************
    ; PIC***** Einstellungen
    EINSTELLUNGEN
    		bsf     STATUS,RP0						; Auswahl Bank 1 
    		movwf   OSCCAL							; Neuladen der Kalibrirungswerte für den internen Takt
    							  
    		movlw	B'00111000'						; 1=Eingang, 0=Ausgang
    		movwf	TRISA
    			
    		movlw	B'00100000'						; 1=Eingang, 0=Ausgang
    		movwf	TRISC
    											  	
    		bcf     STATUS,RP0						; Zurück zu Bank 0
    		
    		clrf	PORTA							; Löschen aller Ausgänge
    		clrf	PORTC							; Löschen aller Ausgänge
    		clrf	INTCON							; Dekavieren eines Interuptes
    
    		
    ;*************************************************************************
    ; HAUPTPROGRAMM
    START
    		movlw	B'11000111'						; Setzt alle Ausgänge von PORTA auf 1
    		movwf	PORTA
    
    		movlw	B'11011111'						; Setzt alle Ausgänge von PORTC auf 1
    		movwf	PORTC
    
    		call	PAUSE1s							; Macht 1 Sekunde Pause
    
    		clrf	PORTA							; Löscht PORT A & C
    		clrf	PORTC
    
    		call	PAUSE1s							; Macht 1 Sekunde Pause
    
    ABARBETUNG
    
    		bsf		PORTA,0							; Schaltet die Positoinsleuchten ein
    		bsf		PORTA,1
    		bsf		PORTA,2
    
    		call	PAUSE250ms						; Macht 250ms Pause
    
    		bcf		PORTA,0							; Schaltet die Positionsleuchten der Flügel aus
    		bcf		PORTA,1
    
    		call	PAUSE250ms						; Macht 250ms Pause
    
    		bcf		PORTA,2							; Schaltet die Positionsleuchte unten aus
    
    		call	PAUSE750ms						; Macht 750ms Pause
    
    		goto	ABARBETUNG						; Geht zum Anfang der abarbeitung
    
    ;*************************************************************************
    ; UNTERPROGRAMM
    
    PAUSE1ms										; Label, wo die Standardwarteschleife beginnt
    		movlw	D'199'							; Dezimalwert für die Zeitkonstante damit PAUSE = 1ms ist
    		movwf	schleife						; Schieben des Wertes 199 in die Variable "schleife"
    												; Ende der Start-Einstellungen für "PAUSE1ms"
    
    PAUSEE											; Einsprungstelle für Pausenschleifen
    		nop
    		nop										; Taste nicht gedrückt, springe zur Marke "HAUPT" DECFSZ	schleife,1		
    		decfsz	schleife,1						; Dekrementiere die Variable "schleife" um 1 und schreibe das Ergebnis zurück in "schleife"
    		goto	PAUSEE							; Ist die Zeit verstrichen? Nein, dann springe zurück zu "PAUSEE"
    												; Neuer Durchlauf bis "schleife" = 0
    		return
    
    ; Mögliche Standardwarteschleife für Zeiten zwischen ~ 2 und 256 ms
    ;
    PAUSE100ms
    		movlw	D'100'
    		movwf	help
    PAUSE100										
    		call	PAUSE1ms
    		decfsz 	help,1							; Dekrementiere die Variable "help" um 1 und schreibe das Ergebnis zurück in "schleife"
    		goto	PAUSE100						; Ist die Zeit verstrichen? Nein, dann springe zurück zu "PAUSE250ms"
    												; Neuer Durchlauf bis "schleife" = 0
    		return
    
    ; Mögliche Standardwarteschleife für Zeiten zwischen ~ 2 und 256 ms
    ;
    PAUSE250ms
    		movlw	D'250'
    		movwf	help
    PAUSE250										
    		call	PAUSE1ms
    		decfsz 	help,1							; Dekrementiere die Variable "help" um 1 und schreibe das Ergebnis zurück in "schleife"
    		goto	PAUSE250						; Ist die Zeit verstrichen? Nein, dann springe zurück zu "PAUSE250ms"
    												; Neuer Durchlauf bis "schleife" = 0
    		return
    
    ; Mögliche Standardwarteschleife für Zeiten zwischen ~ 250ms und 20 s
    ;
    PAUSE500ms	
    		movlw	D'2'
    		movwf	sekunde
    PAUSE500									
    		call	PAUSE250ms
    		decfsz 	sekunde,1						; Dekrementiere die Variable "help" um 1 und schreibe das Ergebnis zurück in "schleife"
    		goto	PAUSE500						; Ist die Zeit verstrichen? Nein, dann springe zurück zu "PAUSE250ms"
    												; Neuer Durchlauf bis "schleife" = 0
    		return
    
    ; Mögliche Standardwarteschleife für Zeiten zwischen ~ 250ms und 20 s
    ;
    PAUSE750ms	
    		movlw	D'3'
    		movwf	sekunde
    PAUSE750									
    		call	PAUSE250ms
    		decfsz 	sekunde,1						; Dekrementiere die Variable "help" um 1 und schreibe das Ergebnis zurück in "schleife"
    		goto	PAUSE750						; Ist die Zeit verstrichen? Nein, dann springe zurück zu "PAUSE250ms"
    												; Neuer Durchlauf bis "schleife" = 0
    		return
    
    ; Mögliche Standardwarteschleife für Zeiten zwischen ~ 250ms und 20 s
    ;
    PAUSE1s	
    		movlw	D'4'
    		movwf	sekunde
    PAUSE1									
    		call	PAUSE250ms
    		decfsz 	sekunde,1						; Dekrementiere die Variable "help" um 1 und schreibe das Ergebnis zurück in "schleife"
    		goto	PAUSE1							; Ist die Zeit verstrichen? Nein, dann springe zurück zu "PAUSE250ms"
    												; Neuer Durchlauf bis "schleife" = 0
    		return
    
    ; Mögliche Standardwarteschleife für Zeiten zwischen ~ 250ms und 20 s
    ;
    PAUSE2s	
    		movlw	D'8'
    		movwf	sekunde
    PAUSE2									
    		call	PAUSE250ms
    		decfsz 	sekunde,1						; Dekrementiere die Variable "help" um 1 und schreibe das Ergebnis zurück in "schleife"
    		goto	PAUSE2							; Ist die Zeit verstrichen? Nein, dann springe zurück zu "PAUSE250ms"
    												; Neuer Durchlauf bis "schleife" = 0
    		return
    
    ; Mögliche Standardwarteschleife für Zeiten zwischen ~ 250ms und 20 s
    ;
    PAUSE3s	
    		movlw	D'12'
    		movwf	sekunde
    PAUSE3									
    		call	PAUSE250ms
    		decfsz 	sekunde,1						; Dekrementiere die Variable "help" um 1 und schreibe das Ergebnis zurück in "schleife"
    		goto	PAUSE3							; Ist die Zeit verstrichen? Nein, dann springe zurück zu "PAUSE250ms"
    												; Neuer Durchlauf bis "schleife" = 0
    		return
    
    		end										; Ende des Programmes

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.02.2006
    Alter
    60
    Beiträge
    114
    Du hast das Register CMCON nicht initialisiert. Dadurch sind die Pins RA0 und RA1 als analoge Eingänge für den Comparator konfiguriert und werden als 0 gelesen (und mithin beim letzten BSF auch als 0 geschrieben.

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied Avatar von pointhi
    Registriert seit
    18.03.2009
    Alter
    28
    Beiträge
    139
    Danke erstmal, ich werde es ausprobieren. Ich schreib dann ins Forum wenn es geklappt hat

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad