DS3231 MAX7219 interrupts

… also known as DS3231 part III. (Have you seen Part I and Part II ?)

zegar1

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”

Leave a Reply