; ****************************************** ; ; Edge triggered D type Flip Flop with SR inputs ; for PIC 12F675 ; ; As written this code will make a 12F675 PIC simulate ; a D type flip flop with Negative Edge triggered clock ; and active low Set and Reset inputs ; ; By changing three instructions in the source code this ; can be made to postive edge triggered with active high ; Set and Reset inputs. ; ; Pin functions when PIC is running this code. ; ; Vdd -|1 8|- Vss ; Data -|2 7|- Qout ; Set -|3 6|- ^Qout ; Res -|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 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 movwf input ; Save it to work with later bcf INTCON,GPIF ; Clear GPIF flag btfss INTCON,INTF ; Was this a Clk edge interupt? goto _SR_Check ; If not goto the SR input check bcf INTCON,INTF ; Clear INTF flag movlw 0x02 ; Setup W for Q=0 ^Q=1 btfsc input,5 ; Test GPIO 5 - D input movlw 0x01 ; If D = 1 setup W for Q=1 ^Q=0 ; We need to Check the R and S inputs here since even if the D ; input has changed these will force the output regardless of ; the state on the D input ; The S & R inputs are active low. To make them active High ; change the btfss instruction for a btfsc _SR_Check btfss input,3 ; Test S input movlw 0x01 ; If S = 0 setup W for Q=1 ^Q=0 btfss input,4 movlw 0x02 ; If R = 0 setup W for Q=0 ^Q=1 movwf GPIO ; write data 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. 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'00011000' ; set up W to movwf IOC ; enable Int on Change for GPIO 3,4 movlw b'00011000' ; set up W to movwf INTCON ; enable port change and edge interupts bcf OPTION_REG,INTEDG ; Interupt on falling edge on GPIO 2 ; use bsf for rising edge on GPIO 2 ;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 GPIO ; set Q=0, ^Q=1 clrf ADCON0 ; turn off A/D convertor bsf INTCON,GIE ; Enable Global Interupts ; ****************************************** ; ; 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 goto _main dt "D Type Flip Flop. Pete Griffiths, May 2004. R1.2" end