Ese artículo de la Wikipic se parece mucho al artículo Conceptos y Explicaciones: El WatchDog en PicManía que a su vez también se parece mucho al anterior Post de este foro Contador con timer0 en los Pic 18 escrito por mí el día de mi cumpleaños del año pasado.
offtopic para leon_pic:
palabras honestas las tuyas amigo. :-)
En el mismo orden de lo iniciado por Manolo voy a estudiar en breve y después "articulear" en este mismo hilo la combinación mágica de los POR & BOR resets.
Como adelanto solo deciros que el uno, POR (Timer Power On Reset) hace que el reset se desenclave pasado un tiempo programable después de haber alcanzado el nivel optimo de hacerlo. Esto nos ayuda a esperar lo suficiente a que todo nuestro PIC esté estabilizado antes de empezar a ejecutar nuestro firmware. Y el otro, BOR (Brown-Out Reset(, mete en un reset automático al PIC cuando se detecta una caída de la alimentación programable.
La combinación de ambos nos dará seguridad de que el PIC no va a intentar realizar nada mientras esta cayendo la tensión de alimentación, al punto que que empiece a caer el PIC entrará en reset, funcionará el BOR, y si es un pico de caída no va a salir del reset hasta un tiempo después, por lo que si nos fluctúa la tensión seguirá disparándose el BOR hasta que tras el POR suficiente quede todo estabilizado y el PIC comience de nuevo a funcionar.
Esta combinación le viene de maravillas a la EEPROM, por ejemplo.
switch(restart_cause())
{
case WDT_FROM_SLEEP:
mostrar_version(); // VERSION
BIP();
case WDT_TIMEOUT:
mostrar_version(); // VERSION
BIP();
case MCLR_FROM_SLEEP:
mostrar_version(); // VERSION
BIP();
case MCLR_FROM_RUN:
mostrar_version(); // VERSION
BIP();
case NORMAL_POWER_UP:
mostrar_version(); // VERSION
BIP();
case BROWNOUT_RESTART: // Aqui se mete casi siempre que sufre ruido la pba
// Reiniciamos la pba pero sin que el usuario se de cuenta
// output_high(PIN_C0); // por eso ni encendemos leds, ni versión, ni pitamos ni nada.
// output_high(PIN_C1);
// output_high(PIN_C2);
// output_high(PIN_C3);
}En efecto, en todos los PIC's en que he probado esto hasta ahora se dá ese efecto, tras un Reset, MCLR a masa, la RAM queda intacta con todos los valores que tenía anteriormente (16F628, 16F777, 16F876, 18F2550 y 18F4550)
Esta muy buena la idea de aprovechar esta caracteristica, que seguramente no esta siquiera documentada... :)
Si la placa no es muy grande un condensador de tántalo de entre 10 y 33uF en una zona central de la placa en la
alimentación general y si la placa es muy grande varios de 1uF distribuidos según criterio junto con algunos de 10nF
y 100nF en la misma línea.
Si hay módulos exteriores lo mismo condensadores de desacoplo de varios tipos mas uno electrolítico entre 1 y 10uF,
lo mas cerca del conector que sea posible. Y las capacidades totales puestas en la línea de alimentación de la
placa no deben superar entre el 10% y 20% de la capacidad total de la fuente de alimentación. Y tener en cuenta que
los condensadores solo tienen influencia en una determinada zona de la placa por eso es de colocarlos repartidos
amen de varias capacidades antes que una grande.
Azicuetano ese programa que colgaste (http://www.todopic.com.ar/foros/index.php?topic=18647.msg130279#msg130279) se asemeja un poco a lo que hacen las bios cuando identifican fallas en la motherboards, el código de pitidos
... La pregunta es... cuando el ordenador hace 3 pitiditos intermitentes y rápidos... el problema es de la RAM o de la tarjeta gráfica??? :D :D :D Siempre se me olvida :mrgreen:
...
No solo no está documentada sino que me volvió loco hasta que descubrí que valores que yo asumía como ceros tenían un valor distinto tras un reset (Nota importante: ¡Que no implicase un corte total de la alimentación!)
Que al principio de mi función de grabación en eeprom implementara el chequeo de un flag que sólo activaría cada vez que fuera a hacer una grabación en la eeprom (si el programa entraba en la función de grabar accidentalmente, como el flag no estaría activado, no haría ninguna grabación).Me apunto esta idea para verificar que las funciones son llamadas siempre desde donde deben. Si utilizamos un flag para cada función y en todas se empieza con un "if (flag)..." estaremos seguro que se ha llegado a ellas de manera correcta.
En referencia a lo que comenta PICmouse... yo siempre hago un retardo de 0.5 segundos al principio de todos mis programas (precisamente para evitar que si reseteamos muy rápido el micro y justo al principio del programa tenemos grabaciones en eeprom, no lo interrumpamos y nos la llene de basura). No tengo comprobado que esa sea la razón pero me gusta hacerlo así más que nada para quitarme paranoias.
Si es cierto lo que comentas RedPIC, desde que supe del funcionamiento del PUT, siempre lo habilito.
En lo de la EEPROM interna, que me cambiaba los valores, me sucedia cuando trabajaba en ASM y me sigue sucediendo trabajando en C.
Es mas una vez por semejante problema, recurri a lo indebido, y era usar 3 posiciones de memoria por dato y en las 3 grababa lo mismo, luego cuando necesitaba ese dato, toma las 3 lecturas y las comparaba, la que mas se repetía, ese era el valor correcto. luego regrababa con las 3 posiciones con el correcto.
Yo se, yo se... algo extremo y malo, pero me saco del lio en el que estaba. Yo tengo la costumbre de usar las interrupciones, dan mayor potencia de funcionamiento y evitan bucles cerrados. Por eso no creo que el problema fuera por falta de tiempo de la escritura de la EEPROM. Cuando trabajaba en ASM, siempre esperaba la interrupción por fin de escritura de la EEPROM.
Aunque ahora, siempre que necesito EEPROM, uso una Externa. La interna no me da buena espina.
Hay circuitos comerciales que dividen la memoria E2Prom en dos partes, una es la pagina de trabajo y la
otra es la imagen de la primera. Siempre se trabaja con la pagina principal, se verifica lo que se escribe,
se dividen las paginas en filas y columnas y se genera un checsun por línea y luego uno general que
es la suma de todos los parciales y si todo esta correcto se actualiza la imagen, este sistema funciona
muy bien cuando se tiene la configuración del programa en E2Prom.
En los arranques siempre se hace un verificado de los checsum de la 1ª pagina.
Me interesa mucho este tema, ya que estoy haciendo una alarma y grabo la clave en la EEPROM, si esta se graba con cualquier valor, no voy a poderr ingresar núnca la clave correcta.
Saludos. :-/ :-/
Pues no tenía ni idea de esa directiva, pero suena muy interesante:
Syntax:
#zero_ram
Purpose:
This directive zero's out all of the internal registers that may be used to hold variables before program execution begins.
Llevando tu método al límite, Iván, si nuestro programa está basado en una máquina de estados, incluso podríamos ir al estado que estaba activo durante el Reset, ¿verdad?
Según tengo entendido la RAM permanece con los mismos valores, por lo que quizás se podría conseguir una transparencia total para el usuario.
Da la impresión de que la EEPROM es algo inestable y que se borra con mucha facilidad. Nada más lejos de la realidad, lo raro es que los adatos estén corruptos y muy dificilmente se borran por ruido. La prueba la tenemos en los propios porgramas almacenados el los pic que duran años y años perfectamente. Yo me inclino a pensar que los problemas con la memoria son debidos a una mala programación. De todas formas con un buen checksum no deberiamos tener más problemas y si los datos guardados no coinciden con los escrito habria que revisar las subrutinas que realizan estas operaciones.
Un saludo
Aunque ahora, siempre que necesito EEPROM, uso una Externa. La interna no me da buena espina.
En efecto, en todos los PIC's en que he probado esto hasta ahora se dá ese efecto, tras un Reset, MCLR a masa, la RAM queda intacta con todos los valores que tenía anteriormente (16F628, 16F777, 16F876, 18F2550 y 18F4550)
Mis pequeños trucos básicos para paliar los efectos del ruido:
Hard:
La fuente de alimentación:
AC: En la entrada un varistor siempre y su filtro con transformador y condensadores junto con su conexión a tierra.
DC: Capacidades variadas, 10nF, 100 a 330nF y Electrolítico
Hola Maunix!!
Creo que estas siendo el unico ganador del campeonato de POSTs, aunque creo que estas corriendo solo!! :mrgreen: :mrgreen:
Hay circuitos comerciales que dividen la memoria E2Prom en dos partes, una es la pagina de trabajo y la
otra es la imagen de la primera. Siempre se trabaja con la pagina principal, se verifica lo que se escribe,
se dividen las paginas en filas y columnas y se genera un checsun por línea y luego uno general que
es la suma de todos los parciales y si todo esta correcto se actualiza la imagen, este sistema funciona
muy bien cuando se tiene la configuración del programa en E2Prom.
En los arranques siempre se hace un verificado de los checsum de la 1ª pagina.
Puedes dar ejemplos de como aplicar esto??
Es interesante el tema!! :mrgreen:
PD2: EPEC y la re@#$!#$! jajaja. :mrgreen: :mrgreen:
Nota sobre PD2: EPEC o Empresa Provincial de Energía de Córdoba.
Joe, Maunix, tu teclado sí que está bien diseñado contra el ruido... :mrgreen:
PD2: EPEC y la re@#$!#$! jajaja. :mrgreen: :mrgreen:
Nota sobre PD2: EPEC o Empresa Provincial de Energía de Córdoba.
Te compadezco. La semana pasada instalaron un generador en mi ciudad (para evitar los cortes en el verano), y como va a sobrar energia, la distribuyen a otra ciudad. Tengo la suerte de vivir por donde pasa la nueva linea que debieron "reforzar", asi que me he pasado toda una semana son energia de 8 a 13.
Realmente, no nos damos cuenta de lo dependientes que somo de la electricidad!!! No soldador, no PDF, no TV, no DVD, no foro, no programar.....y no ruido electrico :)
Menos mal que mi soft de diseño de circuitos corre sobre un cuaderno cuadriculado, si no no se que hubiese hecho :) :) :) :)
Jiji, ese si que es inmune al ruido eléctrico aunque puede no serlo al ruido de la humedad o de que Santino lo agarre para jugar.
CitarJiji, ese si que es inmune al ruido eléctrico aunque puede no serlo al ruido de la humedad o de que Santino lo agarre para jugar.
No habia pensado en eso!!!!!!!!! Ya me voy a la fotocopiadora a hacer un "backup"!! :) :) :)
Si pones esto es materialmente imposible que desborde el perro:
while(TRUE)
{
restart_wdt();
}
Estás continuamente refrescándolo.
WDT sin Postscaler hace que el Reset por desbordamiento sea realmente rápido, quita WDT y empieza por WDT512 o WDT1024, después puedes ir disminuyendo el postscaler hasta que veas donde ocupas mas tiempo. Yo acostumbro a ponerlo muuuuy largo el tiempo del guardián y después lo ajusto a tiempo máximo de mi rutina mas larga (sin reestablecer el contador del Watch Dog).
Tienes también los fuses BROWNOUT_SW y BORV20. El primero anula al segundo y sirve para que tu mismo programa realice on-line el control del BOR. Utiliza solo una combinación del estilo BROWNOUT,BORV43
Si lo que quieres es precisamente provocar un reset, no lo pongas y verás como el perro le da un meneo a tu micro y lo hace arrancar de nuevo.
Si no quieres que te marque el PowerUp Timer al arrancar, desactiva el fuse PUT con NOPUT.
4.) ¿Cómo devuelvo una respuesta de reseteo por el POR?, no hay un caso para el...? o sólo pregunto por el bit del mismo???
la mayoria son normalitos, asi que debes usar NOLVP en el fuse, o que programador usas, para grabar el programa al micro??
Jejeje a lo mejor no me explique bien :mrgreen:... Lo que quiero decir con esto es que como hago para que el micro detecte está causa del reset... Así como hayCreo q es el NORMAL_POWER_UP, no estoy seguro. Depende tambien del pic; mira en su archivo .h (Almenos el pic12f683 lo tiene).
case WDT_TIMEOUT:
case MCLR_FROM_RUN:
case BROWNOUT_RESTART:.... No hay un Case para el POR(Power ON Reset)
Bueno ... quizá mi pregunta este más desviada del tema ... pues todos hablan del WDT y el BOR ... mi inquietud es la siguiente ... resulta que en un proyecto de la universidad tuve que usar el archiconocido sensor de distancias SRF08 ... utilicé este sensor para un experimento de control en donde el profesor me dejó como tarea implementar un Ball&Beam ... este es el famoso experimento de inestabilidad de una barra y una bola en donde la idea del control es centrar la bola en la barra inclinando de un lado al otro la barra, el centro de esta barra esta unido al eje de un motor ....Yo tambien como Diego, pertenezco a la gama de los "No Ilustrados", mis conocimientos son escasos respecto a la electronica y al control.
Pues bien ... este sensor SRF08 fue mi pesadilla pues medía bien la posición de la bola, sin embargo, era demasiado ruidoso. Si la bola estaba centrada en 50cm las mediciones del sensor eran: 50, 51, 49, 47, 52 .... y de vez en cuando una medición incorrecta y absurda como 255, en sí, este es un tipo de ruido digital!!! .. Aunque la bola llegaba a centrarse este ruido hacia que la barra vibrara mucho. Mi solución de principiante fue usar controles en donde la acción derivativa no estuviera directamente asociada al sensor, y tambien atenué con algunos filtros IIR.
Sin embargo, mi profesor me recomendó usar un tipo de filtro llamado filtro Kalman o de Kalman .. no sé ... a su explicación me dijo que este filtro es "inteligente" ... uno le da condiciones iniciales y el filtro "aprende" el comportamiento de la señal haciendo que el ruido se atenúe considerablemente ...
Nunca lo implementé pues ya no me daba la cabeza pa' tanta cosa ... pero me quedó la inquietud ... si alguien ha hecho algo similar o sabe de eso me gustaría oir la experiencia ...
Saludos!
C.P. Nº 14 El Predictor De Smith y El Filtro De Kalman: Ejemplos De Predicción Y Estimación
Serie 1 - Instrumentación en Separadores de Ensayo
Yo, en mi desconocimiento no he pasado de promediar medidas para quedarme con valores medios ... no se siquiera como se llamará esto que hago ...
Bueno, mezcle las cosas.
El cuadernillo practico se llama:CitarC.P. Nº 14 El Predictor De Smith y El Filtro De Kalman: Ejemplos De Predicción Y Estimación
Serie 1 - Instrumentación en Separadores de Ensayo
Si te interesa lo escaneo y lo pongo para leer... :mrgreen:
Tras haber leído con detenimiento el contenido del hilo Hablemos del Ruido (http://www.todopic.com.ar/foros/index.php?topic=18106.0) y después de haber analizado y entendido los famosos “checkpoints” de Azicuetano, he llegado a la conclusión de que es de vital importancia luchar contra el ruido haciendo un buen diseño de nuestros circuitos y aplicando todas las técnicas posibles en el HARDWARE, pero no es menos importante implementar una serie de protecciones en el SOFTWARE que lo hagan robusto, fuerte e inexpugnable.En estos dias he tenido muchos problemas de ruido en una tarjeta que elabore para una maquina en la empresa que trabajo, por el molesto ruido, por lo tanto me he dedicado a investigar sobre el tema del ruido, por lo cual me encontre con un convertidor dc,dc de 24 volts a 5 volts que reduce demasiado el nivel de ruido, cabe mencionar que la tarjeta la elabore en una tarjeta perforada que tiene mucha similitud con un protoboard creo que el problema esta ahi quisiera saber si alguien me puede orientar sobre las caracteristicas de la misma tarjeta, volviendo al tema del convertidor dc,dc les envio el numero por si alguien le interesa, cabe mencionar que el costo es un poco elevado por eso quisiera que alguien me orientara sobre el detalle de la tarjeta perforada tipo protoboard, el numero del convertidor es el siguiente: ten5-2411
Al abrir este hilo pretendo que los que tenéis experiencia en el tema nos contéis cuáles son esos truquillos que cada uno utiliza, con la intención de que aquí vayan saliendo todos ellos y podamos consultarlos en cualquier momento.
Mi experiencia en la lucha contra el ruido es corta, pero para no empezar el hilo sin aportar alguna medida antirruido, hablaré del archiconocido Watchdog. En vez de contarlo yo, os pego el artículo que he extraido de la WikiPIC (http://www.micropic.es/index.php?option=com_mambowiki&Itemid=75).
Watchdog
El Watchdog, o "perro guardian" es un concepto de protección usado para volver a reiniciar el programa cuando éste "se pierde" o realiza una acción no prevista.
Es un dispositivo que resetea al micro cada intervalo de tiempo, salvo que el programa le ponga el contador a 0. De esta manera, si el programa se queda colgado en algún sitio, y no refresca al Watchdog, él se encargará de resetear al micro y evitar el cuelgue.
No es extraño que en microelectrónica se den circunstancias de hardware o firmware no previstas por el diseñador en las que un microprocesador se quede en un estado indeterminado del que le sea imposible salir sin una ayuda externa.
El Watchdog lo que hace fundamentalmente es resetear el micro tras un periodo de tiempo determinado. Su funcionamiento es similar a la Interrupción por Desbordamiento de un Timer, que se produce cuando un Timer que es incrementado continuamente pasa de su valor máximo al mínimo para comenzar de nuevo a contar.
En el caso del Watchdog en lugar de saltar una interrupción se genera un reset automático en el momento de producirse dicho desbordamiento.
Pero evidentemente en condiciones normales, nuestro micro funcionando correctamente, no debería producirse dicho reset automático.
Para evitar que el reset se dispare es para lo que aplicamos el restart_wdt(); o sea que "restauramos" el timer del Watchdog, o lo que es lo mismo: lo volvemos a poner a 0 "a mano" y vuelve de nuevo a iniciar su cuenta para acercarse al abismo y amenazarnos con resetear el micro si antes no lo "restauramos" de nuevo.
Un ejemplo tonto:
Configuramos nuestro Watchdog para que salte cada 5 ms, por ejemplo.
Entramos en una rutina que espera a que le lleguen una docena de caracteres vía RS232, y cada vez que le llega uno hace un restart_wdt().
Al recibir el doceavo carácter sale de la rutina y continua su ejecución normal.
Por manos del demonio se nos escapa el hacha que con la que estábamos haciendo juegos malabares y corta accidentalmente el cable de la RS232, justo cuando el PIC había recibido el carácter número 11 de los 12 que esperaba.
Por lo tanto nuestro programa se queda esperando un carácter que nunca le va a llegar, al menos durante el tiempo en que tardemos en sustituir el cable accidentado.
¿Y qué ocurre entonces con el resto de del programa que debía estar funcionando? pues que todo está detenido indefinidamente
.
Pero, para eso está el Watchdog. Como restaurábamos el contador cada vez que recibíamos un carácter y estos iban llegando, uno a uno en su cadencia natural, el Watchdog no se desbordaba y todo iba bien. Pero tras recibir nuestro 11 carácter y quedarse esperando el 12 nadie ha restaurado el Watchdog por lo que este camina, paso a paso, tick a tick, hasta el temible desbordamiento ... y éste se produce indefectiblemente 5 ms después de haber recibido el onceavo carácter.
El PIC se resetea y todo vuelve a comenzar de nuevo.
Si hemos sido lo suficientemente inteligentes como para escribir un 1 en la EEPROM al iniciar la recepción de los susodichos 12 bytes, y teníamos previsto escribir un 0 en la EEPROM en el mismo sitio para indicar que la última recepción de 12 bytes fue un completo éxito tendremos disponible un indicador veraz y seguro de que al reiniciarse nuestro PIC sabremos fehacientemente que la última recepción fue bien o por el contrario se convirtió en un completo, total y rotundo fracaso y, por lo menos, nos tomaremos con precaución el asunto de la RS232.
Nuestro programa podrá seguir su curso evitando los terrenos pantanosos y habilitando los medios para solventar los problemas que nos hemos encontrado.
MMMmmmhhhh... caviar del bueno...
Es de obligada lectura, pero, si estamos un poco perros (gandules, vagos) como mínimo leer desde la página 28 hasta la 34.
http://www.freescale.com/files/microcontrollers/doc/app_note/AN2764.pdf?fsrch=1
Como dijo Jack el Destripador: ¡Vayamos por partes¡!
Solo con los fuses tenemos para escribir una novela.
#fuses XT, WDT, NOPROTECT, NOCPD, LVP, VREGEN, NOPBADEN, INTRC_IO, MCLR, BROWNOUT_SW, BORV20
LVP es mas peligroso que un tigre en tu dormitorio. En cuanto detecte 5V entra en modo programación. Usa NOLVP salvo que estés programando a bajo voltaje.
WDT sin Postscaler hace que el Reset por desbordamiento sea realmente rápido, quita WDT y empieza por WDT512 o WDT1024, después puedes ir disminuyendo el postscaler hasta que veas donde ocupas mas tiempo. Yo acostumbro a ponerlo muuuuy largo el tiempo del guardián y después lo ajusto a tiempo máximo de mi rutina mas larga (sin reestablecer el contador del Watch Dog).
Tienes también los fuses BROWNOUT_SW y BORV20. El primero anula al segundo y sirve para que tu mismo programa realice on-line el control del BOR. Utiliza solo una combinación del estilo BROWNOUT,BORV43
INTRC_IO y XT son mutuamente excluyentes. O XT para un Cristal Externo menor o igual a 4 Mhz ó INTRC_IO para el oscilador interno pero no los dos al mismo tiempo.
VREGEN Activa el regulador de voltaje para el USB, si no estas usando el USB no te hace falta (Sobre todo si no tiene puesto el condensador en VUSB, patilla 18 del 18F4550, que le hace falta para realizar dicha regulación)
Conclusión: Pon unos fuses del estilo que te propongo mas abajo y prueba ...
#fuses XT, WDT512, NOPROTECT, NOCPD, NOLVP, NOPBADEN, MCLR, BROWNOUT, BORV43, NODEBUG
Y sobre todo Datasheet, mucho Datasheet. :mrgreen:
Además de todo esto también me gusta hacer lo siguiente:No estoy muy deacuerdo con este truquillo Azicuetano, pues (claro que depende de la aplicacion) hacer esto si que cuesta y me refiero al tiempo que desperdicias al poner ese delay para ajustar MAS el WDT. Almenos, en una aplicacion ciclica, como la que comento un post atras, hacer esto no me dejaria hacer esas reviciones. Por el contrario, he oido o leido de mchip ya hace tiempo de una forma para no tener ese tipo de fallas que tenias sin tener que hacerlo asi y es cubriendo toodo lo que no has usado de progrrama con un GOTO creo al incio de tu programa por si el contador de programa se le ocurre saltar por ahi. No recuerdo que nota era y la forma en que se hacia y tampoco lo he echo pero se lee muy interesante implementarlo. Tampoco estoy seguro como se aria eso en CCS, creo q con #ORG o #reserve... bueno.
Si pasamos por el bucle principal cada 10 ms (aproximadamente) configuro el wdt con 18ms y en el bucle principal (si la aplicación me lo permite) hago un retardo de unos 6 o 7 ms para que mi bucle principal tenga una duración de 17 ms (más o menos). Lo que consigo así es ajustar al máximo el wdt. Parece una tontería pero... por no ajustar bien el wdt en varias ocasiones que he tenido problemas de ruido y el wdt no me los ha solventado (porque se me ha refrescado aún sufriendo un salto el contador de programa).
---------------------------------------------------------------------------------------------------------------------------------------------
Esto que comenté hace ya un tiempo lo continuo haciendo. Tengo comprobado que si sufres ruido la ejecución normal del programa (el contador de programa) salta a donde le da la real gana. Si no se ajusta bien el tiempo del WDT se puede dar el caso que, aún saltando a cualquier otra función, al WDT no le de tiempo a desbordarse y no te resetea la aplicación (la consecuencia es evidente, el programa se cuelga jeje).
Este es el truquillo que yo tengo para el WDT. Estoy de acuerdo que quizás es demasiado extremista mi postura, pero bueno, como no cuesta nada hacerlo y tengo comprobado que se pueden sufrir cuelgues si no lo ajustas bien... por eso lo hago :-)
Bueno, voy con el 'restart_cause()' de mis amores.
Con esta función podemos saber cual fue la causa del reinicio del PIC.
Para que la utilizo? Pues... si nuestro hardware se resetea por causa mayor podemos hacer que el usuario ni se entere del cuelgue.
En que tipos de hard-software se puede utilizar esto?? Pues vamos con un ejemplo:
Imaginemos que tenemos una PBA que cada vez que se enciende el usuario la tiene que activar dándole a un pulsador. Si el equipo se cuelga por la noche, estará sin funcionar un buen número de horas. Sin embargo, si al principio de nuestro main somos capaces de saber que fué lo que pasó (por que se reseteó) podremos hacer que el equipo continue funcionando como si nada.
Evidentemente he puesto el ejemplo más tonto, pero, imaginaros que cuando se enciende la pba hace un pitido, o... espera iniciar algún evento que en ese momento no se puede hacer por lo que sea.
El caso es que se puede utilizar casi siempre y... es un buen método para que nadie se de cuenta de nuestra ineptitud (o de la suya propia) :D
Un ejemplo puede ser este. La pba siempre hace un pitido cuando se enciende y muestra por unos displays la versión del soft que tiene grabado. A continuación solo detectaremos cuando la PBA se reinicia por un fallo en la alimentación 'BROWNOUT_RESTART' y lo que haremos es omitir ese pitido inicial y que nos muestre la versión. Aunque el usuario estñe encima de la pba no se dará ni cuenta que se ha reseteado por un fallo en la alimenteción. :mrgreen:Código: [Seleccionar]switch(restart_cause())
{
case WDT_FROM_SLEEP:
mostrar_version(); // VERSION
BIP();
case WDT_TIMEOUT:
mostrar_version(); // VERSION
BIP();
case MCLR_FROM_SLEEP:
mostrar_version(); // VERSION
BIP();
case MCLR_FROM_RUN:
mostrar_version(); // VERSION
BIP();
case NORMAL_POWER_UP:
mostrar_version(); // VERSION
BIP();
case BROWNOUT_RESTART: // Aqui se mete casi siempre que sufre ruido la pba
// Reiniciamos la pba pero sin que el usuario se de cuenta
// output_high(PIN_C0); // por eso ni encendemos leds, ni versión, ni pitamos ni nada.
// output_high(PIN_C1);
// output_high(PIN_C2);
// output_high(PIN_C3);
}
Un saludo desde Alicante.
como seria un ejemplo de como armo el programa y como hago la lectura del adc
while (true)
{
set_adc_channel(0);
delay_us(20);
for(var1=0;var1<8;var1++)
{
volt = read_adc();
delay_us(20);
}
var2=var2+volt;
var1=var1+1;
valor=volt/8;
valor=volt*50/1023;
lcd_gotoxy(2,2);
printf(lcd_putc,"%04.2f",valor );
delay_ms(500);
while (true)
{
for(var1=0;var1<8;var1++)
{
volt += read_adc();
delay_us(62);
}
valor = volt / 8; // No se como lo tomara el compilador si es mejor asi o rotarlo 3 posiciones, es decir valor = volt >> 3
valor = valor * 50 / 1023;
lcd_gotoxy(2,2);
printf(lcd_putc,"%04.2f",valor );
volt= read_adc(); volt += read_adc();o que es lo mismo que ponervolt = volt + read_adc();se me dispara empezando a contar asendente y no para
volt = 0;
#include <16f873a.h>
#device adc=10
#fuses NOWDT,BROWNOUT,XT,NOLVP,PUT
#use delay (clock=4m)
#define use_portb_lcd true
#include <lcd.c>
void main(){
int var1=0;
float valor=0,volt=0,valor2,amper;
//Se habilita el A/D y se declara el PORT a usar
setup_adc_ports(an0_an1_an3);
setup_adc(adc_clock_div_32 );
//Se inicia la LCD
lcd_init();
lcd_gotoxy(3,1);
lcd_putc("iniciando");
delay_ms(2000);
lcd_gotoxy(7,2);
lcd_putc("LPK");
delay_ms(500);
lcd_putc("\f");
lcd_gotoxy(2,1);
lcd_putc("Volt Amper");
delay_ms(1000);
while (true){
set_adc_channel(0);
delay_us(20);
volt = 0; // ACA es donde decia
for(var1=0;var1<8;var1++)
{
volt=volt+ read_adc();
delay_us(62);
}
valor = volt / 8;
valor = valor * 50 / 1023;
lcd_gotoxy(2,2);
printf(lcd_putc,"%04.2f",valor);
set_adc_channel(3);
delay_us(20);
amper = read_adc();
delay_us(500);
valor2=amper*18/1023;
lcd_gotoxy(11,2);
printf(lcd_putc,"%04.3f",valor2);
delay_ms(200);
}
}
Esta técnica (la recuperación de una máquina despues de un apagado) es algo que se hace desde hace mucho tiempo en los sistemas microprocesados, se conoce como arranque en caliente (se mantienen los datos) o arranque en frio (se inicializa la máquina). Es muy conveniente realizar un checksum de la memoria en el momento del arranque y si los datos no son coherentes realizar una arranque en frio, en caso contrario realizar el arranque en caliente.
Un saludo
Por otra parte, espero que no sea problema de software porque sino ya me veo viajando meses para actualizar todas las 213 placas restantes....
- Tenes una instruccion sin sentido:
btfss LCD_PinRS