PicManía by RedRaven
 

Búsqueda personalizada

Conceptos y explicaciones

 

  Una colección de artículos sobre algunos conceptos técnicos de los distintos módulos que los PIC's implementan (como conversiones A/D, osciladores a cuarzo, alimentación... etc.) y que no tienen cabida en otras secciones de esta Web.
 

 


Algunas ideas sobre la Conversión A/D en los PIC's : Voltajes de Referencia
 
Vamos a ver si soy capaz de explicarme razonablemente bien sin liarme demasiado ...
 
  • La conversión Analógica a Digital que es capaz de hacer un PIC consiste en convertir un valor de tensión  (voltaje) que conectemos a un PIN, habilitado para ello, en un valor numérico proporcional a dicha tensión que podemos guardar en una variable y ser utilizado por nuestro programa del PIC.
     

  • Dicho de otra forma: Si entre un pin del PIC podemos tener una tensión, con respecto a GND, entre 0V y 5V y realizamos una conversión Analógico-Digital de ese pin con una precisión de 8 bits entonces el PIC puede "leer" esa tensión en 256 (2^8=256) valores distintos que nos devuelve como resultado de la lectura, siendo el 0 el correspondiente a los 0V y el 255 el correspondiente a los 5V, y todos los intermedios en "saltos" de 0,019V (5V/256).
     

  • Si en lugar de 8 bits estamos utilizando un PIC que tiene una conversor A/D de 10 bits de precisión entonces ese mismo rango de 0V a 5V podemos "leerlo" en 1024 (2^10=1024) valores distintos, siendo el "resultado" 0 el que corresponde a los 0v y el 1023 a los 5V. Cualquier valor intermedio nos devolverá un número equivalente con "saltos" de 0,0049V por valor.
     

  • Hemos visto que el mínimo que podemos convertir es 0V o tensión del nivel del Vss (GND) del PIC y 5V o tensión del nivel de alimentación Vcc del PIC.
     

  • Esto es así si no utilizamos los Voltajes de Referencia, porque si los utilizamos entonces las cosas pueden cambiar a mejor ....
     

  • Me explico: Imaginemos un dispositivo analógico que varía su tensión de salida entre 0V y 1V. Si le aplicamos la conversión A/D como antes con 8 bits de precisión entonces los valores que vamos a obtener son entre 0 y 51 (1*256/5V) con lo que desperdiciamos una parte muy importante del rango posible de conversión, entre 52 y 255 nunca nos va a aparecer como resultado de la misma.
     

  • Entonces el truco está en poner a 1V la patilla VRef+ del PIC con lo que la conversión A/D a realizar en lo que haya presente en nuestro pin a leer se va a efectuar en 256 pasos entre GND y VRef+, no entre GND y Vcc como antes, con lo que obtenemos un resultado 5 veces mas preciso: 1V dividido en 256 trocitos con lo que cada número corresponde con 0,0039V.
     

  • Y todavía se le puede dar una vuelta de tuerca más a este asunto.
     

  • Imaginemos que nuestro dispositivo analógico varía su tensión de salida entre 1V y 2V. Si utilizamos el primer ejemplo que vimos, conversión A/D entre 0V y 5V con 8 bits de precisión, entonces solo obtendremos números entre 51 y 102, perdiendo todos los valores inferiores y superiores a éstos.
     

  • Si utilizamos el ejemplo anterior a éste pero colocando el VRef+ a 2V entonces tendremos valores entre 128 y 255 pero ninguno inferior a 128 ya que nuestra tensión analógica no baja de 1V ....
     

  • Así que la solución está en utilizar otra patilla del PIC, en este caso para VRef-, o sea para ponerle la referencia de tensión mínima a partir de la cual vamos a convertir valores, que junto con la VRef+ tenemos el margen o rango de tensiones a convertir a gusto del consumidor.
     

  • En este segundo ejemplo pondríamos VRef- a 1V y VRef+ a 2V con lo que tendríamos una conversión de 8 bits en la que el 0 correspondería a los 1V y el 255 a los 2V ...
     

  • Todo esto se puede ver en el siguiente diagrama de bloques del conversor A/D de los PIC's de la familia 16F87X que pongo mas abajo:


 


Espero haberme explicado bien.


Los Cristales y El Tiempo.
Cálculo de tiempos según el Cristal oscilador que usamos
 

   En la sección El Rincón del C dedicábamos un artículo al uso de la Interrupción RTCC, en el que mostrábamos una tabla de tiempos que tardaba el TIMER0 en dar una vuelta de manivela completa, que dependía del Preescaler seleccionado. Está tabla de tiempos adjuntaba como nota que el Cristal oscilador utilizado era de 4 Mhz.
 

   Sin embargo soy capaz de imaginar a cualquiera de vosotros, amables Picmaníacos, con los ojos cerrados metiendo la mano en vuestro saco de cristales. Sacando uno al azar. La probabilidad de que dicho cristal sea de 4 Mhz es calculable. Es directamente proporcional al numero de cristales de 4 Mhz que haya en vuestro saco e inversamente proporcional al número de otros tipos de cristales que tengáis en tan heterogénea mezcla. Una pequeña locura.
 

   ¿Que hacemos, entonces, si vais a utilizar un cristal cuyo valor este alejado, o muy alejado, de nuestros 4 Mhz de referencia? Pues fácil y sencillo como juego de chiquillo: Calculamos el Tiempo de RTCC en función del Cristal que vamos a usar, o sea el tema de este artículo.
 

   La primera fórmula que vamos a ver nos da el Tiempo que tarda RTCC en dispararse, sin Preescaler, comenzando TIMER0 en 00h y terminando en FFh, o sea desbordamiento completo:
 

  • Time = (256 * 4) / FOSC  (1)
donde Time es el tiempo en segundos (S) que tarda RTCC en saltar y FOSC es la frecuencia de oscilación de nuestro cristal en Hercios (Hz)
 
Ejemplo:
 

Si uso un cristal de 6 Mhz nuestra fórmula la escribiríamos:

Time = (256 * 4) / 6.000.000 = 1.024 / 6.000.000 = 1.706666e-4 = 0.000171 s = 171 μS (microsegundos)

