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:
And the RC interrupt: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
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


Reply With Quote

Bookmarks