Here is a driver written in assembly for the MCP3204 or MCP3208 12 bit A/D converter.
I've included the PBP defines to use it with the 16F628 and can be dropped in your program exactly as shown.
It will scan through the inputs and store the results in an array.
Code:'************************************************************************************ '* The following must be defined in PBP (PIC16F628) Fuses are example only. '*************************************** FUSES *********************************** @ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _LVP_OFF & _CP_OFF '************************************************************************************ TRISA=%00110000 'PortA data direction. 1=Input, 0=Output. Default is all inputs TRISB=%11100010 'PortB data direction. 1=Input, 0=Output. Default is all inputs CMCON=7 'Turn off analog comparators DEFINE OSC 4 '4 MHz oscillator PAUSE 100 'Wait .1 second '************************************************************************************ ADCE VAR PORTB.3 'A/D Chip enable Output AH VAR BYTE 'Input = Channel select, Output High byte conversion AL VAR BYTE 'Output Low byte conversion CLK VAR PORTB.0 'Clock pin -> Output DATAOUT VAR PORTB.1 'IO -> Processor <-Input DATAIN VAR PORTB.2 'Processor -> IO ->Output RESULT VAR WORD[8] '8 position array. Change to suit your needs SPI_CNT VAR BYTE 'Bit count for SPI ->Output Temp VAR WORD 'Temporary storage a/d readings '*********************************** MAIN PROGRAM *************************** MAIN: J=0 'Clear counter For J=0 to 3 'Loop through 4 inputs. Change to suit your needs AH=J 'Select channel GOSUB MCP3204 'Get A/D data Temp.highbyte=ah 'Add High byte to Temp Temp.lowbyte=al 'Add Low byte to Temp RESULT[J]=Temp 'Store in array NEXT J GOSUB Somewhere and do stuff with RESULT[x] GOTO MAIN END '*********************************** ASM Routine ******************************** MCP3204: ASM swapf _AH,f ;Channel select to high nibble bsf _AH,7 ;Set for single ended rrf _AH,f ;Position channel select for device bsf _AH,7 ;Set start bit bcf _ADCE ;Enable device movlw _AH ;Point to channel select in AH movwf FSR ; / movlw 5 ;send out 5 bits movwf _SPI_CNT call doutw ; / movlw 6 ;read 6 bits movwf _SPI_CNT call dinw ;Null bit + upper 4 bits of data to AH movlw _AL ;Point to AL to read lower 8 bits of data movwf FSR ; / call din8 ; / movlw 0x0f ;Mask out upper 4 bits of AH andwf _AH,f ; / bsf _ADCE ;Disable device goto Done ; doutw movwf _SPI_CNT ; dout bcf _DATAIN ;Assume that the bit to be transfered is a ;'0'. Hence, de-assert DATAIN. rlf INDF, F ;Rotate the actual bit to be transferred into ;the carry bit. btfsc STATUS,C ;Test the carry, if our assumption was ;correct, skip the next instruction. bsf _DATAIN ;No, actual bit was a '1'. Assert DATAIN. bsf _CLK ;Clock (CLK) = '1'. nop ;Adjust the number of nop instructions ;between the assertion and de-assertion of ;CLK in proportion to the PIC operating ;frequency. bcf CLK ;Clock (CLK) = '0'. decfsz _SPI_CNT, F ;Repeat until cnt = 0. goto dout ;Cnt still > 0. rlf INDF, F ;Restore register to its original condition. bcf _DATAIN ;make sure DATAIN is low return ; din8 movlw 8 ;Initialize loop counter. dinw movwf _SPI_CNT ; din bcf STATUS,C ;assume data zero btfsc _DATAOUT ;test DATAOUT for zero bsf STATUS,C ;if not zero set carry rlf INDF, F ;rotate data bsf _CLK ;Clock (CLK) = '1'. nop ;Adjust the number of nop instructions ;between the assertion and de-assertion of ;CLK in proportion to the PIC operating ;frequency.. bcf _CLK ;Clock (CLK) = '0'. decfsz _SPI_CNT, F ;Repeat until cnt = 0. goto din ;Cnt still > 0. return Done nop Endasm RETURN




Bookmarks