Si a este tiempo le aplicamos el máximo Preescaler posible que es el 1:256, nuestra interrupción saltaría cada:

Time = 0.000171 * 256 = 0,043776 S = 43,776 mS (milisegundos)

   Sin embargo es posible, yo diría mas que posible es muy probable, que no os sea útil tener que esperar a toda una interrupción RTCC, de 00h a FFh, sino que necesitéis periodos de tiempo mucho mas concretos. Veamos entonces qué se puede hacer para obtener sucesivas RTCC's cada periodos definidos de tiempo fijado por nosotros.
 

   Decíamos que RTCC salta cada vez que TIMER0 pasa de FFh a 00h, a esto le llamamos desbordamiento de TIMER0. Con la intención de calcular tiempos concretos para este desbordamiento de TIMER0 la técnica que vamos a utilizar es escribir en el contador TIMER0 el valor a partir del cuál queremos que empiece a contar antes de llegar a FFh y pase de nuevo a 00h, que es quien produce el desbordamiento. Cada vez que salte RTCC y dentro de la rutina de tratamiento de esta interrupción volvemos a escribir el valor inicial del contador para iniciar siempre la cuenta de TIMER0 con nuestro valor deseado.
 

   Si en lugar de empezar a contar desde 00h empezamos a contar siempre desde 80h (128 en decimal), exactamente a la mitad del recorrido de TIMER0, entonces nuestra RTCC saltará el doble de veces o lo que es lo mismo habremos dividido su tiempo de desbordamiento por 2, o análogamente habremos multiplicado por 2 su frecuencia, o ... ¡Yá cállate!.
 

   Haciéndole una pequeña transformación a nuestra primera fórmula (1) podemos calcular qué valor hay que escribir en TIMER0 para obtener un tiempo deseado de desbordamiento de RTCC:
 
  •  MiTIMER0 = 256 - (Time / (4/FOSC) )  (2)
donde MiTIMER0 es el valor a escribir en el Contador TIMER0, Time es el tiempo en segundos (S) que deseamos conseguir para RTCC y FOSC es la frecuencia de oscilación de nuestro cristal en Hercios (Hz)
 
Ejemplo:
 

Si deseo un desbordamiento de TIMER0, una RTCC, cada 100 microsegundos, con un cristal de 6 Mhz calcularíamos:

MiTIMER0 = 256 - (0.000100 / (4/6.000.000)) = 106

Luego cargando TIMER0 con 106 (6Ah ) obtendríamos una RTCC cada 100 microsegundos o 0.1 milisegundos o ...

   Y con esto casi hemos acabado con el tema de los tiempos y los cristales. Solo que hay una pregunta que yo mismo me he hecho y que tras profundas deliberaciones, estudios, búsquedas y tostado de pestañas yo mi me conmigo me he respondido. Deseo compartir dicha respuesta con ustedes, amables Picmaníacos:
 
Pregunta: ¿Por qué 256? ¿Por que 4? ¿Qué relación tienen con FOSC?
 
Respuesta: La respuesta no está en el viento, sino en el interior de nuestro PIC, de cómo funciona.
 

   Me explico: Nuestro PIC, como Jesucristo, no es de este mundo. No participa de nuestro continuo espacio-tiempo, sino que vive cuánticamente dando saltitos, pasando de un estado a otro bajo la estricta batuta del Dios Cristal que es quien le interpreta el son al que debe bailar.
 

   FOSC es la velocidad de la batuta. Salta ... salta ... salta .... le dice al PIC, una vez cada 0,00000025 segundos (0.25μs) con un cristal de 4 Mhz, una vez cada 0,00000005 segundos (0.05μs) con un cristal de 20 Mhz. Es lo que se conoce como el Ciclo de Reloj.
 

   Pero nuestro PIC necesita 4 de estos ciclos para ejecutar un sola instrucción, como por ejemplo incrementar en 1 el valor del contador de TIMER0. Es lo que se conoce como Ciclo de Instrucción.
 

   Como nuestro TIMER0 corre raudo y veloz desde 00h hasta FFh, o sea desde 0 hasta 255, o sea que cuenta 256 veces, necesita por lo tanto 256 ciclos de instrucción para dar una vuelta completa o lo que es lo mismo 256 * 4 ciclos de reloj FOSC.
 

 Con un cristal de 4 Mhz, que da un pulso cada 25μs, TIMER0 necesita 256 * 4 * 0.25 μs para dar su vuelta lo que significan 256 μs por vuelta y como el mínimo Preescaler que podemos usar es 1:2 entonces tenemos que la máxima velocidad que puede alcanzar RTCC con un Cristal de 4 Mhz es de 1 vuelta completa cada 512 μs. (Lo que es absolutamente compatible con la tabla de tiempos del artículo dedicado al uso de la Interrupción RTCC y que dio pie al presente artículo)
 

Bello. Sencillo a la par que elegante. Me gusta.
 
 


 

¿Qué es el Watch Dog Timer? I
Y así evitamos que se nos "cuelgue" nuestro PIC.


 

El "Watch Dog Timer" o "Temporizador Perro guardián" es un artificio que se utiliza de antiguo para evitar que los microprocesadores se queden "colgados".

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 WDT 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 WDT 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 WDT, 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 WDT 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 WDT. 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 WDT no se desbordaba y todo iba bien. Pero tras recibir nuestro 11 carácter y quedarse esperando el 12 nadie ha restaurado el WDT 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.
 
 


 

Consiguiendo 4 Mhz para los 48 Mhz necesarios en los PIC's con USB 2.0
 

Voy a intentar explicar un poco de dónde sale esto de los 4 Mhz para el USB 2.0 de los PIC's.

Como nunca me canso de repetir: En los datasheet está TODO, absolutamente todo.

Aquí os pego un trozo de la imagen donde aparece la estructura de configuración de las opciones de los osciladores en los PIC's de la familia 18Fxx5x que son los que soportan el USB 2.0 (Documento 39632b.pdf de Microchip dedicado a los 18F2455-2550-4455-4550 de.pdfgar)
 


Este sistema es complejo debido a la inmensa versatilidad y posibilidades que ofrece.

