Tutorial de PIC: de registros a interrupciones

Tutorial de PIC: de registros a interrupciones

Antes de entrar en los detalles minuciosos de la programación PIC, primero sería importante aprender algunos buenos métodos de programación.

Comprensión de los registros

Para empezar, suponga que escribe un (punto y coma) en cualquier punto del programa, todo lo que venga después de este punto y coma será ignorado por el compilador, hasta que, por supuesto, el carro vuelva a la posición.

La función anterior nos permite agregar comentarios o observaciones de manera que no se conviertan en parte del programa, pero nos facilita identificar el programa con la ayuda de los comentarios al lado. Poner comentarios es una práctica recomendada al programar cualquier CI.



El siguiente paso importante del curso es asignar nombres a las diversas constantes (las aprenderá más adelante con más detalle). Esto también hace que sea más sencillo comprender en qué se escribe, o con respecto a los valores involucrados, en lugar de confundirse con los números incluidos.

Lo anterior debe hacerse en forma de nombres reales para el reconocimiento instantáneo, por ejemplo COUNT, sería importante tener en cuenta que aquí se emplean todas las letras mayúsculas para que sea distinto y también para indicar que es un valor constante.


Como podemos ver, lo anterior se hace en forma de una caja hecha de punto y coma esto solo hace que se vea más limpio. Además, trate de documentar el programa en papel, esta práctica le ayudará a entender las cosas paso a paso.

2. Los registros.

El registro dentro de un PIC es un área que acepta detalles escritos y también permite leerlos. Puede compararlo con una hoja de papel donde puede visualizar el contenido y agregarlo escribiendo sobre él.

La siguiente figura muestra un mapa de archivo de registro típico incrustado dentro de un PIC16F84. El formato no es algo que esté realmente configurado dentro del PIC, es simplemente para indicar cómo se pueden organizar los bits dentro del chip y para comprender algunos de los comandos involucrados.

Puede ver que está básicamente dividido en Banco 0 y Banco 1. El Banco 1 es responsable de controlar el funcionamiento real del PIC, por ejemplo, le indica al PIC qué bits del Puerto A se asignan como entradas y cuáles como salidas.

El banco 2 es solo para manipular la información.

Comprendamos esto con el siguiente ejemplo:

Supongamos que deseamos asignar un bit en PortA alto. Para esto, primero tendríamos que ir al Banco 1 para configurar el bit o pin especificado en el Puerto A en forma de salida. Después de esto, regresamos al Banco 0 y entregamos un 1 lógico (bit 1) a ese pin específico.

Los registros más comunes que nos gustaría usar en el Banco 1 son STATUS, TRISA y TRISB.

STATUS nos ayuda a regresar al Banco 0, TRISA nos permite elegir qué pines en el Puerto A son salidas y cuáles pueden ser entradas, mientras que TRISB facilita seleccionar entre el pin de salida y de entrada en el Puerto B. El registro SELECT en BANK 0 permite al usuario para pasar al Banco 1.

Resumamos todo el concepto con la siguiente descripción:

ESTADO:

Para cambiar del banco 0 al banco 1, comandamos el registro STATUS. Esto se implementa estableciendo el bit # 5 del registro STATUS en 1. Para volver al banco 0, asignamos el bit 5 del registro STATUS a 0. El registro STATUS está ubicado en la dirección 03h, aquí h significa tat el número puede estar en hexadecimal.

TRISA y TRISB:

Estos se encuentran en la dirección 85h y 86h correspondientemente. Para programar un pin como salida o entrada, simplemente entregamos un cero o uno al bit particular en el registro. Ahora bien, esto se puede hacer de dos formas, vía binaria o hexadecimal. En caso de que uno no pueda convertir el parámetro, puede optar por una calculadora científica para implementar los valores.

Ahora tenemos 5 pines en el puerto A, lo que corresponde a 5 pines. Si pretendemos fijar uno de los pines como entradas, entregamos un '1' al bit en particular.

En caso de que quisiéramos asignar uno de los pines como salidas, estableceríamos el pin específico en “0”. Los bits son exactamente iguales a los bits, o más precisamente el bit 0 es RA0, el bit 1 sería RA1, el bit 2 = RA2 y así sucesivamente. Entendamos esto de esta manera:

Suponga que desea fijar RA0, RA3 y RA4 como salidas, mientras que RA1 / RA2 como i / ps, lo haría enviando 00110 (06h). Compruebe que el bit 0 está hacia la derecha como se indica aquí:

Puerto A Pin RA4 RA3 RA2 RA1 RA0

Número de bit 4 3 2 1 0

Binario 0 0 1 1 0

Lo mismo ocurre con TRISB.

PORTA y PORTB

Para que uno de los pines de salida sea alto, solo ofrecemos un '1' para el bit respectivo en nuestro registro PORTA o PORTB. También se puede seguir un procedimiento idéntico para los registros TRISA y TRISB. Antes de pasar rápidamente a nuestra primera codificación de ejemplo, entendamos un conjunto de más registros, a saber: wy f.

W y F

El registro W es un registro ordinario que le permite asignar cualquier valor de su elección. Tan pronto como asigne una magnitud a W, puede continuar agregando esto a otro valor o simplemente moverlo. Con otro valor asignado, los detalles simplemente se sobrescriben en W.

El registro F envía su material escrito a un registro. Requeriríamos que este registro F asigne un valor sobre un registro, puede estar sobre los registros STATUS o TRISA, ya que estos no nos permitirán poner los valores directamente sobre ellos. Un programa de ejemplo

Examinemos el siguiente código de ejemplo que nos mostrará cómo se implementa la instrucción anterior y también observará algunas de las instrucciones del curso.

Comencemos por arreglar el puerto A como se discutió anteriormente.

Para ello necesitamos pasar del Banco 0 al Banco 1, esto se hace configurando el registro STATUS situado en la dirección 03h, bit 5 a 1.

BSF 03h,5

El BSF significa el conjunto de bits F. Estamos usando dos números después de esta instrucción: 03h, que es la dirección del registro STATUS, y el número 5 que corresponde al número de bit.

Entonces, lo que estamos diciendo es “Establecer el bit 5 en la dirección 03h en 1”.

Ahora estamos en el Banco 1.

MOVLW 00110b

Estamos poniendo el valor binario 00110 (la letra b significa que el número está en binario) en nuestro registro de propósito general W. Por supuesto, podría haber hecho esto en hexadecimal, en cuyo caso nuestra instrucción sería:

MOVLW 06h

Cualquiera funciona. MOVLW significa 'Move Literal Value Into W', que en inglés significa poner el valor que sigue directamente en el registro W.

Ahora necesitamos poner este valor en nuestro registro TRISA para configurar el puerto:

MOVWF 85h

Esta instrucción indica 'Mover el contenido de W a la dirección de registro que sigue', en este caso la dirección se refiere a TRISA.

Nuestro registro TRISA en este punto lleva la cifra 00110, o se presenta gráficamente:

Puerto A Pin RA4 RA3 RA2 RA1 RA0

Binario 0 0 1 1 0

Entrada / Salida O O I I O

Entonces, ahora que poseemos nuestros pines del Puerto A, debemos regresar al Banco 0 para ajustar uno de los datos.

BCF 03h, 5

Esta instrucción logra lo contrario de BSF. Implica 'Bit Clear F'. El par de números que corresponden son la dirección del registro, aquí el registro STATUS, así como la cifra de bits, en este caso el bit cinco. Lo que hemos completado exactamente en la actualidad es el bit cinco definido en nuestro

ESTADO registro a 0

En este punto hemos regresado en el Banco 0.
El siguiente es el código todo en un bloque:

BSF 03h, 5 Ir al banco 1
MOVLW 06h Ponga 00110 en W
MOVWF 85h Mover 00110 a TRISA
BCF 03h, 5 Vuelve al banco 0

En las últimas instrucciones, le confirmamos la forma de establecer los pines del puerto IO en el PIC para que sean posiblemente de entrada o salida.

A través de este curso, permítame ayudarlo a enviar datos a los puertos.

Envío de datos a puertos

