Спойлер
Код: Выделить всё
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define sw PIND
#define set 4
#define ok 3
#define up 2
#define down 1
#define setEvent (sw & (1<<set))
#define okEvent (sw & (1<<ok))
#define upEvent (sw & (1<<up))
#define downEvent (sw & (1<<down))
uint8_t sec, min, hr;
int day,dd,mm,yy;
char setFlag;
volatile uint8_t count,count1;
#define timeFormat 24
uint8_t d0,d1,d2,d3;
enum
{
hour=1,
minute,
};
void init_ports()
{
DDRB = 0xFF;
PORTB = 0x00;
DDRD=0x00;
PORTD=0xff;
}
void update_Time();
int bcd_to_char(int8_t num)
{
return ((num/16 * 10) + (num % 16));
}
int dec_to_bcd(int8_t num)
{
return ((num/10)<<4) + (num % 10);
}
void RTC_start()
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while((TWCR&0x80)==0x00);
}
void device()
{
TWDR=0xD0; //RTC write (slave address)
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
TWDR=0x00; // word address write
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void RTC_stp()
{
TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //stop communication
}
void RTC_read()
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while((TWCR&0x80)==0x00);
TWDR=0xD0; //RTC write (slave address)
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
TWDR=0x00; //RTC write (word address)
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //start RTC communication again
while ((TWCR&0x80)==0x00);
TWDR=0xD1; // RTC command to read
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void sec_init(int8_t d)
{
TWDR=d; //second init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void min_init(int8_t d)
{
TWDR=d; //minute init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void hr_init(int8_t d)
{
TWDR=d; //hour init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void day_init(int8_t d)
{
TWDR=d; //days init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void date_init(int8_t d)
{
TWDR=d; //date init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void month_init(int8_t d)
{
TWDR=d; //month init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void yr_init(int8_t d)
{
TWDR=d; //year init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
int sec_rw()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC second read
while((TWCR & 0x80)==0x00);
return bcd_to_char(TWDR);
}
int min_rw()
{
TWCR|=(1<<TWINT); //RTC minute read
TWCR|=(1<<TWEA);
while((TWCR & 0x80)==0x00);
return bcd_to_char(TWDR);
}
int hr_rw()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC hour read
while((TWCR & 0x80)==0x00);
return bcd_to_char(TWDR);
}
int day_rd()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC day read
while((TWCR&0x80)==0x00);
return bcd_to_char(TWDR);
}
int date_rw()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC date read
while((TWCR & 0x80)==0x00);
return bcd_to_char(TWDR);
}
int month_rw()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC month read
while((TWCR & 0x80)==0x00);
return bcd_to_char(TWDR);
}
int yr_rw()
{
TWCR|=(1<<TWINT); //RTC year read
TWCR&=(~(1<<TWEA));
while((TWCR & 0x80)==0x00);
return bcd_to_char(TWDR);
}
void setTime()
{
RTC_start();
device();
sec_init(0);
min_init(dec_to_bcd(min));
hr_init(dec_to_bcd(hr));
RTC_stp();
}
void RTC()
{
RTC_read();
sec=sec_rw();
min=min_rw();
hr=hr_rw();
day=day_rd();
dd=date_rw();
mm=month_rw();
yy=yr_rw();
RTC_stp();
}
char get_SETTINGS(uint8_t count)
{
while(1)
{
update_Time();
if(!upEvent)
{
count++;
if(setFlag == hour)
{
if(timeFormat == 24)
{
if(count > 23)
count=0;
}
hr=count;
}
else if(setFlag == minute)
{
if(count>59)
count=0;
min=count;
}
_delay_ms(100);
}
else if(!(downEvent))
{
count--;
if(setFlag == hour)
{
if(timeFormat == 24)
{
if(count > 23)
count=0;
}
hr=count;
}
else if(setFlag == minute)
{
if(count>59)
count=0;
min=count;
}
_delay_ms(100);
}
else if(!okEvent)
{
_delay_ms(500);
return count;
}
}
}
void setting_Time()
{
setFlag=1;
hr=get_SETTINGS(hr);
setFlag++;
min=get_SETTINGS(min);
setFlag=0;
}
void update_Time()
{
d0=min%10;//минуты
d1=min/10;//десятки минут
d2=hr%10;//часы
d3=hr/10;//десятки часов
}
const uint8_t dig[] = {
0b10000001, //0
0b11110011, //1
0b01001001, //2
0b01100001, //3
0b00110011, //4
0b00100101, //5
0b00000101, //6
0b11110001, //7
0b00000001, //8
0b00100001, //9
0b00000000,//пусто
0b00000001}; //точка
const uint8_t razr[] = {
0b11111110,
0b11111101,
0b11111011,
0b11110111};
uint8_t display[2];
volatile uint8_t i, a=0,k;
volatile uint16_t dot=0;
uint8_t dig1, dig2, dig3, dig4;
void init_timer0()
{
TIMSK =(1<<TOIE0); // timer0 enable
TCCR0 = (1<<CS01); // prescaler 1/1024
TCNT0=128;
sei();
}
void write_display(unsigned char *data)
{
unsigned char mask,i;
for(i = 0; i < 2; i++)
{
mask = 0x80;
for(char k = 0; k < 8; k++)
{
// Сравниваем каждый бит с единицей
if(data[i] & mask)
{
PORTB |= (1 << 0); // DATA 1
PORTB |= (1 << 1); // CLK 1
PORTB &= ~(1 <<1); // CLK 0
}
else
{
PORTB &= ~(1 << 0); // DATA 0
PORTB |= (1 << 1); // CLK 1
PORTB &= ~(1 << 1); // CLK 0
}
mask = mask >> 1; // Сдвигаем биты
}
}
// Защелкиваем регистр
PORTB |= (1 << 2);
PORTB &= ~(1 << 2);
}
ISR (TIMER0_OVF_vect)
{
(k == 4) ? k = 0: k++;
switch(k)
{
case 0:
dig4=dig[d3] ;
display[0] = razr[3];
display[1] = ~ dig4;
write_display(display);
break;
case 1:
dig3=dig[d2];
display[0] = razr[2];
display[1] = ~ dig3;
write_display(display);
break;
case 2:
dig2=dig[d1];
display[0] = razr[1];
display[1] = ~dig2;
write_display(display);
break;
case 3:
dig1=dig[d0];
display[0] =razr[0]; // в крайний левый символ
display[1] =~ dig1; // выводится цифра
write_display(display);
break;
case 4:
dig3=dig[d2];
display[0] =razr[2]; // в крайний левый символ
display[1] =dig[10|dot]; // выводится цифра
write_display(display);
break;
}
}
int main(void)
{
init_ports();
init_timer0();
while (1)
{
RTC();
update_Time();
if (sec&1) dot=0;
else
{
dot=dig[11];
}
if (!setEvent)
{
setting_Time();
setTime();
}
}
}


