Page 8 of DS1307 datasheet states the following:
On first application of power to the device the time and date registers are typically reset to 01/01/00 01 00:00:00.
So, when you apply power to the RTC, it will typically come with its time reset to zeroes. However, as James Cameron pointed out in his answer, the only guaranteed response to power failure is the clock halt (CH) bit 7 of register 0. So, the data may be corrupt at start up. In any case, after you apply power to the device, you'll have to set the time yourself. Then it will start ticking by itself.
Communication with the DS1307 RTC is done via the I2C protocol. One would usually use an MCU to control it. I usually use an ATmega328P to do so without problems. You can use a PIC, Raspberry Pi or an Arduino, or any other popular MCUs out there.
Wiring it is simple enough. Just follow the DS1307 datasheet. The most usual setup is the following:
- Wire
5V
and GROUND
terminals to your board main power supply.
- Place a 3V coin cell on its holder. That will let the RTC to keep time while main power is disconnected.
- Wire the
SDA
and SCL
to the corresponding pins at your MCU board. On the ATmega328P, those are pins 27 and 28, respectively. On Arduino Uno, these are analog input pins A4
and A5
respectively.
- The
SQ
terminal is likely to be wired to the DS1307 SQW/OUT output pin (Square Wave/Output Driver). When enabled, the pin outputs one of four square-wave frequencies (1Hz, 4kHz, 8kHz, 32kHz). It is useful for triggering interrupts in your code, to let the program know when the time (seconds) has changed, for example.
- There is another terminal,
DS
, that I'm not familiar with. Make your you find and read the module manual and understand what it is for while designing the board that will use the RTC.
In your program, you need make your MCU talk to the RTC using the I2C protocol. You can do it by yourself, but the easiest is to just find a library that makes the communication simpler to you. For Arduinos, there's a few libraries out there that were developed specifically to control the DS1307. These libraries will provide functions that you can call from your program to set the initial (current) time and then to read the time whenever needed.
I hope this update addresses your question.
We faced the same problem while working with RTC on my STM32F030 Controller.
Our alarm interrupt triggered once, but it would never trigger again.
The problem was as follows:
- We needed to put the system in low power mode when not in use
- To enable the low power mode, we had to call this function
RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE);
- This function prevents write access to the DBP bit of register
PWR_CR and it makes DBP bit = 0. This bit must be set before we can
change any values of RTC registers (as mentioned in reference
manual)
Reference manual RM0360 for STM32F030 and STM32F070 states that:
After system reset, the RTC registers are protected against
parasitic write access by clearing the DBP bit in the PWR_CR register
(refer to the power control section). DBP bit must be set in order to
enable RTC registers write access. After RTC domain reset, all the RTC
registers are write-protected. Writing to the RTC registers is enabled
by writing a key into the Write Protection register, RTC_WPR. The
following steps are required to unlock the write protection on all the
RTC registers except for RTC_TAFCR and RTC_ISR[13:8].
Write ‘0xCA’ into the RTC_WPR register.
Write ‘0x53’ into the RTC_WPR register.
Writing a wrong key reactivates the write protection. The protection mechanism is not
affected by system reset.
We solved the problem by making following changes to the IRQ handler of RTC:
void RTC_IRQHandler(void)
{
/* Check line 17 has triggered the IT */
if ((EXTI->PR & 0x20000) != 0)
{
/* Makes the DBP bit of PWR_CR register write accessible */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, DISABLE);
/* Writes 1 in the DBP bit of PWR_CR register */
PWR_BackupAccessCmd(ENABLE);
/* Your code here ... */
/* RTC registers are made write accessible */
RTC_WriteProtectionCmd(DISABLE);
/* Clear the RTC Alarm-A Flag */
RTC_ClearFlag(RTC_FLAG_ALRAF);
/* Makes the RTC registers read only */
RTC_WriteProtectionCmd(ENABLE);
/* Locks the DBP bit of PWR_CR register again */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE);
/* Clear the EXTI Line 17 Pending bit (Connected internally to RTC Alarm) */
EXTI->PR |= 0x20000;
}
}
Best Answer
Debuggers are notorious for not updating registers, a few workarounds include:
Copy the registers to variables and try viewing the temporary variables in the debugger. (make sure you protect them somehow to make sure the compiler doesn't optimize them out, if they aren't being used and you have optimizations turned on the temporary variables will be optimized out).
Or use the debugger 'console' or equivalent comm channel with printf statements to print the registers contents.