En el siguiente tutorial, lo completaremos encendiendo y apagando un LED que consiste en un programa completo que detalla y un diagrama de circuito sencillo para que pueda ver el PIC funcionando exactamente como lo anticipamos.

No intente armar y programar su PIC con los resultados a continuación, ya que son solo ilustraciones. Inicialmente, estableceremos el bit 2 del puerto A como salida:

Esto podría ser reconocible por el instructivo anterior. La única distinción podría ser: Hemos arreglado cada bit de los pines en A como salida, entregando 0h al registro de tres estados. Entonces, lo que debe hacer ahora es encender un LED.

Logramos esto programando uno de los pines (el que tiene el LED vinculado) alto. Para decirlo de otra manera, aplicamos un '1' al alfiler. Así es exactamente como se lleva a cabo (observe los comentarios para una aclaración para cada línea):

Por lo tanto, lo que hemos logrado ahora es encender y apagar el LED una vez. Lo que deseamos es que el LED se encienda posteriormente de forma continua.

Lo logramos al obtener el programa para volver al inicio. Logramos esto estableciendo inicialmente una etiqueta al comienzo de nuestro programa, luego informando al programa que vuelva allí. Especificamos una etiqueta de forma bastante sencilla.

Tecleamos un término, digamos INICIO, luego tecleamos el código:

Como se demuestra, inicialmente mencionamos la expresión 'Iniciar' inmediatamente al comienzo del programa.

A continuación, al final del programa, mencionamos claramente 'ir a Inicio'. La instrucción 'goto' realiza exactamente lo que declara.

Este programa enciende y apaga constantemente el LED cada vez que enciende el circuito, y tiende a apagarse una vez que quitamos la electricidad. Quizás deberíamos revisar nuestro programa una vez más:

Seguramente hemos omitido los comentarios, sin embargo aún podemos observar las instrucciones y los números.

Esto puede ser un poco desconcertante más adelante en caso de que intente solucionar problemas del programa y mientras escribe el código, haya memorizado todas las direcciones.

Aunque los comentarios se pueden colocar quietos, podría volverse un poco desordenado. Esto requerirá nombrar los números y podría lograrse con una instrucción adicional: 'equ' La instrucción 'equ' sugiere que algunas cosas podrían ser iguales a otras cosas.

Puede que no sea una instrucción para PIC, sino para el ensamblador. Esta instrucción facilita la asignación de nombre a una ubicación de dirección de registro, o una constante a un término de programación.

Estableceremos algunas constantes para nuestro programa y también seremos testigos de lo sencillo que es leer el programa.

Dado que ahora hemos fijado los valores constantes, podemos proceder configurándolos en nuestro programa. Los valores constantes deben designarse antes de usarlos.

por lo tanto, asegúrese de colocarlos siempre al principio del programa. Reescribiremos el programa excluyendo los comentarios una vez más, para comparar el etiquetado anterior con el último.

Puede ser que pueda notar que las constantes están permitiendo una comprensión un poco más fácil del programa, sin embargo, todavía estamos sin los comentarios, sin embargo, no se preocupe, ya que aún no hemos terminado.

Puede haber una pequeña desventaja de nuestro programa de LED parpadeantes.
Cada instrucción necesita 1 secuencia de reloj para terminar. En caso de que estemos utilizando un cristal de 4MHz, entonces cada instrucción requiere 1 / 4MHz o 1uS para terminar.

Dado que hemos estado empleando solo cinco instrucciones, el LED se activará y luego se apagará en 5uS. Esto podría ser demasiado rápido para que la gente se dé cuenta, además, parecerá que el LED está completamente encendido.

En cambio, lo que deberíamos lograr es producir una inhibición entre encender y apagar el LED. La teoría de la inhibición es que contamos hacia atrás desde una cantidad anterior, por lo que cuando llega a cero, dejamos de contar.

El valor cero significa la conclusión del retraso y seguimos trabajando en nuestro proceso durante todo el programa. Por lo tanto, lo primero que debemos hacer es determinar una constante para utilizar como nuestro contador.

Llamemos a esta constante CONTAR. Después de eso, debemos determinar qué tan significativo es un número desde el que comenzar a contar. Seguramente, la cifra más grande que podríamos incluir es 255, o FFh en hexadecimal. Como mencioné en el tutorial anterior, la instrucción equ asigna una expresión a una situación de registro.

Esto implica que no importa la cantidad que asignemos a nuestro COUNT, coincidirá con los elementos de un registro. En caso de que intentemos designar el valor FFh, vamos a cometer un error una vez que consigamos compilar el programa.

La razón es la ubicación FFh, por lo tanto, no podemos acceder a ella. Por tanto, ¿cómo debemos designar un número genuino? Ciertamente, requerirá una pequeña cantidad de reflexión lateral.

Si quizás designamos nuestro COUNT a la dirección 08h, por ejemplo, esto indicaría un destino de registro objetivo básico. De forma predeterminada, las áreas intactas se establecen en FFh. En consecuencia, si COUNT lleva a 08h, encontrará el valor de FFh mientras lo encendemos por primera vez. Sin embargo, yo, ¿cómo podemos fijar COUNT a otro número ?, todo lo que aplicamos es 'mover' una valoración a este destino primero.

Como ilustración, supongamos que deseamos que COUNT posea un valor de 85h, no podemos mencionar COUNT equ 85h ya que esa es la posición de nuestro registro Tri-State para el Puerto A. Precisamente lo que logramos es lo siguiente: movlw 85h First put el valor de 85h en el registro W movwf 08h

Ahora muévalo a nuestro registro de las 08h. Posteriormente, en caso de que expresemos COUNT equ 08h, COUNT coincidiría con el valor 85h. Delicado, ¿no es así? Por lo tanto, inicialmente determinamos nuestra constante: COUNT equ 08h A continuación debemos reducir este COUNT en uno hasta que se convierta en cero.

Simplemente ocurre que existe una instrucción diseñada para lograr esto para nosotros, haciendo uso de un 'goto' y una etiqueta.

La instrucción que vamos a aplicar es: DECFSZ COUNT, 1 Esta instrucción dice 'Disminuir el registro (aquí es COUNT) por el número que rastrea la coma. Si llegamos a cero, saltemos dos lugares más adelante ''. Encontremoslo en acción primero, antes de colocarlo en nuestro curso.

Lo que hemos realizado es establecer inicialmente nuestro COUNT constante en 255. El segmento posterior coloca una etiqueta, llamada LABEL, cerca de nuestra instrucción decfsz.

El decfsz COUNT, 1 reduce el valor de COUNT en uno y retiene el resultado final directamente en COUNT. Además, verifica para comprobar si COUNT posee un valor de 0.

Si no es así, en ese caso activa el programa para cambiar a la línea siguiente. Ahora tenemos una declaración 'goto' que nos devuelve a nuestra instrucción decfsz.

En caso de que el valor de COUNT funcione igual, entonces la instrucción decfsz da como resultado que nuestro programa salte 2 puntos por delante y se envíe a donde hemos reclamado 'Continuar aquí'.

Por lo tanto, como puede observar, hemos hecho que el programa se siente en un lugar durante un tiempo predestinado antes de continuar. Esto podría denominarse bucle de retardo.

Comprensión de los bucles de retardo

En caso de que necesitemos un retraso más sustancial, podríamos seguir un ciclo tras otro. Los bucles adicionales, el retraso extendido. Permítanos al menos dos, asumiendo que queremos observar el flash LED. Colocaremos estos bucles de retardo en nuestro programa y lo lograremos convirtiéndolo en un programa genuino al introducir comentarios:

Es posible compilar este programa y luego programar el PIC. Obviamente, asegúrese de probar el circuito para verificar si realmente funciona. El siguiente es un diagrama de circuito que debe construir tan pronto como haya programado el PIC.


Bien hecho, podría haber compuesto su primer programa PIC, así como también haber construido un circuito para encender y apagar un LED. Hasta ahora, en caso de que haya seguido estos cursos, es posible que haya aprendido un total de siete instrucciones de 35, pero sin duda hasta ahora puede estar controlando los puertos de E / S.

