Converting PBP interrupt to ASM - 18F25K20


+ Reply to Thread
Results 1 to 12 of 12

Hybrid View

  1. #1
    Join Date
    Jan 2009
    Location
    Huntsville, AL
    Posts
    49


    Did you find this post helpful? Yes | No

    Default Re: Converting PBP interrupt to ASM - 18F25K20

    Sorry I didn't get back to this thread sooner, but I got both interrupts working well for this application. For reference, these interrupts are specific to a quadcopter. The "PULSE_WIDTH" interrupt is reading pulse lengths from an RC reciever (using the "ppm" protocol which puts all channels on a single pin) and the "MOTOR_CONTROL" interrupt is driving mosfets that are connected to PORTC pins 4-7. I've run several verification tests to make sure they are working as intended, and it appears they are. Here is a video of the quadcopter flying with both new asm interrupts implemented:



    The landing was a little rough, but that blame falls on the pilot (me). For completeness, here is the final code I am using for both interrupts:

    Code:
    MOTOR_CONTROL:
    ASM
       banksel _mcount                    ; Variables used in interrupts are stored one bank via config definition - can change bank # as long as vars are in same bank
       movf   _mcount, W                  ; Get index value from variable 'mcount' for array address, store in WREG
       incf   _mcount, f                  ; Increment mcount before changing banks
       lfsr    FSR0, _motor               ; Load the full 12-bit address of motor array into FSR0
       addwf   FSR0L, f                   ; Add offset to low byte of pointer
       movlw   0                          ; clear WREG although carry flag is still active in STATUS REGISTER bit0
       addwfc  FSR0H, f                   ; Add carry to high byte of pointer 
       movf    INDF0, W                   ; Move INDF0 to WREG 
       banksel LATC                       ; Change bank to LATC
       movwf   LATC                       ; Change PORTC outputs based on WREG
       banksel _mcount
       movf    _mcount, W                 ; Get index value from variable 'mcount' for array address, store in WREG
       lfsr    FSR0, _preload             ; Load the full 12-bit address of preload array into FSR0
       addwf   FSR0L, f                   ; Add offset to low byte of pointer
       movlw   0                          ; clear WREG although carry flag is still active in STATUS REGISTER bit0
       addwfc  FSR0H, f                   ; Add carry to high byte of pointer 
       movf    INDF0, W                   ; Move INDF0 to WREG  
       banksel TMR1H                      ; Change bank to TMR1H
       movwf   TMR1H                      ; Load preload byte into TMR1H
    INT_RETURN
    endasm
    And the RC interrupt:

    Code:
    PULSE_WIDTH:
    asm
       banksel _ppm_n                     ; Variables used in interrupts are stored one bank via config definition - can change bank # as long as vars are in same bank
       movff  TMR3L, _nowtmr3             ; Read LB and store in variable 'pausetime' - also loads TMR3H into buffer
       movff  TMR3H, _nowtmr3 + 1         ; Read HB from buffer
       movf   _ppm_n, W                   ; Get index value from variable 'ppm_n' for array address, store in WREG
       rlncf  WREG, W                     ; Multiply WREG by 2 since ppm array is words (16bit)
       lfsr   FSR0, _ppm                  ; Load the full 12-bit address of ppm into FSR0
       addwf  FSR0L, f                    ; Add offset from WREG to low byte of pointer
       movlw  0                           ; clear WREG although carry flag is still active in STATUS REGISTER bit 0
       addwfc FSR0H, f                    ; Add carry to high byte of pointer - pointer is now set to corret register!
    ;subtraction and store           
       movf   _lasttmr3, W                ; W = Low byte of lasttmr3
       subwf  _nowtmr3, W                 ; Subtract WREG from f and store in WREG -> WREG = nowtmr3_L - lasttmr3_L
       movwf  POSTINC0                    ; Store result low byte of array
       movf   _lasttmr3 + 1, W            ; W = High byte of subtrahend
       btfss  STATUS, C                   ; Did LSB subtraction produce a borrow? (C=0)
       incfsz _lasttmr3 + 1, W            ; Yes: W = lasttmr3 + 1 (adds borrow)
       subwf  _nowtmr3 + 1, W             ; Subtract WREG from f and store in WREG -> WREG = nowtmr3_H - lasttmr3_H
       movwf  INDF0                       ; Store result high byte
    ;subtraction end
       incf   _ppm_n, f                   ; increment array index variable ppm_n
       movlw   18h                        ; move 24 (18h) into WREG to compare with ppm_n
       cpfslt _ppm_n, 1                   ; check if ppm_n < WREG (24), skip next instruction if ppm_n < WREG
       clrf   _ppm_n                      ; clear ppm_n if above condition is met
       btg    _ppmwrite                   ; toggle ppmwrite to check if interrupt occured in main program
       bcf    _RCtickle                   ; clear RCtickle to show RC is still receiving signals
       movff  _nowtmr3, _lasttmr3         ; Move current timer3 val to last timer3 val for next interrupt
       movff  _nowtmr3 + 1, _lasttmr3 + 1 ; Move current timer3 val to last timer3 val for next interrupt
    INT_RETURN
    endasm

  2. #2
    Join Date
    Jan 2009
    Location
    Huntsville, AL
    Posts
    49


    Did you find this post helpful? Yes | No

    Default Re: Converting PBP interrupt to ASM - 18F25K20

    Also I forgot to mention: thanks Richard for the help!

  3. #3
    Join Date
    May 2013
    Location
    australia
    Posts
    2,722


    Did you find this post helpful? Yes | No

    Default Re: Converting PBP interrupt to ASM - 18F25K20

    for what it worth you might save a nano second or two

    i'm not exactly sure how the assembler works but SFR's that are in the access bank can be referenced without needing to select bank 15 explicitly, not all SFR's are in access bank
    notice that addwf FSR0L, f works ok with out a banksel 15.
    Technically movwf LATC,f,a would be more correct but the ass seems to interpret movwf LATC correctly no matter what bank is selected



    Code:
    MOTOR_CONTROL:ASM
       banksel _mcount                    ; Variables used in interrupts are stored one bank via config definition - can change bank # as long as vars are in same bank
       movf   _mcount, W                  ; Get index value from variable 'mcount' for array address, store in WREG
       incf   _mcount, f                  ; Increment mcount before changing banks
       lfsr    FSR0, _motor               ; Load the full 12-bit address of motor array into FSR0
       addwf   FSR0L, f                   ; Add offset to low byte of pointer
       movlw   0                          ; clear WREG although carry flag is still active in STATUS REGISTER bit0
       addwfc  FSR0H, f                   ; Add carry to high byte of pointer 
       movf    INDF0, W                   ; Move INDF0 to WREG 
       ;banksel LATC                  not needed LATC is in access bank     ; Change bank to LATC
       movwf   LATC                       ; Change PORTC outputs based on WREG
       banksel _mcount
       movf    _mcount, W                 ; Get index value from variable 'mcount' for array address, store in WREG
       lfsr    FSR0, _preload             ; Load the full 12-bit address of preload array into FSR0
       addwf   FSR0L, f                   ; Add offset to low byte of pointer
       movlw   0                          ; clear WREG although carry flag is still active in STATUS REGISTER bit0
       addwfc  FSR0H, f                   ; Add carry to high byte of pointer 
       movf    INDF0, W                   ; Move INDF0 to WREG  
       ;banksel TMR1H              not needed TMR1H is in access bank           ; Change bank to TMR1H
       movwf   TMR1H                      ; Load preload byte into TMR1H
    INT_RETURN
    endasm
    Warning I'm not a teacher

Similar Threads

  1. Multi servo interrupt program in Mikro Basic converting to PBP
    By queenidog in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 22nd May 2015, 17:17
  2. 16F1827 ASM Interrupt
    By abbtech in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 16th February 2011, 06:47
  3. 18F2480 asm interrupt
    By Richard Storie in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 5th March 2009, 19:40
  4. Replies: 3
    Last Post: - 16th October 2007, 00:01
  5. ASM Interrupt
    By mikep in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 22nd November 2004, 20:06

Members who have read this thread : 11

You do not have permission to view the list of names.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts