Ir ao conteúdo
  • Cadastre-se

Mikroc - DS1307 ( Relógio de Tempo Real )


mycontato

Posts recomendados

:aplausos: Olá a todos !!!! :aplausos:

Pessoal, eu tenho uma dúvida que pode ser a dúvida de muitos que utilizam linguagem C para programação de PIC, utilizando o compilador MikroC, vasculhei a internet, e não achei nada que fosse solucionar minha dúvida, e queria pedir ao administrador, que se possivel, deixar esse tópico fixo, para consultas posteriores. Bom, vamos lá:

Eu estou desenvolvendo um programa utilizando o compilador Mikroc, para o microcontrolador 18F452 da Microchip, onde será exibido a Data e a Hora em um LCD 16x4, estou utilizando para isso o componente DS1307.

Eu criei o programa e esta funcionando normalmente, esta exibindo a data e a hora, mas só que dentro do Void Main, fui obrigado a chamar a rotina do DS1307 e do display LCD, dentro de um laço while, onde a rotina do DS1307 é atualizada constantemente, e a do display LCD também é atualizada, mostrando em tempo real a contagem do DS1307.

Mas só que, como o programa fica preso dentro do laço while, eu não consigo fazer mais nada no programa ao mesmo tempo que o relógio esta sendo exibido no LCD, devido tudo que for realizado fora do laço while, não funciona.

Eu gostaria de saber, se possue alguma outra forma de se fazer a atualização e exibição da Data e da Hora, sem usar laço While, isso é possivel ?!?!? Alguem conhece alguma outra forma ?!?!?

Vejam código:

unsigned short horas,minuto,segundo; 
unsigned short dia, mes, ano, dia_semana;
unsigned short var1, var2;
char *texto;
// Rotina de conversão de dados para BCD
void BCD(unsigned short lin, unsigned short col,unsigned short var) {
var1= (var >> 4) + 0x30; //converte o primeiro nibble em BCD e após em string
LCD_custom_Chr(lin,col,var1);//escreve caractere no LCD
var2= (var & 0x0F) + 0x30; //converte o segundo nibble em BCD e após isso, em string
LCD_custom_Chr_Cp(var2); //escreve caractere no LCD
}
void leitura_rtc() { //rotina de leitura do DS1307
I2C_Start(); //inicializa comunicação i2c
I2C_Wr(0xD0); //end fixo para DS1307: 1101000X, onde x = 0 é para gravação
I2C_Wr(0); //end onde começa a programação do relógio, end dos segundos.
I2C_Repeated_Start(); //Issue I2C signal repeated start
I2C_Wr(0xD1); //end fixo para DS1307: 1101000X, onde x=1 é para leitura
segundo= I2C_Rd(1); //lê o primeiro byte(segundos),informa que continua lendo
minuto= I2C_Rd(1); //lê o segundo byte(minutos)
horas= I2C_Rd(1); //lê o terceiro byte(horas)
dia_semana= I2C_Rd(1);
dia= I2C_Rd(1);
mes= I2C_Rd(1);
ano= I2C_Rd(0); //lê o sétimo byte(ano),encerra as leituras de dados
I2C_Stop(); //finaliza comunicação I2C
}
void grava_rtc(){
I2C_Init(100000);//iniciliza I2C com frequencia de 100KHz
I2C_Start(); //inicializa a comunicação I2c
I2C_Wr(0xD0); //end fixo para DS1307: 1101000X, onde x = 0 é para gravação
I2C_Wr(0); //end onde começa a programação do relógio, end dos segundos.
I2C_Wr(0x04); //inicializa com 04 segundos.
I2C_Wr(0x12); //inicializa com 12 minutos.
I2C_Wr(0x09); //inicializa com 09:00hs (formato 24 horas).
I2C_Wr(0x03); //inicializa com terça
I2C_Wr(0x17); //inicializa com dia 17
I2C_Wr(0x04); //inicializa com mês 04
I2C_Wr(0x07); //inicializa com ano 07
I2C_Stop(); //finaliza comunicação I2C
}
void encontra_dia_semana() {
switch (dia_semana) {
case 01: texto= "DOMINGO"; break; //caso dias_semana = 01 então..
case 02: texto= "SEGUNDA"; break; //caso dias_semana = 02 então..
case 03: texto= "TERCA"; break; //caso dias_semana = 03 então..
case 04: texto= "QUARTA"; break; //caso dias_semana = 04 então..
case 05: texto= "QUINTA"; break; //caso dias_semana = 05 então..
case 06: texto= "SEXTA"; break; //caso dias_semana = 06 então..
default: texto= "sábado"; //se não for nenhum desses então...
}
}
void display_lcd() {
lcd_custom_cmd(lcd_clear); //apaga lcd
Lcd_Custom_Out(1,1,"(Hora)");
BCD(1,7,horas); //conversão da variável horas para BCD
LCD_custom_Chr_Cp(':'); //escreve no display LCD
BCD(1,10,minuto); //conversão da variável minuto para BCD
LCD_custom_Chr_Cp(':'); //escreve no display LCD
BCD(1,13,segundo); //conversão da variável segundo para BCD
Lcd_Custom_Out(2,1,"(Data)");
BCD(2,7,dia); //conversão da variável dia para BCD
LCD_custom_Chr_Cp('/'); //escreve no display LCD
BCD(2,10,mes); //conversão da variável mes para BCD
LCD_custom_Chr_Cp('/'); //escreve no display LCD
BCD(2,13,ano); //conversão da variável ano para BCD
encontra_dia_semana();
Lcd_Custom_out(3,1,texto); //mostra dia da semana
}
void main(){
trisd= 0; //define portd como saida
adcon1= 0x06; //torna todos os pinos AD como i/o de uso geral
Lcd_custom_Config(&PORTD,7,6,5,4,&PORTE,2,0,1);//config LCD no modo 4 bits
Lcd_custom_Cmd(Lcd_CLEAR); //apaga display
Lcd_custom_Cmd(Lcd_CURSOR_OFF); //desliga cursor
grava_rtc();
while(1){
display_lcd(); //escreve no display lcd o valor
leitura_rtc(); //efetua leitura de segundo, minuto e horas do DS1307
delay_ms(200); //delay de 200 milisegundos
}
}

