Tres pulsadores con PIC

Introducción.

En esta ocasión vamos a producir un listado con el que detectar 3 pulsadores A, B y C. Cuando se presione el pulsador A, el programa saltará a una subrutina que se encarga de realizar una operación concreta asignada de antemano por nosotros, una vez ha terminado dicho cometido, la rutina devuelve el control al programa principal.

Si se presiona el pulsador B, el flujo del programa saltará a la rutina asignada y se procederá a la ejecución programada para el pulsador B, después de lo cual el programa principal toma el control y queda a la espera de que sea pulsado algún pulsador y si el pulsador presionado es el C, saltará a la subrutina asignada a este pulsador ejecutándose dicha subrutina, después de lo cual el control es de nuevo asumido por el programa principal. Esto es a grandes rasgos lo que pretendemos hacer.

El Principio.

Lo primero que se debe hacer para escribir un programa es utilizar la ‘plantilla de programa‘ y hacer una copia, esto nos ayudará a iniciar cualquier tipo de programa que se refiera a los PIC, ese es el motivo de su existencia, si se acostumbra a usarla verá las ventajas, ya que tiene la cabecera de un buen número de programas que usan las mismas  primera líneas. Sin embargo se debe personalizar.

Una observación más, para no producir confusión en los conceptos, deberíamos aceptar que: ‘el programador‘ es el software (como IcProg) que utilizamos con el PC para ‘quemar’ los chips; ‘el quemador‘ es el dispositivo hardware (placa PCB) en el que insertamos el chip para grabar (quemar) el programa; ‘el programa‘ es el código o listado de rutinas y subrutinas que una vez ensamblado (.hex) le dice al chip que ha de hacer; y ‘el analista‘, es decir, el hombre es el que crea o escribe el listado. Bueno aclarado esto, seguimos.

Esto lo describiremos para el caso de no disponer de la plantilla. Lo primero que debemos hacer como siempre es; preparar los puertos de E/S y asignar los distintos registros que se vayan a usar en el programa. Es conveniente la disposición del orden del listado después de las declaraciones, seguido de las subrutinas, antes de la rutina principal o cuerpo del programa. Esto permite el normal desarrollo de los distintos pasos y además permite un seguimiento más eficaz a la hora de depurar posibles errores o posibles fallos en el programa.

El esquema.

El esquema que se vaya a usar en el desarrollo del programa es un punto muy importante, a la vista del mismo, pueden surgir ciertas preguntas y soluciones a las mismas y aparecer otras que no se han sospechado en el momento de concebirlo, así pues, el esquema y el programa son casi siempre un todo.

Fig. 1 Esquema para el programa

El Programa.

Si dispone de la plantilla puede saltarse estos primeros pasos, si no, siga adelante. Deben respetarse los nombres de las etiquetas y su forma no duplicando los nombres, el programa MPLAB distingue entre Mayúsculas y minúsculas, otro punto a tener en cuenta es que las líneas de instrucciones deben empezar en la columna 0 y sin número de línea, es muy conveniente recordar el documentar nuestro trabajo, nos será de gran ayuda a largo plazo. También es conveniente guardar la forma en el listado respetando los espacios, para lo cual usaremos los tabuladores a nivel 8.

Lógicamente, de este listado para no confundirnos deben eliminarse las líneas que no se vayan a utilizar, en cada caso. Los listados, deben ser escuetos, procurando limpiar las líneas que no sean necesarias, sin que por esto, se eliminen las notas aclaratorias que son importantes.

No he quitado la cabecera por dos razones: 1- No entorpece ni es causa de ocupar espacio en la memoria y 2- Nos recuerda qué se debe hacer al programar. Por otra parte, se pueden apreciar tres importantes campos o zonas en el listado, las cuales intentaré describir:

    • En primer lugar, encontramos la zona de las DEFINICIONES, en la que se declaran el micro, los includes, las equ’s, es muy importante cumplimentar esta parte ya que de ello dependerá el buen discurrir del programa sin errores, difíciles de interpretar luego.
    • En segundo lugar, tenemos la zona de CONFIGURACIÓN de puertos e inicio de variables [o Set-up]. En esta imprescindible zona, se debe incluir siempre, para acceder a la pagina 1 de la RAM, donde se definen los estados de las líneas de los puertos de forma individual línea a línea o general todo el puerto y terminar con la vuelta a la página 0 para seguir con el programa.
    • Y en tercer lugar, el cuerpo del programa que en cada caso tendrá sus particularidades exclusivas y subrutinas que hemos recopilado y adecuado a nuestro gusto, que deben ir después de la configuración, luego la parte principal que hemos desarrollado.

