Holaaa!!!bueno, aqui dejo un programa que se sale de la tematica de aprendizaje a programar perifericos internos del pic, pero vamos creo que es ilustrativo a la programacion del mismo y hardware, hace tiempo que pense en regalarle un reloj digital a mi niña, y bueno pue sme puse manos a la obra, el conteo y la realizacion del reloj lo realiza todo el pic, aqui el programa:
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR"05
// 29/Noviembre/05
//
// Programa: Reloj digital 7seg
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.236
// Entorno IDE: MPLAB IDE v7.22 Simulador: Proteus 6.7sp3
//
// Notas: Reloj digital en 7seg. Se utiliza un DEC 4555 para realizar el barrido
// de los 7seg, se usa tambien, un BCD-7Seg 4543 para la visualizacion
// de los numeros en el 7seg. El reloj esta compuesto de 4 botones.
// Botones: Hora/Minutos->RB1: Cuando estemos en modo Configuracion,
// pasar de hora a minutos para incrementar.
// + ->RB2: Para incrementar en una unidad el digito actual.
// Configuracion/Ok->RB3: Si se pulsa pasamos al modo
// configuracion para poder actualizar
// la hora actual, una vez actualizada,
// si se pulsa pasamos al modo de reloj
// Conexiones: A0 -> A 4555 DEC
// A1 -> B 4555 DEC
// A2 -> 2 led"s en serie(secundero)
// A5 -> Boton reset(externo)
// B1 -> Boton Hora/Minuto
// B2 -> Boton +
// B3 -> Boton Configuracion/Ok
// B4 -> A 4543
// B5 -> B 4543
// B6 -> C 4543
// B7 -> D 4543
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h> //pic a utilizar
#fuses XT,NOCPD,NOWDT,NOPUT,NOLVP,NOBROWNOUT //ordenes para el programador
#fuses INTRC //oscilador interno
#use delay (clock=4000000) //Fosc=4Mhz
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2)
#use fixed_io(b_outputs=PIN_B4,PIN_B5,PIN_B6,PIN_B7)
#bit RA2=05.2 //secundero
///DEFINICION DE FUNCIONES
void configurar(void);
///VARIABLES GLOBALES
char min1=0,min2=0,hor1=0,hor2=0;
char flag=0,var=119; //variables de ajuste de 1 minuto
char tab[10]={0x00,0b00010000,0b00100000,0b00110000,
0b01000000,0b01010000,0b01100000,0b01110000,0b10000000,0b10010000}; //bcd parte alta 0-9
///LLAMADA FUNCION INTERRUPCION
#INT_TIMER1
void interrupcion()
{
if(flag>var){ //¿Ya es 1 minuto?
var--; //SI -> decremento var...
if(var<118)
var=120; //...ajuste fino de 1min
flag=0; //reset flag para contar 1min
min1++;
if(min1>9){ //¿Se ha mostrado xx:x9?
min1=0; //SI -> reset min1 xx:x0
min2++;
if(min2>5){ //¿Se ha mostrado xx:59?
min2=0; //SI -> reset min2 xx:00
hor1++;
if(hor2==2){ //¿Estamos en modo noche 2x:xx?
if(hor1>3) //SI -> ¿Se ha mostrado 23:59?
goto noche;}//SI -> ve a noche
if(hor1>9){ //No estamos en modo noche-> ¿se ha mostrado 19:59?
noche: hor1=0; //SI -> reset hor1 x0:00 || noche: reset hor1 x0:00
hor2++;
if(hor2>2) //¿Se ha mostrado 23:59?
hor2=0; //SI -> reset hor2 00:00
}
}
}
}
RA2=!RA2; //parpadeo secundero cada 0,5s
set_timer1(3036); //reset TMR1
flag++;
}
///PROGRAMA
void main(void)
{
enable_interrupts(INT_TIMER1); //interrupcion TIMER1 activada
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //configuracion TMR1
set_timer1(3036); //carga TMR1 para desvordar cada 0.5s
enable_interrupts(GLOBAL); //activadas interrupciones
do{ //bucle...
output_low(PIN_A0); //Primer 7seg...
output_low(PIN_A1); //...on
output_b(tab[min1]);
delay_ms(10);
output_low(PIN_A1); //Segundo 7seg...
output_high(PIN_A0); //...on
output_b(tab[min2]);
delay_ms(10);
output_high(PIN_A1); //Tercer 7seg...
output_low(PIN_A0); //...on
output_b(tab[hor1]);
delay_ms(10);
output_high(PIN_A0); //Cuarto 7seg...
output_high(PIN_A1); //...on
output_b(tab[hor2]);
delay_ms(10);
if(!input(PIN_B3)){ //¿Se ha pulsado boton Configuracion?
while(!input(PIN_B3)){} //SI -> elimina rebotes pulsador...
configurar(); //...ve a configurar
}
}while(TRUE); //...infinito
}
///FUNCION QUE CONFIGURA LA HORA ACTUAL
void configurar(void){
boolean sal=0;
char menu=0; //menu=0: incremento minutos || menu=1: incremento horas
disable_interrupts(GLOBAL); //todas las interrupciones desactivadas
do{
do{
output_a(0b00);
output_b(tab[min1]);
delay_ms(10);
output_a(0b01);
output_b(tab[min2]);
delay_ms(10);
output_a(0b10);
output_b(tab[hor1]);
delay_ms(10);
output_a(0b11);
output_b(tab[hor2]);
delay_ms(10);
if(!input(PIN_B1)){ //¿Se ha pulsado boton Horas/Minutos?
while(!input(PIN_B1)){}
menu=!menu; //SI -> Cambia minutos/horas y viceversa
}
if(!input(PIN_B2)){ //¿Se ha pulsado boton +?
while(!input(PIN_B2)){}
sal=1; //SI -> incrementa una unidad el digito(segun variable menu)
}
if(!input(PIN_B3)){ //¿Se ha pulsado boton Ok?
while(!input(PIN_B3)){}
sal=1; //SI -> salir...
menu=2; //...modo Configurar y mostrar hora actualizada
}
}while(sal==0);
sal=0; //reset variable sal
if(menu==0){ //¿Incremento digito de minutos?
min1++; //SI
if(min1>9){ //¿Se ha mostrado xx:x9?
min1=0; //SI -> reset min1 xx:x0
min2++;
if(min2>5) //¿Se ha mostrado xx:59?
min2=0; //SI -> reset min2 xx:00
}
}
if(menu==1){ //¿Incremento digito horas?
hor1++; //SI
if(hor2==2){ //¿Estamos en modo noche 2x:xx?
if(hor1>3) //SI -> ¿se ha mostrado 23:xx?
goto night; //SI -> ve a night
}
if(hor1>9){ //No estamos en modo noche->¿se ha mostrado 19:xx?
night: hor1=0; //SI -> reset hor1 10:xx ||modo noche: reset hor1 20:xx
hor2++;
if(hor2>2) //¿Se ha mostrado 23:xx?
hor2=0; //SI -> reset hor2 00:xx
}
}
}while(menu<2);
enable_interrupts(GLOBAL); //todas las interrupciones desactivadas
set_timer1(3036); //carga TMR1
flag=0; //reset variables...
var=119; //...ajuste de 1min
}
Bien decir, que este no fue el programa final que grabe en el pic....pero bueno, creo que este es mas ilustrativo a la programacion, el que finalmente grabe en el pic manejaba la hora en una variable y mediante una funcion obtenia los valores a representar.....
Ya sabemos que hora es tanto con una RTC como con este ejemplo!!!!
Suerte!!!