Help with the DS3232 RTC

Charli

New Member
This might not have been the easiest IC to jump into trying out I2C with!

The circuit is very simple, just an 08M2 to a DS3232, powered by batteries at 3.6V. The problem is that when i look at the values being fetched from the RTC using debug, they're all set at 255/$FF and never change. The DS3232 datasheet is here- DS3232.pdf. I have the DS3232 connected at V+, 0V and Vbat connected to ground, SDA to picaxe pin C.1 and SCL to pin C.2.

My code is adapted off of the DS1307 code in the picaxe manual, but I think the control registers in the DS3232 are in a different place (page 10 of datasheet)
Code:
symbol control = b9

main:
	hi2csetup i2cmaster, %1101000, i2cslow, i2cbyte
	pause 100
	let control = %00000100
	hi2cout $0E, (control)                      ;set control registers
        hi2cout 0, ($00, $59, $11, $03, $25, $12, $03)
	
	lop:
		high C.4                 ;flashy led, because I like flashy LEDs
		pause 1000
		low C.4
		hi2cin 0,(b0,b1,b2,b3,b4,b5,b6,b7) ;read the time
		debug
		goto lop
So b0 to b7 are always set to 255/$FF (everything I read in is set to 255, if i add the line 'hi2cin $11, (b10, b11)' to read the internal temperature gauge, that reads 255 in debug too)

Any ideas? The eventual plan is to have the DS3232 creating interrupts via one of the alarms, every half hour. Just need to be a bit cleverer when it comes to understanding data sheets!
 

nick12ab

Senior Member
Change this line
Code:
hi2csetup i2cmaster, %1101000, i2cslow, i2cbyte
to
Code:
hi2csetup i2cmaster, %11010000, i2cslow, i2cbyte
The last bit is the read/write bit which although is changed by the PICAXE its inclusion is still required.
 

Charli

New Member
Unsure whether to start a new thread or add onto this one, I was hoping that by adding onto this one there would be a complete 'what to do with a DS3232' thread

So.. interrupts work, yay! However interrupts with the DS3232 do not work, I assume because I am misunderstanding and setting the alarms in the DS3232 wrong

Code:
symbol control = b9
symbol intOccurred = b10

main:
	hi2csetup i2cmaster, %11010000, i2cslow, i2cbyte
	SetInt %00001000, %00001000 ;interrupt on pin 3 high
	intOccurred = 0
       pause 100
	let control = %00000110 ;alarm 2 on, interrupts on
	hi2cout $0E, (control)                      ;set control registers
        hi2cout 0, ($00, $59, $11, $03, $25, $12, $03) ;set the time
        hi2cout $0B, (%10000000, %10000000, %10000000);set the alarm
	
	lop:
		pause 1000
		hi2cin 0,(b0,b1,b2,b3,b4,b5,b6,b7) ;read the time
		;hi2cin $11, (b10, b11)
		debug
		goto lop
		
interrupt:
	if pin3 = 1 then interrupt ;loop until clear
	intOccurred = intOccurred + 1
	debug
	high C.4 ;flashy LED
	pause 500
	low C.4
	setInt %00001000, %00001000 ;turn interrupts on again
	return
The circuit is as described in post 1, but now pin5 (SQW/INT) of the DS3232 is to picaxe pin 3. I think I'm setting the alarms wrong, but I'm not really sure how to set them correctly. I want an alarm that goes off every minute.

In the address map (datasheet page 11)
0B -> Minutes
0C -> Hour
0D -> day or date

The most significant bit of each of these is a flag (bottom of page 12), and for a once per minute alarm I want all 3 flags set- this should alarm on 00 seconds of every minute. Only it doesn't, so I guess that I've missed something.

Anyone familiar with the DS3232? I'm struggling to find any alarm code for it.
 

Charli

New Member
I have pullup resistors on SDA and SCL, missed that I needed one on pin 5! Ok, now added.. and the same result, I can leave it running for 10 mins and not have an interrupt trigger.
 

MartinM57

Moderator
With the pullup in place you will need to set the PICAXE interrupt to be when pin 3 goes low - which is why in the data sheet it calls it SQW/INT, with a bar over the INT.

With your last posted code you could be getting the interrupt straight away and then looping at the first line of the interrupt routine forever - more debugging sertxd's are recommended :D
 

Charli