Pero, qué quieren decir las instrucciones que aparecen en lo que hemos escrito en esta plantilla. Para los que empiezan, voy a describir aquí, estas pocas líneas; en especial las referentes a la configuración de puertos que puede ser algo más confusa. Los que tengan esto por conocido pueden seguir avanzando a su ritmo.

Conviene que el lector se haga una copia en papel del juego de instrucciones, también se puede ver la descripción de instrucciones correspondientes al PIC y en este caso con las del ‘F84A que se describe, para una mejor comprensión de lo que se indica en este artículo y sobre todo como ayuda cuando se proceda a hacer un programa (código).

  • En las definiciones de igualdades o equ’s, denominado mapa de memoria, lo que hacemos es asignar unas localizaciones de memoria a unos registros intrínsecos del propio PIC como son: pclstatusportaportbtrisatrisboption_reg que ya están definidos (en el archivo .inc) en el include y por otra parte ciertas variables que el analista considere necesarias, pueden distinguirse las asignadas por el analista: conta, pausa, etc. Todas ellas como se ha dicho ocupan una celda de memoria numerada en la cual se deposita un valor que puede ser variable o fijo.
  • En unas ocasiones el programa se refiere a la dirección de memoria y en otras al valor depositado en dicha dirección. Esto puede llevar a confusión y hay que tener muy en cuenta lo que se esta haciendo en cada momento para poder seguir el hilo del programa. No se preocupe por el momento, si le cuesta entender el concepto, verá que a medida que haga sus prácticas irá adquiriendo habilidad y experiencia y pronto dominará en cierta medida esta faceta de la programación. Acérquese a algún foro de la red si tiene ocasión y les consulta sus dudas, las respuestas le servirán de inestimable ayuda.

En las siguientes líneas del programa se accede a la parte alta de la memoria los bancos revise las hojas de características y podrá comprender mejor lo que se describe a continuación:

BSF STATUS,RP0 (03,5); Esto quiere decir: Bit Set File, poner a 1 el bit 5 en el archivo f (03 en el ejemplo), por eso es común encontrar en algunos casos en los equ’s la expresión: STATUS equ 0x03h. Así pues, este es el modo de desplazarnos a la página 1, parte alta de la memoria. En ese momento se opera en el espacio de memoria alta y vamos a seguir en ella unos pasos más.

Acto seguido se encuentra la instrucción: MOVLW 01h ; Esto quiere decir, Mueve el Literal 01h al registro de trabajo W. Debe recordar que no se pueden hacer operaciones directas en los puertos, como es el caso. Algo así: MOVWF PORTA,01H es una incorrección ya que este tipo de microcontroladores no admite operaciones directas con los registros.

La siguiente instrucción es: MOVWF PORTA (05h); Esto quiere decir que el valor del literal anterior se deposita en el archivo 05h que es el puerto A y como el valor depositado en W es 01h, el bit 0 será tomado como entrada, los demás bits del puerto A serán salidas.

Una nueva instrucción: MOVLW FFh que hace lo mismo que la anterior, carga un valor literal FFh en el registro W.

La siguiente instrucción es: MOVWF PORTB (06h); Esto quiere decir que todo el puerto B perteneciente al archivo 06h, serán entrada, todas sus líneas por estar a 1, si queremos que una línea sea salida, el bit correspondiente a esa línea debe ponerse a 0.

Como ya hemos configurado las líneas de E/S de ambos puertos (y otras como en el F628 el puerto A es analógico y por eso dispone de una orden para pasarlo a digital con MOVLW 07 y MOVWF COMM), esto depende del micro, es hora de devolver el control del programa al la parte baja de la memoria que es la llamada página 0, por lo que se utiliza la instrucción siguiente:

BCF 03,5 ; Esto quiere decir: Bit Clear File e indica que el bit 5 del archivo 03 será puesto a 1, este archivo 03 contiene la líneas E/S, comúnmente se llaman líneas E/S del puerto. Bien, una vez ejecutada esta instrucción como ya se ha indicado el microcontrolador está en condiciones de poder continuar el proceso del programa con sus rutinas y subrutinas. Desde luego que pueden seguir añadiéndose más instrucciones en esta sección, esto es cuestión de lo que el analista considere oportuno cuidando de no superar el espacio de memoria disponible a tal cometido.

Las siguientes líneas del programa deben contener subrutinas, tablas si las hubiera y a continuación poner la rutina principal, en ella se distingue la Etiqueta normalmente le llamamos inicio, principal o [start] en inglés, seguida de dos puntos y una instrucción.

Aquí empieza el trabajo del analista o lo que es lo mismo, el programa. El siguiente es el listado del programa que nos permite controlar la acción que puede ejecutarse al oprimir uno de los tres pulsadores que hemos propuesto. Sin duda que el lector puede añadir como respuesta a cada subrutina de cada pulsador una llamada a otra subrutina encargada de realizar el cometido que considere el lector – analista.

Creo que es el momento de describir algunas líneas que, ayuden a comprender mejor el funcionamiento del programa mostrado. En el que vemos la línea, con su comentario:

MOVWF PORTB ;define RB0-RB2 como entrada, los otros, salidas

Esto quiere decir: Mueve el contenido de W (que es 07) al archivo 06h (que es el puerto B). Más adelante en la rutina principal.

scaner: BTFSC PORTB,0    ; si bit 0 del puerto B esta en nivel bajo?, salta 1 línea

La etiqueta sirve como punto de referencia único, es decir para las llamadas (CALL’s), ya veremos que ocurre. Le sigue la instrucción: BTFSC PORTB,0 Esto quiere decir: Bit Test, Skip if Clear, se refiere a, comprobar el bit 0 del archivo 06h (puerto B), si es 0 la instrucción CALL  luce1, se ignora, se trata como un NOP y continúa en la línea que sigue, si el resultado de comprobar es 1, se ejecuta el CALL  luce1, saltando a la nueva etiqueta.

En el primer caso, cuando BTFSC es 0, la siguiente instrucción a ejecutar es: BTFSC PORTB,1 lo que significa una nueva comprobación en este caso se prueba si el (segundo bit) bit1 es 0, en cuyo caso saltará una línea, para ejecutar BTFSC PORTB,2 para comprobar el bit2 y si su estado es 0, saltará al principio cerrando la rutina, es decir, a scaner: Permanecerá en este estado (comprobando el estado de los pulsadores) mientras no se presione alguno de los tres pulsadores.

En caso de que BTFSC sea 1, como se ha dicho ejecutará el CALL  luce1. Entonces el micro busca la etiqueta llamada luce1, cuando la encuentra ejecuta la primera instrucción que encuentra, en este caso: MOVLW 0x01 que se corresponde con el rastreo del pulsador 1 lo que carga W con el valor 1, la siguiente instrucción carga el puerto B con el valor de W que ahora es 1. Esto hace que el LED1 se encienda. El proceso que sigue es saltar a una subrutina de retardo que mantiene el LED encendido por un tiempo determinado por ese retardo.

Digamos que el resto de programa hace lo mismo que lo descrito para el pulsador 1 y naturalmente no vamos a insistir. Es interesante observar en este punto, lo que se ha descrito en este código fuente del programa, ya que si modificamos un poco el código, podemos hacer que el LED encendido permanezca así, hasta que un nuevo pulsador sea presionado.

Nota. En referencia al circuito que se muestra más arriba, se puede observar que requiere unos pocos componentes pasivos alrededor del microcontrolador. Sin embargo, una particularidad de este tipo de microcontrolador consiste en la posibilidad de activar por software las resistencias de drenaje de que dispone el puerto B (en los PIC) son conocidas como resistencias pull-up. Estas resistencias confieren unas posibilidades que, mejoran las opciones de los puertos que las disponen.

Cada uno de los pines del PORTB tiene un Pull-up (forzado a alto) débil interno. Un solo bit de control puede conectar a alto todas las líneas del puerto. Esto se configura al aclarar el bit RBPU del registro OPCIÓN (bit7=0). El débil drenaje a alto, se apaga automáticamente cuando el pin del puerto es configurado como una salida. Las resistencias de drenaje son inutilizadas con un Power on Reset (al conectar la tensión). Este es el esquema definitivo que se emplea, las referidas resistencias no aparecen.

 
Fig. 2 Esquema final del programa

Al activar estas resistencias, mediante la aplicación de un el nivel de los pines, toma el valor alto (1) si lo tratamos como entrada y si se trata como salida este hecho se debe tener muy en cuenta ya que es motivo de no pocos quebraderos de cabeza, ya que presenta un estado alto en reposo y por este motivo emplazamos al lector a que, revise el circuito esquemático de los puertos que dispongan de este elemento para comprender su comportamiento y evitar en lo posible efectos no esperados cuando realmente la salida hace lo que se le ha indicado en el código de programa.

