Help!!!
I try to read (or write) from DS1307 RTC with software I2C but i got 0:0:0 (sametimes i got 45:85:85 !!!). The circuit is ok (double checket pull up resistors 4.7KOhm). What is wrong? I try to read without the fuctions BcdToDec (convert Bcd to decimal) same results. I try to read with Hardware I2C same results. I try to increace the I2C_BIT_DELAY , I2C_CLOCK_DELAY , I2C_END_DELAY in i2c.h same results :(
My code
;Variables
Dim sec As byte
Dim min As byte
Dim hour As byte
Dim va as byte
cls
Main:
I2CStart ; Send I2C start condition
I2CSend 208, True ; The Address of DS1307 for Write
I2CSend 0, True ; Set register pointer to zero
I2CStart ; Repeated Start
I2CSend 209, True ; The Address of DS1307 for Read
I2CReceive sec , True ; Read the 00h register (sec)
I2CReceive min , True ; Read the 01h register (min)
I2CReceive hour , False ; Read the 02h register (hour) and transmit no act
I2CStop ; Send I2C stop condition
sec=BcdToDec(sec & 127)
min=BcdToDec(min & 127)
hour=BcdToDec(hour & 63)
locate 0,0
print hour
print ":"
print min
Print ":"
Print sec
wait 500 ms
goto Main
Function DecToBcd(va) as Byte
DecToBcd=(va/10)*16+va%10
End Function
Function BcdToDec(va) as byte
BcdToDec=(va/16)*10+va%16
End Function
Last edit: Dimitris Katsaounis 2013-06-01
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I haven't used the DS1307 but looking at the data sheet it seems like you have to send a I2CStop before sending the repeated start.
I would think it has to complete the address set before starting the next section of sending data.
I really like your DECtoBCD and BCDtoDEC functions. Those should be put in the GCB library somewhere as new commands.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The DS1307 needs to kick off the oscillator, with the seconds register set to zero. All data sent to the registers need to be in BCD form. Here is an initialization routine from a long time ago. Non standard GCB syntax :-).
;**RTC INITIALIZE******
' Set initial DS1307 time / Date
ampm = 96 '12 hour clock (64) + pm bit (32)
'ampm = 64 '12 hour clock (64) + am bit (0)
Secs = 0 'Set seconds to zero in order to get osc going
Mins = 57
Hrs = 10
Day = 4 'Set day of week value
Date = 1 'Day of month value
Month = 5 'Month value
Year = 8 ' Year value
Ctrl = 0 '0x50 Set the SQW pin to 1Hz output
BIN = Secs 'Make sure the Osc is enabled
BINtoBCD BIN 'BIN_TO_BCD
Secs=BCD
BIN = Mins
BINtoBCD BIN 'BIN_TO_BCD
Mins = BCD
BIN = Hrs
BINtoBCD BIN
Hrs = BCD
Hrs = Hrs + ampm 'Need to change Hr = RTC_receive if doing 12 hr. clock
Finally worked!
Thanks guys!!!
The problem was in bit7 of 00h register.
I changed in i2c.h library the constants:
#define I2C_BIT_DELAY 20 us ;Default 2 us
#define I2C_CLOCK_DELAY 10 us ;Default 1 us
#define I2C_END_DELAY 10 us ; Default 1 us
;Variables
Dim sec As byte
Dim min As byte
Dim hour As byte
Dim va as byte
dim DS_AddrWrite as Byte
Dim DS_AddrRead as byte
va=0
cls
DS_AddrWrite=208 ; According to manual 1101000+0
DS_AddrRead=209 ; According to manual 1101000+1
' Set bit 7 of 00h register to 0
I2CStart
I2CSend DS_AddrWrite , True
I2CSend 0, True
I2CSend 0, True
I2CStop
Main:
I2CStart ; Send I2C start condition
I2CSend DS_AddrWrite, True ; The Address of DS1307 for Write
I2CSend 0, True ; Set register pointer to zero
I2CStart ; Repeated Start
I2CSend DS_AddrRead, True ; The Address of DS1307 for Read
I2CReceive sec , True ; Read the 00h register (sec)
I2CReceive min , True ; Read the 01h register (min)
I2CReceive hour , False ; Read the 02h register (hour) and transmit no act
I2CStop ; Send I2C stop condition
sec=BcdToDec(sec & 127)
min=BcdToDec(min & 127)
hour=BcdToDec(hour & 63)
locate 0,0
print hour
print ":"
print min
Print ":"
Print sec
wait 500 ms
locate 0,0
print " "
goto Main
Function DecToBcd(va) as Byte
DecToBcd=(va/10)*16+va%10
End Function
Function BcdToDec(va) as byte
BcdToDec=(va/16)*10+va%16
End Function
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi, This is absolutely great, especially as I am working on a project which needs to incorporate an RTC.
I have duplicated your code into my project, changed the data in the i2c.h file, it compiles okay but when I run it on my PIC Simulator it only displays 45:85:85
Any ideas or suggestions ?
Regards
Keith
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have soldiered on since daybreak on this. I have double checked everything. I can see that I have a clock on RC3 and data on RC4 with the scope but still only 45:85:85 on the display.
My grey area's are in the chip config and Port Dir.
I would really appreciate if one of the forum Guru's could check my code over.
DIR PORTA b'11000000'
' All Port C Outputs except RA6 & RA7 Inputs
DIR PORTB b'00000000'
' All Port B Outputs
DIR PORTC b'11111111'
' All Inputs Port C
DIR PORTD b'00001111'
' All Outputs Port A except RD0 to RD3 Inputs
DIR PORTE b'0000'
' All Outputs Port E
;Variables
Dim sec As byte
Dim min As byte
Dim hour As byte
Dim va as byte
dim DS_AddrWrite as Byte
Dim DS_AddrRead as byte
va=0
cls
DS_AddrWrite=208 ; According to manual 1101000+0
DS_AddrRead=209 ; According to manual 1101000+1
' Set bit 7 of 00h register to 0
I2CStart
I2CSend DS_AddrWrite , True
I2CSend 0, True
I2CSend 0, True
I2CStop
'Main loop
Main:
I2CStart 'Send I2C start condition
I2CSend DS_AddrWrite, True 'The Address of DS1307 for Write
I2CSend 0, True 'Set register pointer to zero
I2CStart 'Repeated Start
I2CSend DS_AddrRead, True 'The Address of DS1307 for Read
I2CReceive sec , True 'Read the 00h register (sec)
I2CReceive min , True 'Read the 01h register (min)
I2CReceive hour , False 'Read the 02h register (hour) and transmit no act
I2CStop 'Send I2C stop condition
sec = BcdToDec(sec & 127)
min = BcdToDec(min & 127)
hour = BcdToDec(hour & 63)
locate 3,12
print hour
print ":"
print min
Print ":"
Print sec
wait 500 ms
locate 3,12
print " "
goto Main
Function DecToBcd(va) as Byte
DecToBcd = (va/10)*16+va%10
End Function
Function BcdToDec(va) as byte
BcdToDec = (va/16)*10+va%16
End Function
Last edit: Keith 2013-06-20
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Does anyone have a quick fix as to when I post code the definition pound is stripped off and the text is is posted in huge charactors... (looks really messy!)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi and thank you kindly for your reply. To be perfectly honest with you, I am batting way above my height with this one. With that in mind could you please elaborate a little when you write, ''set' the clock prior to the read' and, ''set' the clock code'
Many thanks
Keith
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have had similar thoughts about the Data Port, and in times past while making vague attempts with MPLAB IDE I would have been looking for an istruction which would allow RC4.C to enter into Tri-State Mode od Bi-Di Mode.
I have been over GCB like a nasty rash but I cannot find any such instruction which will make RC4 Tri-State or Bi-Directional
I have tried TRISC.4 = 1 and TRISC.4 = 0 as I'm led to believe that any istruction which the GCB Compiler does not make sense of, it passes to the .asm, but that still gives me the dreaded, '45:85:85' which incidentally is what you got when you first identified the problems with the I2C.h file timing parameters.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Help!!!
I try to read (or write) from DS1307 RTC with software I2C but i got 0:0:0 (sametimes i got 45:85:85 !!!). The circuit is ok (double checket pull up resistors 4.7KOhm). What is wrong? I try to read without the fuctions BcdToDec (convert Bcd to decimal) same results. I try to read with Hardware I2C same results. I try to increace the I2C_BIT_DELAY , I2C_CLOCK_DELAY , I2C_END_DELAY in i2c.h same results :(
My code
;Chip Settings
#chip 16F88,4
#config OSC=INTRC_IO, WDT=OFF
;Defines (Constants)
#define LCD_IO 4
#define LCD_RW PORTA.1
#define LCD_RS PORTA.0
#define LCD_Enable PORTA.2
#define LCD_DB4 PORTB.3
#define LCD_DB5 PORTB.5
#define LCD_DB6 PORTB.6
#define LCD_DB7 PORTB.7
#define I2C_MODE Master
#define I2C_DATA PORTB.1
#define I2C_CLOCK PORTB.4
;Variables
Dim sec As byte
Dim min As byte
Dim hour As byte
Dim va as byte
cls
Main:
I2CStart ; Send I2C start condition
I2CSend 208, True ; The Address of DS1307 for Write
I2CSend 0, True ; Set register pointer to zero
I2CStart ; Repeated Start
I2CSend 209, True ; The Address of DS1307 for Read
I2CReceive sec , True ; Read the 00h register (sec)
I2CReceive min , True ; Read the 01h register (min)
I2CReceive hour , False ; Read the 02h register (hour) and transmit no act
I2CStop ; Send I2C stop condition
sec=BcdToDec(sec & 127)
min=BcdToDec(min & 127)
hour=BcdToDec(hour & 63)
locate 0,0
print hour
print ":"
print min
Print ":"
Print sec
wait 500 ms
goto Main
Function DecToBcd(va) as Byte
DecToBcd=(va/10)*16+va%10
End Function
Function BcdToDec(va) as byte
BcdToDec=(va/16)*10+va%16
End Function
Last edit: Dimitris Katsaounis 2013-06-01
I haven't used the DS1307 but looking at the data sheet it seems like you have to send a I2CStop before sending the repeated start.
I would think it has to complete the address set before starting the next section of sending data.
I really like your DECtoBCD and BCDtoDEC functions. Those should be put in the GCB library somewhere as new commands.
Thanks Chuck for reply.
I try to I2CStop before the repeated start but same results :(
The DS1307 needs to kick off the oscillator, with the seconds register set to zero. All data sent to the registers need to be in BCD form. Here is an initialization routine from a long time ago. Non standard GCB syntax :-).
;**RTC INITIALIZE******
' Set initial DS1307 time / Date
ampm = 96 '12 hour clock (64) + pm bit (32)
'ampm = 64 '12 hour clock (64) + am bit (0)
Secs = 0 'Set seconds to zero in order to get osc going
Mins = 57
Hrs = 10
Day = 4 'Set day of week value
Date = 1 'Day of month value
Month = 5 'Month value
Year = 8 ' Year value
Ctrl = 0 '0x50 Set the SQW pin to 1Hz output
BIN = Secs 'Make sure the Osc is enabled
BINtoBCD BIN 'BIN_TO_BCD
Secs=BCD
BIN = Mins
BINtoBCD BIN 'BIN_TO_BCD
Mins = BCD
BIN = Hrs
BINtoBCD BIN
Hrs = BCD
Hrs = Hrs + ampm 'Need to change Hr = RTC_receive if doing 12 hr. clock
BIN = Day
BINtoBCD(BIN)
Day=BCD
BIN = Date
BINtoBCD BIN
Date = BCD
BIN = Month
BINtoBCD BIN
Month=BCD
BIN = Year
BINtoBCD BIN
Year=BCD
BIN = Ctrl
BINtoBCD BIN
Ctrl=BCD
strtaddr = 0
write8bit (DS1307write,strtaddr,Secs)
strtaddr = 1
write8bit(DS1307write,strtaddr,Mins)
strtaddr = 2
write8bit(DS1307write,strtaddr,Hrs)
strtaddr = 3
write8bit(DS1307write,strtaddr,Day)
strtaddr = 4
write8bit(DS1307write,strtaddr,Date)
strtaddr = 5
write8bit(DS1307write,strtaddr,Month)
strtaddr = 6
write8bit(DS1307write,strtaddr,Year)
strtaddr = 7
write8bit(DS1307write,strtaddr,Ctrl)
Finally worked!
Thanks guys!!!
The problem was in bit7 of 00h register.
I changed in i2c.h library the constants:
#define I2C_BIT_DELAY 20 us ;Default 2 us
#define I2C_CLOCK_DELAY 10 us ;Default 1 us
#define I2C_END_DELAY 10 us ; Default 1 us
The new code is now:
;Chip Settings
#chip 16F88,4
#config OSC=INTRC_IO, WDT=OFF
;Defines (Constants)
#define LCD_IO 4
#define LCD_RW PORTA.1
#define LCD_RS PORTA.0
#define LCD_Enable PORTA.2
#define LCD_DB4 PORTB.3
#define LCD_DB5 PORTB.5
#define LCD_DB6 PORTB.6
#define LCD_DB7 PORTB.7
#define I2C_MODE Master
#define I2C_DATA PORTB.1
#define I2C_CLOCK PORTB.4
;Variables
Dim sec As byte
Dim min As byte
Dim hour As byte
Dim va as byte
dim DS_AddrWrite as Byte
Dim DS_AddrRead as byte
va=0
cls
DS_AddrWrite=208 ; According to manual 1101000+0
DS_AddrRead=209 ; According to manual 1101000+1
' Set bit 7 of 00h register to 0
I2CStart
I2CSend DS_AddrWrite , True
I2CSend 0, True
I2CSend 0, True
I2CStop
Main:
I2CStart ; Send I2C start condition
I2CSend DS_AddrWrite, True ; The Address of DS1307 for Write
I2CSend 0, True ; Set register pointer to zero
I2CStart ; Repeated Start
I2CSend DS_AddrRead, True ; The Address of DS1307 for Read
I2CReceive sec , True ; Read the 00h register (sec)
I2CReceive min , True ; Read the 01h register (min)
I2CReceive hour , False ; Read the 02h register (hour) and transmit no act
I2CStop ; Send I2C stop condition
sec=BcdToDec(sec & 127)
min=BcdToDec(min & 127)
hour=BcdToDec(hour & 63)
locate 0,0
print hour
print ":"
print min
Print ":"
Print sec
wait 500 ms
locate 0,0
print " "
goto Main
Function DecToBcd(va) as Byte
DecToBcd=(va/10)*16+va%10
End Function
Function BcdToDec(va) as byte
BcdToDec=(va/16)*10+va%16
End Function
Hi, This is absolutely great, especially as I am working on a project which needs to incorporate an RTC.
I have duplicated your code into my project, changed the data in the i2c.h file, it compiles okay but when I run it on my PIC Simulator it only displays 45:85:85
Any ideas or suggestions ?
Regards
Keith
I have soldiered on since daybreak on this. I have double checked everything. I can see that I have a clock on RC3 and data on RC4 with the scope but still only 45:85:85 on the display.
My grey area's are in the chip config and Port Dir.
I would really appreciate if one of the forum Guru's could check my code over.
my code is;
;Chip Settings
#chip 16F887,20
#config OSC=XT_IO, WDT=OFF
;Defines (Constants)
#define LCD_IO 8
#define LCD_DATA_PORT PORTB
#define LCD_RS PORTD.5
#define LCD_RW PORTD.6
#define LCD_Enable PORTD.7
#define I2C_MODE Master
#define I2C_DATA PORTC.4 'I2C SD1/SDA
#define I2C_CLOCK PORTC.3 'I2C SCK/SCL
DIR PORTA b'11000000'
' All Port C Outputs except RA6 & RA7 Inputs
DIR PORTB b'00000000'
' All Port B Outputs
DIR PORTC b'11111111'
' All Inputs Port C
DIR PORTD b'00001111'
' All Outputs Port A except RD0 to RD3 Inputs
DIR PORTE b'0000'
' All Outputs Port E
;Variables
Dim sec As byte
Dim min As byte
Dim hour As byte
Dim va as byte
dim DS_AddrWrite as Byte
Dim DS_AddrRead as byte
va=0
cls
DS_AddrWrite=208 ; According to manual 1101000+0
DS_AddrRead=209 ; According to manual 1101000+1
' Set bit 7 of 00h register to 0
I2CStart
I2CSend DS_AddrWrite , True
I2CSend 0, True
I2CSend 0, True
I2CStop
'Main loop
Main:
I2CStart 'Send I2C start condition
I2CSend DS_AddrWrite, True 'The Address of DS1307 for Write
I2CSend 0, True 'Set register pointer to zero
I2CStart 'Repeated Start
I2CSend DS_AddrRead, True 'The Address of DS1307 for Read
I2CReceive sec , True 'Read the 00h register (sec)
I2CReceive min , True 'Read the 01h register (min)
I2CReceive hour , False 'Read the 02h register (hour) and transmit no act
I2CStop 'Send I2C stop condition
sec = BcdToDec(sec & 127)
min = BcdToDec(min & 127)
hour = BcdToDec(hour & 63)
locate 3,12
print hour
print ":"
print min
Print ":"
Print sec
wait 500 ms
locate 3,12
print " "
goto Main
Function DecToBcd(va) as Byte
DecToBcd = (va/10)*16+va%10
End Function
Function BcdToDec(va) as byte
BcdToDec = (va/16)*10+va%16
End Function
Last edit: Keith 2013-06-20
Does anyone have a quick fix as to when I post code the definition pound is stripped off and the text is is posted in huge charactors... (looks really messy!)
put "4 ~'s" just before your code and just after to stop all sourceforge formatting.
that is:
Last edit: ofuzzy1 2013-09-30
....
Last edit: Anobium 2013-09-30
This code worked for me.
I believe, however, I may be incorrect, that you need to 'set' the clock prior to the read operation (the code above).
Are you able to write 'set' the clock code?
Hi and thank you kindly for your reply. To be perfectly honest with you, I am batting way above my height with this one. With that in mind could you please elaborate a little when you write, ''set' the clock prior to the read' and, ''set' the clock code'
Many thanks
Keith
this is a test of lines starting with a #
no leading spaces
#one leading space
#two leading spaces
#three leading spaces
Greg replied on a previous post:
Put a Space before the # (pound symbol) kills the ugly text...
Thanks Greg....
Hi Dimitris, and thank you for your reply (as shown below)
I think the portC especially the Portc.4 is input and output port (send the data tou DS1307 and Read data from it).Correct this and find out more here https://sourceforge.net/p/gcbasic/discussion/629990/thread/5b8b6ec1/
I have had similar thoughts about the Data Port, and in times past while making vague attempts with MPLAB IDE I would have been looking for an istruction which would allow RC4.C to enter into Tri-State Mode od Bi-Di Mode.
I have been over GCB like a nasty rash but I cannot find any such instruction which will make RC4 Tri-State or Bi-Directional
I have tried TRISC.4 = 1 and TRISC.4 = 0 as I'm led to believe that any istruction which the GCB Compiler does not make sense of, it passes to the .asm, but that still gives me the dreaded, '45:85:85' which incidentally is what you got when you first identified the problems with the I2C.h file timing parameters.
The 45:85:85 means that reads from the port 255:255:255
Try
Dir portc.3 out
Dir portc.4 out