Buenas,
Estoy haciendo una cuenta atras de los segundos que tiene un dia (86400), y para ello utilizo un PIC16F84A conectado a 5 displays de 7 segmentos. Para calcular un segundo exacto utilizo la interrupcion interna por desbordamiento del PIC, pero no consigo contar un segundo exacto, al no saber exactamente como calcularlo segun la frecuencia del reloj (4 MHz) y los tiempos de cada instruccion.
Os dejo el codigo a continuacion:
#include <16F84A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#use delay(clock=4000000)
#define TICKS 16
#define REFRESH_MS 3
void number(int num) {
output_low(PIN_B0);
output_low(PIN_B1);
output_low(PIN_B2);
output_low(PIN_B3);
output_low(PIN_B4);
output_low(PIN_B5);
output_low(PIN_B6);
switch(num) {
case 0:
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B2);
output_high(PIN_B3);
output_high(PIN_B4);
output_high(PIN_B5);
break;
case 1:
output_high(PIN_B1);
output_high(PIN_B2);
break;
case 2:
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B3);
output_high(PIN_B4);
output_high(PIN_B6);
break;
case 3:
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B2);
output_high(PIN_B3);
output_high(PIN_B6);
break;
case 4:
output_high(PIN_B1);
output_high(PIN_B2);
output_high(PIN_B5);
output_high(PIN_B6);
break;
case 5:
output_high(PIN_B0);
output_high(PIN_B2);
output_high(PIN_B3);
output_high(PIN_B5);
output_high(PIN_B6);
break;
case 6:
output_high(PIN_B0);
output_high(PIN_B2);
output_high(PIN_B3);
output_high(PIN_B4);
output_high(PIN_B5);
output_high(PIN_B6);
break;
case 7:
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B2);
break;
case 8:
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B2);
output_high(PIN_B3);
output_high(PIN_B4);
output_high(PIN_B5);
output_high(PIN_B6);
break;
case 9:
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B2);
output_high(PIN_B5);
output_high(PIN_B6);
break;
}
delay_ms(REFRESH_MS);
}
void control(int place) {
switch(place) {
case 0:
output_high(PIN_A0);
output_high(PIN_A1);
output_high(PIN_A2);
output_high(PIN_A3);
break;
case 1:
output_low(PIN_A0);
output_low(PIN_A1);
output_low(PIN_A2);
output_high(PIN_A3);
break;
case 2:
output_high(PIN_A0);
output_low(PIN_A1);
output_low(PIN_A2);
output_high(PIN_A3);
break;
case 3:
output_low(PIN_A0);
output_high(PIN_A1);
output_low(PIN_A2);
output_high(PIN_A3);
break;
case 4:
output_high(PIN_A0);
output_high(PIN_A1);
output_low(PIN_A2);
output_high(PIN_A3);
break;
case 5:
output_low(PIN_A0);
output_low(PIN_A1);
output_high(PIN_A2);
output_high(PIN_A3);
}
}
void initialize(int u, int d, int c, int m, int d_m)
{
control(1);
number(u);
control(2);
number(d);
control(3);
number(c);
control(4);
number(m);
control(5);
number(d_m);
}
void main()
{
int uni=0, dec=0, cen=4, mil=6, dec_mil=8;
int tick=0;
set_tris_a(0b00000000); // Todas salidas A valor cero. Las entradas van con 1.
set_tris_b(0b00000000); // Todas salidas B valor cero. Las entradas van con 1.
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256|RTCC_8_BIT);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
while(1) {
control(1);
number(uni);
control(2);
number(dec);
control(3);
number(cen);
control(4);
number(mil);
control(5);
number(dec_mil);
if(T0IF) {
tick++;
T0IF=0;
if(tick==TICKS-1) {
set_timer0(0xCB);
}
if(tick==TICKS) {
tick=0;
delay_us(555);
if(dec_mil==0 && mil==0 && cen==0 && dec==0 && uni==0) {
uni=9; dec=9; cen=3; mil=6; dec_mil=8;
initialize(uni,dec,cen,mil,dec_mil);
}
else {
uni--;
if(uni==-1) {
if(dec_mil==0 && mil==0 && cen==0 && dec==0)
uni=0;
else {
uni=9;
dec--;
if(dec==-1) {
if(dec_mil==0 && mil==0 && cen==0)
dec=0;
else {
dec=9;
cen--;
if(cen==-1) {
if(dec_mil==0 && mil==0)
cen=0;
else {
cen=9;
mil--;
if(mil==-1) {
if(dec_mil==0)
mil=0;
else {
mil=9;
dec_mil--;
if(dec_mil==-1)
dec_mil=0;
}
}
}
}
}
}
}
}
}
}
}
}
}
Alguna idea de como calcular un segundo exacto?