; ********************************************************* ; Programmable logic element. ; ; Pete Griffiths, May 2004 ; ; The PIC reads the voltage applied to GP4 (Pin 3) immediatley after ; a reset (or power-up) and this is used to select the following functions. ; To select a new function, adjust the voltage and reset the PIC. ; ; Function ; 0 AND GP4-Vss ; 1 OR Vdd-10K-GP4-2.2K-Vss ; 2 XOR Vdd-10K-GP4-4.7K-Vss ; 3 Astable mode F Vdd-10K-GP4-8.2-Vss ; 4 NAND Vdd-6.8-GP4-10K-Vss ; 5 NOR Vdd-4.7K-GP4-10K-Vss ; 6 XNOR Vdd-2.2K-GP4-10K-Vss ; 7 Astable mode S Vdd-10K-GP4 ; ; Where the voltage applied to GP4 is found by; ((Vdd/8) x Function) + Vdd/16 ; Using a potentiometer or a pair of resistors (values shown above) the function ; can be selected and is independant of supply voltage. ; ; In Astable mode the PIC outputs a square wave. There are two Astable modes ; Fast with periods of 4mS, 10mS, 20mS and 40mS and ; slow with periods of 400mS, 1S, 2S and 4S ; The data on GPIO 0,1 is sampled each cycle and the astable period selected. ; Since this is checked each cycle, the frequency can be changed during operation. ; B A Freq' ; 0 0 1KHz, 2.5Hz ; 0 1 100Hz, 1Hz (1s) ; 1 0 50Hz, 0.5Hz (2s) ; 1 1 25Hz, 0.25Hz (4s) ; ; Inputs are applied to GP0 (Pin 7) and GP1 (Pin 6) with the logic ; function output appearing on GP2 (Pin 5) ; ; If you want an invertor just use a NAND or NOR gate with both inputs tied together. ; ; With a 4Mhz internal clock speed, instructions execute at 1Mhz, so the propogation ; delay from input change to output is of the order of 20 micro Seconds - that's not ; too impressive, but for slow clocked circuits for experimenting and teaching it ; works quite well. I put five of these togther to make a 'D' type flip flop and it ; works great. ; ; ********************************************************* ; #include "p12f675.inc" __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CPD_OFF dOuter EQU 0x20 ;delay loop working variable dInner EQU 0x21 ;delay loop working variable function EQU 0x22 ;Logic function x00 AND. x01 OR. x10 XOR 1xx = Invert output input EQU 0x23 ;Copy of GPIO output EQU 0x24 ;Temp data to output dtime EQU 0x25 ;Software delay ltime EQU 0x26 ;Software delay org 0x00 goto _main org 0x04 return ; *************************************** ; Start of the main code. Here the PIC ; peripherals and I/O are configured. ; It also gets the interbal OSC Calibration ; value and sets the OSCCAL register. ; _main bcf STATUS,RP0 ; Sel Bank 0 movlw 0x07 ; movwf CMCON ; Disable Comparator on GPIO pins movlw b'00001101' ; movwf ADCON0 ; Enable A/D for Channel 3, Left Justified bsf STATUS,RP0 ; Sel Bank 1 ; **************** ; Remove if factory setting at 0x3FF ; has been erased for any reason. ; See 12F675 manual P54 - Sec 9.2.5.1 call 0x3FF ; calls RETLW with factory setting movwf OSCCAL ; Set int OSC to factory calibrated ; **************** movlw b'01011000' ; Enable GP4 Analogue, GP0,1,2 Digital movwf ANSEL ; Disable Analogue on GPIO pins movlw b'11111011' ; Specifiy GPIO port direction movwf TRISIO ; Set GPIO ports as xxIIIOII bcf STATUS,RP0 ; Sel Bank 0 movlw 0x00 ; Initialize output movwf GPIO ; port to 0 movlw 0x10 ; Call a short call _Delay ; delay to allow voltages to settle ; ************************************** ; This part of the code reads the A/D port ; to determine what function is required. ; If you really hate the idea of using the ; A/D convertor for this job, you could ; rework the code so that GPIO 3,4 & 5 are ; used as digital inputs and then read ; the 3 bit binary value directly from these ; ports - but where's the fun in that? ; _adloop bsf ADCON0,1 ; sample the A/D input on GP4 _poll btfsc ADCON0,1 ; wait while conversion takes place goto _poll _readad movf ADRESH,W ; read in analogue data movwf function ; get Hi byte from conversion swapf function,F ; swap nibbles of Hi byte rrf function,F ; Rotate right one bit ; the lowest three bits in function ; now contain the hi three bits from ; the A/D conversion. We need it this ; way for the computed goto's later. _getinput movf GPIO,W ; Get Digital inputs movwf input ; move to temproary working register movlw 0x03 ; andwf input,F ; mask out unwanted bits, keep 2 GPIO bits and store in input call _logic ; call logic function btfsc function,2 ; test third bit of fuction for negated output xorlw 0x04 ; if set, invert the output data (e.g. AND to NAND) movwf GPIO ; and write to GPIO 3 goto _getinput ; and keep looping, sampling input and setting output ; ************************************** ; this computes a goto based on the ; value of function and then jumps to ; the required logic function. A return ; instruction in the logic function code ; itself takes us back to the original call+1 ; _logic movlw 0x03 ; Mask out all but required andwf function,W ; bits of function variable addwf PCL,F ; computed Gotos used to call the logic function ; Changing the order of the goto statments below ; affects what voltage implements what function. ; You could edit this so that you can get the ; required function by taking the Analogue input to ; Vss or Vdd, avoiding the need for any resistors. goto _and goto _or goto _xor goto _astable ; if this called, it never returns from it _and movf input,W ; And Function, takes value in input addwf PCL,F ; and computes a goto to get the output via a Return Literal retlw 0x00 ; 0 and 0 = 0 retlw 0x00 ; 0 and 1 = 0 retlw 0x00 ; 1 and 0 = 0 retlw 0x04 ; 1 and 1 = 1 ; Since the output is Bit 2 we need to return ; with this bit set. _or movf input,W ;OR function, logic as for AND addwf PCL,F retlw 0x00 retlw 0x04 retlw 0x04 retlw 0x04 _xor movf input,W ;XOR function, logic as for AND addwf PCL,F retlw 0x00 retlw 0x04 retlw 0x04 retlw 0x00 ; ******************************************** ; Square wave output routine. ; Operates at either ~1Hz, or ~0.5Hz depending on bit 2 ; of function variable ; _astable clrf output ; clear output _swloop movf GPIO,W ; Read data on inputs A and B andlw 0x03 ; Mask out upper 6 bits call _delay_lookup btfsc function,2 ; test for function bit 2 clear call _LDelay ; call delay in 100mS btfss function,2 ; test for function bit 2 set call _Delay ; call delay in 1mS comf output,F ; toggle bits in output movf output,W ; put result in W movwf GPIO ; write to GPIO port goto _swloop _delay_lookup addwf PCL,F retlw d'2' ; mS / mS x 100 retlw d'5' ; mS / mS x 100 retlw d'10' ; mS / mS x 100 retlw d'20' ; mS / mS x 100 ; ******************************************** ; SUBROUTINE ; Delay loop _Delay movwf dtime ; Call for W x 1mS __Dcall call __1mS decfsz dtime,F goto __Dcall __DlyEnd return _LDelay movwf ltime ; Call for W x 100mS __Dlcall movlw d'100' call _Delay decfsz ltime,F goto __Dlcall return __1mS movlw 0xC6 _next nop addlw 0xFF btfss STATUS,Z goto _next nop nop nop return dt "Pete Griffiths 2004 - R310504.01" end