New Member
I was wandering what that line meant- that never occurred to me at all! Sorry I was being very dense just then, forgot to change anything else! I'll also be highly impressed if I managed to set the alarm registers correctly, I was so caught up in that being the problem that I never really looked at anything else.

so I did change the code to interrupt on pin3 being low, but i still get stuck in the interrupt loop forever the first time I hit it
so, code now, with many sertxds!
Code:
symbol control = b9
symbol intOccurred = b10

main:
	hi2csetup i2cmaster, %11010000, i2cslow, i2cbyte
	setInt %00000000, %00001000 ;interrupt on pin 3 low
	sertxd ("interrupt set")
	intOccurred = 0
       pause 100
	let control = %00000110 ;alarm 2 on, interrupts on
	hi2cout $0E, (control)                      ;set control registers
	sertxd ("control registers set")
        hi2cout 0, ($00, $59, $11, $03, $25, $12, $03) ;set the time
        sertxd ("time set")
        hi2cout $0B, (%10000000, %10000000, %10000000);set the alarm
        sertxd ("alarm set")
	
	lop:
		pause 1000
		hi2cin 0,(b0,b1,b2,b3,b4,b5,b6,b7) ;read the time
		sertxd ("time read: ", #b7, #b6, #b5, #b4, #b3, #b2, #b1, #b0)
		goto lop
		
interrupt:
	sertxd ("in interrupt loop")
	if pin3 = 0 then interrupt ;loop until clear
	intOccurred = intOccurred + 1
	high C.4 ;flashy LED
	sertxd ("flash led, intOccurrred: ", intOccurred)
	pause 500
	low C.4
	setInt %00000000, %00001000 ;turn interrupts on again
	return
It counts up a minute, then hits the interrupt, then loops forever. At least I think it is forever, its been going for some time now. I guess I have to reset it on the DS3232 to stop it? I can work this out, honest!
 
Last edited:

MartinM57

Moderator
In the general case I think you have to read the status registers to determine what caused the /INT to assert (in your case, A2F in regist 0x0F) and then reset the alarm - /INT isn't going to return high of it's own accord so you will be waiting in that loop forever.

Maybe I would use alarm 1 while testing, and set to alarm every 1 second, to avoid waiting for things to happen/not happen every minute :D

Also Google for "DS3232 alarm code example" - there's quite a lot of questions about it. E.g.
http://arduino.cc/forum/index.php/topic,64297.0.html
 

Charli

New Member
Just thought I would share the finished and working code! The trick was to reset the alarm flag- I had some funny idea in my head that it would reset itself after the alarm-second has passed- have no idea where this came from.

Code:
symbol control = b9
symbol intOccurred = b10

main:
	hi2csetup i2cmaster, %11010000, i2cslow, i2cbyte
	setInt %00000000, %00001000 ;interrupt on pin 3 low
	sertxd ("interrupt set")
	intOccurred = 0
       pause 100
	let control = %00000110 ;alarm 2 on, interrupts on
	hi2cout $0E, (control)                      ;set control registers
	sertxd ("control registers set")
        hi2cout 0, ($00, $59, $11, $03, $25, $12, $03) ;set the time
        sertxd ("time set")
        hi2cout $0B, (%10000000, %10000000, %10000000);set the alarm
        sertxd ("alarm set")
	
	lop:
		pause 1000
		hi2cin 0,(b0,b1,b2,b3,b4,b5,b6,b7) ;read the time
		sertxd ("time read: ", #b7, #b6, #b5, #b4, #b3, #b2, #b1, #b0)
		goto lop
		
interrupt:
	sertxd ("in interrupt loop")
	hi2cout $0F, (%11110000) ;clear interrupt flag- this also sets some other stuff that you should probably check, like it makes the temperature conversion only happen every 512 seconds (fine for my application)
	intOccurred = intOccurred + 1
	high C.4 ;flashy LED
	sertxd ("flash led, intOccurrred: ", intOccurred)
	pause 500
	low C.4
	setInt %00000000, %00001000 ;turn interrupts on again
	return
 

nick12ab

Senior Member
Code:
    lop:
        pause 1000
        hi2cin 0,(b0,b1,b2,b3,b4,b5,b6,b7) ;read the time
        sertxd ("time read: ", #b7, #b6, #b5, #b4, #b3, #b2, #b1, #b0)
        goto lop
You can just use a DO : LOOP when nothing links to the label except the end of the loop.
 
Top