ON 20041231@8:00:15 AM at page: http://www.piclist.com/techref/member/NM-ooo-886/index.htm#38352.3335069444 Nirav Mistry[NM-ooo-886] Says
In my application I am trying to interfece a 12-bit ADC (MCP3201 to be specific) to a PIC16XXXX MCU. This ADC is SPI compatible but I do not want to use SPI becuase it is being used by an external serial EEPROM.

My question is Is it possible to use I/O ports "bit-banging" method to make the ADC function.

Following is the code that was written for MCP3201 for 8051 MCU which works. How Can I translate this code into PIC16 instruction, since it does not have instructions such as XCH A,Memory_location.

8051 based code for MCP 3201
;Assume CS,CLK,are output port bits
;data_low,data_high are memory location 30H,31H respectively
;SDATA input port bits

Get_AD: SETB CS ;set the CS high
MOV COUNTER,#15 ;initialize counter to 15

next_bit: CLR CLK ;clear the A/D clock
CLR CS ;clear CS to start A/D conversion
SET CLK ;(This is low-to-high transition for A/D clock)

MOV C,SDATA ;put the serial data of ADC into carry flag
RLC A ;Shift C into the Accumulator (A/D low bits)
XCH A,data_high ;get the data_highbyte(save low data_low for now)
RLC A ;Shift C intothe Accumulator (get A/D high bits)
XCH A,data_high ;get low bits back into Acc for next loop
DJNZ COUNTER, next_bit ;keep doing it until counter goes to zero
MOV data_low,A ;put the Accumulator into data_low
ANL data_high,#0FH ;mask of upper 4 unwanted bits X,X,X,Null
SETB CS ;Set Chip Select high

This is the code that I wrote for MCP3201 with PIC16F648. I do not know if this will work. Someone please help me on this code. I really appreciate your assistance.

;**********************************************************************
; TITLE: GET_AD
; PURPOSE: This subroutines initiates A/D conversion and retrieves
; the A/D sample into data_low and data_high.
;**********************************************************************


GET_AD bsf AD_CS ;set CS hi

movlw #15 ;number of bits to shift 12+x,x,NULL=15
movwf COUNTAD ;COUNTAD = 15
bcf STATUS,C ;C = 0
clrf data_high ;data_high = 00000000

next_bit bcf DCLK ;x,x,Null,D11,D10,D9...D0 CLEAR CLOCK
bcf AD_CS ;clear CS to start conversion CLEAR CS
bsf DCLK ;raise the clock SET CLOCK

btfsc PORTA,DOUT ;if Bit is low, skip the next instruction
bsf STATUS,C ;Otherwise set the carry bit
btfss PORTA,DOUT ;if the Bit is high skip the next instruction
bcf STATUS,C ;otherwise clear the carry bit

rlf data_high,1 ;Rotate carry into data_high, MSB first
rlf data_low,1 ;

decfsz COUNTAD,1 ;decrement counter and retain the value in counter
goto next_bit ;get the next bit
return

ON 20041231@8:01:51 AM at page: http://www.piclist.com/techref/member/NM-ooo-886/index.htm# Nirav Mistry[NM-ooo-886] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\NM-ooo-886\index.htm&version=1