Forum: Mikrocontroller und Digitale Elektronik Assembler Anfängerfrage


von Martin Michael (Gast)


Lesenswert?

org   4
intvec
    bcf  INTCON, GIE  ; disable Interupt

    MOVWF W_TEMP   ;Copy W to TEMP register
    SWAPF STATUS,W   ;Swap status to be saved into W
            ;Swaps are used because they do not affect the status bits
    MOVWF S_TEMP ;Save status to bank zero STATUS_TEMP register
;


    BTFSS    INTCON,INTF  ; Übergehe wenn INTF = 1 ; wechsel an Port RB0
    GOTO  Next1        ;
    MOVLW  B'00000001'      ; RA0 mit xor vernüpfen
    XORWF  PORTA,1        ; invertieren von RA0
        bcf      INTCON, INTF         ; RB0-Interrupt-Flag löschen
    bsf    PORTA,B'00000100'
    GOTO  Int_End
Next1
    BTFSS  INTCON,T0IF
    GOTO  Next2
    MOVLW  B'00000010'      ; RA1 mit xor vernüpfen
    XORWF  PORTA,1        ; invertieren von RA1
    bcf    INTCON,T0IF      ; Timer0 Flag wieder setzen
    GOTO  Int_End

Next2
Int_End



    bsf  INTCON, GIE        ; ensable Interupt
    SWAPF S_TEMP,W         ;Swap STATUS_TEMP register into W
                  ;(sets bank to original state)
    MOVWF STATUS         ;Move W into STATUS register
    SWAPF W_TEMP,F         ;Swap W_TEMP
    SWAPF W_TEMP,W         ;Swap W_TEMP into W

      ; Intrupt servic routine
Int_serv
    RETFIE


;**************************************************************

; Port A/B auf Ausgabe stellen

Init

; Port RA0 auf Ausgabe stellen
        clrf     PORTA                ; LED aus
        bsf      STATUS, RP0          ; auf Bank 1 umschalten
        movlw    B'00000000'          ; PortA RA0-RA3 output
        movwf    TRISA

        movlw    B'00000000'          ; PortA RA0-RA3 output
        movwf    TRISB

        movlw    B'00000011'          ; PortA RA0-RA3 output
        movwf    TRISB


        bcf      STATUS, RP0          ; auf Bank 0 zurückschalten

; RB0-Interrupt einstellen
        bsf      STATUS, RP0          ; auf Bank 1 umschalten
        bsf      OPTION_REG, INTEDG   ; 0-1-Flanke an RB0
    bcf    OPTION_REG, T0CS

        bcf      STATUS, RP0          ; auf Bank 0 zurückschalten
    bcf   INTCON,T0IE      ; Timer 0 einschalten !!!!!!
        bsf      INTCON, INTE         ; RB0-interrupt erlauben

    MOVLW  B'00001111'
    MOVWF  PORTA
    NOP
    NOP
    NOP
    MOVLW  B'00000000'
    MOVWF  PORTA

    bsf      INTCON, GIE          ; Interrupt generell erlauben

loop    goto     loop                 ; eine Endlosschleife

;**********************************************************

        end



Hallo es handelt sich hierbei um einen PIC16F887

Eigentlich sollte die Interruptschleife "INTF",
wenn ich ein 5V Potential auf RB0 gebe richtig

aufgerufen werden, beim PIC16F84A funktionierte dies.

Übersehe ich was.

Martin Michael

von michael_ohl (Gast)


Lesenswert?

Auf ORG 0 den Sprung in deine Initialisierung. Der Prozessor rennt los 
und landet erst einmal in der Interrupt Routine.

Es ist gute Proxis vorne erst einmal auf ORG 0 zwei NOP für den Debugger 
und dann auf ORG 2 den Spung in die INIT zu verwenden.

Die Interrupt Routine würde ich auch mit einem Sprung von ORG 4 ans Ende 
meines Programm legen.

mfG
Michael

von Martin Michael (Gast)


Lesenswert?

Ei das habe ich doch gemacht

Ich dachte das wäre klar


  org   0
  goto  Init

und mir ist auch klar das der Timer0 ausgeschaltet ist.

Es geht mir vor allem darum, ob es richtig ist das bei einer 
Pegeländerung,
ein Interrupt INTE / INTF ausgelöst wird.

Danke

von cdk59 (Gast)


Lesenswert?

Im OPTION_REG nur die Flanke einzustellen dürfte zu wenig sein.
Datenblatt F887 sagt:
......
All of the PORTB pins are individually configurable as an
interrupt-on-change pin. Control bits IOCB<7:0> enable
or disable the interrupt function for each pin. Refer to
Register 3-8. The interrupt-on-change feature is
disabled on a Power-on Reset.
......
Da fehlt wohl noch:

BANKSEL IOCB
movlw b'00000001'
movwf IOCB

von Martin Michael (Gast)


Lesenswert?

Genau, Danke

Ja ich sehe das Datenblatt studieren ist alles

von Martin Michael (Gast)


Lesenswert?

Ich werde mal einen voll funktionsfähigen Assemblercode anfügen

;
;**************************************************************
; Includedatei für den 16F877 einbinden

  list p=16f887
  #include <P16f887.INC>

__CONFIG _CONFIG1, _HS_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF 
& _CPD_OFF & _BOR_OFF  & _IESO_OFF & _FCMEN_OFF & _LVP_OFF ; % _DEBUG_ON
__CONFIG _CONFIG2, _WRT_OFF & _BOR21V

  ERRORLEVEL      -302      ;SUPPRESS BANK SELECTION MESSAGES


;**************************************************************

; Variablennamen vergeben
; werden hier nicht alle benötigt