¿Intentaría cambiar los bucles de retardo para hacer que el LED parpadee más rápido? ¿Cuál parece ser el valor mínimo de COUNT para ver esencialmente el flash LED? O tal vez, querrá incluir un tercer bucle de retardo o bucles de retardo suplementarios después del inicial para estabilizar el LED hacia abajo. una constante única para cada bucle de retardo.

Potencialmente, podría jugar con sus bucles de retardo para hacer que el LED parpadee a una velocidad específica, por ejemplo, después de un segundo. En el siguiente instructivo, veamos cómo podemos utilizar algo conocido como subrutina para mantener el programa compacto y básico. Una subrutina es una parte integral del código, o programa, que puede ser referido como y cuando lo necesite. Las subrutinas se emplean en los casos en los que realiza la misma función con frecuencia.

¿Qué son las subrutinas?

Los beneficios de emplear una subrutina son que probablemente será más sencillo modificar el valor una vez dentro de una subrutina en lugar de, digamos, diez veces a lo largo de su programa, y ​​también contribuye en gran medida a disminuir el nivel de memoria que su programa consume dentro del programa. FOTO. Comprobaremos una subrutina:

Inicialmente, necesitamos proporcionar una designación a nuestra subrutina y, en esta situación, hemos seleccionado RUTINA. Después de eso, escribimos el código que nos gustaría realizar normalmente. Por eso, hemos seleccionado el retardo en nuestro programa de led intermitentes. Por último, concluimos la subrutina tecleando la instrucción RETURN.

Para comenzar la subrutina desde cualquier lugar de nuestro programa, rápidamente escribimos la instrucción CALL y luego la designación de la subrutina.

Consideraremos esto con un poco más de profundidad. Una vez que llegamos a la sección de nuestro programa que CALL xxx, en la que xxx es el nombre de nuestra subrutina, el programa salta a cualquier lugar donde esté instalada la subrutina xxx. Se llevan a cabo las instrucciones dentro de la subrutina.

Siempre que se logra la instrucción RETURN, el programa salta y regresa a nuestro programa principal a la instrucción posterior a nuestra instrucción CALL xxx.

Es posible llamar a la subrutina similar varias veces como desee, lo que explica por qué la utilización de subrutinas reduce la duración general de nuestro programa.

Sin embargo, hay un par de factores que debe conocer. Inicialmente, al igual que con nuestro programa principal, es necesario reconocer cualquier constante específica antes de poder usarla.

Es posible que estos se reconozcan dentro de la subrutina misma o directamente al comienzo del programa principal. Te propongo que reconozcas todo al inicio de tu programa principal, pues entonces reconoces que las cosas están en idéntica situación. A continuación, uno debe asegurarse de que el programa principal omita la subrutina.

Lo que quiero decir con esto es que si coloca la subrutina directamente al final de su programa principal, excepto si utiliza una declaración 'Goto' para saltar de donde está la subrutina, el programa continuará e implementará la subrutina independientemente de si requerirlo o de otro modo.

El PIC no distinguiría entre una subrutina y el programa principal. Revisaremos nuestro programa de led intermitentes, sin embargo esta vez vamos a hacer uso de una subrutina para el bucle de retardo. Idealmente, descubrirás cuánto menos complicado parece el programa, y ​​también descubrirás cómo se aplica la subrutina en la práctica.

Eventualmente, puede observar que al utilizar una subrutina para nuestro ciclo de retardo, podríamos haber reducido las dimensiones del programa.

Cada vez que deseamos un retraso, posiblemente cuando el LED está encendido o apagado, básicamente llamamos a la subrutina de retraso. Al final de la subrutina, el programa vuelve a la línea siguiendo nuestra instrucción 'Llamar'. En la ilustración de arriba, encendemos el LED.

Después de eso, contactamos con la subrutina. Luego, el programa regresa para que podamos apagar el LED. Llamamos a la subrutina una vez más, en caso de que la subrutina se haya completado, el programa regresa y la instrucción subsiguiente que reconoce es 'goto Start'. Para cualquiera que pueda estar intrigado, nuestro primer programa tenía 120 bytes de longitud.

Mediante el uso de la subrutina, podríamos reducir el tamaño de nuestro programa a 103 bytes. Esto no puede sonar tan fantástico, sin embargo, considerando el hecho de que solo tenemos 1024 bytes en total dentro del PIC, cada pequeña cantidad se beneficia.

En el siguiente instructivo, revisemos la lectura de los puertos.

Hasta ahora, hemos estado componiendo el puerto A para que podamos encender y apagar un LED. En este punto, veremos cómo vamos a leer los pines de E / S en los puertos.

Lectura de puertos de entrada / salida

Esto es exactamente para asegurarnos de que podamos vincular un circuito externo e influir en las salidas específicas que ofrece.

Si memoriza de nuestros cursos anteriores, si desea establecer los puertos de E / S, necesitamos saltar del banco 0 al banco 1. Lo lograremos inicialmente:

En este punto, hemos fijado el bit 0 del puerto A para ingresar. ahora debemos examinar si el pin es alto o bajo. Para lograr esto, uno puede utilizar solo una de dos instrucciones:

BTFSC y BTFSS.

La instrucción BTFSC significa 'Haga una prueba de bit en el registro, así como en el bit que designemos.

En caso de que sea un 0, en ese caso omitimos la instrucción subsiguiente '. BTFSS implica 'Haga una prueba de bit en el registro y establezcamos el bit. En caso de que se establezca en 1, omitiremos la instrucción siguiente.

Cuál utilizamos, está determinado precisamente por cómo deseamos que nuestro programa responda mientras estudiamos la entrada. Como ilustración, en caso de que solo estemos esperando que la entrada sea 1, entonces podríamos utilizar la instrucción BTFSS de la siguiente manera:

Codifique aquí:

BTFSS PortA, 0Goto start Continuar aquí:
:

El programa simplemente cambiaría a 'Continuar aquí' siempre que el bit 0 en el puerto A esté programado en 1.

Actualmente escribiremos un programa que podría activar un LED a una velocidad, sin embargo, si un interruptor está confinado, el LED parpadeará dos veces más lento.

Quizás sea posible poner en práctica este programa por su cuenta, aún así, hemos incorporado la lista de alguna manera.

Puede intentar y crear el programa completo para comprobar si ha comprendido los principios. Usaremos el circuito equivalente como antes, con la inclusión de un interruptor RA0 adjunto del PIC y el riel positivo de nuestro suministro.

Lo que hemos logrado aquí es encender el LED. Posteriormente determino si el interruptor está cerrado.

En caso de que esté limitado, a continuación me conecto a nuestra subrutina de retardo. Esto nos proporciona la demora equivalente a la anterior, sin embargo, en este punto lo contactamos dos veces.

Lo mismo se aplica cuando el LED está apagado. En caso de que el interruptor no esté cerrado, tenemos nuestros períodos de encendido y apagado registrados anteriormente.

Si ha estado siguiendo estas lecciones desde el principio, es posible que desee comprender que actualmente ha descubierto diez de las 35 instrucciones para el PIC 16F84. Y cada parte de estos se aprende simplemente encendiendo y apagando un LED.

Hasta ahora, hemos compuesto que el PIC haga parpadear un LED encendido y apagado.

Posteriormente pudimos con nuestro PIC al incluir un interruptor, variando así la velocidad del flash.

Usar el espacio de la memoria de manera eficiente

El único problema es que el programa es bastante largo y bastante ineficaz en cuanto al espacio de memoria. Parecía estar bien mientras incluía los comandos por primera vez, sin embargo, debería haber una forma más fácil de ejecutarlo. Positivamente, analizaremos cómo estábamos literalmente encendiendo y apagando el LED.

movlw 02hmovwf PORTAmovlw 00hmovlw PORTA

Al principio rellenamos nuestro registro w con 02h, luego lo transferimos a nuestro registro PortA para encender el LED. Para apagarlo, empaquetamos w con 00h, después de lo cual lo cambiamos a nuestro registro PortA.

Entre todas estas rutinas, nos vimos obligados a ponernos en contacto con una subrutina para asegurarnos de que podíamos observar el parpadeo del LED.

