Cordial saludo, realice un circuito con el pic 10f200 y he programado un temporizador para 1 hora con un for y 2 variables auxiliares le realizo varias pruebas y trabaja bien pero en ocasiones se cuelga, se que es mejor realizarlo con el tmr0 pero quiero saber que puede estar pasando. cualquiera que fuera la respuesta de esto, aún deseo saber como puedo hacer para realizar un reset o no se si con el whatch dog timer( nunca lo he utilizado y tampoco se en que ocaciones deba hacerlo, podrian orientarme por favor?
Gracias de antemano.Código: C
#include <10F200.h> #FUSES NOWDT,NOMCLR //No Watch Dog Timer #FUSES PROTECT // codigo protegido //#use delay(crystal=4000000) // oscilador con cristal #use delay(CLOCK=4000000) // oscilador interno #DEFINE rele PIN_B1 // le doy un nombre al pin #define accesorios PIN_B2 #define puntilla PIN_B3 #BYTE PORTB=0X06 // lugar de memoria del puerto A ( muy importante ) #USE standard_IO (B) // Optimizamos E/S del PORTB ( muy importante para ahorrar memoria ) //#ORG 0x50, 0XFF // proteger el codigo a partir de la linea 50 unsigned int16 i=0; // variable para el for temporizacion que es mayos a 256 unsigned int x=0; int retencion; // mantiene activado el rele cuando temporiza //int n=0; // variable para el buzzer // prototipos funciones //void sonido (); // funcion de buzzer //xxxxxxxxxxxxxxxxxxxxxxxxx // void main() { //////// configura Gp2 como i/s digital y desabilita el tocki (ocs bit-5) #asm movlw (0B11000000); GPWU = 1, GPPU = 1, T0CS, T0SE, PSA, PS2, PS1, PS0 = 0 option #endasm ///////////////////////////////////////////////////////////////////////////// SET_TRIS_B(0B1100); //set_options (0B000000); PORTB=0; // limpio el puerto delay_ms(1000); output_high(rele); i=0; // variable para el for temporizacion que es mayos a 256 x=0; retencion=1; //Example blinking LED program while(true) { if ((!input(accesorios)) && (input(puntilla))&& (retencion==1))// si es uno llamo funcion sonido { for (i=0;i<6000;i++) { if ((input(accesorios)) || (!input(puntilla))) { retencion=0; output_high(rele); i=0; x=0; break; } delay_ms(10); } x++; if (x==1) { retencion =0; i=0; x=0; output_low(rele); } } while((input(accesorios)) || (!input(puntilla))) { retencion=1; output_high(rele); } } // while tru } // main //>>>>>>>>>>>>> funcion >>>>>>>>>>>>>>>>>>>>>>
gracias por sus respuestas,, me queda un poco dificil la prueba del diodo ya que la temporizacion la estoy haciendo para 1 o 2 horas y lo pruebo unas 3 veces y trabaja bien, cuando lo ensamblo pueden pasar dias y en algun momento ya no temporiza, y no desconecta la carga y me descarga la bateria ( la temporizacion es para desconectar la bateria que tiene como carga una bobina, el pic nunca se queda sin alimentacion)tal vez podria cambiar la forma de temporizacion con el tmr0 pero deseo buscar una opcion para resetear el pic por software y tambien externamente. hay una linea que se pone en positivo siempre que se inicia el proceso pero no se como implemtarla con un transistor para que puetee el negativo solo un instante(un pulso) pero como el voltaje permanece mucho tiempo el reset permanece, necesito algo asi como lograr un pulso por un condensador.
tambien he pensado en el whatchdog pero segun he leido hay que repetir una rutinqa constantemente, nunca lo he usado agradezco alguna orientacion.
while((input(accesorios)) || (!input(puntilla)))
{
retencion=1;
output_high(rele);
}
...
tambien he pensado en el whatchdog pero segun he leido hay que repetir una rutinqa constantemente...
#FUSES WDT,NOMCLR //Watch Dog Timer, no Master Clear
//////// configura Gp2 como i/s digital y desabilita el tocki (ocs bit-5)
#asm
movlw (0B11001111); GPWU = 1, GPPU = 1, T0CS, T0SE=0 , PSA, PS2, PS1, PS0 = 1
option
#endasmSi no se resetea el WDT cada 2" (2304ms) te resetea el micro. restart_wdt(); //<<<<<<<<<<<<<<<<<<<<<<<<
//Example blinking LED program
while(true)
{
if ((!input(accesorios)) && (input(puntilla)) && (retencion==1)) // si es uno llamo funcion sonido
{
for (i=0;i<6000;i++)
{
if ((input(accesorios)) || (!input(puntilla)))
{
retencion=0;
output_high(rele);
i=0;
x=0;
break;
}
delay_ms(10);
}
x++;
if (x==1)
{
retencion =0;
i=0;
x=0;
output_low(rele);
}
}
restart_wdt(); //<<<<<<<<<<<<<<<<<<<<<<<<
while((input(accesorios)) || (!input(puntilla)))
{
retencion=1;
output_high(rele);
}
} // while tru
...Se configura un prescaler con los bits PSA, PS2, PS1, PS0
# segun veo el whatchdog actua cada 2304 milisegundos, viene asi por defecto o hay que configurar algo?
# si estoy haciendo un contador, cada que reinicie el watchdog el contador se reiniciara - entonces perdera el valor de lo que teniaEs que el WDT es para usarse cuando debido a un evento anormal como ruido en alimentación, entradas, interferencia EM o lo que sea, el micro salta del recorrido normal y pasa a ejecutar en cualquier parte o con los registros alterados.
# tengo entendido que no se puede utiza el tmr0 y el whatchdod al tiempo?Tiene un solo prescaler, se asigna al WDT o al Timer0
Basicamente seria..
se configuraria el WDT como si fuese el tmr0
# si ambos al tiempo no pueden utilizarse se podrian ir intercalando a medida que avanza el programa?
# Entonces el wdt se deber utilizar dendro de un bucle para garantizar que siempre este haciendo lo requerido?
# como sabe el WDT que hay interferencias o que se quedo colgado.
no me queda claro donde y cuando lo debo implementar.
se configuraria el WDT como si fuese el tmr0No, además son para usos diferentes, cosa que no estás dispuesto a aceptar.
# si ambos al tiempo no pueden utilizarse se podrian ir intercalando a medida que avanza el programa?Poder se puede, que tenga sentido hacerlo es otro tema.
# Entonces el wdt se deber utilizar dendro de un bucle para garantizar que siempre este haciendo lo requerido?Se el restart_wdt() debe colocarse en aquellos puntos donde si se deja de pasar por determinado tiempo es porque se perdió el control y hay que resetear para retomarlo.
# como sabe el WDT que hay interferencias o que se quedo colgado.No lo sabe, solo sabe que dejaste de resetearlo.
no me queda claro donde y cuando lo debo implementar.Releé las respuestas con mejor luz.
Gracias por sus respuestas ya tomo comienza a tener sentido para mi,,,
por los ruidos que al parecer tengo y me estan bloqueando el pic debere implementar entonces el WDT, como no tengo disponible el tmr0 necesito realizar una temporizacion de 2 horas, generalmente lo hago con "for" y variables auxiliares, podrian recomendarme algo que no este teniendo en cuenta?
gracias de antemano.
...Te dije mas de una vez que lo no tenés disponible es el prescaler, porque hay uno solo, pero si podés usar el timer0 y el wdt. Obviamente escribiendo un código que tenga en cuenta las limitaciones.
por los ruidos que al parecer tengo y me estan bloqueando el pic debere implementar entonces el WDT, como no tengo disponible el tmr0
..................
#FUSES WDT
..................
while( true)
{
restart_wdt(); // para cuando no está pulsado
if (input(pulsador))
..................
while(Cont>0)
{
set_timer0(cont3);
while(get_timer0());
restart_wdt(); //<<<<<<< lo mismo en el siguiente bucle
Cont--;
}
..................
Tal vez no me supe expresar, agradezco la paciencia....Te dije mas de una vez que lo no tenés disponible es el prescaler, porque hay uno solo, pero si podés usar el timer0 y el wdt. Obviamente escribiendo un código que tenga en cuenta las limitaciones.
por los ruidos que al parecer tengo y me estan bloqueando el pic debere implementar entonces el WDT, como no tengo disponible el tmr0
Si el prescaler se asigna al timer0, el WDT será de 18ms --> Por lo tanto hay que resetearlo en menos de 18ms.
El el ejemplo que subiste para el 12F508 los intervalos entre cada decremento de Cont son casi 8ms, luego podés insertar un restart_wdt() sin problemas.
Tal vez no me supe expresar, agradezco la paciencia....Te dije mas de una vez que lo no tenés disponible es el prescaler, porque hay uno solo, pero si podés usar el timer0 y el wdt. Obviamente escribiendo un código que tenga en cuenta las limitaciones.
por los ruidos que al parecer tengo y me estan bloqueando el pic debere implementar entonces el WDT, como no tengo disponible el tmr0
Si el prescaler se asigna al timer0, el WDT será de 18ms --> Por lo tanto hay que resetearlo en menos de 18ms.
El el ejemplo que subiste para el 12F508 los intervalos entre cada decremento de Cont son casi 8ms, luego podés insertar un restart_wdt() sin problemas.
Lo que sucede es que como el 12f508 y el 10f200 no tienen serial propio(lo estoy emulando) tampoco interrupciones, entonces al parecer le estoy pidiendo mucho a este pic y digo que no tengo el TMR0 disponible es por que cuando utilizo el puerto serie no me trabaja el tmr0.
Gracias por sus respuestas,
Cuando un microcontrolador no posee un periférico de comunicación serial (I2c, SPI, RS232, etc.) lo que denominas "emulando" se llama Bit banging, esto implica utilizar un temporizador como generador de reloj para la duración del ancho de los pulsos (velocidad de transmisión) y/o generador de señal de reloj.
Es posible que esa sea la razón del problema del tmr0, sin embargo no he puesto atención a lo que quieres hacer con dicho temporizador.
Tu problema es una mal código escrito quieres solucionar con un parche que posiblemente no te funcione o sea una solución anodina.
....
Lo que sucede es que como el 12f508 y el 10f200 no tienen serial propio(lo estoy emulando) tampoco interrupciones, entonces al parecer le estoy pidiendo mucho a este pic y digo que no tengo el TMR0 disponible es por que cuando utilizo el puerto serie no me trabaja el tmr0.