Help with receiving ACK from slave on i2c bus.

Status
Not open for further replies.
I am not recieving an ACK. Wen I check the carry bit after that routine, it is clear. SO it is sending a NACK.

Which is the 4th pin on the chip tied to Vdd... I have Vdd, IO Vdd and I have the ADDR bit tied to GND (selecting the slave address, I could choose Vdd if I wanted to). I have the Interrupt (pin 7) floating?
 
NOTE: The SDA and SCL Lines ar pulled high by IO vdd by the eval board I'm using from Kionix. Attached is the schematic.
 
According to the data sheet pins 3, 7, 10 & 11 are all Vdd pins and pins 6, 8 & 9 are GND pins.

Do you have a local shop where you could buy a 24LC16 serial EEPROM? They only cost $0.25 from Microchip so shouldn't be too expensive in a retailer.

Edit, see attached.

Mike.
 
Last edited:
Yes, I have all Vdds and ground tied correctly. I need to buy a few things anyway so I will get a few 24LC16s as well and have them shipped fast. I assume you are familiar with this chip and want to ensure my code works with this?

How about the clock pulse delays in my code? if the max i2c rate is 400khz, I would assume the delays are OK?
 
Yes, I'm familiar with that chip and have one on hand that I can hook up to a pic for testing.

I didn't bother checking your delays as the chip you're talking to can run at >3MHz. I did notice you had remove a delay from the receive routine, that is needed.

Mike.
 
I just put some EEPROMs on order. It will likely be a few days at least. I am using the 32kHz internal clock...that is fine?
 
Mike; When I use your I2cInit routine before I do the start command, the bus is not fixed and keeps pulsing the SCL (while looking for SDA to go high). However On my scope, I do see the SDA line High?

Any thoughts?
 
Hi Mike, Without using your i2cInit routine, my code goes into an infinite loop while checking for clock stretching during the ACK. It does not even get to the point where it checks for low SDA.

Any thoughts on this? I stripped my code for easier troubleshoot. I have tried 3 different Evaluation boards...

Thanks Again
Steve




Code:
;.......................................................................................................................
;.......................................................................................................................
;Call proper header, include and source files to initialize PIC
 	LIST  		p=16F684    ; Tells Assembler what PIC is used
 	#INCLUDE	<p16f684.inc>    ; Includes factory defaults for the PIC
;.......................................................................................................................
;Configure PIC optional properties
 __CONFIG     _WDT_OFF & _MCLRE_OFF ; Enables CLKOUT, WDT, and Digital I/O on MCLR/RA3 
;.......................................................................................................................
 ;errorlevel -302, -207, -305	
;.......................................................................................................................
;.......................................................................................................................
;Define Constant Working Register Variables 
	cblock 0x20
	i2c_transmit_byte
	i2c_bit_counter
	pw_counter
	pw_counter1
	wait_startup_counter
	Received_I2C_Byte
	transmit_byte_rs232
	bit_counter_rs232
	delay_counter
	endc
;.......................................................................................................................
;.......................................................................................................................
;Define Global Deifnitions:	
I2C_PORT	equ		PORTC
I2C_TRIS	equ		TRISC

#define		SDA	 	0
#define		SCL 	1	
;.......................................................................................................................
;.......................................................................................................................
START_PROGRAM
;Initialize Inputs/Outputs, and Registers on the PIC16F684.
;Initialize TRISA and TRISB registers. 
 	bsf 	STATUS, RP0			;Bank 1
 	movlw 	b'00000011'		 
 	movwf 	TRISC				;Assigns SDA and SCL Inputs.
 	movlw	b'00000000'		
	movwf	TRISA				;Assigns all TRISA as outputs. 
	movlw	0x03
	movwf	OSCCON				;Loads internal 31.25kHz clock
	bcf		STATUS, RP0			;Bank 0
;......................................................................................................................
;.......................................................................................................................
;READ Register from Kionix KXTJ9 accelerometer -- WHO_AM_I Register located at 0x0F

	call	Clock_Pulse_Delay
	call	Clock_Pulse_Delay
	call	Clock_Pulse_Delay	;Startup Delay


	call	Start_Command		;Start Command	
	call	SAD_W				;Address Slave plus write
	call	ACK					;Get Acknowledge from slave

	btfss	STATUS, C
	goto	$-2
	
;TEST
	bsf		PORTC, 3
done
	goto	done



	goto	START_PROGRAM