Por lo tanto, necesitábamos transferir dos conjuntos de información un par de veces (una vez al registro w y luego a PORTA), así como llamar a una subrutina dos veces (una vez para encendido y otra vez para apagado). Entonces, ¿cómo podríamos lograr esto con mayor eficiencia? Muy simple.

Utilizamos una instrucción diferente conocida como XORF. La instrucción XORF trabaja una función OR exclusiva en el registro que estipulamos con la información que proporcionamos. Creo que tengo que aclarar qué demonios es un quirófano exclusivo antes de continuar. En caso de que tengamos dos entradas y una salida, la entrada solo puede ser un 1 si, y siempre que, las dos entradas difieran. Si bien son los mismos, entonces la salida probablemente será 0. La siguiente es una tabla de verdad, para las personas que elijan verificar estas:

A B F0 0 00 1 11 0 11 1 0

En este punto, comprobaremos lo que sucede si representamos B como nuestra salida anterior, y simplemente modificamos el valor de A:

A B F
0 0 0
0 0 0
1 0 1
1 1 0
1 0 1

Si mantenemos el valor de A igual que 1, y lo ponemos en OR Exclusivo con la salida, la salida cambiaría. En caso de que no pueda notar esto en la tabla de verdad, a continuación se puede ver utilizando binario:

0 Salida de corriente
EX-OR con 1 1 nueva salida
EX-OR con 1 0 nueva salida

Tal vez pueda encontrar que al hacer un OR exclusivo en la salida con 1, ahora cambiaremos la salida de 0 a 1 a 0.
Por lo tanto, para encender y apagar nuestro LED, solo necesitamos un par de oraciones:

MOVLW 02h
PUERTA XORWF, 1

Lo que precisamente estaremos logrando es sumar nuestro registro w con 02h. En ese caso, estamos usando un OR exclusivo para este número sin importar lo que esté en nuestro PortA. En caso de que el bit 1 sea un 1, cambiará a 0. En caso de que el bit 1 sea un 0, cambiará a 1. Examinemos este código una o dos veces, para mostrar cómo se está ejecutando binario:

PUERTA
00010
xorwf 00000
xorwf 00010
xorwf 00000
xorwf 00010

En realidad, no tenemos que cargar el valor idéntico en nuestro registro w cada vez, por lo tanto, es posible lograr esto una vez al principio y simplemente volver a nuestro comando de alternancia. Además, no deberíamos fijar un valor en nuestro registro PortA. ¿La razón? Seguramente, dado que en caso de que al encender sea un 1, podemos alternarlo fácilmente. Yo, alternativamente, un 0 al encenderlo, incluso ahora lo alternaríamos.

Por lo tanto, querrá ver nuestro código recién formado. El primero representa nuestro código LED parpadeante, mientras que el segundo muestra el que tiene la adición del interruptor:

Ojalá pueda encontrar que simplemente haciendo uso de una instrucción sencilla, ahora hemos reducido la escala de nuestro programa. La verdad es que, para mostrar cuánto podríamos reducir nuestros programas, hemos demostrado los dos programas, lo que fueron compuestos y sus dimensiones en la siguiente tabla:

Programa Alter Dimensiones (Bytes)
LED intermitente Original 120
Subrutina LED parpadeante agregada 103
LED intermitente Función XOR utilizada 91
LED Con Interruptor Original 132
LED con función de interruptor XOR utilizada 124.

Por lo tanto, no solo hemos descubierto algunas instrucciones novedosas, ¡ciertamente también hemos reducido el tamaño de nuestras secuencias de comandos!

A continuación, analizaremos cómo puede mover bits individuales, realizar ciertas operaciones aritméticas sencillas, así como tablas de datos.

Administradores lógicos

Dentro del último tutorial presenté la operación OR exclusivo. La función ExOR se entiende como un operador lógico.

Dentro de este tutorial aclararé los operadores lógicos adicionales que promueve el PIC. No habrá ningún tipo de caso en los programas de puntos, sin embargo, aprenderemos métodos fáciles para usar los operadores aplicando pequeñas áreas de código.

AND La función AND básicamente analiza dos bits y entrega un 1 si son iguales y un 0 en caso de que sean distintivos. Por ejemplo, si mencionamos 1 Y 1, el resultado es 1, mientras que en caso de que declaramos 1 Y 0, la consecuencia sería 0.

No hace falta decir que también podemos evaluar palabras, y todo lo que la función AND logra es revisar los dos términos poco a poco. La siguiente instancia muestra dos palabras de 8 bits que se convierten en AND junto con el producto:

11001011
Y 10110011
Es igual a 10000011

Espero que esté de acuerdo, el resultado simplemente tendrá un 1 cada vez que 2 1 estén de la mano en el par de palabras. Podemos utilizar la función AND para verificar los puertos, por ejemplo.

En caso de que estemos comprobando algunos pines de E / S que están vinculados a un circuito, y deberíamos estar atentos a una situación particular en la que solo algunos de los pines están altos, en ese caso podemos leer prácticamente el puerto, después de lo cual Y el resultado con la condición que hemos estado examinando, idéntica a la instancia anterior.

El PIC nos proporciona dos ingredientes para AND.
Son ANDLW y ANDWF. ANDLW nos permite realizar una función AND con los datos del registro W, y una cantidad que estipulemos.

La sintaxis es: ANDLW donde es exactamente a lo que vamos Y con el contenido de W.

La consecuencia de la función AND se almacenaría directamente en el registro W.
ANDWF nos permite realizar una función AND en el registro W y en un registro diferente, por ejemplo un PORT. La sintaxis es: ANDWF, d en el cual es el registro que nos entusiasma, p. Ej. PORTA, yd muestra el PIC donde debe colocar el resultado. Si d = 0, el resultado se pone en el registro W, y d = 1 el resultado final se guarda en el registro que estipulamos. Las dos partes del código a continuación muestran un buen ejemplo de cada función AND.

La inicial es examinar el estado del PORTA, en el que debemos verificar si las entradas son 1100. Podemos colocar el resultado nuevamente en el registro W

movlw 1100
ANDWF 05h, 0 La segunda ilustración ahora podría verificar el contenido del registro W:
ANDLW 1100

O

Ya hemos descubierto una función OR, para ser precisos, el XOR. Esto se convierte en 1 si dos bits no son iguales, pero son diferentes. Puede encontrar otra función OR llamada IOR, que es la OR inclusiva. Esta función generará un 1 en caso de que cualquiera de los bits sea un 1, pero además si cada bit es 1. A continuación se muestra una tabla de verdad clara para ilustrar esto:

A B O / P
0 0 0
0 1 1
1 0 1
1 1 1

¿Qué son los operadores aritméticos?

AGREGAR

Esta función cumple con lo que normalmente dice. ¡Aporta dos cifras! En caso de que la consecuencia de sumar las dos cifras supere los 8 bits, en ese caso probablemente se activará una bandera CARRY. La bandera CARRY se encuentra en la dirección 03h bit 0.

Cuando se programa este bit, las dos cifras superan los 8 bits. Cuando es un 0, en ese caso la consecuencia se ubica dentro de los 8 bits. Como antes, el PIC nos ofrece dos estilos de ADD, específicamente ADDLW y ADDWF. Como habrás asumido, esto es bastante parecido a la función anterior. ADDLW ofrece los contenidos del registro W a los que estipulamos. La sintaxis es: ADDLW ADDWF agrega el contenido del registro W y algún otro registro que designemos.

La sintaxis es: ADDWF, d es donde

SUB

En este punto, supongo que no puede suponer lo que conduce esta función. De hecho, lo sospechabas, esta función
resta un bit de otro. Nuevamente el PIC nos brinda 2 gustos: SUBLW y SUBWF. La sintaxis es precisamente similar a la de la función ADD, aparte de que evidentemente usted escribe SUB en lugar de ADD!

