TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: mauroc146 en 25 de Agosto de 2016, 00:49:31
-
saludos.
Tengo un problema con el timer0 como temporizador de 0ms a 8ms, se retrasa al hacer un delay_ms en el void main() del programa.
Anteriormente hice un programa para controlar un triac usando el timer1 y no tuve inconvenientes, pero ahora lo quise hacer con el timer0, porque el timer1 lo usare para otro propósito, y no puedo hacerlo funcionar
He simplificado el código para encontrar en que estaba fallando y encontré que cuando pongo algún delay de cualquier valor en void main(), el timer0 deja de trabajar como debería.
Si quito los delay y lo simulo en el proteus funciona bien.
He leído que el timer0 es independiente del programa principal y es por eso que, no sé que estoy haciendo mal :(
Gracias por su atención
#include <16F876A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(crystal=4000000)
#use FIXED_IO( B_outputs=PIN_B4,PIN_B3,PIN_B2 )
#INT_EXT
void EXT_isr(void)
{ //uso la interrupcion por pin_b0 para el cruce por cero de la red
set_timer0(120); // aqui cargo el valor del timer0 para el desbordamiento
enable_interrupts (INT_TIMER0); // que sera de 0ms a 8ms para un control de 0º a 180º +-
}
#INT_TIMER0
void TIMER0_isr(void)
{
DISable_interrupts (INT_TIMER0);
output_high(pin_b4); // cuando se desborde el timer0 activa al triac
delay_ms(1); // y espera a la interrupcion externa para activar y cargar
output_low(pin_b4); // nuebamente al timer0
}
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32|RTCC_8_bit); //8.1 ms overflow
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
while(TRUE)
{
output_high(pin_b4); //activo una salida para que aga algo el programa
delay_ms(1); //el problema es cuando pongo un delay de cualquier valor
output_low(pin_b4); //el timer0 deja de funcionar periodicamente (hace cualquier cosa)
delay_ms(1);
}
}
adjunto dos imagenes de la simulacion en proteus
- Tienes que ingresar para ver archivos adjuntos -
-
Te respondi antes:
- Quita delays de las interrupciones
- Limpia la bandera del TMR0 antes de activarlo
- Usa otra salida entre la interrupcion y el loop principal. Para ver si realmente esta fallando.
-
Gracias KILLERJC por la respuesta
Tienes razón el problema fue el delay dentro la interrupción. Lo quite y funciona bien
Pues mira que no había leído que no se debían usar delay dentro de las interrupciones, pues poco a poco se aprende más
Gracias por la pronta respuesta
-
No solo delays, sino que todo aquello que ocupe demasiado tiempo deberia ser sacado de las interrupciones.
El obejtivo de la interrupcion es que atienda la misma y salga rapidamente. Asi seguir ejecutando el loop principal. Si es necesario hacer algo que ocupe mas tiempo, entonces usas una variable de 1 bit, la pones en 1 en la interrupcion, y luego en tu programa principal lees la variable y ejecutas el codigo que sea.
Con un buen entendimiento del programa es posible poner delays en las interrupciones, suponiendo que no tengas mas interrupciones ni sea demasiado importante lo del main. Pero mejor evitarlas.