Como podéis ver en OSC1 y OSC2 conectamos nuestro cristal: 4 Mhz, 8 Mhz, 12 Mhz, 16 Mhz, 20 Mhz, 24 Mhz, 40 Mhz  ó 48 Mhz, que son los cristales validos compatibles con lo que sigue a continuación.

Tened en cuenta que este cristal es el mismo para generar la frecuencia de 48 Mhz necesaria para el USB 2.0 y para el Clock del PIC, que pueden ser la misma o no, según la configuración que al final adoptemos, quiere esto decir que podemos tener el USB a 48 Mhz y nuestro programa en el PIC funcionando a 12 Mhz por ejemplo.

Fijaos en que justo tras el Smicht Trigger del Primary Oscillator salen tres líneas en paralelo que van a módulos distintos con distintas posibilidades.

La primera línea, la superior, va directamente al switch USBDIV que si está a cero indica que la frecuencia base original del cristal es directamente inyectada al USB, si pasa el switch FSEN que elige entre todo el sistema directo/PLL o el Primary Clock del CPU. Esta Opción de inyectar directamente la frecuencia del cristal es obviamente solo posible si usamos un Cristal de 48 Mhz que es lo que necesitamos para el USB.

Cualquier otro cristal debe ser tratado para conseguir los 48 Mhz necesarios.

El módulo USB Clock Source tiene a su entrada un PLL Prescaler, o sea un divisor de frecuencia. En cada una de sus salidas vamos a tener FOSC dividida por 1, 2, 3, 4, 5, 6, 10 ó 12. Y mediante PLLDIV que no es mas que un Multiplexor vamos a seleccionar la que deseamos usar.

Así si nuestro cristal es de 12 Mhz y en PLLDIV colocamos un 010 estaremos dividiendo por 3 el valor de FOSC con lo que tendremos 4 Mhz a la salida del MUX. Si por el contrario el cristal es de 20 Mhz y en PLLDIV colocamos un 100 entonces dividiremos por 5 FOSC con lo que tendremos también 4 Mhz a la salida del MUX.

Esta salida del MUX es lo que utilizamos para inyectársela al PLL de 96 Mhz. Si le metemos 4 Mhz él genera 96 Mhz. Es esta capacidad de pasar de 4 Mhz a 96 Mhz la que nos da la posibilidad de usar un montón de cristales distintos.

Pero 96 Mhz es el doble de lo que nos hace falta para el USB que son 48 Mhz. Asi que inmediatamente después tenemos que tener, y tenemos, un divisor por 2 que es el segundo camino por el que llegamos a USBDIV y en este caso le pondremos un 1 para usar la señal proveniente del PLL.

Fijaos que además de inyectar la señal oscilante en USBDIV también se conecta la señal del PLL a 96 Mhz en un Postscaler, otro divisor, en este caso por 2, 3, 4 ó 6 y cuyas señales van al CPUDIV. O sea que podemos generar una señal de reloj para nuestro PIC, no para el USB sino para la velocidad de ejecución de nuestro programa tomándola del PLL y que puede ser de 16 Mhz, 24 Mhz, 32 Mhz ó 48 Mhz.

Pero además la señal original llegaba en paralelo al Oscilator Postcaler, otro divisor más, que de forma directa, sin pasar por el módulo PLL nos divide la frecuencia original del cristal por 1, 2, 3 ó 4 y que también va a parar al CPUDIV pero desde otro origen. Con este módulo podemos obtener otra gama de frecuencias distinta para hacer correr el programa.

Cual de ambos CPUDIV vamos a utilizar lo seleccionamos con el switch FOSC3:FOSC0 que es de donde sacaremos la definitiva frecuencia de ejecución de programas.

Por último también tenemos disponible una entrada proveniente del Primary Clock y que dividida por 4 llega también a FSEN y podemos utilizarla en lugar de la que le llega desde el canal directo/PLL

Como podéis ver es toda una maravilla cómo esta montado este tema de los osciladores, sobre todo por lo que respecta a las inmensas capacidades que tiene para hacer correr nuestro PIC a decenas de velocidades distintas siendo capaz, al mismo tiempo de tener disponibles los 48 Mhz imprescindibles para el USB 2.0.

Me descubro ante los ingenieros de Microchip y los aplaudo, se lo merecen.
 

 

 


 

Dos Fuentes en Una: Un cuento de potencia.
 
  • En otro tiempo y lugar se planteó la cuestión de si se podría hacer una fuente de alimentación simétrica partiendo de dos fuentes normales y de igual voltaje.
  • Nada mas cierto que es posible hacerlo con tan solo unir el polo positivo de una de ellas al polo negativo de la otra consiguiendo con está unión un polo común de referencia de los voltajes positivo y negativo que constituirían los polos restantes, el positivo de aquella fuente que aportase el negativo al común, y el negativo en aquella en que su aportación al común fuese su polo positivo (ver el esquema al final de este artículo).
  • Pero también se planteó el tema de qué hacer con los chasis de ambas fuentes: ¿Se podrían o deberían unir el uno al otro?
  • Si los negativos de las fuentes están conectados a los respectivos chasis NO se deben unir los chasis. Si se hace conectaríamos el Negativo de la Fuente 1 y los Positivo y Negativo de la Fuente 2 todos juntos. Resultado: Humo y lágrimas.
     
  • Si deseamos unir los chasis debemos primero asegurarnos que desconectamos del chasis el Negativo de la Fuente que aporte el Positivo al común. Y solo después ya podríamos conectar los dos chasis a ese común.  Uno de ellos, el de la fuente que aporta el Negativo al común ya estará conectado al mismo. Para saber si el chasis está o no conectado al negativo debemos medir con el Téster el voltaje que hay entre el positivo de cada fuente y su respectivo chasis.

  • Y con estas ideas se me ocurrió escribir un cuento:

Érase en el País de Las Fuentes dos fuentes de alimentación distintas pero por lo demás absolutamente iguales. Tenían cada una de ellas su Polo Positivo, su Polo Negativo, y entre ellos su Voltaje, que como hemos dicho era el mismo en ambas.

Un buen día la Fuente Uno decidió pedir en matrimonio a la Fuente Dos, en el País de las Fuentes los matrimonios entre fuentes del mismo sexo estaba perfectamente permitido.