Laço While que estou tempo problemas:



while(1){
display_lcd(); //escreve no display lcd o valor
leitura_rtc(); //efetua leitura de segundo, minuto e horas do DS1307
delay_ms(200); //delay de 200 milisegundos
}
[B]TUDO QUE É FEITO AQUI FORA NÃO FUNCIONA[/B]

:lol: Toda ajuda será muito bem vinda. :lol:

:jump: Desde já, muito obrigado a todos. :jump:

Link para o comentário
Compartilhar em outros sites

por exemplo:


int x;
void main()
{
.....
......
....

x = 2;
while(x==2)
{
//Faça seus codigos antes disso:
display_lcd(); //escreve no display lcd o valor
leitura_rtc(); //efetua leitura de segundo, minuto e horas do S1307
// ai voce faz algum comando que defina a variavel x para por exemplo 3 ai ele não faz o loop

Espero ter ajudado.

Link para o comentário
Compartilhar em outros sites

ola

eu ntive um problema parecido

você pode deixar o seu rtc contando

e colocar as otras funcoes dentro do while

foi isso que eu fiz, por exemplo

atualizo as variaves com o tempo antes de dar a volta no laço

no inicio do laço escrevo o tempo

e entre esses 2 eu executo as outras operacoes, nao precisa se preocupar com perda de tempo

pois o trc nao para de contar e normalmente outras execucoes levam microsegundos para serem executadas então nao vai faze diferença nenhuma

você pode colocar um teclado matricial e faze po exemplo

se tecla tal for pressionada faz tal coisa

se outra tecla executa outra coisa

da uma olhadinha no meu topico "problemas com i2c e pic"

lá eu coloquei um programa assim

espero ter ajudado

Link para o comentário
Compartilhar em outros sites

  • 9 meses depois...
  • 1 ano depois...
:aplausos: Olá a todos !!!! :aplausos:

Pessoal, eu tenho uma dúvida que pode ser a dúvida de muitos que utilizam linguagem C para programação de PIC, utilizando o compilador MikroC, vasculhei a internet, e não achei nada que fosse solucionar minha dúvida, e queria pedir ao administrador, que se possivel, deixar esse tópico fixo, para consultas posteriores. Bom, vamos lá:

Eu estou desenvolvendo um programa utilizando o compilador Mikroc, para o microcontrolador 18F452 da Microchip, onde será exibido a Data e a Hora em um LCD 16x4, estou utilizando para isso o componente DS1307.

Eu criei o programa e esta funcionando normalmente, esta exibindo a data e a hora, mas só que dentro do Void Main, fui obrigado a chamar a rotina do DS1307 e do display LCD, dentro de um laço while, onde a rotina do DS1307 é atualizada constantemente, e a do display LCD também é atualizada, mostrando em tempo real a contagem do DS1307.

Mas só que, como o programa fica preso dentro do laço while, eu não consigo fazer mais nada no programa ao mesmo tempo que o relógio esta sendo exibido no LCD, devido tudo que for realizado fora do laço while, não funciona.

Eu gostaria de saber, se possue alguma outra forma de se fazer a atualização e exibição da Data e da Hora, sem usar laço While, isso é possivel ?!?!? Alguem conhece alguma outra forma ?!?!?

Vejam código:

unsigned short horas,minuto,segundo; 
unsigned short dia, mes, ano, dia_semana;
unsigned short var1, var2;
char *texto;
// Rotina de conversão de dados para BCD
void BCD(unsigned short lin, unsigned short col,unsigned short var) {
var1= (var >> 4) + 0x30; //converte o primeiro nibble em BCD e após em string
LCD_custom_Chr(lin,col,var1);//escreve caractere no LCD
var2= (var & 0x0F) + 0x30; //converte o segundo nibble em BCD e após isso, em string
LCD_custom_Chr_Cp(var2); //escreve caractere no LCD
}
void leitura_rtc() { //rotina de leitura do DS1307
I2C_Start(); //inicializa comunicação i2c
I2C_Wr(0xD0); //end fixo para DS1307: 1101000X, onde x = 0 é para gravação
I2C_Wr(0); //end onde começa a programação do relógio, end dos segundos.
I2C_Repeated_Start(); //Issue I2C signal repeated start
I2C_Wr(0xD1); //end fixo para DS1307: 1101000X, onde x=1 é para leitura
segundo= I2C_Rd(1); //lê o primeiro byte(segundos),informa que continua lendo
minuto= I2C_Rd(1); //lê o segundo byte(minutos)
horas= I2C_Rd(1); //lê o terceiro byte(horas)
dia_semana= I2C_Rd(1);
dia= I2C_Rd(1);
mes= I2C_Rd(1);
ano= I2C_Rd(0); //lê o sétimo byte(ano),encerra as leituras de dados
I2C_Stop(); //finaliza comunicação I2C
}
void grava_rtc(){
I2C_Init(100000);//iniciliza I2C com frequencia de 100KHz
I2C_Start(); //inicializa a comunicação I2c
I2C_Wr(0xD0); //end fixo para DS1307: 1101000X, onde x = 0 é para gravação
I2C_Wr(0); //end onde começa a programação do relógio, end dos segundos.
I2C_Wr(0x04); //inicializa com 04 segundos.
I2C_Wr(0x12); //inicializa com 12 minutos.
I2C_Wr(0x09); //inicializa com 09:00hs (formato 24 horas).
I2C_Wr(0x03); //inicializa com terça
I2C_Wr(0x17); //inicializa com dia 17
I2C_Wr(0x04); //inicializa com mês 04
I2C_Wr(0x07); //inicializa com ano 07
I2C_Stop(); //finaliza comunicação I2C
}
void encontra_dia_semana() {
switch (dia_semana) {
case 01: texto= "DOMINGO"; break; //caso dias_semana = 01 então..
case 02: texto= "SEGUNDA"; break; //caso dias_semana = 02 então..
case 03: texto= "TERCA"; break; //caso dias_semana = 03 então..
case 04: texto= "QUARTA"; break; //caso dias_semana = 04 então..
case 05: texto= "QUINTA"; break; //caso dias_semana = 05 então..
case 06: texto= "SEXTA"; break; //caso dias_semana = 06 então..
default: texto= "sábado"; //se não for nenhum desses então...
}
}
void display_lcd() {
lcd_custom_cmd(lcd_clear); //apaga lcd
Lcd_Custom_Out(1,1,"(Hora)");
BCD(1,7,horas); //conversão da variável horas para BCD
LCD_custom_Chr_Cp(':'); //escreve no display LCD
BCD(1,10,minuto); //conversão da variável minuto para BCD
LCD_custom_Chr_Cp(':'); //escreve no display LCD
BCD(1,13,segundo); //conversão da variável segundo para BCD
Lcd_Custom_Out(2,1,"(Data)");
BCD(2,7,dia); //conversão da variável dia para BCD
LCD_custom_Chr_Cp('/'); //escreve no display LCD
BCD(2,10,mes); //conversão da variável mes para BCD
LCD_custom_Chr_Cp('/'); //escreve no display LCD
BCD(2,13,ano); //conversão da variável ano para BCD
encontra_dia_semana();
Lcd_Custom_out(3,1,texto); //mostra dia da semana
}
void main(){
trisd= 0; //define portd como saida
adcon1= 0x06; //torna todos os pinos AD como i/o de uso geral
Lcd_custom_Config(&PORTD,7,6,5,4,&PORTE,2,0,1);//config LCD no modo 4 bits
Lcd_custom_Cmd(Lcd_CLEAR); //apaga display
Lcd_custom_Cmd(Lcd_CURSOR_OFF); //desliga cursor
grava_rtc();
while(1){
display_lcd(); //escreve no display lcd o valor
leitura_rtc(); //efetua leitura de segundo, minuto e horas do DS1307
delay_ms(200); //delay de 200 milisegundos
}
}

Laço While que estou tempo problemas:



while(1){
display_lcd(); //escreve no display lcd o valor
leitura_rtc(); //efetua leitura de segundo, minuto e horas do DS1307
delay_ms(200); //delay de 200 milisegundos
}
[B]TUDO QUE É FEITO AQUI FORA NÃO FUNCIONA[/B]

:lol: Toda ajuda será muito bem vinda. :lol:

:jump: Desde já, muito obrigado a todos. :jump:

preciso de ajuda com esse codigo cpm ´posso ajusta as horae


// Dosya Adi : 14_4.c
// Açiklama : DS1302 RTC
// Notlar : Proteus programi simülasyonu
// : XT ==> 4 MHz
// *****************************************************************
//------------------------------------------------------------------
// DS1302'nin mikrodenetleyiciye baglantilari tanimlaniyor
//------------------------------------------------------------------
#define ds1302 PORTC
#define ds1302_tris TRISC
#define rst_pin F0
#define clk_pin F1
#define data_pin F2
//------------------------------------------------------------------
// DS1302'nin mikrodenetleyiciye baglantilari tanimlaniyor
//------------------------------------------------------------------
unsigned char saniye, dakika, saat, gun, ay, yil, haftaningunu;
char *str=" \0";


//------------------------------------------------------------------
// Hexadesimal degeri LCD'de görüntülemek için text'e dönüstürür.
//------------------------------------------------------------------
void BintoStr(char data)
{
str[0]= 48 + ((data & 0xF0) >> 4); // En degerli dört bit ve
str[1]= 48 + (data & 0x0F); // en degersiz dört bit
// text'e dönüstürüldü
}
//------------------------------------------------------------------
// DS1302'nin mikrodenetleyiciye baglantilari tanimlaniyor
//------------------------------------------------------------------
void init_3wire()
{
// ds1302'ye baglanan pinler yönlendiriliyor.
ds1302_tris.data_pin = 0;
ds1302_tris.rst_pin = 0;
ds1302_tris.clk_pin = 0;

// ds1302'ye baglanan pinler LOW seviyesine çekiliyor
ds1302.data_pin = 0;
ds1302.rst_pin = 0;
ds1302.clk_pin = 0;
}
//------------------------------------------------------------------
// DS1302'nin mikrodenetleyiciye baglantilari tanimlaniyor
//------------------------------------------------------------------
void reset_3wire()
{
// ds1302 resetleniyor
ds1302.clk_pin = 0;
ds1302.rst_pin = 0;
ds1302.rst_pin = 1;
}
//------------------------------------------------------------------
// DS1302'nin mikrodenetleyiciye baglantilari tanimlaniyor
//------------------------------------------------------------------
void write_byte_3wire(unsigned char veri)
{
unsigned char i;
// data pini çikisa yönlendiriliyor.
ds1302_tris.data_pin = 0;
for(i = 0; i < 8; ++i)
{
// Verinin 0. biti 1 ise data_pin HIGH, 0 ise LOW seviyesine
// çekiliyor.
if(veri.F0) ds1302.data_pin = 1; else ds1302.data_pin = 0;
// Saat darbesi uygulaniyor. (yükselen kenar)
ds1302.clk_pin = 0;
ds1302.clk_pin = 1;
veri = (veri>>1); // Veri 1 bit saga kaydiriliyor.
}
}
//------------------------------------------------------------------
// DS1302'nin mikrodenetleyiciye baglantilari tanimlaniyor
//------------------------------------------------------------------
unsigned char read_byte_3wire()
{
unsigned char i, veri;
// data pini veri okumak için girise yönlendiriliyor.
ds1302_tris.data_pin = 1;
veri = 0x00; // Verinin ilk degeri sifir
for(i=0; i<8; ++i)
{
// 1 bit okumak için saat darbesi uygulaniyor
ds1302.clk_pin = 1;
ds1302.clk_pin = 0;
veri >>= 1; // veri bir bit saga kaydiriliyor.
// ds1302'nin data_pininden gene veri 1 ise verinin 7. biti 1
// yapiliyor, aksi durumda verinin 7. biti 0 yapiliyor.
if(ds1302.data_pin) veri.F7 = 1; else veri.F7 = 0;
}
return veri; // okunan veriyi fonksiyon disina tasi
}
//------------------------------------------------------------------
// DS1302'ye tarih, saat ve haftanin günü bilgisi yaziliyor ve
// batarya sarj devresi tespit ediliyor.
//------------------------------------------------------------------
void DS1302_Init()
{
init_3wire(); // 3 yol iletisimi kullanima hazirla
reset_3wire(); // 3 yol iletisimi resetle
write_byte_3wire(0x8E); // kontrol kaydedicisine erisim
// saglaniyor
write_byte_3wire(0); // Yazma korumasi kaldiriliyor.

reset_3wire(); // 3 yol iletisimi resetle
write_byte_3wire(0x90); // trickle charger kaydedicisine
// erisim saglaniyor
write_byte_3wire(0xAB); // 8 Kohm direnç üzerinden 2
// diyotlu sarj birimi seçildi
reset_3wire(); // 3 yol iletisimi resetle
write_byte_3wire(0xBE); // sirali 8 adet kaydediciye
// yazilacagi belirtiliyor.
write_byte_3wire(saniye); // saniye bilgisini yaz
write_byte_3wire(dakika); // dakika bilgisini yaz
write_byte_3wire(saat); // saat bilgisini yaz
write_byte_3wire(gun); // gun bilgisini yaz
write_byte_3wire(ay); // ay bilgisini yaz
write_byte_3wire(haftaningunu); // haftanin günü bilgisini yaz
write_byte_3wire(yil); // yil bilgisini yaz
write_byte_3wire(0); // Kontrol kaydedicisine 0 bilgisi yaz
reset_3wire(); // 3 yol iletisimi resetle
}
//------------------------------------------------------------------
// DS1302'den zaman bilgisi okunuyor.
//------------------------------------------------------------------
void DS1302_ReadTime()
{
reset_3wire(); // 3 yol iletisimi resetle
// DS1302'den sirali saat ve tarih bilgisi okuma baslatiliyor
write_byte_3wire(0xBF);
saniye = read_byte_3wire(); // saniye bilgisini oku
dakika = read_byte_3wire(); // dakika bilgisini oku
saat = read_byte_3wire(); // saat bilgisini oku
gun = read_byte_3wire(); // gun bilgisini oku
ay = read_byte_3wire(); // ay bilgisini oku
haftaningunu = read_byte_3wire();// haftanin günü bilgisini oku
yil = read_byte_3wire(); // yil bilgisini oku
reset_3wire(); // 3 yol iletisimi resetle
}
//------------------------------------------------------------------
// DS1302'den daha tarih, saat ve haftanin günü bilgisini LCD'de
// görüntüler.
//------------------------------------------------------------------
void Display_Time()
{
LCD_Out(1,1,"DATA"); // 1.satir, 1.karakterden yazmaya basla
LCD_Out_Cp(" ");
BintoStr(gun); // gün bilgisini text'e dönüstür
LCD_Out_Cp(str); // ve imlecin bulundugu yerden
// baslayarak yaz
LCD_Out_Cp("-"); // - isareti imlecin bulundugu yerden
// baslayarak yaz
BintoStr(ay); // ay bilgisini text'e dönüstür
LCD_Out_Cp(str); // ve imlecin bulundugu yerden
// baslayarak yaz
LCD_Out_Cp("-"); // - isareti imlecin bulundugu yerden
// baslayarak yaz
LCD_Out_Cp("20"); // yilin ilk 2 hanesini imlecin
// bulundugu yerden baslayarak yaz
BintoStr(yil); // yil bilgisini text'e dönüstür
LCD_Out_Cp(str); // ve imlecin bulundugu yerden
// baslayarak yaz
LCD_Out(2,1,""); // 2.satir, 1.karakterden yazmaya basla
switch(haftaningunu) // haftanin gününü LCD'de görüntüler
{
case 1: LCD_Out_Cp("DOMINGO");break; // haftanin günü 1 ise
// PAZARTESI
case 2: LCD_Out_Cp("SEGUNDA");break; // haftanin günü 2 ise
// SALI
case 3: LCD_Out_Cp("TERCA");break; // haftanin günü 3 ise
// ÇARSAMBA
case 4: LCD_Out_Cp("QUARTA");break; // haftanin günü 4 ise
// PERSEMBE
case 5: LCD_Out_Cp("QUINTA");break; // haftanin günü 5 ise
// CUMA
case 6: LCD_Out_Cp("SEXTA");break; // haftanin günü 6 ise
// CUMARTESI
case 7: LCD_Out_Cp("sábado");break; // haftanin günü 7 ise
// PAZAR
} LCD_Out_Cp(" ");
BintoStr(saat); // saat bilgisini text'e dönüstür
LCD_Out_Cp(str); // ve imlecin bulundugu yerden
// baslayarak yaz
LCD_Out_Cp(":"); // : isareti imlecin bulundugu yerden
// baslayarak yaz
BintoStr(dakika); // dakika bilgisini text'e dönüstür
LCD_Out_Cp(str);
LCD_Out_Cp(":"); // : isareti imlecin bulundugu yerden
// baslayarak yaz
BintoStr(saniye); // saniye bilgisini text'e dönüstür
LCD_Out_Cp(str);
LCD_Out_Cp(" "); // 2 karakter bosluk imlecin bulundugu
// yerden baslayarak yaz
///////////////////////////////
}
//------------------------------------------------------------------
// LCD ve DS1302 RTC birimini kullanima hazirlar.
//------------------------------------------------------------------
void init()
{
// LCD baglantisi tanimlaniyor
LCD_Config(&PORTB,4,5,7,3,2,1,0);
LCD_Cmd(LCD_CURSOR_OFF); // imleci gizle
saniye = 0x50;
dakika = 0x59;
saat = 0x23;
gun = 0x27;
ay = 0x04;
yil = 0x06;
haftaningunu = 0x04; // Persembe
DS1302_Init();
}
//------------------------------------------------------------------
// Ana program DS1302 saat entegresine bir tarih ve saat bilgisi
// yazar. Daha sonra tarih, saat ve haftanin gününü sürekli okuyarak
// LCD ekranda görüntüler.
//------------------------------------------------------------------
void main()
{
init();
do
{
DS1302_ReadTime();
Display_Time();
} while(1);
}
// *****************************************************************

//escreva urgente

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...