… also known as DS3231 part III. (Have you seen Part I and Part II ?)
It is pretty natural to start playing with interrupts as we write program for the clock. There are 3 (in UNO, other boards have different number) internal timer based interrupts. Timer0 and Timer2 are based on 8 bits counters, so I decided to use Timer1 here with 16 bits. The prescaler set to 64 and match register to 2499 did the trick (one could use as well 256;624 or 8;19999 pairs for Timer1 looking for 100Hz refresh).
Two libraries are used here: DS3231 library (see first post), and Eberhard Fahle LedControl (see second one).
In the main procedure (ReadDS3231) only 2 last digits are refreshed every 1/100 second. Other digits are refreshed every second to save some time.
#include "LedControl.h"
#include <Wire.h>
#include <DS3231.h>
//CLK pin 10 CS pin 11 DataIn pin 12
LedControl lc=LedControl(12,10,11,1);
DS3231 Clock;
boolean update_display = true;
void ReadDS3231() {
static int oldsecond;
static unsigned long oldmillis;
int second,minute,hour,hlast,mlast,slast,tens,hundreds;
bool PM, h12;
second=Clock.getSecond();
// this part executed only once in 100 calls
if ( second != oldsecond ) {
oldmillis = millis();
oldsecond = second;
minute=Clock.getMinute();
hour=Clock.getHour(h12, PM);
slast = second % 10;
mlast = minute % 10;
hlast = hour % 10;
second = (second - slast) / 10;
minute = (minute - mlast) / 10;
hour = (hour - hlast) / 10;
lc.setDigit(0,7,hour,false);
lc.setDigit(0,6,hlast,true);
lc.setDigit(0,5,minute,false);
lc.setDigit(0,4,mlast,true);
lc.setDigit(0,3,second,false);
lc.setDigit(0,2,slast,true);
}
// this part executed always (at 100Hz)
tens = (millis()-oldmillis)/100;
hundreds = ((millis()-oldmillis)/10)%10;
lc.setDigit(0,1,tens,false);
lc.setDigit(0,0,hundreds,false);
update_display=false;
}
void setup() {
//clock
Wire.begin(); //clock communication
//display
lc.shutdown(0,false); //wake up MAX72XX
lc.setIntensity(0,6); //set the brightness in range 0 - 15
lc.clearDisplay(0);
//interrupts
cli();//stop interrupts for the time of setting timer1
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
OCR1A = 2499;// set compare match register = (16*10^6) / (x Hz * prescaler) - 1 (must be <65536)
TCCR1B |= (1 << WGM12); // turn on CTC mode
TCCR1B |= (1 << CS11) | (1 << CS10); // Set CS10 and CS11 bits for 64 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
sei();//allow interrupts
}
ISR(TIMER1_COMPA_vect){
update_display=true;
}
void loop() {
if ( update_display ) { ReadDS3231();}
//here other code doing something
}
Have you read earlier parts (I and II)? So it is a time to go on and see part IV!

3 thoughts on “DS3231 MAX7219 interrupts”