Vous êtes sur la page 1sur 8

Relgio e Calendrio Digital com RTC

DS1307

Esse projeto trata-se de um relgio e um calendrio digital. A base


de contagem do tempo o RTC DS1307. O DS1307 na mais do
que um Relgio de Tempo Real que se comunica com o
microcontrolador via I2C.
O DS1307 possui 7 registros internos destinados para a contagem
dos segundos, minutos, horas, dia da semana, dia do ms, ms e
ano. Esse RTC tambm "sabe" se ano bissexto ou no e possui a
opo de horrio 24 horas ou 12 Horas (AM - PM).

Uma coisa ruim que eu acho desse DS1307 que ele trabalha com
nmero BCD ao invs de trabalhar com binrios (que bem mais
fcil).
Ao pressionar a chave S1, altera a seleo de ajuste (segundos,
minutos, ... ). A chave S2 e S3, altera o valor, incrementando-o ou
decrementando-o respectivamente.

No projeto foi utilizado um Clock para o MCU de 4MHz e para o


RTC foi de 32,768KHz.
DOWNLOAD:
Firmware: Clock.hex;
Arquivo de simulao do Proteus: Clock.DSN;
Arquivo
-

Fonte: Clock.asm;

CDIGO-FONTE:
MikroC PRO PIC
1.

sbit LCD_RS at RB4_bit;

2.
sbit LCD_EN at RB5_bit;
3.
sbit LCD_D4 at RB6_bit;
4.
sbit LCD_D5 at RB1_bit;
5.
sbit LCD_D6 at RB2_bit;
6.
sbit LCD_D7 at RB3_bit;
7.
8.
sbit LCD_RS_Direction at TRISB4_bit;
9.
sbit LCD_EN_Direction at TRISB5_bit;
10.
sbit LCD_D4_Direction at TRISB6_bit;
11.
sbit LCD_D5_Direction at TRISB1_bit;
12.
sbit LCD_D6_Direction at TRISB2_bit;
13.
sbit LCD_D7_Direction at TRISB3_bit;
14.
15.
unsigned short segundos, minutos, horas, semana, dia, mes, ano;
16.
unsigned short sgs, mins, hrs, ss, dd, mm, yy;
17.
unsigned short cnt=7;
18.
19.
//Funo para converter BCD para string e escrever no LCD
20.
void BcdToStr(unsigned short x, unsigned short y, unsigned
short var){
21.
unsigned short var1, var2;
22.
var1 = (var >> 4) + 0x30;
23.
Lcd_Chr(x,y,var1);
24.
var2 = (var & 0x0F) + 0x30;
25.
Lcd_Chr_CP(var2);
26.
}
27.
28.
//funo que inicializa a comunicao com o DS1307
29.
void programa_i2c(){
30.
31.
I2C1_Init(100000); //inicializa com frequencia de 100KHz
32.
I2C1_start();
//Envia um sinal de START
33.
I2C1_Wr(0xD0); //Envia o endereo do RTC no barramento para se
fazer a escrita
34.
I2C1_Wr(0x00);
//Endereo do registro 0x00 do RTC (e por
onde vc comea a gravar)
35.
I2C1_Wr(0x00); //define segundos com o valor inicial 0
36.
I2C1_Wr(0x00); //define minutos com o valor inicial 0
37.
I2C1_Wr(0x00); //define horas com o valor inicial 0
38.
I2C1_Wr(0x01); //define dia com o valor inicial 1
39.
I2C1_Wr(0x01); //define data com o valor inicial 1
40.
I2C1_Wr(0x02); //define mes com o valor inicial 2
41.
I2C1_Wr(0x12); //define ano com o valor inicial 12
42.
43.
I2C1_Stop(); // Envia um sinal de STOP
44.
}
45.
46.
//funo para ajustar o valor

