// ATMEGA8 12MHz
#define G0_D PD6
#define G1_B PB1
#define G2_B PB2
#define G3_B PB5
#define DP_C PC1 //PD SETKA
#define E_B PB3
#define G_B PB4
#define B_B PB0
#define F_D PD7
#define A_D PD5
#define D_C PC2
#define C_C PC3
#define SET PD0
#define UP PD1
#define DOWN PD2
#include <avr/io.h>
#include <util/delay.h>
#define ADDR_DS1307 0b1101000
#define CPU_F 12000000 // Clock Speed
#define SCL_F 100000 // // I2C Speed
byte a[4],an,segm,i;
int msec,sec,minute,hour,set;
int set_sec,set_minute,set_hour;
int main() {
TWBR = (((CPU_F)/(SCL_F)-16 )/2) ;
TWSR = 0;
// set_time(22,7,2,26,13,10,0);// год 00-99, ДН 1-7 (1=ВС), месяц 1-12, дата 1-31, час 0-23, минуты 0-59, секунды 0-59
cli();
// (12000000/((18749+1)x64))=10 Hz
OCR1A = 18749;
TCCR1B |= (1 << WGM12);
// Prescaler 64
TCCR1B |= (1 << CS11) | (1 << CS10);
TIMSK |= (1 << OCIE1A);
// (12000000/((155+1)x256))=300.48076923077 Hz
OCR2 = 155;
TCCR2 |= (1 << WGM21);
// Prescaler 256
TCCR2 |= (1 << CS22) | (1 << CS21);
TIMSK |= (1 << OCIE2);
sei();
DDRB|=(1<<G1_B)|(1<<G2_B)|(1<<G3_B)|(1<<E_B)|(1<<G_B)|(1<<B_B);
DDRC|=(1<<D_C)|(1<<C_C)|(1<<DP_C);
DDRD|=(1<<G0_D)|(1<<F_D)|(1<<A_D);
PORTD|=(1<<SET)|(1<<UP)|(1<<DOWN);
while(1) {
sec = (i2c_read_1bit(ADDR_DS1307,0) & 0x0F) + (((i2c_read_1bit(ADDR_DS1307,0) & 0x70) >> 4) * 10);
minute = (i2c_read_1bit(ADDR_DS1307,1) & 0x0F) + (((i2c_read_1bit(ADDR_DS1307,1) & 0x70) >> 4) * 10);
hour = ((i2c_read_1bit(ADDR_DS1307,2) & 0x0F) + ((i2c_read_1bit(ADDR_DS1307,2) & 0x70) >> 4) * 10);
if(((PIND >> SET) & 1) == 0){set++;if(set>3){set=0;}_delay_ms(300);}
set_sec=sec;
set_minute=minute;
set_hour=hour;
if(((PIND >> UP) & 1) == 0 && set==1){set_hour++;if(set_hour>23){set_hour=23;}_delay_ms(300);set_time(255,255,255,255,set_hour,255,255);}
if(((PIND >> DOWN) & 1) == 0 && set==1){set_hour--;if(set_hour<0){set_hour=0;}_delay_ms(300);set_time(255,255,255,255,set_hour,255,255);}
if(((PIND >> UP) & 1) == 0 && set==2){set_minute++;if(set_minute>59){set_minute=59;}_delay_ms(300);set_time(255,255,255,255,255,set_minute,255);}
if(((PIND >> DOWN) & 1) == 0 && set==2){set_minute--;if(set_minute<0){set_minute=0;}_delay_ms(300);set_time(255,255,255,255,255,set_minute,255);}
if(((PIND >> UP) & 1) == 0 && set==3){set_sec=0;_delay_ms(300);set_time(255,255,255,255,255,255,set_sec);}
if(((PIND >> DOWN) & 1) == 0 && set==3){set_sec=0;_delay_ms(300);set_time(255,255,255,255,255,255,set_sec);}
if(set==0){
a[3]=hour/10;
a[2]=hour%10;
a[1]=minute/10;
a[0]=minute%10;
}
if(set==1&&(msec==0||msec==5)){a[3]=10;}else{a[3]=hour/10;}
if(set==1&&(msec==0||msec==5)){a[2]=10;}else{a[2]=hour%10;}
if(set==2&&(msec==0||msec==5)){a[1]=10;}else{a[1]=minute/10;}
if(set==2&&(msec==0||msec==5)){a[0]=10;}else{a[0]=minute%10;}
if(set==3){
if(msec==0||msec==5){a[1]=10;a[3]=10;a[2]=10;}else{a[3]=10;a[2]=10;a[1]=sec/10;}
if(msec==0||msec==5){a[0]=10;a[3]=10;a[2]=10;}else{a[3]=10;a[2]=10;a[0]=sec%10;}
}
if(msec<5){PORTC |=(1<<DP_C);}
if(msec>=5){PORTC &=~(1<<DP_C);}
_delay_ms(100);
}}
ISR(TIMER2_COMP_vect){
switch(i){
case 0: segm=a[0]; an=0; anod();segment(); break;
case 1: segm=a[1]; an=1; anod();segment(); break;
case 2: segm=a[2]; an=2; anod();segment(); break;
case 3: segm=a[3]; an=3; anod();segment(); break;
}i++;if(i>3){i=0;}}
void segment(){
switch(segm){
case 0: PORTD &=~(1<<A_D);PORTB &=~(1<<B_B);PORTC &=~(1<<C_C);PORTC &=~(1<<D_C);PORTB &=~(1<<E_B);PORTD &=~(1<<F_D);PORTB |=(1<<G_B);break;
case 1: PORTD |=(1<<A_D);PORTB &=~(1<<B_B);PORTC &=~(1<<C_C);PORTC |=(1<<D_C);PORTB |=(1<<E_B);PORTD |=(1<<F_D);PORTB |=(1<<G_B);break;
case 2: PORTD &=~(1<<A_D);PORTB &=~(1<<B_B);PORTC |=(1<<C_C);PORTC &=~(1<<D_C);PORTB &=~(1<<E_B);PORTD |=(1<<F_D);PORTB &=~(1<<G_B);break;
case 3: PORTD &=~(1<<A_D);PORTB &=~(1<<B_B);PORTC &=~(1<<C_C);PORTC &=~(1<<D_C);PORTB |=(1<<E_B);PORTD |=(1<<F_D);PORTB &=~(1<<G_B);break;
case 4: PORTD |=(1<<A_D);PORTB &=~(1<<B_B);PORTC &=~(1<<C_C);PORTC |=(1<<D_C);PORTB |=(1<<E_B);PORTD &=~(1<<F_D);PORTB &=~(1<<G_B);break;
case 5: PORTD &=~(1<<A_D);PORTB |=(1<<B_B);PORTC &=~(1<<C_C);PORTC &=~(1<<D_C);PORTB |=(1<<E_B);PORTD &=~(1<<F_D);PORTB &=~(1<<G_B);break;
case 6: PORTD &=~(1<<A_D);PORTB |=(1<<B_B);PORTC &=~(1<<C_C);PORTC &=~(1<<D_C);PORTB &=~(1<<E_B);PORTD &=~(1<<F_D);PORTB &=~(1<<G_B);break;
case 7: PORTD &=~(1<<A_D);PORTB &=~(1<<B_B);PORTC &=~(1<<C_C);PORTC |=(1<<D_C);PORTB |=(1<<E_B);PORTD |=(1<<F_D);PORTB |=(1<<G_B);break;
case 8: PORTD &=~(1<<A_D);PORTB &=~(1<<B_B);PORTC &=~(1<<C_C);PORTC &=~(1<<D_C);PORTB &=~(1<<E_B);PORTD &=~(1<<F_D);PORTB &=~(1<<G_B);break;
case 9: PORTD &=~(1<<A_D);PORTB &=~(1<<B_B);PORTC &=~(1<<C_C);PORTC &=~(1<<D_C);PORTB |=(1<<E_B);PORTD &=~(1<<F_D);PORTB &=~(1<<G_B);break;
case 10: PORTD |=(1<<A_D);PORTB |=(1<<B_B);PORTC |=(1<<C_C);PORTC |=(1<<D_C);PORTB |=(1<<E_B);PORTD |=(1<<F_D);PORTB |=(1<<G_B);break;
}}
void anod(){
switch(an){
case 0: PORTB |=(1<<G3_B);PORTD &=~(1<<G0_D);break;
case 1: PORTD |=(1<<G0_D);PORTB &=~(1<<G1_B);break;
case 2: PORTB |=(1<<G1_B);PORTB &=~(1<<G2_B);break;
case 3: PORTB |=(1<<G2_B);PORTB &=~(1<<G3_B);break;
}}
ISR(TIMER1_COMPA_vect){msec++;if(msec>9){msec=0;}}
void set_time(byte years, byte days, byte monts, byte datas, byte hours ,byte minuteute, byte second){
if(second < 255){i2c_write(ADDR_DS1307,0x00,(second/10<<4)+second%10);}
if(minuteute < 255){i2c_write(ADDR_DS1307,0x01,(minuteute/10<<4)+minuteute%10);}
if(hours < 255){i2c_write(ADDR_DS1307,0x02,(hours/10<<4)+hours%10);}
if(days < 255){i2c_write(ADDR_DS1307,0x03,days);}
if(datas < 255){i2c_write(ADDR_DS1307,0x04,(datas/10<<4)+datas%10);}
if(monts < 255){i2c_write(ADDR_DS1307,0x05,(monts/10<<4)+monts%10);}
if(years < 255){i2c_write(ADDR_DS1307,0x06,(years/10<<4)+years%10);}
}
void i2c_write(byte i2c_addr, byte i2c_reg, byte i2c_dat){
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // START
while (!(TWCR & (1<<TWINT)));
TWDR = i2c_addr << 1;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWDR = i2c_reg;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWDR = i2c_dat;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // СТОП
}
int i2c_read_1bit(byte i2c_addr, byte i2c_reg){
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // START
while (!(TWCR & (1<<TWINT)));
TWDR = i2c_addr << 1;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWDR = i2c_reg;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // START
while (!(TWCR & (1<<TWINT)));
TWDR = (i2c_addr << 1) | 1;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while(~TWCR&(1<<TWINT));
byte i2c_data = TWDR;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // СТОП
return i2c_data;
}