Ir ao conteúdo
  • Cadastre-se

Erro com contagem de tempo - PIC16F628A


Symmetric94

Posts recomendados

Olá a todos

Eu estou fazendo meu projeto de TCC que é um sinal escolar automatizado. Nele nós temos o PIC16F628A, um LCD 16x2 pra mostrar as horas o dia da semana e os ajustes de horario, horario do alarme e dia da semana. O sinal sai no momento em que esta programado, assim como um despertador e aciona uma bobina de rele que faz com que a sirene da escola toque.

O projeto está funcionando, tanto que ja até apresentamos para a banca avaliadora. Cumprindo com o objetivo de acionar a sirene no momento em que esta programada.

O problema é que o tempo não está regulado corretamente, fazendo com que em uma hora no tempo real, se passe uma hora e quatro minutos. E nós precisamos entregar esse projeto para a escola.

Vimos varias formas de se conseguir fazer com que o tempo fique certo(usando os 60Hz da rede como referencia, real time clock, usar as interrupções do timer1) mas não sabemos fazer nenhuma dessas mudanças, não sabemos como desenvolver e nem como essas mudanças fariam comunicação com o nosso microcontrolador.

Alguem poderia me ajudar a fazer com que o relogio do projeto fique com o tempo certo de 1 segundo? Por favor

No link segue o esquema eletrico: http://cachor.ro/pjm

Obrigado.

Link para o comentário
Compartilhar em outros sites

Como foi pedido ai em cima, a programação. Foi compilado no MikroCforPIC.

PS: Não fui eu quem fiz a programação, foi um outro integrante do grupo, não entendo essa programação.

Obrigado

 //Lcd pinout settings
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D7 at RB5_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D4 at RB2_bit;

// Pin direction
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D7_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB2_bit;

int increm = 0;
unsigned short s;
unsigned short h;
unsigned short m;
char segun[4];
char minuto[4];
char hora[4];
char numero[4];

unsigned short contsem=1;
char ajuste[]="Ajuste";
char ajuste1[]="Ajuste";
char segunda[]="Segunda";
char terca[]="Terca";
char quarta[]="Quarta";
char quinta[]="Quinta";
char sexta[]="Sexta";
char sábado[]="sábado";
char domingo[]="Domingo";
char alarme[]="Alarme";
unsigned short i;
unsigned short nalarme=0;
unsigned short parar=0;


//Alarme variaveis
unsigned short ah[20]={7,8,9,10,10,11,12,13,14,15,15,15,16,18,19,20,21,22};
unsigned short am[20]={30,20,10,0,20,10,0,30,20,10,35,55,0,0,0,50,15,55};


void interrupt() //Função reservada do MikroC, não chama no Main porque
{ //Roda por fora dele
intcon.t0if=0; //zere a flag a cada estouro
increm++; //e incremente a variavel de incremento
if(increm==15){
increm=0 ; //Zere-o
s++ ; //E faça um segundo
}
if(contsem==7){
contsem=0;
}
if(h>23){
h=0;
contsem++;
}
if(m>59){
m=0;
s=0;
h++;
}
if(s>59){
m++;
s=0;
}
}



void horamin(){
bytetostr(m,minuto); //conversão de variável para caractere
Lcd_out(2,6,minuto); //Minutos

Lcd_out(2,6,":"); //doispontos

bytetostr(h,hora); //conversão de variável para caractere
Lcd_out(2,3,hora); //hora

}

void exibe(unsigned short ah, unsigned short am, unsigned short alarme){
bytetostr(am,minuto);
Lcd_out(2,6,minuto);
Lcd_out(2,6,":");
bytetostr(ah,hora);
Lcd_out(2,3,hora);
bytetostr(ah,hora);
bytetostr(alarme,numero);
Lcd_out(1,11,numero);
delay_ms(100);
}

