jueves, 30 de julio de 2015

Reloj con DS1307 y PIC 18f877

Un proyecto en el cual se desarrollará un reloj con el circuito integrado DS1307 y un microcontrolador de gama media 16f877.
Para el desarrollo he utilizado una librería de las varias que circulan por la web, después de haberlo examinado y probado.
Este proyecto fue desarrollado según requerimientos especificados, se lee el reloj cada segundo y se muestra en un display de 7 segmentos construido con diodos leds.
posee 5 pulsadores para controlar su funcionamiento como es poner la hora, cambiar a cronómetro pausar.
También posee una salida para alarma que nos avisará cuando inicia la cuenta regresiva, todo según requerimientos.
El proyecto está desarrollado en CCS 4.114 compiler y simulado en software Proteus 7.9.
En este artículo les mostraré toda la documentación para poder desarrollarlo, ustedes podrán adaptar el proyecto a sus necesidades.
El programa incluye la configuración del reloj para salida de pulsos a 1 Hz y actualización de la hora.
A continuación les muestro el diagrama de flujo del programa:






El diagrama del circuito para la simulación en proteus: 

Al final podrás encontrar el enlace para descargarlo.

























Para poder desarrollar una placa decircuito impreso y mostrar en un display construido con leds de 5mm les muestro un posible circuito hecho con Eagle 6.1.0.


