Querían conseguir de este modo una nueva fuente a la que llamarían Simétrica y que tendría lo mejor de ambas, la Fuente Uno pondría todo su voltaje positivo y la Fuente Dos haría lo mismo con todo su voltaje negativo.

Para que esto fuese posible la Fuente Uno debería tener en común con la Fuente Dos su Polo Negativo. La Fuente Dos debía aportar como polo común su Polo Positivo. A la unión de ambos polos le llamarían Polo Cero. Así el voltaje entre el Polo Positivo de la Fuente Uno y el nuevo Polo Cero sería el mismo que antes tenía ésta, +Voltaje. Pero el voltaje entre el Polo Negativo de la Fuente Dos y el nuevo Polo Cero sería igual pero negativo, estaría por debajo del Polo Cero, -Voltaje.

Y, voilá, así nació la nueva Fuente Simétrica, con su Polo Positivo, su Polo Cero y su Polo Negativo, y entre ellos +Voltaje y -Voltaje .... y el doble de Voltaje si tomábamos  la diferencia entre el Positivo y el Negativo.

Pero hete aquí que el pérfido Constructor de Fuentes hizo algo que desbarató todos estos felices planes de nuestras dos Fuentes. Sin encomendarse a Dios ni al Diablo unió los Polos Negativos de cada una de las fuentes a sus respectivos Chasis. Esto no era extraño en él y lo hacía cada vez que tenía la mas mínima oportunidad ...

Y así cuando nuestras dos cándidas fuentes intentaron consumar su matrimonio, y unieron la una su Polo Positivo con la otra su Polo Negativo, y se acercaron los chasis la una a la otra, y se rozaron ... Pusieron en Corto la Masa de la Fuente Uno con el Positivo y la Masa de la Fuente Dos ....

Humeó durante un instante, se escucho un fuerte chasquido y la Fuente Dos murió fundida. Fue una muerte brillante pero breve.

Y colorín, colorado, este cuento ha terminado.

Moraleja: Cuidado al unir los chasis de las fuentes, nunca se sabe a quien están conectados.

 

 


El PORTA de los PIC's y una de sus particularidades.
Push-Pull y Open-Drain, dos en uno.
  • Los pines 0 a 3 y 5 del PORTA de los PIC's, en uso como I/O digital, comparte características similares con los otros puertos del PIC, PORTB o PORTC por ejemplo. Pero debido al uso alternativo del pin 4 del PORTA como External Clock Input para el TIMER0 (T0CKI) este pin tiene una configuración un tanto especial.

  • En el esquema inferior puede comprobarse cómo están conectados interiormente ambos tipos de pines. Los "normales" mediante dos transistores Canal-N y Canal-P en configuración Totem-pole conectados a Vdd y Vss, mientras que el RA4, el "raro", solo tiene implementada la parte inferior del Totem-pole, y por lo tanto desconectado del Vdd. A esta última configuración se le conoce como Open Drain u Open Collector (Colector Abierto en Español)


 

RA0:RA3 & RA5, los "normales"
 
  • Cuando el bit del TRIS es 1 y la puerta AND inferior tiene su salida a 0 entonces la puerta OR superior tiene su salida a 1. En esta situación ninguno de ambos transistores, TRP y TRN, conducen y por lo tanto el PIN está aislado del flip-flop de datos. El PIN está en estado de input.
  • Cuando el bit del TRIS es 0 entonces el estado complementario (negado) del flip-flop de Datos es inyectado (gated) a ambos transistores: Cuando Data es 0 entonces TRN conduce y TRP no, dándole al Pin una salida de 0; cuando Data es 1 entonces es TRP quien conduce y TRN no lo hace y por lo tanto el Pin tiene un 1 en su salida. En esta sitación el Pin sigue el estado del flip-flop de datos. La fuente de corriente se obtiene a través de la relativamente baja resistencia del transistor activo. Esto nos proporciona un máximo absoluto de 20 a 25 mA.
RA4, el "raro"
 
  • Cuando el bit del TRIS es 1 entonces la salida de la puerta AND es 0 y por lo tanto TRN no conduce, teniendo su salida a alta impedancia. RA4 está en estado de input.
  • Cuando el bit del TRIS es 0 entonces la puerta AND hace un seguimiento invertido del estado del flip-flop de Datos, si el Dato es 0 entonces TRN conduce y "tira a tierra" al Pin, cuando el Datos es 1 entonces TRN no conduce y el Pin queda "flotando".
  • Si conectamos RA4 a Vdd mediante una resistencia pull-up tendremos entonces disponible Vdd, menos la caida en la resistencia pull-up, cuando el Dato sea 1 y directamente masa cuando sea 0.
 
Un ejemplo con enjundia: Un Driver de Relé con uno u otro tipo de Pin.
  • Supongamos que queremos conectar a nuestro Pin un Relé de 12V y con un consumo aproximado de unos 200 mA.
  • En RA0: Para este voltaje y consumo necesitamos un buffer externo que nos haga de driver para el relé. Con un simple transistor bipolar podemos conseguirlo (Ver Mis transistores favoritos). Como la mínima ganancia de un transistor de este tipo es de 100 y asumiendo un voltaje entre base y emisor de unos 0.7V entonces con una resistencia de 1K8 ohmios le daremos a la base una corriente de unos 2 mA que llevará a nuestro transistor a saturar y por ello a activar el relé cuando el pin del PIC tenga un voltaje por encima de unos 4.3V.

  • En RA4: Como hemos visto anteriormente RA4 es un poco diferente, "raro" decíamos, y solo tiene dos estados conocidos, o flotante cuando ponemos un 1 en su salida o conectado a masa cuando ponemos un 0. Es lo que decíamos que era Open-Drain u Open-Collector.
  • Un Open-Drain, Open-Collector o Colector Abierto, para entendernos, no tiene fuente de corriente, así que la carga debe ser conectada a su propia fuente de corriente, una resistencia pull-up conectada a Vdd.
  • En este caso conectamos la resistencia de 1K8 ohmios a 12V generando la corriente que necesita nuestra carga. Cuando el Pin RA4 tenga un estado lógico alto o 1 no influirá en la base del transistor Driver y por lo tanto estará conduciendo y activando el Relé, y cuando su estado lógico esa 0 derivará a masa la corriente de base, a través de la resistencia pull-up, y dejará de conducir con lo que desactivará el Relé.

 


