; ****************************************** ; ; Edge triggered JK type Flip Flop ; for PIC 12F675 ; ; As written this code will make a 12F675 PIC simulate ; a JK type flip flop with Edge selectable triggered clock ; and active high JK inputs ; ; GPIO 5 is checked after reset and the logic level sets ; the flip flop to clock on either negative or postive CLK ; edges acording to the following: ; GPIO 5 = 1 -> Negative edge clk ; GPIO 5 = 0 -> Positive edge clk ; ; ; J K | Q ^Q ; ------------ ; 0 0 | u u ; 1 0 | 1 0 ; 0 1 | 0 1 ; 1 1 | t t ; ------------ ; u = unchanged ; t = toggle ; ; Pin functions when PIC is running this code. ; ; Vdd -|1 8|- Vss ;Clk Edge Sel -|2 7|- Qout ; J -|3 6|- ^Qout ; K -|4 5|- Clk ; ; Written by Pete Griffiths, May 2004 ; ; ****************************************** #include "p12f675.inc" __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CPD_OFF cblock 0x20 input output push_status push_w endc ; ***************************************** ; Reset start point ; org 0x000 goto _init ; ***************************************** ; Interrupt Service Routine ; org 0x004 _intserv ; Save W and Status movwf push_w swapf STATUS,W bcf STATUS,RP0 ; Sel bank 0 movwf push_status ; Process interrupt movf GPIO,W ; Get data from GPIO inputs andlw 0x18 ; Mask out bits not needed movwf input ; Save it to work with later btfss INTCON,INTF ; Was this a Clk edge interupt? goto _exit ; This should never execute bcf INTCON,INTF ; Clear INTF flag ; J K | Q ^Q ; 0 0 | u u ; 1 0 | 1 0 ; 0 1 | 0 1 ; 1 1 | t t ; u = unchanged ; t = toggle movf input,W btfsc STATUS,Z ; If J & K low, output unchanged goto _exit xorlw 0x18 ; Test if J & K high, toggle output btfsc STATUS,Z goto _toggle movlw 0x10 andwf input,W btfss STATUS,Z ; test and skip next if J low goto _J ; else J must be high _K movlw 0x02 ; set Q=0, ^Q=1 goto _setQ _J movlw 0x01 ; set Q=1, ^Q=0 goto _setQ _toggle movlw 0x03 xorwf output,W ; toggle Q & ^Q _setQ movwf GPIO ; write to GPIO ports movwf output ; save to output ; Saving and restoring the registers isn't strictly needed ; since the main loop does nothing, but this is an exercise ; in using interupts so they're here for completeness. ; ; Restore W and Status and return from Interupt. _exit swapf push_status,W movwf STATUS swapf push_w,F swapf push_w,W retfie ; This instruction sets the GIE bit ; in INTCON register and returns from ; interupt ; ****************************************** ; Startup initialisation _init ;Initialise needed registers in Bank 1 bsf STATUS,RP0 ; Sel Bank 1 call 0x3ff ; Get OSCAL value movwf OSCCAL ; write to OSCCAL register clrf ANSEL ; Set ports for digital mode movlw b'11111100' ; set up W to movwf TRISIO ; enable GPIO 0,1 for output movlw b'00010000' ; set up W to movwf INTCON ; enable edge interupts bcf OPTION_REG,NOT_GPPU ; enable global pull up bsf WPU,5 ; enable global pull up on GPIO5 ;Initialise needed registers in Bank 0 bcf STATUS,RP0 ; Sel Bank 0 movlw 0x07 ; Set up W to movwf CMCON ; turn off Comparator ports movlw 0x02 ; Set up W to movwf output ; Set initial state of output movwf GPIO ; and update physical output Q=0, ^Q=1 clrf ADCON0 ; turn off A/D convertor movf GPIO,W andlw b'00100000' ; mask in bit 5 bsf STATUS,RP0 ; select bank 1 bsf OPTION_REG,INTEDG ; CLK interupt on rising edge on GPIO 2 btfsc STATUS,Z ; if bit 5 low set up negative clock goto _main bcf OPTION_REG,INTEDG ; CLK interupt on negative edge on GPIO 2 ; ****************************************** ; ; Sit in an endless loop, any changes to inputs ; will cause an Interrupt to occur and the ; interupt service routine will set the outputs ; Q and ^Q accordingly so we do nothing here. ; Could put a sleep instruction here but since ; power is not an issue we keep it simple. _main bcf STATUS,RP0 ; Select bank 0 bsf INTCON,GIE ; Enable Global Interupts bsf INTCON,INTF ; Enable edge interupts _forever goto _forever dt "JK Type Flip Flop. Pete Griffiths, May 2004. R1.1" end