Incremento En caso de que deseáramos incluir 1 a un número en el PIC, podríamos absolutamente hacer uso de la función ADD y utilizar el número uno. ~ La dificultad con esto es que primero debemos colocar la figura en el registro W, luego usar el control ADDLW 1 para incrementarlo. En caso de que queramos incluir 1 en un registro, puede ser peor aún. Primero debemos colocar el número 1 en el registro W, luego usar ADDWF, 1. Por lo tanto, por ejemplo, para incluir 1 en la ubicación 0C, digamos, necesitaríamos poseer la siguiente parte del script:

movlw 01
addwf 0c, 1

Existe un método más fácil de realizar esto. Podemos ejercer el mando INCF. La sintaxis es: INCF, d donde, es el registro, o lugar, en el que estamos interesados, y d muestra el PIC donde debe colocar el resultado. En el caso d = 0, el resultado está dentro del registro W, y en el caso d = 1, la consecuencia se establece en el registro que estipulamos.

Al utilizar esta instrucción individual, podemos realmente el cincuenta por ciento de la codificación. En caso de que deseáramos que el resultado se restaurara en el registro W, en ese caso empleando la instancia anterior, podríamos haber tenido que incluir un comando adicional para cambiar los elementos de 0C nuevamente al registro W, después de lo cual colocar el registro 0C nuevamente en no importa lo que fuera.

Existe un comando de incremento. Es INCFSZ. Este comando puede incrementar el registro que estipulamos, sin embargo, si el registro es igual a 0 después del incremento (eso ocurrirá mientras incluimos 1 a 127) después, el PIC probablemente pasará por alto la instrucción subsiguiente. La parte del código a continuación refleja esto:

Bucle incfsz 0C
Ir a bucle
:
:
Resto del programa.

En la parte anterior del código, 0C se incrementará en 1. A continuación, poseemos una instrucción que informa al PIC que regrese a nuestra etiqueta llamada Loop, y que incremente 0C en 1 nuevamente. Esto continúa hasta que 0C es igual a 127. En esta circunstancia, cuando incrementamos 0C en 1, 0C ahora coincidirá con 0. Nuestra instrucción INCFSZ podría informar al PIC que omita la instrucción subsiguiente, que en este caso es la declaración goto, por lo tanto, el PIC seguirá adelante con el resto del programa.

Decremento

A estas alturas ya hemos hablado de la función de disminución en el entrenamiento anterior, por lo tanto, no la revisaré más.

Complemento

La instrucción final en esta discusión revertiría cada bit del registro que estipulamos. La sintaxis es: COMF, d donde

Comprensión de las operaciones de bits

Esto podría utilizarse, por ejemplo, para intercambiar rápidamente los pines de un puerto de salida a entrada, etc. Las funciones de bits nos permiten dar forma a un solo bit dentro de una expresión. Nos permiten proceder, configurar y deshacernos de bits individuales en registros o números que estipulemos.

Al final de este curso, revelaremos un programa diseñado para crear un conjunto de luces de secuencia que avanzan hacia adelante y luego hacia atrás. Observamos que esto se logró anteriormente cuando examinamos la función OR exclusiva, en la que aplicamos OR Exclusivamente a los puertos con una expresión. Hasta ahora hemos notado algunas funciones de bits cuando establecemos los puertos en el PIC, y

Permítanme reiterar su utilización aquí.

BCF

Esta instrucción borrará un bit que estipulemos en un registro que designemos. La sintaxis
es:
BCF,

Empleamos esto anteriormente para cambiar de la página 1 a la página 0 eliminando un bit en el registro STATUS. También podemos usarlo para fijar un bit a 0 en cualquier registro / ubicación diferente. Por ejemplo, en caso de que deseáramos establecer el tercer bit en 11001101 guardado en la sección 0C en 0, podríamos
insertar:

BCF 0C, 03

BSF

Esta instrucción fijaría cualquier bit que estipulemos en 1 en cualquier registro que indiquemos. Utilizamos esto anteriormente para pasar de la página 0 a la página 1. La sintaxis es: BSF ,, y se utiliza precisamente en el mismo método que BCF anterior.

BTFSC Hasta ahora podríamos establecer o borrar un bit en un registro. Sin embargo, imagínese si tenemos que comprobar básicamente si un bit es un 1 o un 0 en un registro.

Seguramente, es posible utilizar BTFSC. Indica el registro de prueba de bits F y omite si está despejado. Esta instrucción va a analizar el bit que designamos en el registro. En caso de que el bit sea un 0, la instrucción informaría al PIC que omita la instrucción subsiguiente.

Podríamos utilizar esta instrucción en caso de que deseáramos marcar una bandera, por ejemplo, la bandera de acarreo. Esto nos ahorra la necesidad de leer el registro STATUS y buscar los bits individuales para saber qué banderas están fijas. 29 Por ejemplo, en caso de que quisiéramos comprobar si el indicador Carry se estableció en 1 después de haber agregado 2 cifras, podríamos escribir lo siguiente:

BTFSC 03h, 0
continuar aquí si se establece en 1
o aquí si se establece en 0

En caso de que el estado del bit sea 1, en ese caso se completará la instrucción posterior a BTFSC. En caso de que se establezca en 0, en ese caso se omite la instrucción siguiente. La siguiente parte del código muestra en las que podría emplearse:

Lazo :
:
:
BTFSC 03,0
Ir a bucle

En el código anterior, el PIC simplemente saldrá del bucle en caso de que el bit 0 del registro STATUS (o el indicador Carry) esté definido en 0. De lo contrario, se ejecutará el comando goto.

BTFSS

Esta instrucción indica el registro de prueba de bits F y se omite si está establecido. Esto puede ser comparable a la instrucción BTFSC, aparte de que el PIC omitiría la instrucción subsiguiente si el bit que hemos estado evaluando se establece en 1, en lugar de 0.

CLRF

Esta instrucción fijaría todos los detalles de un registro en 0. La sintaxis es:

CLRF
Empleamos esto anteriormente para establecer la salida de los puertos en 0, aplicando CLRF 85h. Además, lo empleamos para arreglar los puertos para incluir todos los pines a la salida utilizando CLRF
05h.

CLRW

Esto podría parecerse a la instrucción CLRF, excepto que borra el registro W. La sintaxis es bastante simple:

CLRW

RLF y RRF

Estas direcciones transportarían un bit en un registro en una sola ranura hacia la izquierda (RLF) o hacia la derecha (RRF) en un registro. Por ejemplo, si necesitáramos 00000001 y empleáramos RLF, en ese caso podríamos poseer 00000010. En este punto, ¿qué ocurre en caso de que haya 10000000 y se aplique la instrucción RLF? Seguramente, el 1 estaría posicionado en la bandera de acarreo. En caso de que apliquemos la instrucción RLF una vez más, el 1 volvería a aparecer al principio. Lo mismo ocurre, sin embargo, al revés, para la instrucción RRF. El caso en el punto siguiente muestra esto para la instrucción RLF, en la que podemos ver los 8 bits de un registro, así como la bandera de acarreo:

C 87654321
0 00000001
RLF 0 00000010
RLF 0 00000100
RLF 0 00001000
RLF 0 00010000
RLF 0 00100000
RLF 0 01000000
RLF 0 10000000
RLF 1 00000000
RLF 0 00000001

Programa de ejemplo

Ahora veremos un código de ejemplo que se puede compilar y manejar. Generaría una luz de secuenciación comenzando en PortA bit 0, yendo a PortB bit 8 y
luego regresando.
Conecte los LED a cada uno de los pines del puerto. Tendremos un poco
procedimientos señalados en este tutorial.

TIME EQU 9FH Variable para el bucle de retardo.
PORTB EQU 06H Dirección del puerto B.
TRISB EQU 86H Puerto B Dirección tristate.
PORTA EQU 05H Port A address.
TRISA EQU 85H Puerto A Dirección Tristate.
STATUS EQU 03H Registro de selección de página.
COUNT1 EQU 0CH Registro de bucle.
COUNT2 EQU 0DH Registro de bucle.

ESTADO BSF, 5 Ir a la página 1
MOVLW 00H y configuración
MOVWF TRISB ambos puertos A y B
MOVLW 00H a la salida,
MOVWF TRISA luego regrese a
ESTADO BCF, 5 página 0.
MOVLW 00H Borrar puerto A.
PUERTA MOVWF

