TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: fonta2 en 22 de Noviembre de 2003, 14:38:00
-
Hola.Estoy desarrollando un proyecto con un PIC16F872 que va a 8Mhz.Necesito generar una señal (modulada) cada 6 minutos.Yo lo he realizado mediante una interrupción de 1s (con un contador) y luego ir contando 6 minutos (mediante otro contador),pero me ocurre que el tiempo no es preciso, se puede desviar hasta 1 minuto o includo más si pasa mucho tiempo.Este tiempo debe de ser muy preciso, un error de 1s sería válido.¿Estoy pidiendo mucho a este PIC para que me de una presición de 1s?, ¿Puede tener tanto error un cristal de cuarzo junto con el PIC?.Admito cualquier sugerencia.
Muchas gracias a todo el foro.
-
ese error no es lógico. por que no pones el codigo y le hechamos un vistazo....
.
de todas formasdebes usar una interrupcion con uno de los timers interno. si la velocidadno es critica baja el tiempo de reloj.
saludos
-
Hola Pacalaconcurso, gracias.Es código del proyecto es el siguiente:
#include <16F872.h>
#device adc=8 ICD=true //!SOLO PARA DEPURAR!
#use delay(clock=8000000)
#fuses HS, NOPROTECT, NOBROWNOUT, NOWDT, NOLVP
#byte PORTC=0x07
#bit PORTC7=PORTC.7
#bit PORTC0=PORTC.0
#byte PORTB=0x06
#bit PORTB0=PORTB.0
#byte PORTA=0x05
#bit derecha=PORTA.2
#bit abajo=PORTA.3
#bit enter=PORTA.4
#bit menu=PORTA.5
#bit ldr=PORTA.1
#bit open=PORTC.1
#bit led=PORTC.2
#define hi PORTC0=PORTC7=1
#define lo PORTC0=PORTC7=0
#define N_CICLOS_S 346 //Constante para emitir la
//señal modulada
#define N_CICLOS_U 21 //Constante para emitir la
//señal modulada
#define INT_1S 122 //Constante para contar 1s
#define MIN_STBY 6 //Constante para emitir la señal
//cada 6min
byte segundos; //Variable para contar los segundos
byte minutos; //Variable que lleva la cuenta de los
//minutos
byte cont_1s; //Variable para contar 1s
byte cont; //Contador auxiliar
short seg; //Bit que cambia de estado cada 1s
short min; //Bit que cambia de estado cada 1min
short estado; //Bit que indica el estado del equipo
short bit_ini; //Bit que indica si el equipo ha arrancado por
//primera vez
#int_RTCC
RTCC_isr()
{
if(--cont_1s==0)
{
++segundos;
cont_1s=INT_1S;
seg=(seg ? 0
; //Cambia el estado de seg
}
if(segundos==59)
{
segundos=0;
++minutos;
min=(min ? 0
; //Cambia el estado de min
}
if(minutos==59)
{
minutos=0;
segundos=0;
}
}
void sec_inicio(void)
{
for(cont=1;cont<N_CICLOS_S/2;++cont)
{
hi;
delay_us(13);
lo;
delay_us(9);
}
for(cont=1;cont<N_CICLOS_S/2;++cont)
{
hi;
delay_us(13);
lo;
delay_us(9);
}
lo;
delay_us(4500);
}
void sec_final(void)
{
lo;
for(cont=1;cont<=N_CICLOS_U;++cont)
{
hi;
delay_us(13);
lo;
delay_us(13);
}
lo;
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_counters(RTCC_INTERNAL,RTCC_DIV_64);
enable_interrupts(INT_RTCC);
disable_interrupts(GLOBAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
set_tris_c(0x02); //Puerto C como salidas y entradas
estado=0; //El equipo está apagado
lo;
cont_1s=INT_1S;
seg=min=0; //Flag de minutos y segundos a 0
bit_ini=0; //No ha arrancado el equipo
delay_ms(320);
while(1)
{
if(ldr==0)
{
delay_ms(32);
if(ldr==0)
{
if((estado==0)&&(bit_ini==0))
{
sec_inicio(); //Genera señal modulada
estado=1;
bit_ini=1; //El equipo ha arrancado
delay_ms(20000);
}
if((estado==1)&&(bit_ini==1))
{
sec_inicio(); //Genera señal modulada
estado=1;
disable_interrupts(GLOBAL); //Desactiva TMR0
minutos=segundos=0;
}
if((estado==0)&&(bit_ini=1))
{
estado=1;
disable_interrupts(GLOBAL); //Desactiva TMR0
minutos=segundos=0;
sec_final(); //Genera señal modulada
delay_ms(180);
sec_final(); //Genera señal modulada
delay_ms(180);
sec_final(); //Genera señal modulada
delay_ms(2000);
}
}
}
else
{
delay_ms(32);
if(ldr==1)
{
if((estado==1)&&(bit_ini==1))
{
sec_inicio(); //Genera señal modulada
cont_1s=INT_1S;
enable_interrupts(GLOBAL); //Activa int. TMR0
minutos=segundos=0;
estado=0; //Equipo apagado
}
if((estado==0)&&(segundos==0)&&(minutos==MIN_STBY))
{
sec_final(); //Genera señal modulada
cont_1s=INT_1S;
minutos=segundos=0;
led=(led ? 0
; //cambia el estado del led
}
}
}
}
}
La interrupcion la genera el Timer0 cada 8,192ms, esta interrupción sirve para contar los segundos y los minutos.Cada 6 minutos (si estado=0 y segundos=0) se debe de generar la señal modulada sec_final().Este tiempo se retrasa cada vez mas, ¿Puede ser por los if anidados que tengo?.Utilizo el ICD1 para depurar junto con el MPLAB.
Gracias a todo el foro y en especial a Pacalaconcurso.
Un saludo.