47.
void escrita_i2c(unsigned short registro, unsigned short
valor){
48.
49.
i2c1_stop(); //caso o barramento estiver ocupado envia um sinal
de STOP
50.
i2c1_start(); // envia um sinal de START
51.
i2c1_wr(0xD0);
//endereo do RTC no barramento e fazer a
escrita
52.
i2c1_wr(registro); //endereo do registro(segundos=0x00, ...)
53.
i2c1_wr(valor); // valor que voc quer escrever
54.
i2c1_stop(); //envia um sinal de STOP
55.
56.
}
57.
58.
//funo que daz a leitura dos dados
59.
void leitura_i2c(){
60.
i2c1_start(); // Envia um sinal de START
61.
i2c1_wr(0xD0); //endereo no barramento e indicao de escrita
62.
i2c1_wr(0x00); //endereo inicial
63.
i2c1_Repeated_Start(); //Restart no barramento
64.
i2c1_wr(0xD1); // endereo no barramento e indicao de leitura
65.
segundos = i2c1_rd(1); //l o 1 endereo e informa que ira
continuar a leitura
66.
minutos = i2c1_rd(1); //l o 2 endereo e informa que ira
continuar a leitura
67.
horas
= i2c1_rd(1); //l o 3 endereo e informa que ira
continuar a leitura
68.
semana = i2c1_rd(1); //l o 4 endereo e informa que ira
continuar a leitura
69.
dia = i2c1_rd(1); //l o 5 endereo e informa que ira
continuar a leitura
70.
mes = i2c1_rd(1); //l o 6 endereo e informa que ira
continuar a leitura
71.
ano = i2c1_rd(0); //l o 7 endereo e informa que no ira mais
ler
72.
i2c1_stop(); // envia um sinal de STOP
73.
}
74.
75.
void encontrar_semana(){
76.
switch(semana){
77.
case 1: Lcd_Out(2,13,"DOMINGO");break;
78.
case 2: Lcd_Out(2,13,"SEGUNDA");break;
79.
case 3: Lcd_Out(2,13," TERCA ");break;
80.
case 4: Lcd_Out(2,13,"QUARTA ");break;
81.
case 5: Lcd_Out(2,13,"QUINTA ");break;
82.
case 6: Lcd_Out(2,13," SEXTA ");break;
83.
case 7: Lcd_Out(2,13,"SABADO ");break;
84.
}
85.
}
86.
//funo que escreve no LCD qual ajuste voc est fazendo

