PDA

View Full Version : DS1307 not running?



Sabahan
- 30th May 2014, 11:04
I had try to use a DS1307 on my recent project to keep track of the time,but seems the device is not working,it keep give me value for all return,below is my detup and my code

MCU : PIC16F877A
RTC : DS1307 with 32.768 KHz Crystal
Crystal : 4Mhz
others : Bat termial of DS1307 is grounded
Pull up resistor is connected to SDA and SCL

the code

'************************************************* ***************
'* Name : UNTITLED.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 29/05/2014 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************

' Name : RTCXU.pbp
' Compiler : PICBASIC PRO Compiler 2.6
' Assembler : MPASM
' Target PIC : PIC16F877A or similar type
' Hardware :
' Oscillator : 4MHz external
' Keywords : I2CREAD, I2CWRITE, LCDOUT
' Description : PICBASIC PRO program for an LCD clock program
' using the Dallas DS1307 I2C RTC.
'

' Define LOADER_USED to allow use of the boot loader.
' This will not affect normal program operation.
' Define LOADER_USED 1

' RESET_ORG can be set to move the BASIC program out of the way
' of any boot loader running from location 0, such as the
' Microchip USB boot loader
'Define RESET_ORG 800h
TRISD = %00000000
TRISC = %00000000

Define OSC 4 ' Core is running at 4MHz

' Define LCD pins
DEFINE LCD_DREG PORTD
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTD
DEFINE LCD_RSBIT 1
DEFINE LCD_EREG PORTD
DEFINE LCD_EBIT 0
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
' Alias pins
SDA Var PORTC.0
SCL Var PORTC.1

' Allocate variables
RTCYear Var Byte
RTCMonth Var Byte
RTCDate Var Byte
RTCDay Var Byte
RTCHour Var Byte
RTCMin Var Byte
RTCSec Var Byte
RTCCtrl Var Byte

ADCON1 = 15 ' PORTA and E digital
Low PORTE.2 ' LCD R/W low = write
Pause 100 ' Wait for LCD to startup

' Set initial time to 8:00:00AM 06/21/05
RTCYear = $05
RTCMonth = $06
RTCDate = $21
RTCDay = $02
RTCHour = $08
RTCMin = 0
RTCSec = 0
RTCCtrl = 0
Gosub settime ' Set the time
Goto mainloop ' Skip over subroutines

' Subroutine to write time to RTC
settime:
I2CWrite SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
Return

' Subroutine to read time from RTC
gettime:
I2CRead SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
Return

' Main program loop - in this case, it only updates the LCD with the time
mainloop:
Gosub gettime ' Read the time from the RTC

' Display time on LCD
Lcdout $fe, 1, hex2 RTCMonth, "/", hex2 RTCDate, "/" , hex2 RTCYear
lcdout $fe,$c0,hex2 RTCHour, ":", hex2 RTCMin, ":", hex2 RTCSec

Pause 500 ' Do it about 2 times a second
Goto mainloop ' Do it forever

End


Can anyone please pointing out what have I done wrong?

EarlyBird2
- 30th May 2014, 11:39
Check the data sheet which says -

The slave address byte contains the 7-bit DS1307 address, which is 1101000, followed by the direction bit (R/W), which for a write is 0.

so
I2CRead SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]

should be

I2CRead SDA, SCL, $D0, $D0, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]

and read

I2CRead SDA, SCL, $D0, $D1, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]

obviously you need to sort out the control as you are using $D0 for that? Which if you are not using SQWO $00 I think.

Sabahan
- 30th May 2014, 13:35
Thank you,I will try it out,and yes,I let the SQWO float

richard
- 30th May 2014, 14:03
not sure what version of pbp you are using but you could try
DEFINE I2C_SLOW 1


your original CODE LOOKS PRETTY GOOD TO ME

I2CWrite SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
I2CWrite SDA, SCL, $D0, 0, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear] would do

Return

' Subroutine to read time from RTC
gettime:
I2CRead SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
I2CRead SDA, SCL, $D0, 0, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear] would do
Return

sometime the rtc osc needs a wake up
i2cwrite sda,scl,$D0,0,[%10000000] ' FORCE CLK OSC TO START st bit
i2cwrite sda,scl,$D0,0,[0] ' FORCE CLK OSC TO START

if you don't have a battery on the 1307 the vbatt pin nees to be grounded , if left floating the chip can be difficult

ps this is for pbp 3 not sure about earlier verrsions

EarlyBird2
- 30th May 2014, 14:21
Richard,

The control and Address are wrong in the I2C instructions. Control should be $0 if not using the SQWO. The address should be $D0 for write and $D1 for read. Or that is the way I interpret the data sheet.