El código del programa es el siguiente:
#include <Cronometro.h>
#include <DS1307FIN.c>
#byte PORTB = 0x06 // Identificador para el puerto B.
#byte PORTD=0X08
#byte PORTA=0X05
#byte PORTC=0X07
#BYTE OPTION_REG=0X81
#Priority  int_ext, int_rb
#use fast_io(C)
int hr=0;
int min=0;
int sec=0;
int8 modo=0;
int banderaleerclk=0;
int banderaescribirhora=0;
byte CONST DISPLAY[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
int digit;     // resultado de la conversion bin2bcd
int8 banderapause=0;
void tiempo(void)
{
int16 z=0;
int16 y=0;
for(z=0;z<10;z++)
{
for(y=0;y<100;y++)
{}
z++;
}
}
void muestra()
{
int8 temp1=0;
digit= bin2bcd(hr);     //convierte hora a bcd
temp1=swap(digit) & 0b00000001; //filtra para leer solo la hora
temp1=DISPLAY[temp1];
bit_set(PORTA,0);
PORTD=temp1;
tiempo();
bit_clear(PORTA,0) ;   
temp1=swap(digit) & 0b00001111;
temp1=DISPLAY[temp1];
bit_set(PORTA,1);
PORTD=temp1;
tiempo();
bit_clear(PORTA,1) ;
digit=bin2bcd(min);     //convierte minutos a bcd
temp1=swap(digit) & 0b00001111;
temp1=DISPLAY[temp1];
bit_set(PORTA,2);
PORTD=temp1;
tiempo();
bit_clear(PORTA,2) ;   
temp1=swap(digit) & 0b00001111;
temp1=DISPLAY[temp1];
bit_set(PORTA,3);
PORTD=temp1;
tiempo();
bit_clear(PORTA,3) ;
}
void muestra2()
{
int8 temp=0;
digit= bin2bcd(min);     //convierte min a bcd
temp=swap(digit) & 0b00001111;
temp=DISPLAY[temp];
bit_set(PORTA,0);
PORTD=temp;
tiempo();
bit_clear(PORTA,0) ;    
temp=swap(digit) & 0b00001111;
temp=DISPLAY[temp];
bit_set(PORTA,1);
PORTD=temp;
tiempo();
bit_clear(PORTA,1) ;
digit=bin2bcd(sec);     //convierte sec a bcd
temp=swap(digit) & 0b00001111;
temp=DISPLAY[temp];
bit_set(PORTA,2);
PORTD=temp;
tiempo();
bit_clear(PORTA,2) ;   
temp=swap(digit) & 0b00001111;
temp=DISPLAY[temp];
bit_set(PORTA,3);
PORTD=temp;
tiempo();
bit_clear(PORTA,3) ;
}
#int_rb
void pulsadores()
{
delay_ms(50);
int temp =PORTB & 0b11110000;
switch(temp)
 {
 case 0b11100000:
 if(banderapause==1) {
 if (modo==0){
 if (hr<12){hr++;}
 else{hr=0;}
             }
 else{
  if (min<60){min++;}
 else{min=0;}}
 }

    //PIN RB4
 break;
 case 0b11010000:
  if(banderapause==1){
  if (modo==0){
 if (min<60){min++;}
 else{min=0;}
  }
  else
  {
   if (sec<60){sec++;}
 else{sec=0;}
  }
  }
    //PIN RB5
 break;
 case 0b10110000:
 if (modo==1)
 {
 modo=0;
 }
 else{
 disable_interrupts(int_ext);
     min=60;
     sec=0;
    //PIN RB6
    if(banderapause==0)
    {
    output_high(pin_b1);      //alarma
    PORTD=0;
    delay_ms(3000);
     output_low(pin_b1);
      enable_interrupts(int_ext);
    }
     modo=1;
 }
 break;
 case 0b01110000:          //inicia cronometro
 if (banderapause==0){
 banderapause=1;
 disable_interrupts(int_ext);
 }
 else
 {
 banderapause=0;
 output_high(pin_b1);      //alarma
    delay_ms(3000);
     output_low(pin_b1);
  enable_interrupts(int_ext);
 }
    //PIN RB7

 break;
 default:
 break;
 }
 }
#int_ext
void cuentaseg()
{
switch (modo)
{
case 0:          //caso reloj
banderaleerclk=1;
break;
case 1:       //caso cronometro
if (sec >0)
{
sec--;
}
else if(sec==256)
{
min--;
sec=59;
}
if (min==5 && sec==0)     //en 5 minutos aviso alarma
{output_high(pin_b1);}
if(min==4 && sec==56)  //corta alarma
{output_low(pin_b1);}
if(min==0 && sec==5)  //alarma final
{output_high(pin_b1);}
if (min==0 && sec==0)
{
//aviso de cuenta cero
{output_low(pin_b1);}
modo=0  ;                  //vuelve a función reloj
}
break;
}
}
#int_timer0
void tmr_error()
{
 disable_interrupts(INT_TIMER0);
 set_timer0(0);
if(input(pin_c1)==0)
{
banderaescribirhora=1;
}
}
void main()
{
PORTD=0;
PORTB=0;
PORTA=0x00;
set_tris_c(0b11111100);
set_tris_d(0x00);
Set_tris_a(0x00);
set_tris_b(0xf1);
 // ds1307_init();
 // ds1307_am(hr);
 ds1307_get_time(hr,min,sec);
 if((sec & 0b10000000)==0b10000000)   //PARA INICIAR SOLO LA PRIMERA VEZ
 {
  ds1307_init();
  ds1307_am(hr);
 }
 setup_timer_0(RTCC_INTERNAL |RTCC_DIV_256);
set_timer0(0);
ext_int_edge(L_TO_H);
  enable_interrupts(int_ext);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
delay_ms(2000);
while(1)      //se repite indefinidamente
{
if(input(pin_c1)==0 && banderapause==1)
{
 enable_interrupts(INT_TIMER0);
}
else
{
disable_interrupts(INT_TIMER0);
}
switch (modo)
{
case 0:
if(banderaleerclk==1)
{
banderaleerclk=0;
disable_interrupts(GLOBAL);
 ds1307_get_time(hr,min,sec);
 enable_interrupts(GLOBAL);
}
if (banderaescribirhora==1){
banderaescribirhora=0;
if(banderapause==1 && modo==0)  //si está en reloj y interrupción deshabilitada
{
ds1307_set_date_time (10, 06, 15, 2, hr, min, sec); /// se escribe en el displositivo
 ds1307_am(hr);
}
}
muestra();
break;
case 1:
muestra2();
}
}
}



Ahora una vista del modelo de nuestra placa del circuito con SketchUp y Eagle :












Las librerías para el programa puedes descargarlo a continuación:
Codigo y DSN:Aqui
















8 comentarios:

  1. Todos tus proyectos son estupendos y completos , ojala haya mas :)

    ResponderBorrar
  2. ME PARECE INTERESANTE PERO NO SE PUEDE DESCARGAR LA LIBRERIA, NI DEL PRTEUS.

    ResponderBorrar
  3. Muy interesante pero los vínculos ya no funcionan.

    ResponderBorrar
  4. Muy interesante pero los vínculos ya no funcionan.

    ResponderBorrar
  5. AMIGO PUEDE COMPARTIR EL ARCHIVO EN PCB

    ResponderBorrar
  6. hola. como seeria para pasar al formato de 24h?

    ResponderBorrar
  7. Wynn Casino and Resort | DRMCD
    Wynn Las 영주 출장샵 Vegas and Encore offer the ultimate in 거제 출장샵 luxury hotel accommodations, sensuous spa treatments, delectable dining and exciting 울산광역 출장샵 casino gaming. All within 평택 출장마사지 a 군포 출장샵 15-minute drive

    ResponderBorrar