Inicio del programa principal

RUNMOVLW
01H Establecer el primer bit MOVWF
PORTB en el puerto B. LLAME
RETRASO Espere un momento LLAME
DEMORA
Mueva el bit en el puerto B a la izquierda, luego haga una pausa.
PORTB, 1CALL
RETRASO
DELAYRLF
PORTB, 1CALL
RETRASO
DELAYRLF
PORTB, 1CALL
RETRASO
DELAYRLF
PORTB, 1CALL
RETRASO
DELAYRLF
PORTB, 1CALL
RETRASO
DELAYRLF
PORTB, 1CALL
RETRASO
DELAYRLF
PORTB, 1CALL
RETRASO
DELAYRLF
PORTB, 1 Esto mueve el bit a la bandera de acarreo
Ahora vaya al puerto A y mueva el bit a la izquierda.
PORTA, 1 Esto mueve el bit del indicador cero a PortACALL
DELAYCALL DELAYRLF
PUERTA, 1 LLAMADA
RETRASO
DELAYRLF
PUERTA, 1 LLAMADA
RETRASO
DELAYRLF
PUERTA, 1 LLAMADA
RETRASO
DEMORA
Mueva el bit hacia atrás en el puerto ARRF
PUERTA, 1 LLAMADA
RETRASO
DELAYRRF
PUERTA, 1 LLAMADA
RETRASO
DELAYRRF
PUERTA, 1 LLAMADA
RETRASO
DELAYRRF
PORTA, 1 Esto mueve el bit a la bandera cero Ahora mueva el bit
de vuelta en el puerto BRRF
PORTB, 1CALL
RETRASO
DELAYRRF
PORTB, 1CALL
RETRASO
DELAYRRF
PORTB, 1CALL
RETRASO
DELAYRRF
PORTB, 1CALL
DELAYCALL DELAYRRF
PORTB, 1CALL
RETRASO
DELAYRRF
PORTB, 1CALL
RETRASO
DELAYRRF
PORTB, 1CALL
RETRASO
RETRASO Ahora estamos de vuelta donde empezamos, GOTO
CORRE vamos de nuevo.

Existe una gran opción en el conjunto de entrenamiento que le permite hacer uso de una tabla de datos.

Una tabla de datos es solo una lista de citas de datos, en la que se revisa todo en función de algunas consideraciones.
Por ejemplo, podría tener un circuito que utiliza un PIC que cuenta la cantidad de instancias en que un pin de entrada se vuelve alto en 1 segundo. Después de eso, puede exhibir el número en una pantalla de 7 segmentos.

Tan pronto como se inicia la sincronización, el PIC comienza a contar la cantidad de ocasiones en que el pin sube. Después de 1 segundo, visita la mesa y mira hacia arriba los datos; debe mostrar el número en la pantalla que simboliza la cantidad de situaciones en las que el pin se colocó alto. Esto puede ser beneficioso, ya que no determinamos cuál podría ser la cifra hasta que el PIC haya cumplido su estimación.

Al utilizar una tabla, podemos permitir que el PIC determine qué figura representar. En este punto, antes de continuar mostrándole cómo funciona la tabla de datos, es posible que tenga que decirle que el PIC mantiene la ruta del paradero en el programa mientras el programa está funcionando.

Facilita para quienes han realizado determinada programación en BASIC. De lo contrario, no se preocupe, es posible que desee seguir aprendiendo sobre la teoría. Imagine que hay un programa BÁSICO similar al que se presenta a continuación:

10 AÑOS K = 0
11 K = K + 1
12 SI K> 10 ENTONCES GOTO 20 ELSE GOTO 11
20 IMPRIMIR K
21 FIN

El programa comienza en la línea 10. Tan pronto como K está programado en 0, avanza a la línea 11. Después de haber incluido 1 a K, procedemos a la línea 12.

En este punto, podríamos tener curiosidad si K es mayor que 10. En caso de que lo sea, a continuación nos dirigimos a la línea 20, o bien volvemos a la línea 11.

La línea 20 documenta la K y la línea 21 concluye el programa. BASIC emplea estadísticas de línea para ayudar al programador a mantener un registro de dónde están los problemas, ya que las etiquetas no están autorizadas. El PIC emplea etiquetas para escapar entre destinos, ¿o puede realmente?

Utilizamos las etiquetas para asegurarnos de estar al tanto de dónde están los problemas, así como para asegurarnos de poder informar al PIC de una manera simple dónde buscar.

Precisamente lo que ocurre es que el PIC se aprovecha de un contador de línea interior llamado Contador de Programa. El contador de programa (abreviado como PC) sigue la pista del destino de la memoria donde se encuentra la instrucción actual.

Siempre que le informamos al PIC que visite una etiqueta seleccionada, este comprende el punto de memoria y, por lo tanto, aumenta la PC hasta que ve ese destino de memoria. Este es precisamente el mismo método que revisamos el programa BÁSICO anterior. A continuación se muestra un segmento de código, con los espacios de memoria, o los elementos de la PC, junto a cada instrucción:

Instrucción de PC0000 movlw 03
0001 movwf 0C
0002 Loop decfsc 0C
0003 goto Loop
0004 fin

En la demostración anterior, hemos fijado la PC en 0000. En esto tenemos la instrucción movlw 03. Cuando el PIC ha implementado estos datos, incrementa la PC para que se escanee la instrucción subsiguiente. En este punto, el PIC visualiza movwf 0C. La PC se incrementa una vez más.

Ahora el PIC estudia decfsc 0C. En caso de que los detalles de 0C no sean 0, en ese caso la PC se incrementa en 1, así como la siguiente instrucción, goto Loop, informa a la PC que regrese a la posición 0003, donde se encuentra dicho Loop. En caso de que los detalles de 0C sean 0, entonces se aconseja a la PC que incremente en 2, simplemente omita la instrucción siguiente.

Comprensión de las tablas de datos

Esto coloca la PC en la posición 0004, donde finaliza el programa. Los destinos los fija el ensamblador y, en general, no deberíamos preocuparnos por lo que está logrando la PC. Hasta que, encontramos la necesidad de tenerlo bajo control al igual que lo hacemos cuando utilizamos tablas de datos. La forma más conveniente de describir cómo funciona una tabla de datos es comenzar con una ilustración.

PC equ 02
movlw 03
tabla de llamadas
:
mesa addwf PC
retlw 01
retlw 02
retlw 03
retlw 04
retlw 05
retlw 06
retlw 07
regreso

La instrucción inicial es asignar la etiqueta PC con la dirección del Contador de Programa (02h). Lo haremos poco después de poner el valor de 03h en el registro w. Después de eso nos comunicamos con la mesa. La línea principal de la tabla de subrutinas aumenta los detalles del registro W (03h) al contador del programa.

Esto hace que el contador del programa suba en 3 o, para decirlo de otra manera, estimula el contador del programa para que avance 3 líneas. Mientras el contador llega 3 líneas hacia abajo, el PIC reconoce la instrucción retlw. Este comando envía el valor que le sigue al registro W, después de lo cual vuelve de la subrutina. RETLW básicamente significa Retorno, literal a W.

Vea que coloqué una coma después de la palabra Retorno. Como estamos en una subrutina, necesitamos una instrucción de retorno para que salga a la superficie. Por lo tanto, el RET en la instrucción. Después de la instrucción RETLW hay un número, y esto es exactamente lo que se coloca en el registro W.

En este caso es la figura 3. Podríamos designar cualquier cantidad al registro W, siempre que esta figura se combine con el Contador de Programa en la subrutina de la tabla, vamos a descubrir una instrucción retlw. En la ilustración anterior, esto implica que podemos poseer cualquier número del 1 al 7. En caso de que procedamos más allá de la subrutina, es posible que podamos terminar de realizar una sección adicional del programa. Por esta razón, normalmente es una decisión inteligente colocar la tabla de datos exactamente hacia el final del programa PIC, por lo tanto, si nos sobrepasamos en ese caso, llegaremos a la conclusión del programa de todos modos.