;---------------------------------------------------------------------------------------
;Sub Routines for PIC
;---------------------------------------------------------------------------------------
;i2c Routines
;----------------------------------
Start_Command
	call	Set_SCL_High
	call	Set_SDA_High
	call	Clock_Pulse_Delay
	call	Set_SDA_Low
	call	Clock_Pulse_Delay			;(S) - Sets SDA low while SCL is high
	return
;----------------------------------
SAD_W
	movlw	0x1C
	call	Send_i2c_Byte				;(SAD+W) Slave Address plus write.
	return
;----------------------------------
ACK
	call	Set_SCL_High
	call	Set_SDA_High				;Release SCL and SDA
Clock_Stretch
	btfss	I2C_PORT, SCL
	goto	Clock_Stretch				;Wait for slave to release clock line
	call	Clock_Pulse_Delay
	bcf		STATUS, C
	call	Clock_Pulse_Delay
	call	Clock_Pulse_Delay
	btfsc	I2C_PORT, SDA
	return								;Clear carry for NACK
	bsf		STATUS, C					;Set carry for ACK
	return
;----------------------------------

;Send i2c Byte:
Send_i2c_Byte
	movwf	i2c_transmit_byte
	movlw	0x08	
	movwf	i2c_bit_counter
Send_i2c_Bit
	call	Set_SCL_Low
	call	Clock_Pulse_Delay
	rlf		i2c_transmit_byte, f		;MSB is now in carry
	btfsc	STATUS, C
	call	Set_SDA_High
	btfss	STATUS, C
	call	Set_SDA_Low
	call	Clock_Pulse_Delay
	call	Set_SCL_High
 	call	Clock_Pulse_Delay
	decfsz	i2c_bit_counter, f
	goto	Send_i2c_Bit
	call	Set_SCL_Low
	call	Clock_Pulse_Delay
	return
;-------------------------------------	
	

;Routines to Set SDA and SCL High/Low
Set_SCL_High
	bsf		STATUS, RP0				;Bank 1
	bsf		I2C_TRIS, SCL			;Sets SCL as an input
	bcf		STATUS, RP0				;Bank 0	
	return

Set_SCL_Low
	bcf		I2C_PORT, SCL			;Sets SCL port pin low
	bsf		STATUS, RP0				;Bank 1
	bcf		I2C_TRIS, SCL			;Sets SCL as an output
	bcf		STATUS, RP0				;Bank 0
	return	

Set_SDA_High
	bsf		STATUS, RP0				;Bank 1
	bsf		I2C_TRIS, SDA			;Sets SDA as an input (high impedance)
	bcf		STATUS, RP0				;Bank 0
	return

Set_SDA_Low
	bcf		I2C_PORT, SDA			;Sets SDA port pin low
	bsf		STATUS, RP0				;Bank 1
	bcf		I2C_TRIS, SDA			;Sets SDA as an output
	bcf		STATUS, RP0				;Bank 0
	return	

;---------------------------------------------------------------------------------------
;---------------------------------------------------------------------------------------
;Delays
Clock_Pulse_Delay
	movlw	0xFF
	movwf	pw_counter
Clock_Pulse_Delay_Wait
	nop
	movlw	0x03
	movwf	pw_counter1
Clock_Pulse_Delay_Wait1
	decfsz	pw_counter1, f
	goto	Clock_Pulse_Delay_Wait1
	decfsz	pw_counter, f
	goto	Clock_Pulse_Delay_Wait
	return

I2cInit	
	bcf		PORTC,SCL
	bcf		PORTC,SDA
	bsf		STATUS,RP0	;1
	bsf		TRISC,SCL
	bsf		TRISC,SDA
	bcf		STATUS,RP0
ClockLoop
	btfsc	PORTC,SDA
;	goto	BusFixed
	bcf		PORTC,SCL
	bsf		STATUS,RP0
	bcf		TRISC,SCL
	goto	$+1
	bsf		TRISC,SCL
	bcf		STATUS,RP0
	goto	ClockLoop


	end
 
If that is the case then something other than the pic is holding the clock line low. I have no idea what would cause that.

Mike.
 
Extremely odd because I can see the SCL line go high on my oscilliscope during that routine. It makes me think it is still something with the code. I should be in bank 0 for all of the communication right? The only time I should be in bank 1 is to set the TRIS ports?

Steve
 
Mik; I found something interesting; When I disconnect the accelerometer from the circuit during the issue I have, both the SCL and SDA lines go low. When the accelrometer is connect, both lines are high..

Any thoughts here?
 
How can they be low? The pins should both be input and the pullups should pull them high. Something is wrong with the hardware.

Mike.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…