void semana(){
if(contsem==0){Lcd_Out(1,4,domingo);}
else if(contsem==1){Lcd_Out(1,4,segunda);}
else if(contsem==2){Lcd_Out(1,4,terca);}
else if(contsem==3){Lcd_Out(1,4,quarta);}
else if(contsem==4){Lcd_Out(1,4,quinta);}
else if(contsem==5){Lcd_Out(1,4,sexta);}
else if(contsem==6){Lcd_Out(1,4,sábado);}
}

void semana2(){
if(contsem==0){Lcd_Out(2,4,domingo);}
else if(contsem==1){Lcd_Out(2,4,segunda);}
else if(contsem==2){Lcd_Out(2,4,terca);}
else if(contsem==3){Lcd_Out(2,4,quarta);}
else if(contsem==4){Lcd_Out(2,4,quinta);}
else if(contsem==5){Lcd_Out(2,4,sexta);}
else if(contsem==6){Lcd_Out(2,4,sábado);}
}
void calibrar(){
if(porta.f2 == 1){parar=1;Lcd_Cmd(_LCD_CLEAR);}
while(parar==1){
horamin();
Lcd_Out(1,4,ajuste1);
delay_ms(300);
if(porta.f0 == 1){m++;}
else if(porta.f1 == 1){h++;}
else if(porta.f3 == 1){parar=0;Lcd_cmd(_LCD_CLEAR);}
else if(porta.f2 == 1){parar=2;Lcd_cmd(_LCD_CLEAR);}
}
while(parar==2){
Lcd_cmd(_LCD_CLEAR);
Lcd_Out(1,4,ajuste);
semana2();
delay_ms(300);
if(porta.f3 == 1){parar=0;}
else if(porta.f0 == 1){contsem++;Lcd_cmd(_LCD_CLEAR);}
else if(porta.f2 == 1){parar=3;Lcd_cmd(_LCD_CLEAR);}
}

while(parar==3){
Lcd_cmd(_LCD_CLEAR);
Lcd_Out(1,4,alarme);
delay_ms(300);
while (nalarme<20){
if(porta.f3 == 1){parar=0 ;nalarme=30;}
else if(porta.f2 == 1){nalarme++;}
else if(porta.f1 == 1){ah[nalarme]++;}
else if(porta.f0 == 1){am[nalarme]++;}
if (ah[nalarme]>23){ah[nalarme]=0;}
if (am[nalarme]>59){am[nalarme]=0;}
exibe(ah[nalarme],am[nalarme],nalarme+1);
delay_ms(200);
}
Lcd_cmd(_LCD_CLEAR);
parar=0;
nalarme=0;
}
}

void main() {

TRISA.f0 = 1; //RA1 e 2
TRISA.f1 = 1; //como entrada
TRISB = 0; //PortB todas como saída
PORTB = 0x00; //iniciando em estado zero todas as Portb
PORTA = 0b11111; //iniciando em estado 1 RA0 e RA1
//TMR0 = 0; //Timer 0 ativado
OPTION_REG = 0b000000111; //registrando Prescaller de 256, ativado, com clock interno
INTCON.GIE = 1; //Global Interrupt Ativo.
INTCON.T0IE=1; // interrupção não mascarada.

CMCON |= 0x07; //desativa os comparadores

Lcd_Init(); // Inicie o LCD
Lcd_Cmd(_LCD_CLEAR); // Limpe tudo
Lcd_Cmd(_LCD_CURSOR_OFF); // E desligue o cursor

s=55; // valores previos de hora minuto e segundo
m=59;
h=18;


while(1){
//Lcd_cmd(_LCD_CLEAR);
Lcd_out(2,9,":"); //doispontos

bytetostr(s,segun); //conversão de variável para caractere
Lcd_out(2,9,segun); //hora

horamin(); //chama hora minuto
semana();
calibrar();
for (i=0;i<20;i++){
if (ah[i]==h && am[i]==m && s < 10 && contsem!=0 && contsem!=6){ // condição do disparo
portb.f6 = 1; //disparo do sinal
}
if (ah[i]==h && am[i]==m && s == 10 && contsem!=0 && contsem!=6){ // condição do disparo
portb.f6 = 0; //disparo do sinal
}
}
delay_ms(500); //Tempo de exibição (tempo de refresh)

}
}