Esto aplicado a nuestro programa, hace que evitemos el uso de las tres resistencias (R5, R6 y R7 en el esquema) ya que como se ha descrito las entradas de los pulsadores no requieren de las mencionadas resistencias (se han activado por software) y naturalmente están a nivel positivo (H), esto hace que al presionar un pulsador ingresemos un 0 en dicha entrada y con pocos cambios en el software habremos logrado adaptar el programa. En el ejemplo mostrado, ya está contemplado este hecho. Veamos otra modificación del programa.

Modificación.

La modificación que se refiere, consiste en cambiar de sitio una línea del código fuente, nos referimos a la línea de aclarado del puerto A, para entender mejor lo que se pretende vamos a describir con detalle lo que ocurre al llegar el flujo del programa a la etiqueta luce1:

Al activar estas resistencias, mediante la aplicación de un el nivel de los pines, toma el valor alto (1) si lo tratamos como entrada y si se trata como salida este hecho se debe tener muy en cuenta ya que es motivo de no pocos quebraderos de cabeza, ya que presenta un estado alto en reposo y por este motivo emplazamos al lector a que, revise el circuito esquemático de los puertos que dispongan de este elemento para comprender su comportamiento y evitar en lo posible efectos no esperados cuando realmente la salida hace lo que se le ha indicado en el código de programa.

Esto aplicado a nuestro programa, hace que evitemos el uso de las tres resistencias (R5, R6 y R7 en el esquema) ya que como se ha descrito las entradas de los pulsadores no requieren de las mencionadas resistencias (se han activado por software) y naturalmente están a nivel positivo (H), esto hace que al presionar un pulsador ingresemos un 0 en dicha entrada y con pocos cambios en el software habremos logrado adaptar el programa. En el ejemplo mostrado, ya está contemplado este hecho. Veamos otra modificación del programa.

Modificación.

La modificación que se refiere, consiste en cambiar de sitio una línea del código fuente, nos referimos a la línea de aclarado del puerto A, para entender mejor lo que se pretende vamos a describir con detalle lo que ocurre al llegar el flujo del programa a la etiqueta luce1:

Al activar estas resistencias, mediante la aplicación de un el nivel de los pines, toma el valor alto (1) si lo tratamos como entrada y si se trata como salida este hecho se debe tener muy en cuenta ya que es motivo de no pocos quebraderos de cabeza, ya que presenta un estado alto en reposo y por este motivo emplazamos al lector a que, revise el circuito esquemático de los puertos que dispongan de este elemento para comprender su comportamiento y evitar en lo posible efectos no esperados cuando realmente la salida hace lo que se le ha indicado en el código de programa.

Esto aplicado a nuestro programa, hace que evitemos el uso de las tres resistencias (R5, R6 y R7 en el esquema) ya que como se ha descrito las entradas de los pulsadores no requieren de las mencionadas resistencias (se han activado por software) y naturalmente están a nivel positivo (H), esto hace que al presionar un pulsador ingresemos un 0 en dicha entrada y con pocos cambios en el software habremos logrado adaptar el programa. En el ejemplo mostrado, ya está contemplado este hecho. Veamos otra modificación del programa.

Modificación.

La modificación que se refiere, consiste en cambiar de sitio una línea del código fuente, nos referimos a la línea de aclarado del puerto A, para entender mejor lo que se pretende vamos a describir con detalle lo que ocurre al llegar el flujo del programa a la etiqueta luce1:

Considerando los comentarios, parece bastante claro que hace cada línea, por lo tanto a continuación se muestra la misma subrutina modificada.

Se aprecia que se ha puesto la instrucción CLRF PORTA al entrar en la subrutina y se ha eliminado esta misma instrucción de la cuarta línea donde se encontraba. Esto hace que se pongan a cero todas las salidas del puerto, apagando los LEDs que hubiera, lo que sigue ya está descrito anteriormente y sin embargo, al salir de la subrutina con el RETURN, el LED permanecerá encendido mientras no se pulse otro pulsador. Esta rutina muestra cómo conseguir un testigo del último pulsador presionado.

Se aprovechan las rutinas principal, la de rastreo de pulsadores y las subrutinas que se encargaran de cada función. Lea y estudie las rutinas de las ‘Librerías de Rutinas’, estas ya sabe que funcionan, aproveche las que le interesen, puede dar por seguro que funcionan. Copie y pegue lo que le interese de cada una de las subrutinas y únala a su programa. Preste atención a las etiquetas, lazos, etc.

En ocasiones una subrutina puede causar verdaderos quebraderos de cabeza y nos resultan difíciles de depurar, debido a que tienen todo el aspecto de estar bien concebidas y sin embargo, no producen lo que esperábamos, en próximos artículos, veremos algún pequeño ejemplo o ‘truco’ de este tipo de ‘fallos’ y cómo corregirlos.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.