Ajustando TIMER0 para conseguir un segundo.
Por Jóse Modulay del Foro Todopic
 
Esas mates...
Con un cristal de 4 MHz tienes un periodo de reloj de 1/4 MHz = 0.25 us
Como cada ciclo máquina son 4 ciclos de reloj, tienes un ciclo máquina de 0.25 us * 4 = 1 us.
Es decir, el timer se incrementa en una unidad cada microsegundo.
La idea es buscar que el timer interrumpa cada cierto tiempo x,y que ese tiempo x sea divisor exacto de 1 segundo, por ejemplo 25 us, 100 us, 2 ms, 10 ms, etc...
Además de esto, habrá que usar una variable contador que se irá incrementando cada vez que el timer se desborde, comprobando su valor cada vez que esto sucede y así llevar el control del tiempo transcurrido.
La fórmula, medida en segundos, que determina el periodo de desbordamiento de un timer de 8 bits (timer 0) es:

T = (256 - precarga) * Preescaler * 4 / Fosc

Si fijamos el Preescaler a 16...

T = (256 - precarga) * 16 * 4 / 4 MHz
=> precarga = 256 - T * 62500

T es la base de tiempos que andamos buscando y precarga es el valor que se le carga al timer tras cada interrupción para que vuelva a empezar a contar a partir de él.
Se trata de buscar un valor para T que sea divisor de 1 segundo y que al multiplicarlo por 62500 el resultado sea un número entero.
Por ejemplo 4 ms:

precarga = 256 - 4 ms * 62500 = 256 - 250 = 6

O sea, para conseguir la base de tiempos de 4 ms tendrás que cargar al timer con el valor 6 (con Preescaler establecido a 16).
Hecho esto, para temporizar un segundo tendrás que contar:
 1 s / 4 ms = 250 interrupciones
 
Referencias en esta misma página:
Los Cristales y El Tiempo

Template para el uso de la Interrupción RTCC mediante el TIMER0
Una aplicación práctica de RTCC : Cronopic 1.0

 


Notas 18F4550: Power On Reset (POR) y Brown Out Reset (BOR) en sus puertos.
 
Es muy corriente entre los primerizos, y aún entre los expertos, cometer cierto tipo de errores que son de fácil solución pero que sólo después de haberlos vivido se tienen en cuenta antes de enfrentar un nuevo diseño. Pero somos animales que tropezamos múltiples veces en la misma piedra.
 
Uno de de los errores mas usuales consiste en dar por supuesto el estado, funcionamiento y/o configuración, de un cierto pin de cualquier puerto tras un Power On Reset, o sea justo después de haber dado la corriente a nuestro PIC.
 
Este error se comete fundamentalmente por dos causas:
 
  • La primera y principal es la de no haber leído el Datasheet del Micro que estamos usando.
     
  • La segunda causa es la de sin leer tampoco el datasheet suponer erróneamente, y la mayoría de las veces inconscientemente, que dicho estado o funcionamiento es igual al de ese otro PIC de la misma o parecida serie con el que hemos trabajado mucho y que nos conocemos al dedillo.
Por ejemplo: Supongamos que hasta ahora he trabajado mucho con el 16F877 y empiezo ha hacerlo ahora con el 18F4550. No es extraño encontrarnos con que la mitad del PORTB no funciona. En el 16F877 todo el PORTB se inicia como Entradas Digitales mientras que en el 18F4550 más de la mitad de dicho puerto, RB0:RB4, lo hace como Entrada Analógica mientras el resto, RB5:RB7 está efectivamente configurado como Entrada Digital.
 
Estas situaciones son tan usuales que hasta la propia Microchip toma medidas especiales en sus Datasheets enmarcando, destacando y cambiando el color del fondo en sus comentarios al respecto. Si editáis cualquier PDF de un PIC podréis encontrar en cada epígrafe de cada puerto un rectángulo "Note" con estas circunstancias a las que nos estamos refiriendo.

Es mi intención pues también remarcar en este post estos comentarios o notas, no solo con el fin de tenerlas en cuenta con respecto al 18F4550 del que trata el hilo, sino en cualquier otro PIC con el que trabajéis. He seleccionado el 4550 porque es con el que trabajo más a menudo, sirva por tanto de ejemplo.

PORTA



En POR los pines RA0 a RA3 del PORTA se configuran como Entradas Analógicas, el pin RA4 como entrada digital.

PORTB



En POR los pines RB0 a RB4 del PORTB se configuran como Entradas Analógicas, los pines RB5 a RB7 como entradas digitales. Pero se puede utilizar el fuse PBADEN para que RB0 a RB4 se inicialicen en POR como entradas digitales también. Si no se especifica serán al POR analógicos.

PORTC



Todo el PORTC se configura en POR como entradas digitales.

PORTD



Todo el PORTD se configura en POR como entradas digitales.



Cuando ponemos en marcha el módulo PWM se deshabilita automáticamente el SSP del PORTD.

PORTE



En POR los pines RE0 a RE2 del PORTE se configuran como Entradas Analógicas.



En POR el pin RE3 del PORTE se configura como Entradas Digital solo si tenemos deshabilitado el Master Clear Reset.


Ea, hasta la próxima.


 
 

 


Escribiendo un Byte en la EEPROM en el tiempo justo.
Que ni nos sobre ni nos falte.
 

   El escribir la EEPROM requiere un tiempo que en relación a la velocidad de funcionamiento del PIC es un tiempo realmente largo, del orden de algunos milisegundos, tiene que direccionar, poner el dato, y darle a la EEPROM un pico de tensión para fijarlo y esperar a que se estabilice.

   Un error muy común es no darle tiempo al PIC a que realice una buena escritura, un valor muy normal que yo utilizaba antes era el de 5 ms colocando un delay_ms(5) tras escribir el byte y siempre me quedaba la duda razonable de si era demasiado corto, o de si estaba desperdiciando tiempo esperando mas de la cuenta.

   Ahora he cambiado de estrategia al saber que hay una interrupción que se dispara cuando se ha completado un ciclo correcto de escritura, #int_eeprom. Esta interrupción es absoluta, independiente del tiempo que necesite el PIC para escribir correctamente, se dispara cuando ha terminado y punto. Así que lo que hago es:

  • Habilito la interrupción int_eeprom

  • Pongo un flag a 1;

  • Escribo el byte en la EEPROM;

  • Espero a que el flag vuelva a 0;

  • Deshabilito la interrupción int_eeprom

  • Regreso de  la rutina de escritura de un byte.
     

  • En la interrupción int_eeprom pongo el flag a 0;

