This is another attempt to create a servo driver based on instant interrupts. This one almost works, but not quite. I may attempting the imposible; if so, could someone please tell me. I really don't know how to interpret assembly routines.

This servo driver is based on Darrel Taylor's DT_INTS-14/TimerTemplate which can be found on this Forum. It is easy to set up a 50 hz interrupt to start and repeat standard servo frames. In addition to running a servo I'm driving a brushless motor controller, which also runs on standard servo frames. Testing is done with real hardware, including a motor, controller, and servo.

The routine shown below works as long as I do not attempt to change the motor drive pulses from full on to full off. The motor actually starts and runs at full speed. However, in order to stop the motor it is necessary to apply full off pulses. When I attempt to do this the program somehow scans through and picks up the full off setting, and applies this to the whole sequence. The result is that the motor will not start.

Most of the code shown is just a copy of the TimerTemplate. I added the interrupt handler and the few lines in the main section.


Code:
'device is PIC 16F684

'set registers
        '...done...
        
        DEFINE OSC 8         '8 Mhz oscillator

'declare variables
        '....done...
        
' initialize ports and variables
        portc.1 = 0               'turn off servo
        portc.4 = 0               'initialize servo pulse low
        portc.5 = 0               'initialize throttle pulse low 
        throttlepos = 400         '2*(200) = full throttle
        servopos = 300            '2*(150) = mid range of servo
        MTtime = 100              '10.0 second motor run time
        BKtime = 15               '1.5 second brake time
        ticks = 0                 '0.02 seconds per tick
        tenths = 0                '1/10 seconds
        seconds = 0               'seconds
        sum = 0                   'total time in tenths, e.g. 100 = 10.0 sec.

'arm the motor 
          'Phoenix-10 brushless motor controller requires throttle-off arming
          'for 4 seconds
          '....done...

INCLUDE "DT_INTS-14 for F684.bas"    ; Base Interrupt System with wsave for F684
INCLUDE "ReEnterPBP.bas"             ; Include if using PBP interrupts

ASM
INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
        INT_Handler   TMR1_INT,   ReloadTMR1,   ASM,  no    ; MUST be first
        INT_Handler   TMR1_INT,   _T1handler,   PBP,  yes
    endm
    INT_CREATE               ; Creates the interrupt processor
ENDASM

;--- Match the desired interrupt frequency -------------------
;--- See http://DarrelTaylor.com/DT_INTS-14/TimerTemplate.html for more Info.
@Freq       = 50                  ; 50 Hz Frequency of Interrupts 
@Prescaler  = 1                   ; Timers Prescaler setting
T1CON = $00                       ; $00 = Prescaler 1:1, TMR1 OFF

@ INT_ENABLE  TMR1_INT            ; enable Timer 1 interrupts

GOSUB StartTimer                  ; Start the Timer
        
        portc.1 = 1                'turn on servo power
        low Led                    'turn on led
Main:                            
  ;   ---- Your Main Program goes here ----

        if sum => MTtime then     'motor fully on for 10.0 seconds
        high led                  'turn off led .. this signals end of motor run
        goto newtime1             'try to reset throttle to full off
        endif

newtime1:                         ' brake motor for 1.5 seconds
       
'        throttlepos = 200     ' 2*(100) throttle full off; brake on. This is 
                               'the problem line. Does not work when uncommented

        if sum => (MTtime + BKtime) then   'motor off, braking done
        low led                            'turn on led; signals end of braking
        goto DT      
        endif
GOTO Main
    '-------------------------------------------
DT:     
@ INT_DISABLE  TMR1_INT        ; disable Timer 1 interrupts
     portc.1 = 0               'turn off servo
     end                       'sleep until next power on cycle

;____This routine is Called on each TMR1 Interrupt____________________________

T1handler:  'interrupts are every 20 ms. These interrupts start each servo frame
            'and also clock elapsed time. 
           
            pulsout portc.5,throttlepos   'send pulse to motor speed controller
            pulsout portc.4,servopos      'send pulse to servo (pulse range is 
            Ticks = Ticks + 1             '1 ms to 2 ms for both pulses)
        if Ticks = 5 then
           Ticks = Ticks - 5
           Tenths = Tenths + 1
             if tenths = 10 then
               Seconds = Seconds + 1
               Tenths = 0
             endif
           sum = 10*Seconds + Tenths  'calculate time in tenths of seconds
         endif
  ;   ---- ---------------------------------- ----
@ INT_RETURN

;---[TMR1 reload - interrupt handler]-----------------------------------------
ASM                               ; Calculate Timer Reload Constant
ReloadInst  = 8                   ; # of Intructions used to reload timer
  if ((Prescaler == 1)||(Prescaler == 2)||(Prescaler == 4)||(Prescaler == 8))
MaxCount    = 65536 + (ReloadInst / Prescaler)
TimerReload = MaxCount - (OSC*1000000/4/Prescaler/Freq)
    if ((TimerReload < 0) || (TimerReload > (65535-ReloadInst)))
        error Invalid Timer Values - check "OSC", "Freq" and "Prescaler"
    endif
  else
      error Invalid Prescaler
  endif
ENDASM

@Timer1 = TMR1L                   ; map timer registers to a word variable
Timer1       VAR WORD EXT
TimerReload  CON EXT              ; Get the External Constant
TMR1ON       VAR T1CON.0          ; Alias the Timers ON/OFF bit

;---Reload Timer1------
ASM
ReloadTMR1
    MOVE?CT  0, T1CON, TMR1ON     ;  1     stop timer
    MOVLW    LOW(TimerReload)     ;  1     Add TimerReload to the 
    ADDWF    TMR1L,F              ;  1     value in Timer1
    BTFSC    STATUS,C             ;  1/2
    INCF     TMR1H,F              ;  1
    MOVLW    HIGH(TimerReload)    ;  1
    ADDWF    TMR1H,F              ;  1
    MOVE?CT  1, T1CON, TMR1ON     ;  1     start timer
  INT_RETURN
ENDASM
     
;---Start/Stop controls -----
StartTimer:
    Timer1  = TimerReload         ; Load Timer
    TMR1ON = 1                    ; start timer
RETURN

StopTimer:
    TMR1ON = 0                    ; stop timer
RETURN