Тема: Attiny2313 + ds1307
Основная статья - http://rcl-radio.ru/?p=94223
Доработка корректировки времени:
set_time(21,2,3,9,17,28,0);
если установить в устанавливаемом значении число 255, оно не будет изменено.
пример: set_time(21,2,3,9,17,255,0); - минуты не будут изменены
#define SDA 3 // PB3
#define SCL 2 // PB2
#define SQW 4 // PB4
byte bb;
void setup(){
DDRB &= ~(1 << SQW);PORTB |= (1 << SQW);
// set_time(21,2,3,9,17,28,0);// год 00-99, ДН 1-7 (1=ВС), месяц 1-12, дата 1-31, час 0-23, минуты 0-59, секунды 0-59
ds_write(0x07, 0b00010000); // выход SQW, частота 1 Гц
delay(500);
}
void loop() {
byte sec = (ds_read(0) & 0x0F) + (((ds_read(0) & 0x70) >> 4) * 10);
byte min = (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
byte hour = ((ds_read(2) & 0x0F) + ((ds_read(2) & 0x70) >> 4) * 10);
byte day = (ds_read(3) & 0x0F);
byte datat = ((ds_read(4) & 0x0F) + ((ds_read(4) & 0x70) >> 4) * 10);
byte mont = ((ds_read(5) & 0x0F) + ((ds_read(5) & 0x70) >> 4) * 10);
byte year = ((ds_read(6) & 0x0F) + ((ds_read(7) & 0x70) >> 4) * 10);
if(((PINB >> SQW) & 1)==1){bb = 0;}else{bb = 2;}
if(sec >= 0 && sec <= 25){print_time(hour *100 + min, bb, 7, 0);}
if(sec > 25 && sec <= 30){print_time(datat *100 + mont, 0, 7, 0);}
if(sec > 30 && sec <= 50){print_time(hour *100 + min, bb, 7, 0);}
if(sec > 50 && sec <= 55){print_time(datat *100 + mont, 0, 7, 0);}
if(sec > 55){print_time(sec, 0, 7, 1);}
}
void tm_dec(byte dig) {
for (int i = 0; i < 8; i++) {
DDRB |= (1 << 0); del();
if (dig & 0x01) DDRB &= ~(1 << 1);
else DDRB |= (1 << 1); del();DDRB &= ~(1 << 0); del();
dig = dig >> 1;}
DDRB |= (1 << 0);
DDRB &= ~(1 << 1); del();
DDRB &= ~(1 << 0); del();
if (((PINB >> 1) & 1) == 0) DDRB |= (1 << 1); del();DDRB |= (1 << 0); del();
}
void tm_stop() {
DDRB |= (1 << 1); del();
DDRB &= ~(1 << 0); del();
DDRB &= ~(1 << 1); del();
}
void tm_start() {
DDRB |= (1 << 1); del();
}
void print_time(int t, byte pd_t, int br, bool mn) {
tm_start(); tm_dec(0b10001000 + br); //tm_stop();tm_start();
tm_dec(0x40); tm_stop(); tm_start();
int data0,data1;
if(mn==1){data0 = 10;data1 = 10;}
else{data0 = t / 1000;data1 = t / 100 % 10;}
int data2 = t / 10 % 10;
int data3 = t % 10;
for (byte n = 0; n < 4; n++) {
int data;
switch (n) {
case 0: data = data0; break;
case 1: data = data1; break;
case 2: data = data2; break;
case 3: data = data3; break;
}
switch (data) { // XGFEDCBA
case 0: data = 0b00111111; break; // 0
case 1: data = 0b00000110; break; // 1
case 2: data = 0b01011011; break; // 2
case 3: data = 0b01001111; break; // 3
case 4: data = 0b01100110; break; // 4
case 5: data = 0b01101101; break; // 5
case 6: data = 0b01111101; break; // 6
case 7: data = 0b00000111; break; // 7
case 8: data = 0b01111111; break; // 8
case 9: data = 0b01101111; break; // 9
case 10: data = 0b00000000; break; // пусто
}
if (n == 0) {data0 = data;}
if (n == 1) {data1 = data;}
if (n == 2) {data2 = data;}
if (n == 3) {data3 = data;}
}
switch (pd_t) {
case 1 : data2 = data2 + 0b10000000; break;
case 2 : data1 = data1 + 0b10000000; break;
case 3 : data0 = data0 + 0b10000000; break;
}
tm_dec(0xC0); tm_dec(data0); tm_dec(data1); tm_dec(data2); tm_dec(data3); tm_stop();
}
void del() {delayMicroseconds(200);}
bool i2c_read_bit() {
bool i2c_bit = 1;
DDRB &= ~(1 << SDA);
delayMicroseconds(10);
DDRB &= ~(1 << SCL);
if((PINB >> SDA) & 1) i2c_bit=0;
delayMicroseconds(10);
DDRB |= (1 << SCL);
return i2c_bit;
}
byte i2c_write_byte(byte data){
for (byte i=0; i<8; i++){i2c_write_bit((data&0x80)==0);data<<=1;}
return i2c_read_bit();
}
byte i2c_read_byte(byte a){
byte i, data=0;
for(i=0; i<8; i++){if (!i2c_read_bit()) data++;if(i!=7) data<<=1;}
i2c_write_bit(a);return data;
}
void i2c_write_bit(byte b){
delayMicroseconds(5);
if(b){DDRB |= (1 << SDA);}else{DDRB &= ~(1 << SDA);}
delayMicroseconds(5);
DDRB &= ~(1 << SCL);
delayMicroseconds(10);
DDRB |= (1 << SCL);
}
void i2c_start(){
delayMicroseconds(10);
DDRB &= ~(1 << SDA); DDRB &= ~(1 << SCL);
delayMicroseconds(10);
DDRB |= (1 << SDA); PORTB &= ~(1 << SDA);
delayMicroseconds(10);
DDRB |= (1 << SCL); PORTB &= ~(1 << SCL);
delayMicroseconds(10);
}
void i2c_stop() {
DDRB |= (1 << SDA);
delayMicroseconds(10);
DDRB &= ~(1 << SCL);
delayMicroseconds(10);
DDRB &= ~(1 << SDA);
}
byte ds_read(byte reg){
byte data = 0;
i2c_start();
i2c_write_byte(0b11010000);
i2c_write_byte(reg);
i2c_start();
i2c_write_byte(0b11010001);
data = i2c_read_byte(0);
i2c_stop();
return data;
}
void ds_write(byte reg, byte data){
i2c_start();
i2c_write_byte(0b11010000);
i2c_write_byte(reg);
i2c_write_byte(data);
i2c_stop();
}
void set_time(byte years, byte days, byte monts, byte datas, byte hours ,byte minute, byte second){
if(second < 255){ds_write(0x00,(second/10<<4)+second%10);}
if(minute < 255){ds_write(0x01,(minute/10<<4)+minute%10);}
if(hours < 255){ds_write(0x02,(hours/10<<4)+hours%10);}
if(days < 255){ds_write(0x03,days);}
if(datas < 255){ds_write(0x04,(datas/10<<4)+datas%10);}
if(monts < 255){ds_write(0x05,(monts/10<<4)+monts%10);}
if(years < 255)ds_write(0x06,(years/10<<4)+years%10);
}