Here is a rapid fire project I made for my son. It has four states, 1) off, 2) 20 shot/sec, 3) 10shots/sec and 4) 5 shots/sec. You control the speed by tapping on the SYNC switch on the 360 controller. I used a 12F683. This will only work for the newer (CG or common ground) controllers.
The x-box trigger is a pot. when the trigger is pulled the wiper voltage goes from near zero to 3 volts. This circuit changes the pin (GP0) from input (tri-state) to a output with zero volts. There may be a little overkill, I was playing with Darrel's Instant Interrupts
Hope it helps a littleCode:@ __CONFIG _FCMEN_OFF & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTOSCIO ANSEL = %00000000 'Make sure Analog functions are turned OFF (should not be needed) CMCON0 = 7 'comparators off OPTION_REG.7 = 0 'enable weak pullups TRISIO = %00100101 WPU = %00000100 'weak pullup OPTION_REG.6 = 0 'falling edge trigger ;***** VARIABLE DEFINITIONS****************** STATE Var byte ;programmed state '';************************************************************************ ' _______ ' VDD -|1 8|- VSS ' GP5 -|2 7|- GP0 TriggerR out -> ' GP4 -|3 6|- GP1 ' GP3 -|4_____5|- GP2 <- sync ' ' ' ' '*********GPIO pin names************************************************** LED var GPIO.5 'led output useing player 4 led Sync var GPIO.2 'sync switch input TRIGGERR var GPIO.0 'rapid trigger output '********************************************************************** INCLUDE "DT_INTS-14.bas" ; Base Interrupt System 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, _TriggerOut, PBP, yes INT_Handler INT_INT, _ChangeState, PBP, yes endm INT_CREATE ; Creates the interrupt processor ENDASM TMR1H = $A0 ' load timer1 with $00FF TMR1L = $B3 T1CON = $00 @ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts @ INT_ENABLE INT_INT ; enable external (INT) interrupts ;--- Change these to match the desired interrupt frequency ------------------- ;--- See http://DarrelTaylor.com/DT_INTS-14/TimerTemplate.html for more Info. @Freq = 20 ; Frequency of Interrupts in Hz @Prescaler = 1 ; Timers Prescaler setting T1CON = $00 ; $30 = Prescaler 1:8, TMR1 OFF ; $00=1:1, $10=1:2, $20=1:4, $30=1:8 -- Must match @Prescaler value State = 0 goto Main '*************************************************************************** ChangeState: ' Three states rapid fire 20 SPS 10 SPS and off pause 10 if sync = 0 then ' Switch debounce if state = 3 then state = 0 select case state case 0 'twenty shots per sec gosub starttimer case 1 'ten shots per sec T1CON = $11 case 2 ' five shots per second T1CON = $21 case 3 'off T1CON = $00 'timer off TRISIO = %00100101 end select state = state + 1 endif @ INT_RETURN '*************************************************************************** TriggerOut: TRIGGERR = 0 'Trigger 0 TRISIO.0 = 0 ' Trigger output the 0 low LED 'turn on led TRISIO.5 = 0 'make led a output pause 25 'pause 25 ms high led 'turn off led TRISIO.0 = 1 'put trigger in tristate mode (float) input LED 'put led in tristate mode (PCP method) @ INT_RETURN '*************************************************************************** Main: 'nothing happening here yet just using interupts for this project goto main ;---[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
Dave





Bookmarks