The code is written in C with the WinAVR compiler.

// program name: LED driver MAX7219 - clock
// date: 2016.07.15
// author: www.avrprojects.net
// target device : ATMEGA328
// hardware: MAX7219, 7 segment LED display 4 digit

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define F_CPU = 8000000UL

#define clk_low 0b11111110
#define clk_high 0b00000001
#define load_low 0b00000000
#define load_high 0b00000010
#define din_low 0b11111011
#define din_high 0b00000100

// adress
#define noop 0x00
#define digit0 0x01
#define digit1 0x02
#define digit2 0x03
#define digit3 0x04
#define digit4 0x05
#define digit5 0x06
#define digit6 0x07
#define digit7 0x08
#define decode 0x09
#define intense 0x0A
#define scanlim 0x0B
#define shutdown 0x0C
#define distest 0x0F
#define dp 0b10000000


char second = 0;
int time_cntr = 0; //global variable for number of Timer 0

/// Timer 0 overflow interrupt service routine
ISR(TIMER0_OVF_vect)
{
//8.000.000hz/64=125000hz = 8µmS x 125 ticks = 1mS
//set timer/counter to 255-125 = 130
TCNT0= 130;
time_cntr++;
if (time_cntr == 250) /*check for one second, increment counter*/
{
time_cntr = 0 ;
second++;
}
}

void clk_pulse(void)
{
PORTC = PORTC & clk_low;
//_delay_ms(1);
PORTC = PORTC | clk_high;
//_delay_ms(1);
PORTC = PORTC & clk_low;
}

void send_bits(unsigned char data)
{
int i;
for (i = 0; i < 8; i++)
{
// consider leftmost bit
// set line high if bit is 1, low if bit is 0
if (data & 0x80)
PORTC = PORTC | din_high;
else
PORTC = PORTC & din_low;
// pulse clock to indicate that bit value should be read
clk_pulse();
PORTC = PORTC & din_low;
// shift byte left so next bit will be leftmost
data <<= 1;
}
}

void send_data(unsigned char adress, unsigned char data)
{
send_bits(adress);
send_bits(data);
PORTC = load_low;
PORTC = load_high;
}


void test(void) // test display
{
{
send_data(distest,0x01);
_delay_ms(1000);
send_data(distest,0x00);
}
}

int main (void)

{
// init
DDRC = 0xFF; //set PORTC as output
PORTC = 0; // reset PORTC

char hour = 11;
char minute= 18;

//set timer 0 prescaler to clk/256*/
TCCR0A = 0b00000000;
TCCR0B = 0b00000100;
// enable Timer 0 overflow interrupt*/
TIMSK0 = 0x01;
sei();

// init display
send_data(shutdown,0x01);
send_data(scanlim,0x03);
send_data(intense,0x04);
send_data(decode,0x0F);
test();

while(1)
{
{
send_data(digit0,hour / 10);
send_data(digit1,hour % 10 | dp);
send_data(digit2,minute / 10);
send_data(digit3,minute % 10);
if (second > 59)
{
second = 0;
minute++;
if (minute>59)
{
minute = 0;
hour++;
if (hour>23)
{
hour = 0;
}
}
}
}
}
}