#include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES MCLR //Master Clear pin enabled
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=4000000)
#byte TRISA=0x85
#byte TRISB=0x86
#byte PORTB=0x06
char const RTCCxS=20; // Número de RTCC's para 10 mseg con 4 Mhz / 1:2.
int8 const i_ADJ_TIME=27;
// VARIABLES GLOBALES
int nRTCC=0x00; // Contador de interrupciones RTCC completas
int mseg=0x0; // mili segundos del Reloj
int seg=0x0; // segundos del Reloj
int D1=0x00; // Contenido de los Displays
int D2=0x00;
int D3=0x00;
int D4=0x00;
int l_digit, h_digit; // Resultado de la conversión bin2bcd
int f_mostrar=0x00; // index general
int f_arranque=0x00; // index general
int f_stop=0x00; // index general
void display_reloj(void); // Función que muestra el contenido del reloj
void time2bcd(void); // Función que convierte seg y mseg a 4 x BCD
void bin2bcd(int valor); // Función que convierte de Binario a BCD
#int_RTCC
void RTCC_isr()
{
if(++nRTCC==RTCCxS){
nRTCC=0x00;
output_toggle(PIN_B2);
if(++mseg>99){
output_toggle(PIN_B3);
mseg=0;
if(++seg>59){
seg=0;
}
}
}
set_timer0(i_ADJ_TIME);
}
#int_TIMER1
void TIMER1_isr(void){
if(INPUT(PIN_B0)==0){
if(f_mostrar==0){
f_mostrar=1;
mseg=0;
seg=0;
}
}
else{
disable_interrupts(INT_TIMER1);
}
}
#int_EXT
void ext_isr(){
//f_arranque=~f_arranque;
set_timer1(45535);
enable_interrupts(INT_TIMER1);
}
void main(){
int kmseg=0x00;
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_2);
//El timer1 interrumpira cada (65535-45535)*4*1/4000000=20,00mSeg
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
set_timer1(45535);
// setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
ext_int_edge(H_TO_L);
disable_interrupts(INT_RTCC);
set_timer0(i_ADJ_TIME); //Precargo el TIMER0 para obtener 1mSeg justo
TRISA=0xF0;
TRISB=0b00000011; //Rb0, 1 entradas, el resto salida
output_a(~0x00); //Saco todos 1 en el BCD
output_b(input_b() | 0xF0); //Mando a 5 Rb4 a 7 LE
delay_us(100); //Aseguro la señal LE
output_b(input_b() & 0x0F); //Vuelvo a 1 los LE
enable_interrupts(INT_RTCC); //Ya puedo comenzar a interrumpir por timer
// enable_interrupts(INT_TIMER1); //Ya puedo comenzar a interrumpir por timer
enable_interrupts(INT_EXT); //Ya puedo comenzar a interrumpir por timer
enable_interrupts(GLOBAL);
// start=1; //Esto lo saco cuando pueda usar las INT EXT
do{ // Bucle infinito
if(mseg!=kmseg){ // si cambia el mili segundo actualizo las
time2bcd(); // variables con lo que hay que mostrar
kmseg=mseg;
}
if (f_mostrar==1){
display_reloj(); // Muestra constantemente
}
}While(TRUE);
}
void display_reloj(void){ // Función que muestra el contenido del reloj
output_a(D1); // Muestro 1er carácter de segundo
output_high(PIN_B4);
delay_us(20);
output_low(PIN_B4);
output_a(D2); // Muestro 2do carácter de segundo
output_high(PIN_B5);
delay_us(20);
output_low(PIN_B5);
output_a(D3); // Muestro 1er carácter de minuto
output_high(PIN_B6);
delay_us(20);
output_low(PIN_B6);
output_a(D4); // Muestro 2do carácter de minuto
output_high(PIN_B7);
delay_us(20);
output_low(PIN_B7);
}
void time2bcd(void){ // Función convierte minutos y segundos a 4 x BCD
bin2bcd(seg); // Paso de binario a BCD el segundo y actualizo
D1 = ~h_digit; // contenido a mostrar
D2 = ~l_digit;
bin2bcd(mseg); // Paso de binario a BCD el minuto y actualizo
D3 = ~h_digit; // contenido a mostrar
D4 = ~l_digit;
}
void bin2bcd(int valor){ // Función que convierte de Binario a BCD
h_digit=0;
if (valor>=10){
do{
valor-=10;
h_digit++;
} while (valor>=10);
}
l_digit=valor;
}