El tema de las interrupciones puede ser el más largo y difícil de abordar.

No puede encontrar ningún método sencillo para detallar las interrupciones; sin embargo, con un poco de suerte hacia el final de esta parte, es posible que pueda aplicar interrupciones en sus propios programas.
Hemos separado la sección en 2 etapas. Eso es para permitir separar el tema en secciones, también para proporcionarle una práctica plit para una fácil comprensión.

¿Qué es exactamente una interrupción? Seguramente, como indica el término, una interrupción es una técnica o una señal que impide que un microprocesador / microcontrolador realice cualquier cosa que esté realizando, que podría suceder algo diferente.

Permítame darle una ilustración diaria. Piense que se está relajando en su propia casa, conversando con otra persona. De repente suena el teléfono.

Dejas de hablar y tomas el teléfono para hablar con la persona que llama. Una vez que tiene su interacción telefónica, decide volver a conversar con la persona antes de que sonara el teléfono. Es posible considerar la rutina principal mientras conversa con alguien, el timbre del teléfono interrumpe su conversación y la interrupción de la rutina es el método de hablar por teléfono.

Mientras la conversación telefónica llega a su fin, regresa a su rutina principal de charlar. Esta ilustración es precisamente cómo interrumpe un procesador para que actúe.

El programa principal está en funcionamiento, llevando a cabo cierta función en un circuito, sin embargo, cuando se produce una interrupción, el programa principal se detiene mientras se realiza una rutina diferente. finaliza la rutina, el procesador vuelve a la rutina primaria como antes.

Entender las interrupciones

El PIC posee 4 fuentes de interrupción. Podrían dividirse en un par de grupos. Dos son fuentes de interrupciones que se pueden utilizar externamente al PIC, mientras que las otras dos son procesos internos. Permítanme aclarar los dos tipos externos aquí. Los otros dos se describirán en diferentes tutoriales una vez que lleguemos a los temporizadores y al almacenamiento de datos.

Si revisa el pin-out del PIC, notará que el pin 6 es RB0 / INT. En este punto, RB0 es claramente el bit 0 del puerto B. El INT representa que también podría configurarse como un pin de interrupción externo. Además, los pines 4 a 7 del puerto B (pines 10 a 13) también se pueden utilizar para interrupciones. Antes de que podamos emplear los pines INT u otro puerto B, debemos realizar dos tareas. Primero debemos informar al PIC que utilizaremos interrupciones.

A continuación, debemos designar qué pin del puerto B vamos a utilizar como una interrupción en lugar de un pin de E / S. Dentro del PIC puedes encontrar un registro conocido como INTCON, y está en la dirección 0Bh. En este registro descubrirá 8 bits que pueden estar habilitados o deshabilitados. El bit 7 de INTCON se conoce como GIE. Esta es la habilitación de Interrngupt Global. Fijar esto en 1 informa al PIC que emplearemos una interrupción.

El bit 4 de INTCON se conoce como INTE, INTerrupt Enable. Poner este bit en 1 transmite al PIC que RB0 será un pin de interrupción. La configuración del bit 3, llamado RBIE, informa al PIc que vamos a utilizar los bits del puerto B 4 a 7. En este punto, el PIC comprende cuándo este pin puede estar alto o bajo, debe detener lo que está funcionando y proceder con una interrupción. rutina. En este punto, debemos informar al PIC si la interrupción probablemente estará en el borde ascendente (0V a + 5V) o en el borde descendente (+ 5V a 0V) de la transformación de la señal.

En pocas palabras, deseamos que el PIC interrumpa cada vez que la señal se mueva de baja a alta o de alta a baja. Por morosidad, se puede establecer que se coloque en el borde ascendente.

El 'disparo' del flanco está programado en un registro adicional llamado registro OPCIÓN, en la dirección 81h. El bit que nos entusiasma es el bit 6, a menudo denominado INTEDG.

Establecer esto en 1 activa el PIC para interrumpir en el borde de montaje (estado predeterminado) y establecerlo en 0 estimula al PIC para interrumpir en el borde deslizante. Si desea que el PIC se active en el borde ascendente, entonces ciertamente no tiene que hacer nada en este momento.

En este punto, lamentablemente, el registro de opciones está en el banco 1, lo que significa que disfrutamos de modificar del banco 0 al banco 1, establecer el bit en el registro de opciones y luego volver al banco 0. La clave aquí es realizar cada bit. del Banco 1 se registra en un solo golpe, por ejemplo, estableciendo los pines del puerto, luego regresa al Banco 0 si ha terminado.

Bien, en consecuencia, hemos notificado al PIC qué pin probablemente será la interrupción y dónde se disparará el borde, ¿qué sucede en el programa y en el PIC cada vez que ocurre la interrupción? Ocurren un par de cosas. En primer lugar, se programa una 'bandera'.

Esto informa al procesador interno del PIC que ha ocurrido una interrupción. A continuación, el contador del programa (del que hablé en el tutorial anterior) apunta a una dirección específica dentro del PIC. Echemos un vistazo rápido a todos estos de forma individual. Bandera de interrupción En nuestro registro INTCON, el bit 1 es la bandera de interrupción, llamada INTF. En este punto, siempre que surja una interrupción, es probable que este indicador se fije en 1.

Cuando no hay una interrupción, la bandera se coloca en 0. Además, casi todo se logra. En este punto, es posible que se esté preguntando '¿cuál es el punto?'. Seguramente, aunque esta bandera está programada para 1, el PIC no puede reaccionar, y no lo hará, a otra interrupción. Por tanto, expresemos que provocamos una interrupción. La bandera probablemente se fijará en 1 y el PIC podría ir a nuestra rutina para trabajar la interrupción.

Cuando esta bandera no estaba fijada a 1, y se le permitió al PIC continuar respondiendo a la interrupción, entonces presionar continuamente el pin podría hacer que el PIC regresara al comienzo de nuestra rutina de interrupción, y de ninguna manera completarla. Volviendo a mi ilustración del teléfono, es similar a levantar el teléfono e inmediatamente una vez que se procede a hablar, comienza a sonar de nuevo, ya que otra persona desea hablar con usted.

Es recomendable completar un diálogo y luego tomar el teléfono nuevamente para hablar con la persona siguiente. Puede encontrar un pequeño problema con esta bandera. Aunque el PIC establece rápidamente este indicador en 1, ¡no lo vuelve a establecer en 0! Esa actividad debe ser ejercida por el programador, es decir, usted. Esto se puede lograr sin esfuerzo, ya que estoy seguro de que, y debe lograrse después de que el PIC haya llevado a cabo la rutina de interrupción.

Ubicación de la memoria Siempre que encienda inicialmente el PIC, o en caso de que exista un reinicio, el contador de programa se inclina a la dirección 0000h, que podría estar inmediatamente al comienzo de la memoria del programa. Pero, en el caso de que haya una interrupción, el Contador de Programa indicaría la dirección 0004h.

Por lo tanto, mientras redactamos nuestro programa que tendrá interrupciones, primero debemos informar al PIC que salte la dirección 0004h y mantenga la rutina de interrupción que comienza en la dirección 0004h discreta del resto del programa.

Esto puede ser sencillo de realizar. Inicialmente, comenzamos nuestro programa con un comando conocido como ORG. Este comando indica Origen o inicio. Nos ceñimos a ella con una dirección. Dado que el PIC comienza en la dirección 0000h, escribimos ORG 0000h. Después de eso, debemos omitir la dirección 0004h. Logramos esto colocando una instrucción GOTO, acompañada de una etiqueta que da consejos a nuestro programa principal.

Después de eso nos adherimos a este comando GOTO con un ORG más, este momento con la dirección 0004h. Será después de este comando que insertemos nuestra rutina de interrupción. En este punto, posiblemente podamos escribir nuestra rutina de interrupción directamente después del segundo comando ORG, o podemos colocar una instrucción GOTO que apunte a la rutina de interrupción.