Con esto me aseguro de que el PIC tiene el tiempo suficiente y necesario para escribir su byte, ni más ni menos tiempo del que realmente necesite.

La implementación de esto en CCS C es:

 
     
  #int_eeprom
/** \brief Interrupción por : Fin escritura EEPROM interna.
*
*/
void interrupt_service_rutine_eeprom(void) {

   flag_Writing_INTERNAL_EEPROM=0;

}

...

void writeByteINTEEPROM(int8 memAddress, int8 data){

   flag_Writing_INTERNAL_EEPROM=1;
   enable_interrupts(int_eeprom);
   write_eeprom (memAddress, data);
   while(flag_Writing_INTERNAL_EEPROM==1){/*Wait for write finish*/}
   disable_interrupts(int_eeprom);
}
  
 
 

 

 

 


El Timer Power-Up.
Para que todo se estabilice antes de empezar.
 

   Cuando la alimentación del PIC comienza a crecer de 0 hasta VCC, en el momento de darle corriente o cuando el MCLR después de haber sido tirado a GND comienza a su vez a subir de GND a VCC, está el PIC aún en Reset, hasta alcanzar un nivel determinado de voltaje en el cuál se produce un POR (Power On Reset) que es una señal que indica que el Reset puede ya efectivamente desbloquearse y dejar al PIC correr alegre y jubiloso. En ese momento arranca el oscilador de programa que tras estabilizarse hace que el Reset Interno se desbloquee y comience a funcionar el PIC con nuestro programa.

   Pero en este estado pueden producirse aún fluctuaciones de VCC que oscilen alrededor del nivel de disparo de dicho POR por lo que los amables señores de Microchip han implementado aún otro artificio intermedio, entre el POR y el comienzo del funcionamiento del oscilador, que consiste en un Timer que se pone en marcha con dicho POR y que durante su cuenta mantiene aún a GND la señal del Reset, alargando o estirando el tiempo que el Reset se mantiene en GND mientras los voltajes de VCC y/o MCLR alcanzan su nivel óptimo. Cuando completa su cuenta levanta el Reset a VCC y el PIC comienza entonces a correr.

   En el PIC 18F4550 que es el que os muestro de ejemplo dicho TPWRT tarda 66 ms como mínimo (mas 2 ms si está activado el PLL) Ved el cronograma de activación de las distintas señales que muestra grafica y claramente como funciona este sistema:
 


 

Nota: En CCS C este Timer se activa con el fuse PUT

 


¿Qué es el módulo CCP?
 

Muchas veces he contestado privadamente a esta pregunta, así que ha llegado el momento de hacer un artículo y publicarlo en PicManía para que todos puedan acceder a él.
 

El nombre del módulo CCP viene dado por las iniciales del acróstico de Input Capture, Output Compare y Pulse Width Modulation. que desde la negrura de los tiempos ha sido llamado módulo CCP.
 

El por qué tres funciones aparentemente tan dispares aparecen juntas en un único módulo, y no sólo en los PIC de Microchip sino hasta donde alcanza mi conocimiento es un bloque generalizado entre los distintos fabricantes como Motorola o Atmel, estriba en su conjunción con un Timer.
 

Intentaré describir lo mas claro que pueda como funciona este sistema, aunque antes vamos a ver qué ocurre con la mucho mas simple Interrupción Externa por PB0 de un PIC16 (ó PB1 y PB2 en los PIC18) teniendo como objetivo el intento de saber cuanto dura un pulso externo.
 

La situación a que nos enfrentamos es un pulso que estando en estado lógico bajo cambia a estado lógico alto durante un tiempo y transcurrido éste vuelve a su estado inicial bajo. Es un pulso bajo-alto-bajo y deseamos medir cuánto dura ese estado alto intermedio.
 

Esto mismo podemos describirlo como el tiempo que tarda en aparecer un flanco de bajada tras haber aparecido un inicial flanco de subida. En la Serie Técnicas en C me dedicaba a mostrar cómo realizarlo de tres formas distintas.
 

Nuestro problema estriba entonces en implementar un método para realizar lo siguiente:
 

  • 1.-Esperamos a recibir un flanco de subida
  • 2.-Guardamos estado inicial de un Timer
  • 3.-Esperamos a recibir un flanco de bajada
  • 4.-Guardamos estado final del mismo Timer
  • 5.-Restamos estado inicial del final del Timer y obtenemos tiempo entre flancos.

Si la señal la conectamos al PIN_B0 de un PIC16 (ó PB1 y PB2 en los PIC18) con la Interrupción Externa tenemos solucionados los puntos 1 y 3 de la tarea que nos hemos propuesto, conocer cuando llegan ambos flancos. Las tareas 2 y 4, guardar los valores del Timer tenemos que escribirlo nosotros, habilitar las variables y leer el Timer que deseamos. Es el método descrito en Tiempo en Alto con INTEXT donde en cada cambio de flanco realizamos su correspondiente t1=get_timer1();. Fíjaos que el tema está en get_timer().
 

Si por el contrario en vez de usar la Interrupción Externa usamos el módulo CCP configurado para la función Input Capture tendremos la facilidad de realizar dos tareas al mismo tiempo. Si le decimos al PIC que espere en CCP un Input Capture por flanco de subida cuando éste llegue y se dispare la Interrupción CCP tendremos ya en valor del Timer guardado en su registro CCPRxH:CCPRxL, o sea que las tareas 1 y 2 por un lado y las 3 y 4 de nuestra lista por otro estarán completadas. Es lo que describimos en Tiempo en Alto con INTCCP en donde en lugar del get_timer1() usamos el muchísimo mas directo t1=CCP_2 que es cómo se llama el registro registro CCPRxH:CCPRxL en CCS C.
 

