Parte 2 – Introducción a la programación en assembler con el PIC16F877A
Tiempo total: 32 días con 11:12:17 hrs
En esta publicación se explican las instrucciones de ensamblador utilizando la hoja de datos del PIC16F877A, empezando con el parpadeo de un led y calculando el tiempo de retardo para el ejemplo.
Datasheet
La hoja de datos del microcontrolador utilizada es la siguiente:
http://www.utp.edu.co/~eduque/arquitec/PIC16F877.pdf
Ejemplo 1: encendido de led
La siguiente imagen muestra el código a explicar:
Las primeras dos instrucciones indican el tipo de procesador y la librería a utilizar.
LIST p=16F877A
INCLUDE
A continuación, antes de escribir el programa debemos de establecer las siguientes instrucciones:
ORG 0x00
GOTO INICIO
ORG 0X04
; rutina de interrupción
ORG 0x05
INICIO
…
Básicamente, ORG 0x00 indica en donde debe de iniciar el programa una vez el PIC16F877A ha sido reiniciado, ORG 0x04 sirve para escribir las instrucciones necesarias en el caso que suceda una interrupción (una instrucción con más valor que las instrucciones de nuestro programa), y por ultimo ORG 0x05 indica en donde inicia el código de nuestro programa. Por la razón que las instrucciones a utilizar son simples, este código lo omito del ejemplo.
Las siguientes instrucciones son la definición de variables; en la página 13 de la hoja de datos observamos la distribución de la memoria RAM del microcontrolador, observando que para utilizar las variables ubicadas en las direcciones 0x20 y 0x21 (como las hemos definido), debemos de estar en el banco0 (se explica más adelante). En resumen, las variables de nuestro programa deben de estar en las direcciones de propósito general del banco 0 (de x20h a 7fh).
CONT1 EQU 0x20
CONT2 EQU 0x21
La instrucción BCF significa bit clear f, su sintaxis es BCF m,n y su función es poner a cero el bit n de la variable m; en este caso la variable RP0 es el bit 5 y RP1 es el bit 6, en este caso los bits 5 y 6 son los que se encargan de la selección de página para el direccionamiento directo de la memoria de datos (2do párrafo, página 15 del datasheet); la selección de pagina se refiere a la distribución por bancos indicados en la página 13 del datasheet.
Para saber que página se selecciona, se usan números binarios, así RP0=1 y RP1=1 es el decimal 3, RP0=0 y RP1=1 es 2 y más.
BCF STATUS,RP0 ; Accede a banco 0
BCF STATUS,RP1
La instruccion CLRF significa clear f y pone a 0 todos los bits de la variable indicada. En este caso, observamos PORTA que pertenece al banco 0, motivo por el cual configuramos los bits RP0 y RP1 de la variable STATUS en las instrucciones anteriores.
El cambio de valor de PORTA en tiempo real representa el estado de las patitas del microcontrolador; dado que PORTA es de 6 bits (página 16 del datasheet), si su valor es 111000 significa que las patas PORTA0, PORTA1, PORTA2 tienen un valor de 0V, y las patas PORTA3, PORTA4, PORTA5 tienen un valor de 5v.
CLRF PORTA ; Limpia PORTA
La instrucción BSF (bit set f), pone el bit RP0 de la variable STATUS a 1, es decir que le indicamos al PIC que utilizaremos ahora las variables del banco 1 (página 13 del datasheet).
BSF STATUS,RP0 ; Accede a banco 1
Observamos ahora que trabajamos con la variable TRISA que forma parte del banco 1; CLRF pone a 0 todos los bits de la variable TRISA, la cual se utiliza para indicar que patitas son entradas (valor 1) y cuales son salidas (valor 0). Entrada significa que el PIC recibirá un voltaje de 0V o 5V de una fuente externa, salida significa que el PIC enviara un valor de 0V o 5V a una de sus patas para una fuente externa.
CLRF TRISA ; Configura todas las patitas de PORTA como salidas
Ahora, regresamos al banco 0:
BCF STATUS,RP0 ; Regresa a banco 0
El siguiente bloque de instrucciones, inicia con la palabra LED, la cual es la etiqueta que representa el conjunto de instrucciones que le precede. BSF PORTA,0 pone a 1 el bit 0 de PORTA (cambia de 0V a 5V la patita PORTA0), significa que el led encenderá.
LED BSF PORTA,0 ; La línea RA0 de PORTA toma el valor de 1, se enciende el LED
Ahora, observamos CALL RETARDO, significa que las siguientes instrucciones a ejecutar son las que preceden a la etiqueta RETARDO.
CALL RETARDO ; Llamada a la rutina de retardo
Y básicamente, las instrucciones se vuelven a repetir, apagando y encendiendo el led mientras se llama a un retardo y se repiten de nuevo las instrucciones que preceden a la etiqueta LED.
BCF PORTA,0 ; La línea RA0 de PORTA toma el valor de 0, se apaga el LED
CALL RETARDO ; Llamada a la rutina de retardo
GOTO LED ; Va a la etiqueta Encled
En el bloque de instrucciones de RETARDO, observamos las instrucciones MOVLW y MOVWF. Estas dos instrucciones funcionan de la siguiente manera, MOVLW mueve el valor indicado .255 (decimal 255, en hexadecimal es FF y en binario son ocho unos) a la variable W; MOVWF mueve el valor de W a la variable indicada (CONT1). Recordemos que el máximo valor que una variable maneja es de 8bits, que es 255 decimal o FF en hexadecimal.
RETARDO MOVLW .255 ; w = xFF
MOVWF CONT1 ; cont1 = w
También observamos la instrucción DECFSZ, que significa decrementar el valor de la variable indicada y saltar la siguiente instrucción si el resultado es cero.
REP2 DECFSZ CONT2,1 ; si cont2=cont2-1 es cero, salta
GOTO REP2 ; hacia etiqueta REP2
Tiempo de retardo
El código para retardar el apagado y encendido del led es el siguiente:
A continuación analizamos el tiempo que cada instrucción toma para ejecutarse:
Aquí tenemos que todas las instrucciones consumen una unidad de tiempo, a diferencia de la instrucción GOTO que consume 2 unidades de tiempo. En el cálculo, DECFSZ consume 1(X-1) unidades de tiempo, y en la última vez que se ejecute CONT2 será cero y llamara a una instrucción GOTO o bien, realizara un salto a la siguiente instrucción, por este motivo DECFSZ consume 1(X-1)+2 unidades de tiempo.
Si observamos bien, la ecuación final de unidades de tiempo es la siguiente:
=2 + N(2+1(M-1) + 2 + 2(M-1)) + 1(N-1) +2 + 2(N-1)
=2 + N(1+3M) + 3N – 1
=1 + 4N + 3NM
Significa que si el valor de N y M son 255, y si utilizamos un cristal de 4MHz significa que cada unidad de tiempo es de 1uS, entonces F(N,M) para N y M igual a 255, el tiempo de retardo es igual a 196096uS = 0.196096 segundos.
Parte 3
En la siguiente parte se explicara cómo utilizar el Datasheet para entender las instrucciones y la asignación de valores a las variables del PIC16F877 antes de llamar alguna instrucción o asignar valores a otras variables; se utilizara el ejemplo de encender y apagar una secuencia de leds, así como también como utilizar el convertidor analógico digital CAD.
Para ver la parte 3, por favor sigue el siguiente enlace:
Parte 1
Para ver la parte 1, por favor sigue el siguiente enlace:
Referencias
[http://www.utp.edu.co/~eduque/arquitec/PIC16F877.pdf]
[http://perso.wanadoo.es/luis_ju/pic3/pic3_reg.html]
[http://www.circuitoselectronicos.org/2009/04/ejemplos-sencillos-para-el.html]
[http://micropic.galeon.com/instrucciones.htm#call]
[https://es.wikipedia.org/wiki/PIC16F87X]
[http://perso.wanadoo.es/luis_ju/pic/pic04.html]
[https://es.wikipedia.org/wiki/Se%C3%B1al_anal%C3%B3gica]
[https://www.youtube.com/watch?v=5xvxQvLghW0]
[https://www.youtube.com/watch?v=k3w2F857jq4]
[https://www.youtube.com/watch?v=iwGHgkpRUew]
[https://www.youtube.com/watch?v=O_6NIm6encw]
[https://www.youtube.com/watch?v=sEfSu9Szjv8]
[https://carlosalbertosainz.wordpress.com/2014/04/28/practica-4-manejo-del-convertidor-analogico-digital/]
[http://tutor.al-williams.com/pic-inst.html]
[http://www.circuitoselectronicos.org/2011/02/retardos-por-software-en-los.html]
[http://es.ncalculators.com/digital-computation/hex-decimal-converter.htm]
[http://es.ncalculators.com/digital-computation/binary-decimal-converter.htm]
[http://www.binaryhexconverter.com/hex-to-binary-converter]
[http://www.wolframalpha.com]
[http://www.todopic.com.ar/foros/index.php?topic=36505.0]
[http://www.solodrivers.com/manuales/programacion_ensamblador8]