| |
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?
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
Descargar)
|
 |
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. |
Esta página se modificó el
27/12/2008
|