Como podéis ver el CCP en Input Capture lo que hace realmente es capturar el valor de un Timer cuando se presenta un flanco determinado. Nosotros lo utilizamos en nuestro ejemplo para conmutar el flanco a detectar y medir el ancho del pulso. Otras aplicaciones sólo dependen de la imaginación del artista.
 

De forma simétrica o complementaria a ésta de recoger el valor del Timer cuando hay un cambio externo es el modo Output Compare del CCP. Este modo de funcionamiento del CCP es justo lo contrario al anterior: Producimos un cambio de estado en el pin del CCP cada vez que el Timer alcanza un valor determinado. O sea que ponemos el registro CCPRx a un valor que nos interese y cuando el Timer llega a ese valor el pin se pone en Alto, en Bajo o conmuta, según programemos su función. Esto lo podéis ver en Onda Simétrica Mediante INTCCP en modo Compare donde utilizamos este método para generar un pulso.
 

Insisto de nuevo en la idea: Input Capture determina el valor del Timer al cambiar el estado del pin, Output compare cambia el estado del pin cuando el Timer llega a un valor determinado. Son maravillosamente simétricos y complementarios.
 

Y por fin nos queda el PWM que no es mas que especialización del anterior. Activando ésta función del CCP lo que hacemos es cargar dos valores del Output Compare para generar un ancho de pulso de salida determinado y qué porcentaje del mismo va a estar en alto y cuál en bajo, o sea que modulamos el ancho de pulso. Este PWM es como un Output Compare sofisticado con el que con muy poco código podemos controlar todos los parámetros del pulso que necesitamos generar.
 
Bueno y eso es todo por ahora amigos.

 


El concepto de Timeout (y un ejemplo de uso en C)
 
 Idea   Descripción (o un poco de filosofía barata)

Hay procesos que no sabemos cuánto duran (en tiempo) pero si sabemos cuánto es el máximo que pueden durar (o que queremos que duren).

A este tiempo máximo vamos a llamarlo periodo para timeout (o salida de tiempo).

Un definición estándar en Informática podría ser : Parámetro que indica a un programa el tiempo máximo de espera antes de abortar una tarea o función. O darla por concluida que es tipo de timeout que vamos a implementar en nuestro pequeño ejemplo.

Uno de los usos mas frecuentes del control de procesos mediante timeout es para abandonar procesos que deberían acabar normalmente pero que por cualquier circunstancia no prevista o incontrolada no se acaba.

Si durante un proceso P la única condición de salida del mismo es S y hay veces en que no se produce entonces el proceso P se quedará "colgado" al no abandonar nunca su funcionamiento dado que la condición S no se produce.

El uso de timeout consiste es arrancar un timer al mismo tiempo que se inicia el proceso P. Y en éste se implementan dos salidas posibles, nuestra anterior salida S y en paralelo (OR) una nueva: la de haber cumplido el tiempo T que hemos fijado para el timer.

A esta nueva condición de salida la conocemos como Salida por Timeout.


 Arrow   Ejemplo (o la imaginación al poder)

Supongamos, imaginemos, planteemos un ejemplo donde lo que hemos visto nos sirva para algo (en caso contrario estaría un poco fuera de lugar ¿no?)

Supongamos, decíamos, que tenemos una recepción vía USART serie de N caracteres, número que desconocemos y que unas veces es un solo carácter y otras todo un string de decenas de ellos.

Nunca sabemos cuando va a llegar el primero ni cuantos van a seguirle, pero sabemos que van a venir todos mas o menos juntos, uno tras otro (o en pequeños paquetes) pero que nunca, nuca, nunca va a haber entre dos caracteres consecutivos mas de unos pocos milisegundos, digamos 5 ms por poner un ejemplo concreto.

Podemos entonces decir que: Si recibimos un carácter inicial cualquier otro nos llegará antes de 5 ms, si pasan mas de esos 5 ms entonces el paquete a recibir está completo, ya ha acabado y podemos procesarlo.

En este caso es razonable decir también que si establecemos un timeout de 10 ms tendremos la seguridad de que hemos recogido el paquete completo.

Vamos entonces a acotar nuestro ejemplo describiendo lo que debemos implementar:

Recibimos todos los caracteres que nos vayan llegando, cada vez que nos llega uno de ellos activamos un timer que cuente el paso de 10 ms y lo ponemos a cero, si el timer llega a completarse es que han pasado esos mismos 10 ms tras la recepción del último carácter. Ponemos entonces un flag en alto indicando esta circunstancia y paramos el timer.

Si recibimos un nuevo carácter todo comenzará de nuevo.

Notad que el truco está en "reiniciar el timer del timeout cada vez que se recibe un carácter. Sólo cuando se dejen de recibir caracteres el timer completará su recorrido y hará saltar el indicador de timeout"


 Exclamation   Implementación en C (o un razón para justificarme ante ustedes)

Bueno ahora solo nos queda escribir un poco de código que le enseñe a nuestro PIC que todo lo anterior no solo es posible hacerlo sino exactamente cómo queremos que lo haga.

Primero vamos a montar un timer que desborde cada 10 ms mediante su particular interrupción. En principio no la habilitamos ya que esto se hará cuando se reciba el primer carácter. (con ánimo de no complicar innecesariamente este ejemplo voy a dar por valido el que el Timer0 se desborda exactamente cada 10 ms, esto no es necesariamente cierto pero el hacer eso es cuestión de configurar correctamente el timer, y no aporta ni quita nada al ejemplo que estamos estudiando)

 

     
  ///////////////////////////////////////
// RAM
///////////////////////////////////////

int1 flagTimeOut = 0x00; // Flag quea indica timeout completo, inicializado a 0


///////////////////////////////////////
// INTERRUPCIONES : TIMER0 para timeout
///////////////////////////////////////

#int_timer0
void timer0_isr() { // Interrupción por desbordamiento de timer0

   flagTimeOut = 1;

}
 
 

 

 
 

Después una simple #int_rda que recibe caracteres sobre un buffer, pero tiene la particularidad de que habilita/inicializa el timer cada vez que recibe un nuevo carácter:

 
     
  ///////////////////////////////////////
// RAM
///////////////////////////////////////

int xbuff=0x00; // Índice: siguiente char en cbuff
char cbuff[lenbuff]; // Buffer de recepción