UDATA 0x20
Ziffer1    RES 1    ; Wert des LSD
Ziffer2    RES 1    ; Wert der zweitkleinsten Stelle
Ziffer3    RES 1    ; Wert der zweitgrößten Stelle
Ziffer4    RES 1    ; Wert des MSD
Digit    RES 1    ; Ziffernzähler
ar      RES 1
TastCount1  RES 1    ; zum Zählen der Timerdurchgänge
TastCount2  RES 1    ;


W_TEMP      EQU 0x71  ; Backup für Akkuregister
S_TEMP      EQU 0x72  ; Backup für Statusregister
PortA_Temp    EQU  0x73
PortB_Temp    EQU  0x73

;**************************************************************
; los gehts mit dem Programm

  org   0
  goto  Init

;**************************************************************
; die Interuptserviceroutine

  org   4
intvec
    bcf  INTCON, GIE  ; disable Interupt

    MOVWF W_TEMP   ;Copy W to TEMP register
    SWAPF STATUS,W   ;Swap status to be saved into W
            ;Swaps are used because they do not affect the status bits
    MOVWF S_TEMP ;Save status to bank zero STATUS_TEMP register

    MOVFW   PORTB        ; Status von Port B sichern
    MOVWF   PortB_Temp

CheckInt
    BTFSS    INTCON,RBIE      ; Übergehe wenn INTE = 1 ; wechsel an Port 
RB0
    GOTO  Next1        ;
    BTFSS  INTCON,RBIF      ; RBIE "UND" RBIF
    GOTO  Next1        ;

    MOVFW  PortB_Temp      ; PortB Eingang mit xor vernüpfen
    XORWF  PORTA,1        ; invertieren von RA0
        bcf      INTCON, RBIF        ; RB0-Interrupt-Flag löschen
    bsf    INTCON, T0IE    ; Timer Interrupt setzen

    GOTO  Next1;Int_End
Next1
    BTFSS  INTCON,T0IE
    GOTO  Next2
    BTFSS  INTCON,T0IF      ; T0IE "UND" T0IF
    GOTO  Next2
    DECFSZ  TastCount1
    GOTO  Next2

    MOVLW  0xFF        ; Anzahl Timer Durchgänge
    MOVWF  TastCount1      ; für neues Starten

    bcf    INTCON,T0IF      ; Timer0 Flag wieder löschen
    bcf    INTCON,T0IE      ; Timer0 Disabel

    GOTO  Next2;Int_End

Next2
    BTFSS  INTCON,INTE
    GOTO  Next3
    BTFSS  INTCON,INTF      ; INTE "UND" INTF
    GOTO  Next3
    bcf    INTCON,INTF      ; INTF Flag wieder löschen
    GOTO  Next3;Int_End

Next3
Int_End

    SWAPF S_TEMP,W         ;Swap STATUS_TEMP register into W
                  ;(sets bank to original state)
    MOVWF STATUS         ;Move W into STATUS register
    SWAPF W_TEMP,F         ;Swap W_TEMP
    SWAPF W_TEMP,W         ;Swap W_TEMP into W

    bsf  INTCON, GIE        ; enable Interupt
      ; Intrupt servic routine
Int_serv
    RETFIE


;**************************************************************

; Port A/B auf Ausgabe stellen

Init
    MOVLW  0xFF
    MOVWF  TastCount1


; Port RA0 auf Ausgabe stellen
        clrf     PORTA                ; LED's aus
        BANKSEL  TRISA

        movlw    B'00000000'          ; PortA RA0-RA3 output
        movwf    TRISA
         movlw    B'00001111'          ; PortB RB4-RB7 output
        movwf    TRISB        ; PortB RB0-RB3 input

      BANKSEL ANSEL        ; alle Ports Digital
      CLRF    ANSEL
      CLRF    ANSELH

      BANKSEL ADCON0
      CLRF    ADCON0

      BANKSEL ADCON1
      CLRF    ADCON1        ; End Port Dugital Diffination


      BANKSEL CCP1CON
      CLRF    CCP1CON

    BANKSEL CCP2CON
      CLRF    CCP2CON

      BANKSEL IOCB        ;
    movlw b'00001111'      ; Set Port RB0-RB1 INTERRUPT-ON-CHANGE
    movwf IOCB

      CLRF    WPUB        ;WEAK Pull-Up deaktiviert

    BANKSEL OPTION_REG

      bcf    OPTION_REG,PSA    ;bit 3 = 0 PSA: Prescaler Assignment bit
                  ;1 = Prescaler is assigned to the WDT
                  ;0 = Prescaler is assigned to the Timer0 module
    MOVFW  B'00000111'      ;bit 2-0 PS<2:0>: Prescaler Rate Select bits
                  ;110 - 1:64 ; 111 - 1:128

        bsf      OPTION_REG, INTEDG   ; 0-1-Flanke
    bcf    OPTION_REG, T0CS  ; Internal Timer Foac/4

        BANKSEL INTCON             ; auf Bank 0 zurückschalten
    bcf   INTCON,T0IE      ; Timer 0 AUS schalten !!!!!!
        bsf      INTCON, INTE         ; Intern Interrupts erlauben
    bsf    INTCON, RBIE    ; RB -interrupt erlauben

    BCF     INTCON,RBIF      ; Flags löschen
      BCF     INTCON,INTF          ; !!!!

    MOVLW  B'00001111'      ; Nur zum Test
    MOVWF  PORTA        ; Led RA0-4 an
    NOP
    NOP
    NOP
    MOVLW  B'00000000'      ; und wieder aus
    MOVWF  PORTA


    bsf      INTCON, GIE          ; Interrupt generell erlauben
loop    goto     loop                 ; eine Endlosschleife

;**********************************************************

        end

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.