Link para o comentário
Compartilhar em outros sites

Alguem postou o codigo de um relogio usando um rtcc externo e display 7-seg. Dá uma olhada....


Proje Adý: 7 SEGMENT DÝSPLAY ÝLE SAAT-TARÝH-SICAKLIK GÖSTERGESÝ

- 16F877
- DS1302
- LM35
*/

//----- ds1302 pinleri tanýmlanýyor --------------------------------------------
#ifndef rtc_sclk
#define rtc_sclk pin_c1
#define rtc_io pin_c2
#define rtc_rst pin_c0
#endif
//------------------------------------------------------------------------------

#include <16f877.h>
#device adc=10
#fuses XT,NOWDT,NOPROTECT
#use delay (clock=20000000)

#include <DS1302.c>
#include <math.h>
#define set pin_c4
#define mod pin_c5
#define arttir pin_c6
#define azalt pin_c7

byte saniye,dakika,saat,gun,ay,yil,haftanin_gunu;

char display1_onlar,display1_birler,display2_onlar,display2_birler,display3_onlar,display3_birler;

const int display_digit[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; // ortak anotlu için
int i;
int set_degeri=0; // 1=saat 2=tarih
int mod_degeri=0; // 1=saat,gun 2=dakika,ay 3=saniye,yýl
unsigned long int sicaklik_bilgisi;
float sicaklik_degeri,sicaklik_voltaj;
int sicaklik_ekrani=0; //1=aktif, 0=pasif

//------------------------------------------------------------------------------

//----- displaylerin hepsi taranýyor -------------------------------------------
void display_tara()
{

output_d(0b00000001);
output_b(display_digit[display1_onlar]);
delay_ms(2);
output_d(0b00000010);
output_b(display_digit[display1_birler]);
delay_ms(2);
output_d(0b00000100);
output_b(display_digit[display2_onlar]);
delay_ms(2);
output_d(0b00001000);
output_b(display_digit[display2_birler]);
delay_ms(2);
output_d(0b00010000);
output_b(display_digit[display3_onlar]);
delay_ms(2);
output_d(0b00100000);
output_b(display_digit[display3_birler]);
delay_ms(2);

} // display tara
//------------------------------------------------------------------------------

//-------- sicaklik gosterimi icic tarama --------------------------------------
void sicaklik_tara()
{

output_d(0b00000001);
output_b(display_digit[display1_onlar]);
delay_ms(2);
output_d(0b00000010);
output_b(display_digit[display1_birler]);
delay_ms(2);
output_d(0b00000100);
output_b(0x9c); // derece simgesi
delay_ms(2);
output_d(0b00001000);
output_b(0xc6); // C harfi
delay_ms(2);
output_d(0b00000000);

}
//------------------------------------------------------------------------------

//------- gecisler icin animasyon ----------------------------------------------
void gecis_animasyon()
{
output_d(0x00);
delay_ms(300);

output_d(0b00000001);
output_b( 0xb6 );
delay_ms(100);
output_d(0b00000010);
output_b( 0xb6 );
delay_ms(100);
output_d(0b00000100);
output_b( 0xb6 );
delay_ms(100);
output_d(0b00001000);
output_b( 0xb6 );
delay_ms(100);
output_d(0b00010000);
output_b( 0xb6 );
delay_ms(100);
output_d(0b00100000);
output_b( 0xb6 );
delay_ms(100);

output_d(0x00);
delay_ms(300);
}
//------------------------------------------------------------------------------

//------- sadece display1 taranýyor --------------------------------------------
void display1_tara()
{
output_d(0b00000001);
output_b(display_digit[display1_onlar]);
delay_ms(2);
output_d(0b00000010);
output_b(display_digit[display1_birler]);
delay_ms(2);
}
//------------------------------------------------------------------------------

//------- sadece display2 taranýyor --------------------------------------------
void display2_tara()
{
output_d(0b00000100);
output_b(display_digit[display2_onlar]);
delay_ms(2);
output_d(0b00001000);
output_b(display_digit[display2_birler]);
delay_ms(2);
}
//------------------------------------------------------------------------------

//------- sadece display3 taranýyor --------------------------------------------
void display3_tara()
{
output_d(0b00010000);
output_b(display_digit[display3_onlar]);
delay_ms(2);
output_d(0b00100000);
output_b(display_digit[display3_birler]);
delay_ms(2);
}
//------------------------------------------------------------------------------

//------- SET konumunda displayler taranýyor -----------------------------------
void set_konumunda_display_tara()
{
output_d(0x00);
delay_ms(300);
display_tara();
display_tara();
display_tara();
display_tara();
display_tara();
}
//------------------------------------------------------------------------------

//------------- saat tarih ayarý -----------------------------------------------
void ayarlar()
{

if (input(set))
{
while(input(set))
{
if(sicaklik_ekrani==1){ sicaklik_tara(); }
else { display_tara(); }
output_low(pin_a1);output_low(pin_a2);
}
set_degeri=1;
}
else { goto ayardan_cik; }

while(set_degeri==1) //saat ayarý
{
output_e(0b001);

rtc_get_time(saat,dakika,saniye);
display1_birler=saat%10;
display1_onlar=saat/10;
display2_birler= dakika%10;
display2_onlar=dakika/10;
display3_birler=saniye%10;
display3_onlar=saniye/10;
set_konumunda_display_tara();

if(input(set)){ while(input(set)){display_tara();} set_degeri=2; goto set1_den_cik; }

if(input(mod)){ while(input(mod)){display_tara();} mod_degeri=1; }

while(mod_degeri==1) //saat ayarlanýyor.
{

for(;;)
{
display1_birler=saat%10;
display1_onlar=saat/10;
display1_tara();

if(input(arttir)){saat++; while(input(arttir)){display1_tara();} if(saat==24){saat=0;} }
if(input(azalt)){saat--; while(input(azalt)){display1_tara();} if(saat==-1){saat=23;} }
if(input(mod)){while(input(mod)){display1_tara();} mod_degeri=2; goto mod1s_cik;}
write_ds1302(0x84,get_bcd(saat)); //saat degeri gonder. 0-23
delay_ms(5);
} //for smod1
} //while mod deger = 1
mod1s_cik:

while(mod_degeri==2) //dakika ayarlanýyor.
{

for(;;)
{
display2_birler=dakika%10;
display2_onlar=dakika/10;
display2_tara();

if(input(arttir)){dakika++; while(input(arttir)){display2_tara();} if(dakika==60){dakika=0;} }
if(input(azalt)){dakika--; while(input(azalt)){display2_tara();} if(dakika==-1){dakika=59;} }
if(input(mod)){while(input(mod)){display2_tara();} mod_degeri=3; goto mod2s_cik;}
write_ds1302(0x82,get_bcd(dakika)); //dakika degeri gonder. 00-59
delay_ms(5);
} //for smod2
} //while mod deger = 2
mod2s_cik:

while(mod_degeri==3) //saniye ayarlanýyor.
{

for(;;)
{
display3_birler=saniye%10;
display3_onlar=saniye/10;
display3_tara();

if(input(arttir)){saniye++; while(input(arttir)){display3_tara();} if(saniye==60){saniye=0;} }
if(input(azalt)){saniye--; while(input(azalt)){display3_tara();} if(saniye==-1){saniye=59;} }
if(input(mod)){while(input(mod)){display3_tara();} mod_degeri=0; goto mod3s_cik;}
write_ds1302(0x80,get_bcd(saniye)); //saniye degeri gonder. 00-59
delay_ms(5);
} //for smod3
} //while mod deger = 3
mod3s_cik:

delay_us(1);
} // while set deger = 1
set1_den_cik:


while(set_degeri==2) //tarih ayarý
{
output_e(0b010);

rtc_get_date(gun,ay,yil,haftanin_gunu);
display1_birler=gun%10;
display1_onlar=gun/10;
display2_birler= ay%10;
display2_onlar=ay/10;
display3_birler=yil%10;
display3_onlar=yil/10;
set_konumunda_display_tara();

if(input(set)){ while(input(set)){display_tara();} set_degeri=0; goto set2_den_cik; }

if(input(mod)){ while(input(mod)){display_tara();} mod_degeri=1; }

while(mod_degeri==1) //gun ayarlanýyor.
{

for(;;)
{
display1_birler=gun%10;
display1_onlar=gun/10;
display1_tara();

if(input(arttir)){gun++; while(input(arttir)){display1_tara();} if(gun==32){gun=1;} }
if(input(azalt)){gun--; while(input(azalt)){display1_tara();} if(gun==0){gun=31;} }
if(input(mod)){while(input(mod)){display1_tara();} mod_degeri=2; goto mod1t_cik;}
write_ds1302(0x86,get_bcd(gun)); //gun degeri gonder. 1-31
delay_ms(5);
} //for tmod1
} //while mod deger = 1
mod1t_cik:

while(mod_degeri==2) //ay ayarlanýyor.
{

for(;;)
{
display2_birler=ay%10;
display2_onlar=ay/10;
display2_tara();

if(input(arttir)){ay++; while(input(arttir)){display2_tara();} if(ay==13){ay=1;} }
if(input(azalt)){ay--; while(input(azalt)){display2_tara();} if(ay==0){ay=12;} }
if(input(mod)){while(input(mod)){display2_tara();} mod_degeri=3; goto mod2t_cik;}
write_ds1302(0x88,get_bcd(ay)); //ay degeri gonder. 1-12
delay_ms(5);
} //for tmod2
} //while mod deger = 2
mod2t_cik:

while(mod_degeri==3) //yil ayarlanýyor.
{

for(;;)
{
display3_birler=yil%10;
display3_onlar=yil/10;
display3_tara();

if(input(arttir)){yil++; while(input(arttir)){display3_tara();} if(yil==100){yil=0;} }
if(input(azalt)){yil--; while(input(azalt)){display3_tara();} if(yil==-1){yil=99;} }
if(input(mod)){while(input(mod)){display3_tara();} mod_degeri=0; goto mod3t_cik;}
write_ds1302(0x8C,get_bcd(yil)); //yil degeri gonder. 00-99
delay_ms(5);
} //for tmod3
} //while mod deger = 3
mod3t_cik:

delay_us(1);
} // while set deger = 2
set2_den_cik:

ayardan_cik:
output_e(0b000); //lambalar söndü
} // void ayar
//------------------------------------------------------------------------------

//--------- saat basi alarm caliyor --------------------------------------------
void saat_basi_alarm()
{
if ((display2_onlar==0)&(display2_birler==0))
{
output_high(pin_c3); delay_ms(100); output_low(pin_c3); delay_ms(100);
output_high(pin_c3); delay_ms(100); output_low(pin_c3);
}
}
//------------------------------------------------------------------------------

//------- ana program ----------------------------------------------------------
void main ()
{
output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);
output_e(0x00);
delay_ms(2);
setup_adc(adc_clock_internal);
setup_adc_ports(AN0);

rtc_init(); // DS1302 baþlangýç ayarlarý yapýlýyor
delay_ms(20);
//rtc_set_datetime(1,02,10,7,21,20); // Tarih ve Saat ayarlarý yapýlýyor

for(;;)
{

gecis_animasyon();

output_low(pin_a2);
output_high(pin_a1);

for(i=0;i<250;i++) //for saat
{
if (input(set)){ayarlar();output_low(pin_a2);output_high(pin_a1);}
rtc_get_time(saat,dakika,saniye); // DS1302'den saat,dakika,saniye bilgileri alýnýyor
display1_birler=saat%10; // birler basamaðý için % iþareti ile mod lu bölme yapýlarak 10 a bölümünden kalan hesaplanýyor.
display1_onlar=saat/10; // saat degerini 10 a bölüp onlar basamaðý hesaplanýyor.
display2_birler= dakika%10;
display2_onlar=dakika/10;
display3_birler=saniye%10;
display3_onlar=saniye/10;
display_tara();
delay_ms(5);
} // for saat

saat_basi_alarm();

output_low(pin_a1);
output_low(pin_a2);

gecis_animasyon();

output_low(pin_a1);
output_high(pin_a2);

for(i=0;i<250;i++) //for tarih
{
if (input(set)){ayarlar();output_low(pin_a1);output_high(pin_a2);}
rtc_get_date(gun,ay,yil,haftanin_gunu);
display1_birler=gun%10; // birler basamaðý için % iþareti ile mod lu bölme yapýlarak 10 a bölümünden kalan hesaplanýyor.
display1_onlar=gun/10; // saat degerini 10 a bölüp onlar basamaðý hesaplanýyor.
display2_birler= ay%10;
display2_onlar=ay/10;
display3_birler=yil%10;
display3_onlar=yil/10;
display_tara();
delay_ms(5);
} // for tarih

output_low(pin_a1);
output_low(pin_a2);

gecis_animasyon();

sicaklik_ekrani=1;
for(i=0;i<=250;i++) //for sicaklik
{

if (input(set)){ayarlar();}
set_adc_channel(0);
delay_us(20);
sicaklik_bilgisi= read_adc();
sicaklik_voltaj=(0.0048828125*sicaklik_bilgisi)*1000;
sicaklik_degeri=floor((sicaklik_voltaj/10)+2);
display1_birler=(int)sicaklik_degeri%10;
display1_onlar=(int)(sicaklik_degeri/10);
sicaklik_tara();
delay_ms(5);
}//for sicaklik
sicaklik_ekrani=0;

} //for sonsuz
} // main

