-         

Ergebnis 1 bis 6 von 6

Thema: Einstieg codierung eigentlich ganz simpel oder doch nicht?

  1. #1

    Einstieg codierung eigentlich ganz simpel oder doch nicht?

    Anzeige

    Hallo,

    hatte folgendes bereits bei microcontroller.net schon geschrieben:

    "
    Hallo,

    ich bin grade dabei ein elektronisches Handrad für eine CNC-Fräse zu
    bauen.
    Für die Anzeige der aktiven Achse breuchte ich eine Logik, die mir aus 2
    Leitungen 4 LED ansteuert.
    Ich weiß das könnte man auch einfach mit der 74 TTL reihe (4 and und 2
    invertern) realisieren. Aber ich wollte jetzt doch etwas mal mit einem
    PIC16F84A machen. Also dachte ich mir ich les mal ein bisschen im I-Net
    nach, bin aber leider noch nicht auf einen grünen Zweig gekommen.
    Ich weiß durch spurt mittlerweile, dass ich erstmal die ein ung augänge
    initalisieren muss mit dem TRISx-Register soweit ich das verstanden
    habe, nur dann wird es schwierig.
    Könnte mir vielleich jemand einen einfachen und übersichtlichen
    Lösungsweg zeigen? Das soll jetzt nicht so sein lass einfach mal die
    anderen das machen, ich hab jetzt mittlerweile 1,5 Tage investiert aber
    sehe leider immer noch keinen richtigen Ansatz´, wäre also für jede Hilf
    dankbar.
    Ich hab mir das so gedacht, den Port A des PIC16F84A nehme ich als
    Eingang und den Port B als Ausgang.
    Input #1 = RA2
    Input #2 = RA3
    LED x = RB4
    LED y = RB5
    LED z = RB6
    LED a = RB7

    LEDx= nicht(Input #1) und nicht(Input #2)
    LEDy= Input #1 und nicht(Input #2)
    LEDz= nicht(Input #1) und Input #2
    LEDa= Input #1 und Input #2

    ich weiß etwas blöd geschrieben aber wusste nicht wie sonst.
    Und wie bereits gesagt ich weiß ein PIC ist dafür etwas Oversized, aber
    ich habe mich bewusst dafür entschieden, um mal mit etwas einfachen in
    Assembler anzufangen.
    Oder ist Assembler nicht so gut für den Anfang? Ich kann leider bis
    jetzt keine Programmiersprache, außer Java, das lernen wir gerade an der
    UNI.

    Ich hoffe mir kann jemand helfen und schon mal vielen vielen Dank für
    eure Mühe.

    Danke Jo
    "

    leider habe ich keine für mich gute Antwort bekommen
    also habe ich mich daran gemacht mal etwas zu experimentieren,
    nach ettlichen verschiedenen Ansätzen bin ich nun zu diesem Ergebnis gelangt :

    Code:
    	list p=16f84a
    ;**************************************************************
    ;*  	Pinbelegung
    ;*	----------------------------------	
    ;*	PORTA: 	Eingänge
    ;*		0 - PIN 17 - Tastereingang
    ;*		1 - PIN 18 - n.c.
    ;*		2 - PIN 01 - Input #4
    ;*		3 - PIN 02 - Input #5
    ;*		4 - PIN 03 - n.c.
    ;*	PORTB:
    ;*		0 - PIN 06 - Tastersignal 
    ;*		1 - PIN 07 - n.c.	
    ;*		2 - PIN 08 - n.c.
    ;*		3 - PIN 09 - n.c.
    ;*		4 - PIN 10 - LED x-Achse
    ;*		5 - PIN 11 - LED y-Achse
    ;*		6 - PIN 12 - LED z-Achse
    ;*		7 - PIN 13 - LED a-Achse
    ;*	
    ;**************************************************************
    ;
    ;jorues 30.03.2007
    ;
    ; Handradlogik
    ;
    ; Taktquelle: 4 MHz
    ;
    ;**************************************************************
    ; Includedatei für den 16F84A einbinden
    
    	#include <P16f84a.INC>
    
    ; Configuration festlegen
    ; bis 4 MHz: Power on Timer, kein Watchdog, XT-Oscillator
    
    	__CONFIG	_PWRTE_ON & _WDT_OFF & _XT_OSC
    
    ;**************************************************************
    ; Variablen festlegen
    
    Input  Equ	0x20
    Input_kor	Equ	0x21
    Result	Equ 0x22
    
    ; Constanten festlegen
    	
    Ini_con Equ	B'00000000'		; TMR0 -> Intetupt disable
    Ini_opt	Equ	B'00000010'		; pull-up
    digit0 Equ B'00000000'		; Wert0 festlegen
    digit1 Equ B'00000100'		; Wert1 festlegen
    digit2 Equ B'00001000'		; Wert2 festlegen
    digit3 Equ B'00001100'		; Wert3 festlegen
    LED_X Equ B'00010000'		; LED für X-Achse
    LED_Y Equ B'00100000'		; LED für Y-Achse
    LED_Z Equ B'01000000'		; LED für Z-Achse
    LED_A Equ B'10000000'		; LED für A-Achse
    ;*************************************************************
    ; Das Programm beginnt mit der Initialisierung
    
    Init	bsf     STATUS, RP0	; Bank 1
    	movlw   Ini_opt     	; pull-up on
    	movwf   OPTION_REG 		;
    	movlw	B'11111111'		; PortA alle inputs 
    	movwf	TRISA			; 
    	movlw	B'00000000'		; PortB alle outputs 
    	movwf	TRISB			;
    	bcf     STATUS, RP0		; Bank 0
    	clrf	PORTA		
    	clrf	PORTB		
    				
    	movlw   Ini_con     	; Interupt disable
    	movwf   INTCON
    	clrw
    ;****************************************************************
    
    Main
    	
    	movfw	PORTA	     	; Port A lesen und nach W kopieren
    	movwf	Input			; von W in Input (0x20) kopieren
    	clrw					; W löschen
    	bcf	Input,0			;
    	bcf	Input,1			; alle Bits von Input1 bis auf entscheidende Bits 2 und 3 werden 			
    	bcf	Input,4			; auf 0 gesetzt
    	bcf	Input,5			;
    	bcf	Input,6			;
    	bcf	Input,7			;
    	movfw	Input			; Input in Input_kor schreiben
    	movwf	Input_kor
    	clrw					; W löschen		
    
    
    ;****************************************************************
    ; Input vergleichen	
    
    X_achse
    
    	movfw	Input_kor 			; Input_kor wird in W geladen
    	xorwf	digit0,0 			; Input_kor und digit0 werden verglichen, Ergenbins in W
    	movwf	Result				; Ergebnis wird in Result gespeichert
    	clrw						; W löschen
    
    	btfss	Result,2			; nächste Zeile überspringen wenn Bit Nr.2 den Wert 1 hat
    	btfsc	Result,3			; nächste Zeile überspringen wenn Bit Nr.3 den Wert 0 hat
    	goto	Y_achse				; sprung zu Y_achse
    	bsf	PORTB,7					; Bit 7 von PORTB wird auf high gesetzt, die LED für X-Achse leuchtet
    	goto Main
    	
    ;****************************************************************
    Y_achse
    
    	clrf	PORTB
    
    	movfw	Input_kor 			; Input_kor wird in W geladen
    	xorwf	digit1,0 			; Input_kor und digit1 werden verglichen, Ergenbins in W
    	movwf	Result				; Ergebnis wird in Result gespeichert
    	clrw						; W löschen
    
    	btfss	Result,2			; nächste Zeile überspringen wenn Bit Nr.2 den Wert 1 hat
    	btfsc	Result,3			; nächste Zeile überspringen wenn Bit Nr.3 den Wert 0 hat
    	goto	Z_achse				; sprung zu Z_achse
    	bsf	PORTB,6					; Bit 6 von PORTB wird auf high gesetzt, die LED für Y-Achse leuchtet
    	goto Main
    	
    ;****************************************************************
    Z_achse
    
    	clrf	PORTB
    
    	movfw	Input_kor 			; Input_kor wird in W geladen
    	xorwf	digit2,0 			; Input_kor und digit2 werden verglichen, Ergenbins in W
    	movwf	Result				; Ergebnis wird in Result gespeichert
    	clrw						; W löschen
    
    	btfss	Result,2			; nächste Zeile überspringen wenn Bit Nr.2 den Wert 1 hat
    	btfsc	Result,3			; nächste Zeile überspringen wenn Bit Nr.3 den Wert 0 hat
    	goto	A_achse				; sprung zu A_achse
    	bsf	PORTB,5					; Bit 5 von PORTB wird auf high gesetzt, die LED für Z-Achse leuchtet
    	goto Main
    ;****************************************************************
    A_achse
    
    	clrf	PORTB
    
    	movfw	Input_kor 			; Input_kor wird in W geladen
    	xorwf	digit3,0 			; Input_kor und digit3 werden verglichen, Ergenbins in W
    	movwf	Result				; Ergebnis wird in Result gespeichert
    	clrw						; W löschen
    
    	btfss	Result,2			; nächste Zeile überspringen wenn Bit Nr.2 den Wert 1 hat
    	btfsc	Result,3			; nächste Zeile überspringen wenn Bit Nr.3 den Wert 0 hat
    	goto	X_achse				; sprung zu X_achse
    	bsf	PORTB,4					; Bit 4 von PORTB wird auf high gesetzt, die LED für A-Achse leuchtet
    	goto Main
    
    ;****************************************************************
    	end
    beim Umsetzen in eine hex gibts folgende Meldungen, welche soweit ich weiß weiter nicht schlimm sind:

    Code:
    Message[302] C:\ASM\ROUTINE.ASM 63 : Register in operand not in bank 0.  Ensure that bank bits are correct.
    Message[302] C:\ASM\ROUTINE.ASM 65 : Register in operand not in bank 0.  Ensure that bank bits are correct.
    Message[302] C:\ASM\ROUTINE.ASM 67 : Register in operand not in bank 0.  Ensure that bank bits are correct.
    Beim Brennen gibts auch keine Fehler.

    Aber leider funktioniert das ganze auf dem Testboard garnicht. Es geschieht nichts. Der ResetPin liegt auf VDD daran kanns also nicht liegen.

    Kann jemand den Code mal anschauen, sicher gibt es einfachere Lösungen aber das war das einzige was mir in meinem ersten Code so eingefallen ist.


    Vielen Vielen Vielen Dank
    Jo

  2. #2

    Hilfe

    Kann mir den keiner helfen?
    Jo

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    17.09.2006
    Ort
    Essen
    Alter
    56
    Beiträge
    83
    Schau dir mal unter Microchip\MPASM Suite\Template\Code das Grundgerüst eines Programms für deinen Controller an. In deinem Code fehlt
    ORG 0x000 ; processor reset vector
    goto main ; go to beginning of program
    MFG
    Ralf

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    31.12.2006
    Ort
    Wien
    Alter
    53
    Beiträge
    7

    Versuch einer Antwort

    Hallo,

    ich möchte vorausschicken, dass ich mit dem PIC keine Erfahrung habe, also prozessor- und hardwarespezifische Einstellungen kann ich nicht kommentieren, und mit CNC-Fräsen kenn' ich mich auch nicht aus. Aber ich komme mit Deinem Code nicht so recht klar. Der Assembler-Einstieg ist (von Java kommend) schon etwas heftig (aber zweifellos lohnenswert; einfacher wäre C). Mein Tip: zeichne Dir mal die Register Deines PICs auf, nimm das Handbuch und führe jeden einzelnen Befehl auf dem Papier aus lt. Handbuch. Da lernst Du viel und findest auch so manches Problem.

    Ich hab' das jetzt mal anhand von http://www.sprut.de/electronic/pic/a...e/befehle.html (schau da mal hin!) versucht:

    Code:
    Main 
        
       movfw   PORTA         ; Port A lesen und nach W kopieren >> W = PORTA
       movwf   Input         ; von W in Input (0x20) kopieren >> Input = W, brauchen wir aber nicht mehr
    			
    >> jetzt soll W "gereinigt" werden, also alle Bits = 0 außer Bits 2 und 3
    >> das geht einfach mit W = W & 0x0C, also bitweises AND mit 00001100
    
       andlw   12            ; W = W & 0x0C, Zero-Flag in STATUS ggf. auf 1 wenn Ergebnis 0
    
    >> folgender Code ergo unnötig
    
       clrw                  ; W löschen
       bcf   Input,0         ; 
       bcf   Input,1         ; alle Bits von Input1 bis auf entscheidende Bits 2 und 3 werden           
       bcf   Input,4         ; auf 0 gesetzt 
       bcf   Input,5         ; 
       bcf   Input,6         ; 
       bcf   Input,7         ; 
       movfw   Input         ; Input in Input_kor schreiben
    
    >> hier geht's weiter
    
       movwf   Input_kor 	 >> Input_kor = W
    
    >> jetzt haben wir also den Originalzustand von PORTA in Input und den sauberen Zustand in Input_kor und W
    
       clrw               ; W löschen  >> nicht nötig, wir brauchen Input_kor ja gleich wieder
    
    
    X_achse 	 >> Du willst PORTB auf 00010000 (LED_X) wenn Input_kor = 00000000 (digit0)
    
       movfw   Input_kor          ; Input_kor wird in W geladen >> hier nicht nötig, aber für die anderen Achsen schon
    
    >> jetzt W mit digit0 vergleichen
    
       xorwf   digit0,0          ; Input_kor und digit0 werden verglichen, Ergenbins in W 
    
    >> wenn W gleich digit0, dann liefert XOR 0; das setzt das Zero-Flag in STATUS, und das kannst Du testen
    
       movwf   Result            ; Ergebnis wird in Result gespeichert >> wenn Du magst, brauchen wir aber nicht
    
    >> ab hier löschen
       clrw                  ; W löschen 
       btfss   Result,2         ; nächste Zeile überspringen wenn Bit Nr.2 den Wert 1 hat 
       btfsc   Result,3         ; nächste Zeile überspringen wenn Bit Nr.3 den Wert 0 hat 
       goto   Y_achse            ; sprung zu Y_achse 
    
    >> hier geht's weiter
       bnz     Y_achse	     ; >> ungleich 0, war's also nicht (Branch on Non Zero)
    
    >> kapier ich nicht: Ergebnis ist 10000000 in PORT B; LED_X ist aber als 00010000 definiert
    >> sollte das nicht bsf PORTB,4 sein (Bits von rechts nach links numeriert, also 76543210 )?
    >> ein Fehler, der mir auch schon das Leben schwer gemacht hat, ist, dass mit 1 die Leitung auf +5V geht
    >> das klappt nur, wenn die LED richtig herum eingebaut ist, also Prozessor, Vorwiderstand, LED, Masse
    >> wenn LED zwischen Prozessor und +5V, dann muss der Port auf 0
       bsf   PORTB,7               ; Bit 7 von PORTB wird auf high gesetzt, die LED für X-Achse leuchtet 
    
    >> dann solltest Du da noch eine Pause einbauen, und alle Leitungen z.B. in Main auf 0 setzen
    >> siehe http://www.sprut.de/electronic/pic/p...t/lauflich.htm
    
       goto Main
    Wie gesagt, bin kein PIC-Experte und mache auch viele Fehler (aber am ATmega12... Hoffentlich hilft's trotzdem etwas.

    LG
    Wolfgang

  5. #5

    Danke

    Hallo,

    danke für die Tipps. In der Tat waren da ein paar Fehler in der PIN-Zuordnung bei den LEDs .

    Hab den Code jetzt mal wie folgt umgestalltet. Wußte leider noch nichts mit flags anzufangen. Jetzt weis ich aber um was es etwa geht:

    Code:
    	list p=16f84a
    ;**************************************************************
    ;*  	Pinbelegung
    ;*	----------------------------------	
    ;*	PORTA: 	Eingänge
    ;*		0 - PIN 17 - Tastereingang
    ;*		1 - PIN 18 - n.c.
    ;*		2 - PIN 01 - Input #4
    ;*		3 - PIN 02 - Input #5
    ;*		4 - PIN 03 - n.c.
    ;*	PORTB:
    ;*		0 - PIN 06 - Tastersignal 
    ;*		1 - PIN 07 - n.c.	
    ;*		2 - PIN 08 - n.c.
    ;*		3 - PIN 09 - n.c.
    ;*		4 - PIN 10 - LED x-Achse
    ;*		5 - PIN 11 - LED y-Achse
    ;*		6 - PIN 12 - LED z-Achse
    ;*		7 - PIN 13 - LED a-Achse
    ;*	
    ;**************************************************************
    ;
    ;jorues 30.03.2007
    ;
    ; Handradlogik
    ;
    ; Taktquelle: 4 MHz
    ;
    ;**************************************************************
    ; Includedatei für den 16F84A einbinden
    
    	#include <P16f84a.INC>
    
    ; Configuration festlegen
    ; bis 4 MHz: Power on Timer, kein Watchdog, XT-Oscillator
    
    	__CONFIG	_PWRTE_ON & _WDT_OFF & _XT_OSC
    ;***************************************************************
    ; Variablen festlegen
    
    Input  Equ	0x20
    Input_kor	Equ	0x21
    Result	Equ	0x22
    loops   Equ     0x24            ; Zähler für Warteschleife 
    loops2  Equ     0x25            ; Zähler für Warteschleife  
    
    ; Constanten festlegen
    	
    Ini_con Equ	B'00000000'		; TMR0 -> Intetupt disable
    digit0 Equ B'00000000'			; Wert0 festlegen
    digit1 Equ B'00000100'			; Wert1 festlegen
    digit2 Equ B'00001000'			; Wert2 festlegen
    digit3 Equ B'00001100'			; Wert3 festlegen
    LED_X Equ B'10000000'			; LED für X-Achse
    LED_Y Equ B'01000000'			; LED für Y-Achse
    LED_Z Equ B'00100000'			; LED für Z-Achse
    LED_A Equ B'00010000'			; LED für A-Achse
    ;*************************************************************
    ;Reset vector
    ; This code will start executing when a reset occurs.
    
            ORG 0x0000
    
    ;**************************************************************
    ; Das Programm beginnt mit der Initialisierung
    
    Init	
    
    	bsf     STATUS, RP0		; Bank 1
    	movlw	B'11111111'		; PortA alle inputs 
    	movwf	TRISA			; 
    	movlw	B'00000000'		; PortB alle outputs 
    	movwf	TRISB			;
    	bcf     STATUS, RP0		; Bank 0
    	clrf	PORTA		
    	clrf	PORTB		
    				
    	movlw   Ini_con     		; Interupt disable
    	movwf   INTCON
    	clrw
    
    ;****************************************************************
    Main
       
    	movfw   PORTA		; Port A lesen und nach W kopieren >> W = PORTA
    				;
    	movwf   Input         	; von W in Input (0x20) kopieren >> Input = W
    				;
    	andlw   12            	; W = W & 0x0C, Zero-Flag in STATUS ggf. auf 1 wenn Ergebnis 0
    				;
    	movwf   Input_kor     	; Input_kor = W
    				; jetzt haben wir also den Originalzustand von PORTA in Input und den sauberen 
    				; Zustand in Input_kor und W
    				;
     	clrw               	; W löschen  >> nicht nötig, wir brauchen Input_kor ja gleich wieder
    				;
    	clrf	PORTA		; Alle Leitungen auf 0 (LOW)
    	clrf	PORTB		;
    
    ;****************************************************************************************************************
    ;PORTB auf 10000000 (LED_X) wenn Input_kor = 00000000 (digit0)
    
    X_achse     			
    	
    	call    Wait            ; Wartezeit 
       	movfw   Input_kor	; Input_kor wird in W geladen 
    				; 
    	xorwf   digit0,0        ; Input_kor und digit0 werden verglichen, Ergenbins in W
    				; wenn W gleich digit0, dann liefert XOR 0; das setzt 
    				; das Zero-Flag in STATUS, und das kannst Du testen
    				;
    	movwf	Result          ; Ergebnis wird in Result gespeichert >> wenn Du magst, brauchen wir aber nicht
    				;
    	bnz	Y_achse        	; >> ungleich 0, war's also nicht (Branch on Non Zero)
    	bsf	PORTB,7         ; Bit 7 von PORTB wird auf high gesetzt, die LED für X-Achse leuchtet
    
    ;****************************************************************************************************************
    ;PORTB auf 01000000 (LED_Y) wenn Input_kor = 00000100 (digit1)
    
    Y_achse     			
    
    	call    Wait            ; Wartezeit 
       	movfw   Input_kor	; Input_kor wird in W geladen 
    				; 
    	xorwf   digit1,0        ; Input_kor und digit1 werden verglichen, Ergenbins in W
    				; wenn W gleich digit1, dann liefert XOR 0; das setzt 
    				; das Zero-Flag in STATUS, und das kannst Du testen
    				;
    	movwf	Result          ; Ergebnis wird in Result gespeichert >> wenn Du magst, brauchen wir aber nicht
    				;
    	bnz	Z_achse        	; >> ungleich 0, war's also nicht (Branch on Non Zero)
    	bsf	PORTB,6         ; Bit 6 von PORTB wird auf high gesetzt, die LED für Y-Achse leuchtet
    
    ;****************************************************************************************************************
    ;PORTB auf 00100000 (LED_Z) wenn Input_kor = 00001000 (digit2)
    
    Z_achse
         			
    	call    Wait            ; Wartezeit 
       	movfw   Input_kor	; Input_kor wird in W geladen 
    				; 
    	xorwf   digit2,0        ; Input_kor und digit2 werden verglichen, Ergenbins in W
    				; wenn W gleich digit2, dann liefert XOR 0; das setzt 
    				; das Zero-Flag in STATUS, und das kannst Du testen
    				;
    	movwf	Result          ; Ergebnis wird in Result gespeichert >> wenn Du magst, brauchen wir aber nicht
    				;
    	bnz	A_achse        	; >> ungleich 0, war's also nicht (Branch on Non Zero)
    	bsf	PORTB,5         ; Bit 5 von PORTB wird auf high gesetzt, die LED für Z-Achse leuchtet
    
    ;****************************************************************************************************************
    ;PORTB auf 00010000 (LED_A) wenn Input_kor = 00001100 (digit3)
    
    A_achse     			
    
    	call    Wait            ; Wartezeit 
       	movfw   Input_kor	; Input_kor wird in W geladen 
    				; 
    	xorwf   digit3,0        ; Input_kor und digit3 werden verglichen, Ergenbins in W
    				; wenn W gleich digit3, dann liefert XOR 0; das setzt 
    				; das Zero-Flag in STATUS, und das kannst Du testen
    				;
    	movwf	Result          ; Ergebnis wird in Result gespeichert >> wenn Du magst, brauchen wir aber nicht
    				;
    	bnz	X_achse        	; >> ungleich 0, war's also nicht (Branch on Non Zero)
    	bsf	PORTB,4         ; Bit 4 von PORTB wird auf high gesetzt, die LED für A-Achse leuchtet
    
    ;****************************************************************************************************************
       	
    	goto Main 
    
    ;****************************************************************************************************************
    ; Warteschleife 250 ms
    
    Wait
            movlw   D'250'          ; 250 ms Pause
            movwf   loops 
    
    Wai
            movlw   .110           ; Zeitkonstante für 1ms
            movwf   loops2
    Wai2    nop                    ; 
            nop
            nop
            nop
            nop
            nop
            decfsz  loops2, F      ; 1 ms vorbei?
            goto    Wai2           ; nein, noch nicht
                                   ;
            decfsz  loops, F       ; 250 ms vorbei?
            goto    Wai            ; nein, noch nicht
            retlw   0              ; das Warten hat ein Ende
    
            end
    Habs jetzt auch versuch, mit dem Ergebnis, dass nach dem einschalten erst RB7 und kurz darauf RB5 auf high, logisch 1, gehen.

    Ich bin mir immer noch nicht so sicher, ob mein Grundgerüst stimmt.
    Vielleicht könnte da ein PIC experte mal schnell einen Blick darauf werfen???

    Vielen Dank euch allen

    LG Jo

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    31.12.2006
    Ort
    Wien
    Alter
    53
    Beiträge
    7

    Ergänzung

    Am Ende der Achsen-Routinen fehlt jetzt das "goto main", und die Warteschleife ist besser unmittelbar nach dem "bsf PORTx".

    Ansonsten musst Du mal sehen, was wirklich an den Input-Ports anliegt.

    LG
    Wolfgang

Berechtigungen

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