… 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”