// =============================== // AUTHOR: Chanandler Bong // CREATE DATE: 6/10/2018 // Binary Clock using Attiny85 with 16Mhz internal clock // =============================== //Pin connected to ST_CP of 74HC595 int latchPin = 0; //Pin connected to SH_CP of 74HC595 int clockPin = 1; ////Pin connected to DS of 74HC595 int dataPin = 2; volatile int sec_fraction = 0; volatile int secs = 0; volatile int mins1 = 1; volatile int mins2 = 1; volatile int hours1 = 1; volatile int hours2 = 1; void setup() { GIMSK |= (1 << PCIE); // pin change interrupt enable PCMSK |= ((1 << PCINT4)|(1 << PCINT3)); // pin change interrupt enabled for PCINT4 and PCINT3 sei(); // enable interrupts //set pins to output pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); // initialize timer1 cli(); // disable all interrupts initTimer(); sei(); // enable all interrupts } ISR(TIMER0_COMPA_vect){ // timer compare interrupt routine sec_fraction++; if(sec_fraction == 62){ //16mhz/1024/1hz = 15625/256 = 61 (61 compare matchs to make a full second) (256 is for OCR0A) sec_fraction = 0; updateClock(); } } ISR(PCINT0_vect){ if(PINB & (1 << PB3)){ delay(10); if(PINB & (1 << PB3)){ updateH(); initTimer(); } } if(PINB & (1 << PB4)){ delay(10); if(PINB & (1 << PB4)){ updateM(); initTimer(); } } } void loop() { //ground latchPin and hold low for as long as you are transmitting digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, (0xE0)+ mins1); //Mins 1 digitalWrite(latchPin, HIGH); digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, (0xD0)+ mins2 ); //Mins 2 digitalWrite(latchPin, HIGH); digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, (0xB0)+ hours1); //Hours 1 digitalWrite(latchPin, HIGH); digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, (0x70) + hours2); //Hours 2 digitalWrite(latchPin, HIGH); } void updateClock(){ secs++; if (secs == 60) { secs = 0; mins1++; } if (mins1 == 10) { mins1 =0; mins2++; } if (mins2 == 6){ mins2 = 0; hours1++; } if (hours1 == 10){ hours1 = 0; hours2++; } if (hours2 == 3){ hours2 = 0; } } void updateH() { sec_fraction = 0; secs=0; hours1++; if (hours1 == 10){ hours1 = 0; hours2++; } if (hours2 == 3){ hours2 = 0; } } void updateM() { sec_fraction = 0; secs=0; mins1++; if (mins1 == 10) { mins1 =0; mins2++; } if(mins2 == 6) { mins2 = 0; } } void initTimer(){ TCCR0A = 0; TCCR0B = 0; TCNT0 = 0; OCR0A = 256; // compare match register TIMSK |= (1 << OCIE0A); // enable timer compare interrupt TCCR0B |= (1 << WGM02); // CTC mode (clear timer on compare) TCCR0B |= ((1 << CS02)|(1 << CS00) ); // 1024 prescaler }