Hi
please help!
I have a small problem with i2c bus,I am using 12c508 pin 7 for data and pin
3 for clock (internal clock,masterclear off )
the i2c device is standard < startbit/address/data/stopbit >
The code will work fine if I have my scope lead connected to data line(pin
4) ,I think this is adding capacitance to this line
so i removed the scope lead and fitted 33pf capacitor between the data pin
and ground, this also worked fine
But if I remove the cap the pic 12c508 wont talk to the i2c device ..
I have also moved the data and clock to other pins on pic but have the same
problem.
I also tried to slow down the rate the pic sends data to i2c device still no
good..
The code I am using, is one I have used many times to talk to other i2c
devices
but on this device I am having no joy.
the device has pull up10k resistors on data and clock lines
Can anyone help??
any help will be greatly appreciated
many thanks
Tom
What device are you trying to talk to?
Is there a chance that it doesn't ACK on address and the device in your
prior application did? If the last bit of the address sent is low then the
capacitor would keep the data line low long enough for your code to think it
received an ACK and keep going. Without the cap, your code sees no ACK and
stops. Just a hunch. Seeing your code and knowing what device you are
trying to talk to would help.
Hi Ken
Thhe device is sending ack,but all i am doing for this is wasting one clock
pulse
so my code cant hang there.And infact when i use my emulator i can see that
the code is flowing fine .
here is the output code
DATOUT_
CLRF COUNT1
MOVLW .8
MOVWF COUNT1 ;this is the sub that i use to send out
the 8 bits of data and the ack wast clock pulse
LOOP1_ ;sclk is i2cbus clock and
sdata is i2c bus data
BCF SCLK
BCF SDATA
RLF TXBUF ;SENDS DATA TO EEPROM
BTFSC C
BSF SDATA
NOP
NOP
NOP
NOP
BSF SCLK
NOP
NOP
NOP
NOP
NOP
BCF SCLK
NOP
NOP
NOP
NOP
DECFSZ COUNT1
GOTO LOOP1_
CLRF TXBUF
BSF SCLK
NOP
NOP
NOP
BCF SCLK
RETURN
Are you operating at a faster speed than you have in the past?
If so try putting a NOP between any 2 writes to the port.
Example:
sdata is i2c bus data
BCF SCLK
nop ; ADD to make sure port is correct.
BCF SDATA
On Tue, Jan 11, 2000 at 06:48:54PM -0000, dvdmods wrote:
> The code will work fine if I have my scope lead connected to data line(pin
> 4) ,I think this is adding capacitance to this line
Do you have _MCLR_OFF in your __CONFIG? Just checking.
I don't immediately see anything wrong other than the back-to-back BCF's
mentioned by Giles. These should definitely be avoided at high clock speeds
yet this doesn't seem to explain your original observation that it DOES work
with added capacitance on the SDATA line and not with the capacitance
removed.
I would be interested in seeing the code that generates the start condition
and the stop condition.
Ken
>DATOUT_
> CLRF COUNT1
> MOVLW .8
> MOVWF COUNT1 ;this is the sub that i use to send
out {Quote hidden}
>the 8 bits of data and the ack wast clock pulse
> LOOP1_ ;sclk is i2cbus clock and
>sdata is i2c bus data
> BCF SCLK
> BCF SDATA
> RLF TXBUF ;SENDS DATA TO EEPROM
> BTFSC C
> BSF SDATA
> NOP
> NOP
> NOP
> NOP
> BSF SCLK
> NOP
> NOP
> NOP
> NOP
> NOP
> BCF SCLK
> NOP
> NOP
> NOP
> NOP
> DECFSZ COUNT1
> GOTO LOOP1_
> CLRF TXBUF
> BSF SCLK
> NOP
> NOP
> NOP
> BCF SCLK
> RETURN
The scope adds capacitance.
That menas the waveform will be skewed.
Translated that, I believe, causes the signal
to "strech" or causes the period to change.
You may try to slow that signal down some.
Or perhaps there is a rise time issue.
Maybe you can use a better probe and see
what happens.
I'd be interested in the wiring and grounding.........LOTS of projects
don't work because of that. I use 1/2" copper tape or a solid ground
plane to bread board things. I even got a promotion once for fixing an
'engineer's' design that used 3/32 ground RUNS to a 10 Mhz disk drive
head amplifier design.
--
________________________________________________________________
Dennis K. Gearon (Kegley)
Scientific Instrument Technician, School of EIT
Oregon Institute of Technology - One of USA's 100 Best College Buys
3201 Campus Drive
Klamath Falls, OR 97601
Voice 1-541-885-1563
FAX 1-541-885-1689
email .....gearondKILLspam@spam@oit.edu
I am here only to be truly helpful
________________________________________________________________
Thankx to all that are looking at this problem
Speed........ Is there any way i can make the pic clock through the code
slower, but still use the internal 4mhz osc
and change this speed half way into my programme?( i dont think its
possible)
Good piont about the back to back bcf`s they now have 2 nops in-between
here is the start and stop code ect
I have never tried this, but how about using the TMR0 interupt. Have it
'burn' a few cycles then return on every instruction cycle (if you are not
using it). Then, when you want to go slow, just enable it, disable to
resume normal speed.
Sounds goofy and alot of good clock cycles will just go down the drain, but
what the heck, try it and let me know if it worked.
TAS
At 07:30 PM 1/12/2000 -0000, dvdmods wrote: {Quote hidden}
>i2c probem stil>>>>>
>
>Thankx to all that are looking at this problem
>Speed........ Is there any way i can make the pic clock through the code
>slower, but still use the internal 4mhz osc
>and change this speed half way into my programme?( i dont think its
>possible)
>Good piont about the back to back bcf`s they now have 2 nops in-between
>here is the start and stop code ect
>
>BSTART_
> CLRF GPIO
> MOVLW B'00101110'
> TRIS GPIO
> BCF SCLK
> BCF SDATA
> NOP
> NOP
> NOP
> NOP
> BSF SDATA
> NOP
> NOP
> NOP
> NOP
> BSF SCLK
> NOP
> NOP
> NOP
> NOP
> BCF SDATA
> NOP
> NOP
> NOP
> NOP
> BCF SCLK
> NOP
> NOP
> NOP
> NOP
> RETLW 0
>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>BSTOP
> MOVLW B'00101110' (loooking at my code i cant remember why i have
>this here)
> TRIS GPIO
> BCF SCLK
> BCF SDATA
> NOP
> NOP
> NOP
> BSF SCLK
> NOP
> NOP
> NOP
> NOP
> BSF SDATA
> NOP
> NOP
> NOP
> NOP
> BCF SCLK
> NOP
> NOP
> NOP
> BCF SDATA
> NOP
> NOP
> NOP
> RETLW 0
>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>DATAOUT_
> CLRF COUNT
> MOVLW .8
> MOVWF COUNT
> LOOP3_
> BCF SCLK
> NOP
> NOP
> BCF SDATA
> NOP
> RLF TXBUF
> BTFSC C
> BSF SDATA
> NOP
> NOP
> BSF SCLK
> NOP
> NOP
> BCF SCLK
> NOP
> NOP
> DECFSZ COUNT
> GOTO LOOP3_
> CLRF TXBUF
> BSF SCLK
> NOP
> NOP
> BCF SCLK
> RETURN
>
>
-----------------------------------------------------------------
Sent from the desk of:
Terry Allen Steen, EE engineeringKILLspammarinapower.com
332 McLaws Circle, Ste 111 757-258-8800 (Voice)
Williamsburg, Va 23185 757-258-8805 (FAX)
-----------------------------------------------------------------
!I AM A WHALE MAIL USER! If you have a large file to send, goto http://www.whalemail.com send them to: mplengineer
Give me your account and I will use it also
-----------------------------------------------------------------
Visit our web-site: http://www.marinapower.com
-----------------------------------------------------------------
After watching this thread for a while, it occurs to me that a scope lead or
cap could possibly change the signal level just a bit in addition to
delaying it as has been suggested. Have you tried biasing the signal up or
down with a very large resister?
>i2c probem stil>>>>>
>
>Thankx to all that are looking at this problem
>Speed........ Is there any way i can make the pic clock through the code
>slower, but still use the internal 4mhz osc
>and change this speed half way into my programme?( i dont think its
>possible)
No, but, if you have stack space free you could make a delay subroutine ...
something like:
Then call it before toggling the clock line .. i.e. replace:
BSF SCLK
NOP
NOP
NOP
NOP
NOP
NOP
BCF SCLK
with:
BSF SCLK
CALL DELAY
BCF SCLK
As for your code .. it appears to be generating the start and stop
conditions correctly but one thing it does that is a little odd is leave the
clock and data lines low by default. I don't think that this will cause any
problems (Microchip's literature doesn't say anything about what goes on
inbetween a stop condition and the next start condition so I assume that
clock cycles occuring in this interval are ignored) but it will cause your
circuit to draw more current if you are using a typical I2C bus with
external pullup resistors. Leaving these lines high inbetween operations is
typical. Are you using pullup resistors? If so, what size?
Another thing .. are the pins you are using (particularly for the SDATA)
open-drain outputs? If not, you should change the code at the bottom of the
data output loop from:
> GOTO LOOP3_
> CLRF TXBUF
> BSF SCLK
> NOP
> NOP
> BCF SCLK
> RETURN
To:
GOTO LOOP3_
CLRF TXBUF
BSF SCLK
NOP
NOP
BCF SCLK
NOP
BCF SDATA ;Make sure SDATA is low so ACK doesn't collide
RETURN
This will prevent high currents from flowing when the EEPROM is driving
SDATA low for an ACK and the PIC is driving it high because the last bit
clocked out was high. Note that a collision will still occur for a coupple
of microseconds but this is better than leaving this condition for a longer
period of time.
Ideally, you should use the external pullup resistors (or at least the one
on the SDATA line) and toggle the line(s) by toggling the bit in the TRIS
register instead of the bit in the PORT register -- set the bit in the PORT
register low so that when the TRIS bit is low the line is driven low and
when the TRIS bit is high the line is not driven and is pulled high by the
resistor unless it is being pulled low by the EEPROM.
(ignore the above if the line you are using is an open-drain output)
One final note, the sequence:
> BSF SCLK
> NOP
> NOP
> BCF SCLK
will violate the timing requirements of many EEPROMS if your PIC is using a
4MHz clock. Insert at least one additional NOP unless you have a fast
EEPROM.
Other than these recommendations I see nothing wrong. I'm still not sure
why adding capacitance should make it work unless the start condition setup
time of your EEPROM is greater than 5 microseconds. If so, change:
> BSF SCLK
> NOP
> NOP
> NOP
> NOP
> BCF SDATA
To include at least one additional NOP (or call the DELAY subroutine I
suggested). If your EEPROM is slow, you should probably increase all of the
delays a bit just to provide a little extra margin.
Uck! This is *not* how you do it, at least according to the IÓC
specs. You clear both SDATA and SCLK in the initialisation code and
*never* alter them again.
Now, you should have four macros defined called something like DLOKLO,
DHIKHI, DLOKHI and DHIKLO or such, each based on the construct:
DHIKHI macro
MOVLW B'00101110'
TRIS GPIO
GOTO $+1
endm
I've not specified the others because I don't happen to know which of
your bits are SDATA and SCLK, but you'll figure that. Significant
points:
1} GOTO $+1 is two NOP (cycle) delays but takes only one instruction.
Repeat as necessary to obtain desired delay.
2} Using MOVLW plus TRIS takes two cycles anyway, you didn't want to
do it any faster anyway, so it's as efficient as it gets. It avoids
spurious setting of bits for three reasons; firstly it sets bits
*explicitly*, not dependent on their current states, secondly it uses
the TRIS bits which theoretically should not be easily "glitched" by
port status and thirdly, it is two instructions and allows settling time
anyway.
3} The standard defines open-collector; this does it.
I'm just re-inforcing Ken Webster's comments really.
--
Cheers,
Paul B.
> Paul B. Webster wrote:
>
> >DHIKHI macro
> > MOVLW B'00101110'
> > TRIS GPIO
> > GOTO $+1
> > endm
>
>
> Slick! I like that. Especially the GOTO $+1 trick. Good call! Now I may
> have to go back and update some of my old libraries.
and if you want a 4-cycle single-instruction delay:
call some_return_in_your_code
Of course, you run the risk of stack overflow on a 12c50x part.
> and if you want a 4-cycle single-instruction delay:
>
> call some_return_in_your_code
>
> Of course, you run the risk of stack overflow on a 12c50x part.
I had to use something similar once when I had no room whatsoever to
create a delay of about 5 or 6 instructions. I was lucky enough to be
able to CALL the last part of a subroutine because those instructions
did not upset anything.