//write_ds1302(0x84,get_bcd(saat)); //saat degeri gonder. 0-23
//write_ds1302(0x82,get_bcd(6)); //dakika degeri gonder. 00-59
//write_ds1302(0x80,get_bcd(7)); //saniye degeri gonder. 00-59

//write_ds1302(0x86,get_bcd(7)); //gun degeri gonder. 1-31
//write_ds1302(0x88,get_bcd(1)); //ay degeri gonder. 1-12
//write_ds1302(0x8a,get_bcd(3)); //haftanýn gün degeri gonder. 1-7
//write_ds1302(0x8c,get_bcd(9)); //yýl degeri gonder. 00-99
/*

Obs: o codigo foi feito no CCS e os comentarios estão numa lingua que nem faço ideia.......

Link para o comentário
Compartilhar em outros sites

O segundo é dado por:

Prescaler x ciclo_de_máquina x quantidade_overflow x 256-TMR0_inicio

256 x 0.000001 x 15 x (256-0) = 0,98304 S <--esse é o que estão utilizando

pode usar as configurações acima da seguinte forma:

prescaler = 1:32

cristal 4Mhz = 0.000001 S ciclo de máquina

quantidade de overflow = 250

TMR0_inicio = 131 -> 256-131=125

32 x 0.000001 x 250 x 125 = 1S <--tente usar esse


void interrupt() //Função reservada do MikroC, não chama no Main porque
{ //Roda por fora dele
intcon.t0if=0; //zere a flag a cada estouro
increm++; //e incremente a variavel de incremento
if(increm==250){
increm=0 ; //Zere-o
TMR0 = 131
s++ ; //E faça um segundo
.
.
.
PORTA = 0b11111; //iniciando em estado 1 RA0 e RA1
//TMR0 = 0; //Timer 0 ativado
OPTION_REG = 0b000000100; //registrando Prescaller de 32, ativado, com clock interno
INTCON.GIE = 1; //Global Interrupt Ativo.
TMR0 = 131

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...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!