///////////////////////////////////////
// INTERRUPCIONES : RDA Recepción USART
///////////////////////////////////////

#int_rda
void serial_isr() { // Interrupción recepción serie USART

  if(kbhit()){ // Si hay algo pendiente de recibir ...
    cbuff[xbuff++]=getc();
    set_timer0(0);
    enable_interrups(int_timer0);
  }
}
 
 
 

 

 
 

Y por fin en nuestro main() lo que hacemos es habilitar la recepción RDA pero no el Timer0 y esperar en el bucle infinito a que salte el Timeout para poder procesar la recepción:

 
     
 
void main() {

  enable_interrupts(int_rda); // Habilitamos la interrupción por recepción serie
  enable_interrupts(global);  // Habilitamos las interrupciones


  do{ // inicio del Bucle infinito

    if(flagTimeOut ==1){             // Si hemos completado una recepción ...
      flagTimeOut =0;                // lo desmarcamos para poder reiniciar el tema
      disable_interrups(int_timer0); // detenemos el timer0
      disable_interrupts(int_rda);   // deshabilitamos int serie mientras procesamos


      execute_lo_que_sea();          // Aqui procesamos lo recibido sobre cbuff.

      xbuff=0x00;                    // reiniciamos el buffer de recepción
      enable_interrupts(int_rda);    // Habilitamos int recepción serie
    }

  }while(TRUE);                      // final del Bucle infinito
}
 
 
 

 

 
 

Bueno, creo que eso es todo. Espero que os sirva de algo.  Mr. Green

 


 

¿Qué es el Watch Dog Timer? II
Nuevas reflexiones sobre el Watch Dog.


 

El mejor programa, el mas elaborado, el mas perfecto y revisado del mundo, el mas libre de bugs y limpio de inconsistencias y redundancias puede contener en su entrañas la posibilidad remota de que, bajo ciertas circunstancias totalmente impredecibles, extrañas y recónditas pero reales a fin de cuentas, se cuele en ese limbo indefinido del que nunca sale.

Podemos llegar a la conclusión de que nuestro mas preciado programa es fiable en un 99%. Es ese 1% restante es el que nos puede joder la vida.

Siempre es bueno colocar esta salvaguarda última para que nuestro programa no entre en una situación de bucle infinito sin salida posible. El Wachtdog es la solución. Si no es refrescado en el lapsus de tiempo que definimos reseteará el PIC y nuestro programa comenzará a ejecutarse de nuevo. La situación imponderable, no medible, inimaginable ha sido salvada y nuestra aplicación vuelve por sus fueros y comienza de nuevo a caminar.

Esto lleva a dos consideraciones:

.- El Watchdog debe ser activado solo cuando hayamos alcanzado ese 99% de fiabilidad de nuestro programa.

En caso contrario nos va a ser muy difícil detectar nuestras propias inconsistencias e incongruencias, nuestros fallos de diseño, nuestra falta de imaginación (revivir en nuestra cabeza lo que debe estar ocurriendo en el núcleo del PIC) serán ocultados, enmascarados, diluidos por el funcionamiento del Watchdog.

Tenemos que poner todo nuestro empeño en que nuestro programa funcione sin Watchdog. Cuando estemos seguros de ello podremos activarlo para prevenir aquello que no hemos sido capaces de prever. Prevenir lo imprevisto (curiosa frase)

.- Una vez decididos a activar el Watchdog hay que ser muy precavidos (ó listos ó inteligentes ó despiertos ó cautos) sobre dónde colocar los refrescos del Watchdog.

Por un lado no podemos poner refrescos sin ton ni son, a tontas o a locas, en cualquier sitio porque nos parece bien, sin tener en cuenta su potencial riesgo de bucle sin salida.

En este caso el Watchdog no nos serviría de nada ya que si acertamos a colocar el refresco justo dentro de un proceso realmente infinito y sin salida (es posible hacerlo: yo lo hice una vez y me dio dolores infinitos de cabeza) el bucle sería definitivamente infinito ya que al ser refrescado precisamente en él, nuestro Watchdog no nos sacaría nunca de él.

Por otro lado hay que prever lo contrario, cualquier proceso normal y válido de nuestro programa cuya duración supere (o pueda superar) el del vencimiento del Watchdog. Es de cajón darse cuenta de que en estos procesos potencialmente largos debe tenerse prevista la posibilidad de que se nos desborde el Watchdog y nos lo dejemos a medio realizar. Debemos por tanto colocar en él un refresco.

Un ejemplo típico y tópico de esto es cuando están involucrados procesos de comunicaciones en las que estamos esperando recibir algo que, por vaya usted a saber qué circunstancias, no nos llega.

Mi consejo final: No debemos abusar de los refrescos y hay que colocarlo/s en aquel/llos puntos en que se den las dos siguientes circunstancias:

a.- Si el programa pasa por allí es que todo va bien.
b.- Si el programa pasa por allí el Watchdog puede desbordar.

Yo usualmente empiezo por activarlo sin refresco alguno y compruebo que efectivamente se resetea el PIC.

Después coloco un solo refresco, en el punto de inicio o vuelta al bucle infinito normal de mi programa (En C sería justo detrás de mi
while(true)) y compruebo si los distintos procesos "caben" en el tiempo de desborde.

Y por último coloco un refresco en cada uno de los que se que consumen mas tiempo.

Con esta forma me aseguro de que he ajustado al mínimo indispensable los puntos de refresco con tal de que el Watchdog me sirva para algo en lo que realmente se me ha escapado y no he sido capaz de prever.

Espero que os sirva.
 
 
 

 



Nota: Esta página Web esta repleta de imágenes, textos, logotipos y demás material extraídos de los mas variados medios de los que no soy ni autor ni depositario de los correspondientes derechos de autor, uso y/o reproducción. Si Ud. es depositario de dichos derechos y desea que el material correspondiente sea eliminado de esta Web no dude en ponerse en contacto conmigo mediante e-mail y será inmediatamente retirado. Gracias.
 
Visitas
Totales : 84090 Hoy: 12 Activas: 1 Vistas: 84090

Esta página fue modificada el 07-08-2010 22:42:20

           
 DmSoft WAMP Escribir Unreal