87.
void funcao(unsigned short num){
88.
lcd_Out(1,13,"ADJ");
89.
switch(num){
90.
case 0: Lcd_Out(1,17,"SGS");break;
91.
case 1: Lcd_Out(1,17,"MIN");break;
92.
case 2: Lcd_Out(1,17,"HRS");break;
93.
case 3: Lcd_Out(1,17,"DIA");break;
94.
case 4: Lcd_Out(1,17,"DATE");break;
95.
case 5: Lcd_Out(1,17,"MES ");break;
96.
case 6: Lcd_Out(1,17,"ANO");break;
97.
case 7: Lcd_Out(1,17,"OFF");break;
98.
}
99.
}
100.
101. void main(){
102. bit oldstate;
103.
104. TRISD = 255;
105. Lcd_Init(); //inicia LCD
106. Lcd_Cmd(_LCD_CLEAR); //Limpa LCD
107. Lcd_cmd(_LCD_CURSOR_OFF); //desliga cursor do LCD
108.
109. programa_i2c();
110.
111. funcao(7);
112.
113. while(1){
114. BcdToStr(1,1,horas);
115. Lcd_Out_CP(":");
116. BcdToStr(1,4,minutos);
117. Lcd_Out_CP(":");
118. BcdToStr(1,7,segundos);
119. BCdToStr(2,1,dia);
120. Lcd_Out_CP("/");
121. BCdToStr(2,4,mes);
122. Lcd_Out_CP("/");
123. BCdToStr(2,7,ano);
124.
125.
126. leitura_i2c();
127.
128. if(!PORTD.F0){
129. oldstate=1;
130. }
131. //para cada vez que pressionar o botao, altera a funo de
ajuste
132. if(PORTD.F0 && oldstate) {
133. cnt++;

134.
if(cnt==8) cnt=0;
135.
funcao(cnt);
136.
oldstate=0;
137. }
138.
139. if(cnt==0){
140.
if(PORTD.F1 && !PORTD.F2){
141.
sgs = Bcd2Dec(segundos); //recebe
valor, converte-o
142.
sgs++; // incrementa-o
143.
if(sgs==60) sgs=0;
144.
escrita_i2c(0x00,Dec2Bcd(sgs));
//converte-o e escreve no RTC
145.
}else if(!PORTD.F1 && PORTD.F2){
146.
sgs = Bcd2Dec(segundos);
147.
sgs--;
148.
if(sgs<0 || sgs>59) sgs=59;
149.
escrita_i2c(0x00,Dec2Bcd(sgs));
150.
}
151. }else if(cnt==1){
152.
if(PORTD.F1 && !PORTD.F2){
153.
mins = Bcd2Dec(minutos);
154.
mins++;
155.
if(mins==60) mins=0;
156.
escrita_i2c(0x01,Dec2Bcd(mins));
157.
}else if(!PORTD.F1 && PORTD.F2){
158.
mins = Bcd2Dec(minutos);
159.
mins--;
160.
if(mins<0 || mins>59) mins=59;
161.
escrita_i2c(0x01,Dec2Bcd(mins));
162.
}
163. }else if(cnt==2){
164.
if(PORTD.F1 && !PORTD.F2){
165.
hrs = Bcd2Dec(horas);
166.
hrs++;
167.
if(hrs==24) hrs=0;
168.
escrita_i2c(0x02,Dec2Bcd(hrs));
169.
}else if(!PORTD.F1 && PORTD.F2){
170.
hrs = Bcd2Dec(horas);
171.
hrs--;
172.
if(hrs<0 || hrs>23) hrs=23;
173.
escrita_i2c(0x02,Dec2Bcd(hrs));
174.
}
175. }else if(cnt==3){
176.
if(PORTD.F1 && !PORTD.F2){
177.
ss = Bcd2Dec(semana);
178.
ss++;
179.
if(ss==8) ss=1;

180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.

escrita_i2c(0x03,Dec2Bcd(ss));
}else if(!PORTD.F1 && PORTD.F2){
ss = Bcd2Dec(semana);
ss--;
if(ss==0) ss=7;
escrita_i2c(0x03,Dec2Bcd(ss));
}
}else if(cnt==4){
if(PORTD.F1 && !PORTD.F2){
dd = Bcd2Dec(dia);
dd++;
if(dd==32) dd=1;
escrita_i2c(0x04,Dec2Bcd(dd));
}else if(!PORTD.F1 && PORTD.F2){
dd = Bcd2Dec(dia);
dd--;
if(dd<1 || dd>31) dd=31;
escrita_i2c(0x04,Dec2Bcd(dd));
}
}else if(cnt==5){
if(PORTD.F1 && !PORTD.F2){
mm = Bcd2Dec(mes);
mm++;
if(mm==13) mm=1;
escrita_i2c(0x05,Dec2Bcd(mm));
}else if(!PORTD.F1 && PORTD.F2){
mm = Bcd2Dec(mes);
mm--;
if(mm==0) mm=12;
escrita_i2c(0x05,Dec2Bcd(mm));
}
}else if(cnt==6){
if(PORTD.F1 && !PORTD.F2){
yy = Bcd2Dec(ano);
yy++;
if(yy==100) yy=0;
escrita_i2c(0x06,Dec2Bcd(yy));
}else if(!PORTD.F1 && PORTD.F2){
yy = Bcd2Dec(ano);
yy--;
if(yy<0 || yy>99) yy=99;
escrita_i2c(0x06,Dec2Bcd(yy));
}
}
encontrar_semana();
delay_ms(200);

228. }
229. }

Vous aimerez peut-être aussi