richard
- 30th May 2014, 14:39
the ds1307 has 8 registers for the rtc function addressed from 0 to 0x07
the control reg address is 0x07 bits 7 and 4 control the sqwe , if you only use the time keeping function the control reg can be ignored
to set the time you start at register address 0 (sec min hours ......)
to read just minutes start from address 1 etc
pbp will set bit 0 of the device address ($d0 in this case) as required (at least pbp3 will not sure about pbp2xx)

the ram goes from 0x08 to 0x3f trying to write or read from regs $d0 or $d1 will not have meaning full results

EarlyBird2
- 30th May 2014, 15:03
Richard,

Now I understand the datasheet refers to the control as address, how confusing. I did not realise that the eighth bit is added automatically.

Thanks for that.

EarlyBird2
- 30th May 2014, 15:25
Having read the data sheet again I found this near the end

7359

How confusing that makes us both wrong. I must learn to read the whole data sheet in future.

EarlyBird2
- 30th May 2014, 15:45
Check this link

http://www.picbasic.co.uk/forum/showthread.php?t=12671

richard
- 30th May 2014, 16:27
I will say again pbp will set bit 0 of the i2c device address as required
by running :-
I2CRead SDA, SCL, $D0, 0, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear]

it will write 0 to the control address logic of the 1307 and then read 7 bytes
try it !

EarlyBird2
- 30th May 2014, 17:28
I will say again pbp will set bit 0 of the i2c device address as required
by running :-
I2CRead SDA, SCL, $D0, 0, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear]

it will write 0 to the control address logic of the 1307 and then read 7 bytes
try it !

$D0 is write

I2CRead SDA, SCL, $D1, 0, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear]

Is read according to the data sheet and the example in #9.

Interestingly the data sheet extract shown in #8 says to do

I2CWrite SDA, SCL, $D0, 0

reset the write pointer then

I2CRead SDA, SCL, $D1, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear]

to read the time.

But the example code in #9 works by using

I2CRead SDA, SCL, $D1, 0, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear]

So I am curious to find out from Sabahan what works in his case.

Sabahan
- 31st May 2014, 01:24
After I post this question here ,I retry my setup and it start functioning,I had not change anything,the unsuccessful attempt maybe due to the ripple from my power supply,I had added two filter capacitor to the setup,the earlier setup may have cause the mcu keep restarting itself.

richard
- 31st May 2014, 05:38
glad to see you got it to go

steve
here is an extract from the pbp3 manual

The upper 7 bits of the Control byte contain the control code along with chip select or additional address information, depending on the particular device. The low order bit is an internal flag indicating whether it is a read or write command and should be kept clear.

as I said bit 0 is set as required by the pbp complier

EarlyBird2
- 31st May 2014, 08:09
Richard,

I am amazed that it works using $D0 for read and write control. Simply because this is not how others have coded the I2C instruction for this device in the past and it worked for them. Also the data sheet is very specific on the procedure to use for write and read procedures which obviously PBP3 is not following but still works.

Does this mean that read the manual and the data sheet is no longer good advice?

EarlyBird2
- 31st May 2014, 08:23
Mystery solved, in my mind anyway, The I2C command has been changed in PBP3 and the PBP3 manual does point this out. So older code written for previous versions of PBP needs modifying accordingly. When reading the data sheets these changes need to be taken into account.

richard
- 31st May 2014, 08:23
not at all , the i2cread macro actually performs two functions when supplied with the "optional" address field
I2CREAD DataPin, ClockPin, Control, {Address,} [Var{,Var...}]{,Label}
when an address is supplied it writes " address " to the device and then sets bit0 of the control byte and performs the read('s)
exactly as per your uploaded graphic from the data sheet.
its simply a case of rtfm for pbp i2cread command and then to actually understand it.
if you don't believe it get a logic analyser and see it for yourself

PS I just found my old pbp2.60a manual ,the i2cread command for that version is exactly the same as for pbp3

EarlyBird2
- 31st May 2014, 08:36
Thanks Richard,

It is not a case of not believing but a case of not understanding. There are many posts that contradict how this device is coded and they worked which is an anomaly to me. Your post #16 is a very good explanation. Today I have learned something which is why, and I am sure others, come to this forum.

richard
- 31st May 2014, 08:54
simple explanation for their success is as I said in post 13 .
bit 0 is set as required by the pbp complier .
probably should have said
bit 0 is set and or cleared as required by the pbp complier.
but the book indicates bit0 should always be 0
the 24lcxxx example in the manual makes usage of this (Address) function fairly clear I think

EarlyBird2
- 31st May 2014, 09:06
I found #16 a better explanation. Thanks again.