PDA

View Full Version : I2C eeprom and DS1307 @40MHz problem



ius01
- 12th July 2007, 05:17
Ok heres my setup,

320x240 graphics lcd
24lc512 eeprom
ds1307 rtc
pic18f6585 @ 40MHz

my problem is when i read at normal speed off the i2c bus the eeprom works fine, the ds1307 only works when i run the i2c bus at 100KHz (DEFINE I2C_SLOW 1).

the define cannot be changed throughout the program, so i am forced to read the i2c bus at slow speed, i need high speed. i have 4.7k pullups.

Has anyone had problems reading the rtc @ 40MHz?

i am considering writing my own subroutines to read the rtc so it doesnt interfere with my i2c statements.

DynamoBen
- 14th July 2007, 16:36
My most recent project used the DS1307. If you take a peek at the datasheet for the RTC it does state that you have to communicate at the lower speed. Looks like you are stuck unless you want to try to switch speeds or burn up more pins by moving it to its own buss.

ius01
- 18th July 2007, 03:04
I fixed the problem, heres how i did it.

I wrote my own Read I2C and Write I2C routines using LOW Sda and High Scl and SHIFTIN and SHIFTOUT commands with delays to clock at 100KHz.

please post if you want the code.

Bruce
- 18th July 2007, 19:48
I wouldn't mind seeing what you came up with.

P.S. Excellent website you have there.

Charles Linquis
- 19th July 2007, 01:20
I'm interested in seeing your code as well.

Steve_88
- 19th July 2007, 02:44
I'm fairly sure there was an article in nuts & volts describing the interfacing of a BSII to a DS1307 a while back using shiftin/shiftout

ius01
- 19th July 2007, 06:49
This is my code, please be aware that it drives a graphic lcd, has eeproms and also drives a touchscreen, it is still full of bugs.

But the Readtime, and Writetime commands work, please be aware that there isnt many comments because of the size of the program.

Please refer to the datasheet for reading and writing to the current addresses to the DS1307.

Ioannis
- 19th July 2007, 07:18
I have not checked the whole program, but as a start I recommend to change every command that access port pins from pinXXX=1 to HIGH pinXXX and respectively for the =0 to LOW pinXXX.

I used to reserve some bytes the way you did it but this method does not take into account the memory page issues of the PIC. So if you are sure the program is just short enough to fit in the first page do it. Otherwise, let the compiler take care of the issue.

Ioannis

Bruce
- 19th July 2007, 15:12
PBP uses macros to set the correct register bank when you use pinxx=0,
pinxx=1, etc, so bank switching shouldn't be an issue, but read-modify-write
can cause you a lot of headaches.

If you have pinxx=0, pinxx=1, etc, in a row, then you'll have problems with
read-modify-write. Especially running at higher oscillator speeds like 40MHz.

If you change pin aliases from say pinCS var PORTC.4 to pinCS var LATC.4
that will help eliminate r-m-w glitches for the 18F series.

Example from your code;

Pin aliases
ctrlA VAR PORTC.0
ctrlB VAR PORTC.1
ctrlC VAR PORTC.2
ctrlD VAR PORTC.3

Then farther down you set/clear portc pins in succession;
ctrlA = 1
ctrlB = 0
ctrlC = 1
ctrlD = 0

This uses bsf and bcf on port pins, and can definitely cause you grief with
read-modify-write.

If you change your pin aliases to point to LAT registers, you should never
have problems with read-modify-write.

ctrlA VAR LATC.0
ctrlB VAR LATC.1
ctrlC VAR LATC.2
ctrlD VAR LATC.3

Then it will set/clear portc LAT pins, and not read the port first, modify the
value, and write it back. This writes to port latch registers VS directly to the
port pins. Just be sure you setup TRIS registers first.

So this is now OK to do without read-modify-write issues;
ctrlA = 1
ctrlB = 0
ctrlC = 1
ctrlD = 0

If you use HIGH & LOW commands, PBP inserts a ton of extra code, so this
can definitely save on code space. If you do use HIGH & LOW, then do NOT
use HIGH or LOW commands with LAT registers.

PBP uses an offset (from the port register physical address) to figure out
where the TRIS register is, and it doesn't point to the TRIS reg if you use
HIGH & LOW commands with LAT registers.

So stuff like HIGH LATC.4 or HIGH pinCS (if it's aliased pinCS var LATC.4) is
not a good idea. It's not going to automatically make the pin an output by
clearing TRISC.4, and it's going to clear some other register bit at the wrong
offset address.

Places where you have stuff like this;
PORTG.0 = 0
PORTG.1 = 0
PORTG.2 = 0, etc, I would also change to LATG.0=0, LATG.1=0, etc, but only
if I couldn't just write directly to the whole port at once with PORTG = ?.

On 14-bit core, if you need to write to port pins in succession, you're almost
always better off using HIGH pin.x, LOW pin.x, etc, since you don't have LAT
registers on these, and the additional code inserted helps eliminate r-m-w
glitches.

Ioannis
- 20th July 2007, 07:41
Sorry, I did not see that this was about 18F series.

I just expressed my experience on 16F PIC's using directly pin control.

Well descibed Bruce!

Ioannis