Realmente está relacionado con la opción de su parte. Para informar al PIC que ofrece llegado la conclusión de la rutina de interrupción debemos posicionar el comando RTFIE hacia el final de la rutina. Este comando significa el regreso de la rutina de interrupción. Mientras que el PIC se da cuenta de esto, el contador de programa indica la posición final en la que se encontraba el PIC antes de que ocurriera la interrupción. Hemos establecido a continuación una breve sección de código para mostrar lo anterior:

Hay un par de cosas de las que debe estar informado al utilizar interrupciones. La inicial tiende a ser que si está utilizando el registro idéntico en su programa principal y la rutina de interrupción, tenga en cuenta que los detalles del registro probablemente se alterarán cuando se produzca la interrupción.

Por ejemplo, utilicemos el registro w para reenviar datos al programa principal del puerto A, por lo tanto, puede utilizar adicionalmente el registro w en la rutina de interrupción para cambiar los datos de un destino a otro.

En caso de que no tenga cuidado, el registro w incluiría el último valor que recibió mientras estuvo en la rutina de interrupción, por lo que cuando regrese de la interrupción, esta información se enviará al puerto A en lugar del valor que poseía antes. ocurrió la interrupción.

El medio en torno a esto es guardar momentáneamente los detalles del registro w antes de utilizarlo una vez más en la rutina de interrupción. El segundo es el hecho de que puede encontrar un retraso entre el momento en que se produce una interrupción y el momento en que puede surgir la siguiente. Si bien lo entiende, el PIC posee un reloj exterior, que posiblemente podría ser un cristal o podría ser una combinación de resistencia-condensador.

No importa cuál sea la frecuencia de este reloj, el PIC lo divide por 4 y luego lo utiliza para su sincronización interna. Por ejemplo, en caso de que tenga un cristal de 4MHz vinculado a su PIC, en ese caso, el PIC ejecutará las instrucciones a 1MHz. Esta sincronización interior se conoce como ciclo de instrucción. En este punto, la hoja de datos afirma (sin duda en letra diminuta) que necesita habilitar de 3 a 4 rondas de instrucciones entre interrupciones.

Mi sería habilitar 4 rondas. La razón detrás de la demora es que el PIC requiere tiempo para saltar a la dirección de interrupción, la bandera y regresar lejos de la rutina de interrupción. Por lo tanto, tenga esto en cuenta si trabaja con un circuito alternativo para activar una interrupción para el PIC.

En este punto, un punto es el hecho de que si utiliza los bits 4 a 7 del puerto B como interrupción. No puede elegir pines específicos en el puerto B para que funcionen como una interrupción.

Por lo tanto, en caso de que permita estos pines, es probable que estén todos disponibles. Por lo tanto, por ejemplo, no puede simplemente tener los bits 4 y 5; es probable que los bits 6 y 7 estén habilitados al mismo tiempo. ¿Cuál es exactamente el propósito de obtener cuatro bits para representar una interrupción? Seguramente, es posible que tenga un circuito conectado al PIC, en caso de que cualquiera de las cuatro líneas se eleve, en ese caso, esto puede ser un problema en el que necesite que el PIC influya instantáneamente.

Una ilustración de esto podría ser una alarma de seguridad doméstica, en la que cuatro sensores están conectados a los pines 4 a 7 del Puerto B. Cualquier sensor específico puede hacer que el PIC active una alarma, y ​​la rutina de señalización de alarma es la rutina de interrupción. Esto evita la revisión constante de los puertos y permite que el PIC continúe con diferentes asuntos. En el siguiente tutorial, vamos a componer un programa para gestionar una interrupción.

Nos ocupamos de muchos conceptos básicos en el último tutorial, por lo que creo que ha llegado el momento de componer nuestro primer programa.

El programa que escribiremos contará la cantidad de ocasiones en que encendemos un interruptor y luego mostraremos el número.

El programa contará de 0 a 9, visible en 4 LED en forma binaria, junto con la entrada o interrupción probablemente estará en RB0.

Lo primero que debemos hacer es informar al PIC que salte la dirección a la que apunta el Contador de Programa cada vez que se produce una interrupción.

Observará que estamos empleando un método único para exhibir números hexadecimales. Antes de que sucediera, aplique F9h en el que h indicaba hexadecimal. Podríamos escribir esto como 0xF9, que es la estructura que vamos a emplear a partir de ahora.

Ahora necesitamos decirle al PIC que vamos a usar interrupciones, y estamos usando el pin 6 de RB0 como pin de interrupción:

bsf INTCON, 7GIE - Habilitación de interrupción global (1 = habilitada)
bsf INTCON, 4INTE - Habilitación de interrupción RB0 (1 = habilitación)
Voy a borrar la bandera de interrupción por si acaso (¡nunca confío en nada!)
bcf INTCON, 1INTF - Borrar bit de bandera por si acaso

Actualmente debemos establecer nuestros 2 puertos. Tenga en cuenta que como ahora estamos utilizando RB0 como un pin de interrupción, esto debe establecerse como una entrada:

Vamos a utilizar una variable llamada COUNT para almacenar el número de recuentos de conmutadores. Simplemente podríamos incrementar el valor en el puerto A, pero verá por qué estoy usando una variable cuando escribimos nuestra rutina de interrupción.

Por lo tanto, nuestro programa principal está compuesto, y en este punto debemos informar al PIC cómo proceder siempre que se produzca una interrupción. En este ejemplo, nuestra interrupción probablemente será el interruptor. Justo lo que nos gustaría que hiciera el PIC es uno para el COUNT ajustable cada vez que el interruptor está confinado.

Sin embargo, solo deseamos mostrar cuántas veces el interruptor se apaga de 0 a 9. Anteriormente, dije que podríamos haber simplemente incrementado el valor en el puerto A cada vez que hay una interrupción. Sin embargo, el puerto A tiene 5 bits, en caso de que simplemente incrementemos el puerto, vamos a poseer el conteo más alto de 31. Hay un par de explicaciones por las que seleccioné no moverme hasta 31.

Inicialmente, emplearemos una pantalla de 7 segmentos, que como máximo solo podría ir de 0 a 15 (0 a F en hexadecimal). A continuación, también deseo mostrarle algunos de los comandos aritméticos con los que tropezó en las últimas lecciones.

Por tanto, continuaremos con nuestra rutina de interrupción. Actualmente, lo primero que debemos lograr es almacenar brevemente los detalles de nuestro registro w, ya que lo hemos estado aplicando para cambiar el contenido de COUNT a PORTA. En caso de que no lo guardemos, en ese caso podríamos entregar un número totalmente diferente debido a nuestra aritmética. Por lo tanto, logremos eso primero:

En este punto entendemos si el valor de COUNT es 9 o más. Justo lo que tenemos que lograr ahora es si COUNT es más de 9, volver a colocarlo en 0, o bien regresar al programa principal para asegurarnos de que podamos entregarlo al puerto A. El comando BTFSS, ya que entiende, sería el siguiente
instrucción en caso de que la bandera de acarreo esté programada, es decir, COUNT = 10:

Lo único que queda por hacer ahora es ingresar colectivamente y determinar valores para nuestras constantes, lo que podemos realizar desde el comienzo de nuestro programa.

Cada vez que active el interruptor, los LED contarán en binario de 0000 a 1010 y luego volverán a 0000.

La siguiente figura muestra el diagrama de circuito compatible con el código explicado anteriormente. Curiosamente, encontrará que el condensador de sincronización se ha incluido en el diseño. Esta es una pequeña y agradable táctica a través de la cual tienes la libertad de evitar la inclusión del capacitor en caso de que no tengas ninguno contigo durante ese tiempo.

Aquí la capacitancia entra en juego a través de la capacitancia parásita a través del pin del oscilador y la tierra.
Por supuesto, puede que no parezca una forma muy inteligente de evitar un condensador en la práctica, ya que el valor parásito puede variar con diferentes condiciones dadas.

Otra sección que se puede ver en el circuito es la red de denuncia a través del conmutador. Esto evita la interferencia durante la conmutación mecánica y evita que el PIC se confunda si la conmutación fue una palanca única o múltiples.




Artículo anterior: Circuito temporizador de motor bidireccional programable Siguiente: Cómo funcionan los circuitos Buck-Boost