Universidad Tecnológica de Querétaro

Anuncio
Universidad
Tecnológica de
Querétaro
Firmado digitalmente por Universidad Tecnológica
de Querétaro
Nombre de reconocimiento (DN): cn=Universidad
Tecnológica de Querétaro, o=Universidad
Tecnológica de Querétaro, ou,
[email protected], c=MX
Fecha: 2011.08.31 09:54:12 -05'00'
Manual de Lenguaje Ensamblador para el PIC18F252
UNIVERSIDAD TECNOLÓGICA
DE QUERÉTARO
Manual de Lenguaje Ensamblador para el PIC18F252
Empresa:
A y B AUTOMATIZACIÓN
Memoria
Que como parte de los requisitos para obtener el título de:
TÉCNICO SUPERIOR UNIVERSITARIO EN
MECATRÓNICA ÁREA AUTOMATIZACIÓN
Presenta
Andrés Castelán Acosta
Ing. R. Jesús Tapia Armas
Asesor de la UTEQ
Ing. Ernesto Alonso Partida
Asesor de la Empresa
Santiago de Querétaro, Qro, Agosto 2011
0
RESUMEN
El proyecto consiste en un manual para la programación de
microcontroladores
en
lenguaje
ensamblador,
incluyendo
ejemplos
de
programación; para esto es necesario conocer las instrucciones del lenguaje
ensamblador, sus funciones, la manera de redactarlo, las características
propias de los Microcontroladores que se vayan a utilizar, algebra booleana y
saber estructurar problemas diagrama de flujo; al saber conjuntar estos
conocimientos se logra obtener un mayor dominio en la resolución de
problemas lógico-matemáticos y al usar en particular este lenguaje se facilitarán
otros software de programación más avanzados; en conclusión se llega a
obtener una mejor perspectiva en la resolución de problemas, no solo
matemáticos o lógicos, sino en general, las actividades en la estadía no solo se
limitaron a la realización de un manual, sino, de diversas actividades más,
como: cableado eléctrico de diversas máquinas, diseño de prototipos de
herramentales, visitas a diversas empresas para instalar, dar mantenimiento o
reparar maquinas, etc.; que también brinda mucho experiencia y conocimientos.
1
ABSTRACT
The elaboration of an assembler language programming manual is presented in
this document; examples are included so the reader can learn how to write
instructions, functions and its syntax. It is devoted to the characteristics of
several microcontrollers, Boole algebra, structure and flow diagramming. If we
grab this knowledge, we will get greater dominion in math-logic problem solving
too. It is also easier learning advanced programming after this language.
Summarizing: we can have a better sight in problem solving, not only math or
logic but in general. During this period in the industry, other activities have been
made: tool prototyping, client visiting, machinery electric cabling, maintenance
and repair. All those are sources of knowledge and experience.
2
INDICE
Página
Resumen
1
Abstract
2
Índice
3
I. INTRODUCCIÓN
4
II: ANTECEDENTES
4
III. JUSTIFICACIÓN
5
IV. OBJETIVOS
5
V. ALCANCE
6
VI. FUNDAMENTACIÓN TEÓRICA
6
VII. PLAN DE ACTIVIDADES
10
VIII. RECURSOS MATERIALES Y HUMANOS
12
IX. DESARROLLO DEL PROYECTO
13
X. RESULTADOS OBTENIDOS
32
XI. ANÁLISIS DE RIESGO
32
XII. CONCLUSIONES
33
XIII. RECOMENDACIONES
33
XIV. REFERENCIAS BIBLIOGRÁFICAS
34
ANEXO 1
35
3
I. Introducción
El siguiente reporte consiste en la elaboración de un manual de lenguaje
ensamblador enfocado principalmente para el microcontrolador PIC18F252 de
Microchip, el nivel del manual es considerado para principiantes o básico.
Muchas veces se llegan
sencillas,
y
una
solución
a resolver problemas grandes con soluciones
sencilla
puede
ser
la
implementación
de
Microcontroladores, con este se pueden hacer conversiones de binario a
decimal y desplegar el dato en display o LCD, tomar señales de sensores o
interruptores y activar señales de salida cuando ciertas condiciones se cumplan,
adquirir y mandar datos mediante el protocolo RS-232, etc., y así como estas
hay muchas aplicaciones, pero para poderlas desarrollarlas es necesario tener
el conocimiento del equipo que se va a utilizar, es por esto que se decide hacer
un manual para aquellos que deseen hacer aplicaciones de este tipo.
II. Antecedentes
En las diferentes empresas, talleres y en las mismas
instituciones
escolares se presentan problemas de automatización, acondicionamiento de
señal, conversiones de sistemas numéricos u otras cosas, y muchas veces las
personas encargadas de realizar dicha actividad no encuentran la manera de
atacar el problema o la forma de hacerla resulta muy costoso o compleja, es por
eso que se decide hacer un manual de lenguaje ensamblador para
Microcontroladores como opción a resolver problemas de esta índole.
4
III. Justificación
Para poder entender y aplicar los alcances de un Microcontrolador y lo
que puede llegar a hacer es necesario saber la arquitectura del mismo
hardware, las instrucciones y funciones que requiere y usar el software, y tener
una mente ingeniosa, porque teniendo lo anterior, la única limitación es el
programador; aunque pareciera que esto está enfocado únicamente a la
informática, también se deben tener conocimientos electrónica, programación,
sensores, matemáticas y diversas materias en común; es por eso que se hace
un manual para poder guiar de manera sencilla y completa en la programación
básica.
IV. Objetivos

Desarrollar un manual de lenguaje ensamblador para un PIC en
particular con un nivel de conocimientos adecuado para ser considerado
para nivel bajo o principiante.

Un manual con 4 ejemplos explicados paso a paso cada uno con
diagrama de flujo e imágenes que faciliten la interpretación, así también
las características del principales Microcontrolador.
5
V. Alcances
Conocer la programación en el lenguaje, tanto de instrucciones como
conocer los aspectos que son necesarios para programar algún otro
Microcontrolador. Poder desarrollar programas sencillos, como el encendido y
apagado de un LED, hasta conversión de BCD a 7 segmentos, así como
también la compilación, simulación y programación del PIC, todo esto enfocado
a dar ser otra opción para la resolución de problemas de automatización.
VI. Fundamentación teórica
Sistemas digitales: Es una combinación de dispositivos diseñados para
manipular cantidades físicas o información que estén representadas en forma
digital, es decir que solo pueden tomar valores discretos. Los sistemas digitales
utilizan el sistema de numeración binaria, el cual cuanta con solo dos números,
el 0 nivel bajo y el 1 nivel alto o bits. Un bit es una señal electrónica que puede
estar encendida (1) o apagada (0). Es la unidad más pequeña de información
que utiliza un ordenador. Son necesarios 8 bits para crear un byte.
Para la implementación de los circuitos digitales, se utilizan puertas
lógicas (AND, OR y NOT), estas puertas siguen el comportamiento de algunas
funciones del Álgebra de Boole.
Sistema Binario: En el sistema Binario o de base 2, cuanta solamente con dos
dígitos el 0 y el 1, empezamos con el 0 y después el 1, y para formar un número
más grande, se van añadiendo 0 y 1 la izquierda del número que ya tenemos.
6
En el sistema binario sólo puede haber dos valores para cada dígito: un 0=
desactivado ó un 1= activado. En la figura 6.1 se muestra la conversión de
sistema binario a hexadecimal y decimal.
Figura 6.1. Tabla de conversión
Lenguaje ensamblador: El lenguaje ensamblador es un lenguaje de
programación de bajo nivel para las computadoras, microprocesadores,
Microcontroladores, y otros circuitos integrados programables.
Características
El código escrito en lenguaje ensamblador posee una cierta dificultad de
ser entendido ya que su estructura se acerca al lenguaje máquina, es decir, es
un lenguaje de bajo nivel.
Con el lenguaje ensamblador se tiene un control muy preciso de las
tareas realizadas por un microprocesador por lo que se pueden crear
segmentos de código difíciles y/o muy ineficientes de programar en un lenguaje
7
de alto nivel, ya que, entre otras cosas, en el lenguaje ensamblador se dispone
de instrucciones del CPU que generalmente no están disponibles en los
lenguajes de alto nivel.
El lenguaje ensamblador cuenta con un juego de instrucciones y estas se
pueden dividir en grupos:

CISC (Complex Instruction Set Computer): Juego de Instrucciones
Complejo, más de 80 instrucciones

RISC (Reduced Instruction Set Computer): Juego de Instrucciones
Reducido, unas 35 instrucciones. Los Microcontroladores PICmicro son
de este tipo.

SISC (Specific Instruction Set Computer): Juego de Instrucciones
Específico, para una mejor presentación las instrucciones se pueden
clasificar según la función que desempeñan en un programa.
Microcontrolador: Un Microcontrolador es un dispositivo electrónico capaz de
llevar a cabo procesos lógicos. Estos procesos o acciones son programados en
lenguaje ensamblador por el usuario, y son introducidos en este a través de un
programador.
Diagramas de flujo: Un diagrama de flujo u organigrama es una
representación diagramática que ilustra la secuencia de las operaciones que se
realizarán para conseguir la solución de un problema. Los diagramas de flujo se
dibujan generalmente antes de comenzar a programar el código frente a la
computadora. Los Diagramas de flujo se dibujan generalmente usando algunos
8
símbolos estándares. Algunos símbolos estándares, que se requieren con
frecuencia para diagramar programas de computadora se muestran a
continuación:
Inicio o fin del programa
Pasos, procesos o líneas de instrucción de
programa de cómputo
Operaciones de entrada y salida
Toma de decisiones y Ramificación
Líneas de flujo
Display, para mostrar datos
Envía datos a la impresora
Tabla 6.1. Simbología de diagrama de flujo
9
VII. Plan de Actividades
El plan de actividades fue concebido tomando en cuenta los aspectos
para la realización de un manual de lenguaje ensamblador a nivel básico o
principiante, estos aspectos fueron analizados para la obtención del manual y
representados en una gráfica de Gantt. Se realizó una lista numerando las
actividades, la gráfica de Gantt corresponde a la figura 7.1.
1. Asignación del proyecto: Se plantea el proyecto, es decir lo que se va a
realizar durante la estadia.
2. Investigar sobre el microcontrolador a utilizar: Asignado el proyecto, se
toma plantea los pasos a seguir para el manual y se decide que el
primero es definir el microcontrolador a usar.
3. Investigación del lenguaje ensamblador: Teniendo el microcontrolador se
busca el set de instrucciones de este, y se empieza a adentrar al
lenguaje ensamblador.
4. Realización de programas y ejemplos: Con los conocimientos del PIC y
del lenguaje de programación se procede a la realización de programas y
ejemplos, para comprender el funcionamiento del programa, terminado
los programas se intentan programar o en su defecto simular para ver su
corecta operación.
5. Actividades diversas: Durante todo la estadia no solo se enfoca al
desarrollo del manual, sino, también a desempeñar actividades diversas
que surguen a lo largo de la estancia, que también sirven para la
formación y adquisición de conocimientos en el area.
6. Realización del manual: Con los conocimientos obteidos de la
programación se empieza a desarrollar un manual con la información
necesaria para su comprensión y programas que sirvan de ejemplos para
el entendimiento de las instrucciones.
10
7.1. Grafica de Gantt.
11
VIII. RECURSOS MATERIALES Y HUMANOS
EL presente capitulo muestra los recursos utilizados en el desarrollo del
proyecto, tanto los recursos materiales; como máquinas y herramientas, así
como también los humanos.
Equipo y material
Cantidad
Costo Unitario
Costo
Computadora
56
$5.00
$280.00
Programador de PICkit
1
$400.00
$400.00
Sistema mínimo para microcontrolador
1
$200.00
$200.00
PIC18F252
1
$100.00
$100.00
MPLAB IDE V8.70
1
$50.00
$50.00
ISIS
1
$50.00
$50.00
PICkit 2
1
$50.00
$50.00
56 horas
$70.00
$3,500.00
Software
Recursos Humanos
Horas Hombre
TOTAL
$5,050.00
12
IX. DESARROLLO DEL PROYECTO
En este capítulo se presentan las actividades realizadas para la
elaboración del manual basando las actividades de la gráfica de Gantt mostrada
en el capítulo VII.
9.1. Definir Microcontrolador
Para la realización del manual de lenguaje ensamblador fue necesario
hacerlo para un Microcontrolador en particular, ya que aunque estos
microcontroladores tengan algunas similitudes físicas o de programación
pueden variar las instrucciones en el lenguaje ensamblador, las capacidades de
almacenamiento de memoria de datos o instrucciones son distintas, la
frecuencia de operación, entradas analógicas, etc.
El PIC18F252 es el que se eligió para este manual, ya que era con el que
se contaba, aunque el manual sea dirigido a este Microcontrolador en particular,
los ejemplos o programas pueden funcionar haciendo las adecuaciones
necesarias, o basándose en los diagramas de bloques.
Las características del Microcontrolador son obtenidas de su hoja de
datos (Data Sheet), en este caso son obtenidas de la página web de Microchip,
de donde se obtuvieron los siguientes datos:
13
Características:
Características
PIC18F252
Frecuencia de Operación
DC-40Hz
Memoria de Programa (Bytes)
32K
Memoria de Programa (Instrucciones)
16384
Memoria de Datos (Bytes)
1536
Memoria de Datos EEPROM (Bytes)
256
Fuentes de Interrupciones
17
Puertos de Entrada/Salida
Ports A, B, C
Timers
4
Captura, Comparación/Módulos PWM
2
Comunicación Serie
MSSP, Addessable, USAR
Comunicación Puerto Paralelo
--------
Módulo de10-bit Analógico-Digital
5 canales de entrada
POR, BOR, Instructions de RESET, Stack
RESERT (y retardos)
Full, Stack Underflow (PWRT, OST)
Detector de baja Tensión Programable
Si
Brown-Out Reset Programable
Si
Set de Instrucciones
75 Instrucciones
28-pin DIP
Encapsulado
28-pin SOIC
Tabla 9.1 Características del Microcontrolador PIC 18F252
Esta tabla muestra aspectos importantes del Microcontrolador, como
pueden ser: la frecuencia de operación, el tamaño de las memorias, los puertos
14
de entrada y salida, canales analógicos y la cantidad de instrucciones, entre
otros. El diagrama de pines, figura 9.1, también es una parte importante a
resaltar, ya que de manera gráfica muestra el Microcontrolador:
Figura 9.1. PIC18F252
Completando la selección del Microcontrolador y teniendo la información
básica de este, ya es posible hacer la introducción al lenguaje ensamblador con
respecto a las instrucciones que utiliza.
9.2. Instrucciones del Lenguaje Ensamblador
El lenguaje ensamblador es un lenguaje de programación muy básico,
por lo tanto también su juego de instrucciones, lo cual genera ventajas y
desventajas, una de las ventajas es tener al estar realizando el programa a bajo
nivel se puede hacer más eficiente el programa, es decir, que con menos
15
espacio en la memoria realice lo que se desea y con mayor velocidad, ya que el
programador define las subrutinas y cada parte del programa, a diferencia de
utilizar algún software de programación más avanzado que ya cuenta con
funciones especiales que facilitan la programación pero, no siempre resultan de
los más eficientes.
Tabla 9.2.Set de instrucciones del PIC18FXXX
16
La tabla 9.2 muestra las instrucciones del PIC18FXX2, con una breve
descripción de lo que realizan y de los ciclos que consume cada una de las
instrucciones.
Los Registros: Un registro es un lugar dentro del PIC que puede ser escrito,
leído o ambas cosas. Piensa en un registro como si fuese un trozo de papel
donde tú puedes ver la información o escribirla. La figura de más abajo muestra
el mapa de registros del interior del PIC18F252. La figura 9.3 es solo para
mostrar donde están los diferentes bits y piezas dentro del PIC, y ayudará a
explicar unos cuantos comandos.
Tabla 9.3. Bancos
17
La primera cosa que se nota es que está dividido en Bancos. El Banco 1
es utilizado para controlar las propias operaciones del PIC para decirle al PIC
cuales bits son entradas y cuales son salidas. El Banco 0 se utiliza para
manipular los datos.
9.3. Realización de programas y ejemplos
La manera más fácil y eficiente de saber cómo programar un
Microcontrolador es programando, y mejor forma de plantear la resolución de un
problema de programación es realizando un diagrama de flujo, que nos muestre
de manera gráfica la resolución del proyecto.
Como primer programa se realizó el encendido y apagado de un LED,
para hacer esto es necesario primero configurar un puerto como salida o un
solo bit de ese puerto, el cual va a mandar un dato en alto o bajo (encender o
apagar) a esto se le llama inicialización de puertos, después de tener el bit que
va a ser el que controle el encendido y apagado del LED, se hace el proceso de
encendido y apagado, esto se va a ser dándole instrucciones al bit elegido, es
decir, si se tiene el bit 7 del puerto C conectado al LED y configurado como
salida, y deseamos que encienda y apague el LED en un ciclo infinito, entonces
sí se representa gráficamente mediante un diagrama, figura 9.2, este quedara
de la siguiente forma:
18
Figura 9.2.Diagrama de flujo
De esta manera se facilita la realización del programa, así que con este
diagrama de flujo se realizó el primer programa para la introducción al lenguaje
ensamblador; para la inicialización del puerto C se hizo la siguiente parte del
código:
BSF
MOVLW
MOVWF
BCF
STATUS, 5
00h
94h
STATUS, 5
; BANCO 1 PARA MODIFICAR EL PUERTO C
; TODOS COMO SALIDA
; LUGAR DEL REGISTRO TRISC
; REGRESA AL BANCO CERO
Así se hace la configuración del cualquier puerto, moviéndose de un
banco a otro y asignado los bits en 0 para salidas y en 1 para entradas, ahora
19
para asignar que uno o varios bits estén en alto se pone el bit en 1 o en bajo en
0.
MOVLW
MOVWF
B’1000 0000 ; BIT 7 PUERTO C ACTIVADO
82h
; SE ASIGNAN AL PUERTO C
Se inició el programa con todos los puertos apagados, ahora se muestra
como se activa el bit 7 del puerto C
MOVLW
MOVWF
B’0000 0000 ; TODOS LOS PUERTOS APAGADOS
82h
; SE ASIGNA AL PUERT C
Para la parte del ciclo se utilizó una etiqueta y el GOTO. El GOTO manda
a la etiqueta, entonces la etiqueta fue asignada en la parte del inicio del
programa.
BSF
MOVLW
MOVWF
BCF
INICIO
MOVLW
MOVWF
MOVLW
MOVWF
GOTO
STATUS, 5
00h
94h
STATUS, 5
; BANCO 1 PARA MODIFICAR EL PUERTO C
; TODOS COMO SALIDA
; LUGAR DEL REGISTRO TRISC
; REGRESA AL BANCO CERO
B’0000 0000 ; TODOS LOS PUERTOS APAGADOS
82h
; SE ASIGNAN AL PUERTO C
B’1000 0000 ; BIT 7 PUERTO C ACTIVADO
82h
; SE ASIGNA AL PUERT C
INICIO
La importancia de saber el cristal que se usó es para determinar el
tiempo que dura el programa ejecutándose o una parte de él, en este caso es
20
necesario poner un retardo para que la duración del encendido y apagado sea
mayor, ya que con un cristal de 20MHz. La fórmula para determinar un ciclo de
instrucción es la siguiente:
(
)*4= CI.
Entonces, si tenemos un cristal de 20MHz un ciclo de maquina dura
.2µs, entonces un retardo se realiza mediante sumas o restas de un valor
predefinido, esto se hace mediante el DECFZ, que es una instrucción que
decrementa en un y cuando llega al 0 salta a una instrucción, o INCFZ que en
lugar de restar suma en un hasta llegar a 0.
Entonces se realiza el delay ciclando esta instrucción y el tiempo va a ser
igual al valor que tenga la variable a decrementar
o incrementar, esto
multiplicado por la cantidad de ciclos que dure la instrucción dentro del retardo y
multiplicado por el ciclo de instrucción, y se puede meter un retardo dentro de
otro retardo las veces necesarias para obtener un mayor tiempo.
Para este programa se realizó un doble anidado, bucle o retardo. Para
hacer el tiempo total va a ser igual al CONT2xTIEMPO1x3=TIEMPO2 y el
TIEMPO1=CONT1xCIx3 y el diagrama de la figura 9.3 muestra la gráficamente
la forma de realizarlo.
21
Figura 9.3.Diagrama de Retardo
Con el diagrama se realizó la siguiente parte del programa, llamada
RETARDO o DELAY:
;;;;;;;;;;;;;;;SUBRUTINA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RETARDO
MOVLW
.255
;ASIGNA 255 EN DECIMAL A W
MOVWF
CONT2
;CONT2 TOMA EL VALOR DE W
CICLO2
MOVLW
.255
;W TOMA EL VALOR DE 255
MOVWF
CONT1
;CONT1 ES IGUAL 1 255
CICLO1
22
DECFSZ
GOTO
DECFSZ
GOTO
RETURN
CONT1,1
CICLO1
CONT2,1
CICLO2
;DECREMENTA EN 1 A CONT1
;SIGUE RESTANDO HASTA Q LLEGUE A 0
;CUANDO LLEGA A 0 RESTA A CONT2
;HASTA QUE ESTE TAMBIÉN LLEGUE A 0
;LLEGA A 0 Y REGRESA DE DONDE LO
;LLAMARON
Entonces el valor del tiempo que va a durar es retardo es el siguiente, si
un ciclo de maquina dura (1/20MHz)x(4)=2 μs, las instrucciones en cada ciclo
son 3 y la variable es de 255, si multiplicamos estos tres nos da un primer
tiempo;
TIEMPO1=(2μs)x(3)x(255); TIEMPO1= 153 ms,
y el TIEMPO2=(153 ms)x(3)x(255), el TIEMPO2 = 0.117045 s,
aun es un tiempo muy corto, así que lo llamaremos 5 veces, lo que dio un
retardo de 0.585225.s entre encendido y apagado del LED.
Figura 9.4.Programa final.
23
Se redactó el programa correspondiente al programa de encendido y
apagado del LED, lo que dio como resultado lo siguiente:
;;;;;;;;;;;;;; INICIALIZACIÓN DE VARIABLES;;;;;;;;;;;;;;;;;;;;;;;;;
CONT1
EQU 08h ;CONT1 SE GUARDA EN LA MEMORIA 08h
CONT2
EQU 09h ;CONT2 SE GUARDA EN LA MEMORIA 09h
ORG 0X00
;;;;;;;;;;;;;;CONFIGURACIÓN DE PUERTOS;;;;;;;;;;;;;;;;;;;;;;;
BSF
STATUS, 5 ; BANCO 1 PARA MODIFICAR EL PUERTO C
MOVLW
00h
; TODOS COMO SALIDA
MOVWF
94h
; LUGAR DEL REGISTRO TRISC
BCF
STATUS, 5 ; REGRESA AL BANCO CERO
;;;;;;;;;;;;;;;;;;;;;;INICIO DEL PROGRAMA;;;;;;;;;;;;;;;;;;;;;
INICIO
MOVLW
B’0000 0000 ; TODOS LOS PUERTOS APAGADOS
MOVWF
82h
; SE ASIGNAN AL PUERTO C
CALL
RETARDO
CALL
RETARDO
CALL
RETARDO
CALL
RETARDO
CALL
RETARDO
MOVLW
B’1000 0000 ; BIT 7 PUERTO C ACTIVADO
MOVWF
82h
; SE ASIGNA AL PUERT C
CALL
RETARDO
CALL
RETARDO
CALL
RETARDO
CALL
RETARDO
CALL
RETARDO
GOTO
INICIO
END
;;;;;;;;;;;;;;;SUBRUTINA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RETARDO
MOVLW
.255
;ASIGNA 255 EN DECIMAL A W
MOVWF
CONT2
;CONT2 TOMA EL VALOR DE W
CICLO2
MOVLW
.255
;W TOMA EL VALOR DE 255
MOVWF
CONT1
;CONT1 ES IGUAL 1 255
CICLO1
DECFSZ
CONT1,1
;DECREMENTA EN 1 A CONT1
GOTO
CICLO1
;SIGUE RESTANDO HASTA Q LLEGUE A 0
DECFSZ
CONT2,1
;CUANDO LLEGA A 0 RESTA A CONT2
24
GOTO
RETURN
CICLO2
;HASTA QUE ESTE TAMBIÉN LLEGUE A 0
;LLEGA A 0 Y REGRESA DE DONDE LO
;LLAMARON
Este fue el programa final realizado, se escribió en el MPLAB IDE V8.70
que es un software para programación de lenguaje ensamblador para PIC’s. La
pantalla principal se muestra en la figura 9.4:
Figura 9.4.MPLAB
25
Para poder desarrollar un programa se posiciono el mouse, en la barra
de herramientas>Proyect>Proyect Wizard… y abrirá una ventana que ira
preguntando paso a paso lo necesario para configurar el software para el
Microcontrolador a usar, el lenguaje y donde se guarda el proyecto, figura 9.5.
Figura 9.5.Pasos Proyect Wizard.
Se encontró que existe diversas forma para agregar hojas nuevas para
escribir el código, se encontraron dos formas, la primera y más sencilla es
dándole clic derecho a Source Files>Add File y abrirá una nueva ventada en la
cual se asigna el nombre y dirección donde se quiere guardar el archivo .ASM,
figura 9.6; y la segunda manera es dándole en el icono de New File y
automáticamente abrirá un nuevo archivo en blanco, solamente hay que tener
26
cuidado al guardarlo, se debe asignar ese archivo al proyecto y ponerle la
extensión .ASM, figura 9.7.
Figura 9.6. Método uno.
Figura 9.7. Método dos.
27
En la hoja nueva que aparece se escribió el codigo generado
anteriormente, y se compiló, la compilación es la manera de generar el codigo
.HEX, qu es el que se necesita para posteriormente programar el PIC.
Lo compilación se hace con un icono en la barra de herramientas,
situado casi a la mitad de la barra, la figura 9.8 muestra el icono.
Figura 9.8. Compilación
Cuando existe un error de código el compilador marca una falla, esta
muestra donde ocurre y una breve descripción, en la figura 9.9 muestra una
falla errónea que se obtuvo al compilar.
Figura 9.9. Falla al compilar.
28
El error es de código, ya que la instrucción BSS no existe, y por esto
mismo también genera otro error con STATUS, que son los que se muestran en
la imagen.
Cabe resaltar que en la práctica solo me marcó los errores de
programación, esto quiere decir que aunque la compilación haya sido exitosa no
quiere decir que el programa realizado funcione como se planeó. Una
compilación exitosa es mostrada en la figura 9.10.
Figura 9.10. Compilación Exitosa.
Cuando se obtuvo el .HEX ya fue posible la programación al PIC, se
puede utilizar cualquier software de programación, siempre y cuando se tenga
el programador adecuado para el software.
29
Este programa fue simulado en ISIS, que es programa anexo a
PROTEUS, la simulación esta mostrada en las siguientes dos imágenes, figura
9.11 y figura 9.12, en la primera se muestra el apagado del LED y la segunda el
encendido, además que se muestra la conexión del Microcontrolador.
Figura 9.11. LED apagado.
La segunda figura muestra cuando el LED está encendido.
Figura 9.12. LED encendido.
30
La simulación fue elegida por problemas con el programador que se
contaba, ya que al programar el PIC este no hacia ninguna función, entonces
para la verificación del programa se optó por la simulación en ISIS. Este
software de simulación es sencillo de usar, para la selección de los objetos se
puso Component Mode y se seleccionó la librería, y en la librería se seleccionan
primeramente los componentes a utilizar y se van guardando en la parte de
DEVICES o componentes, la figura 9.13 muestra de una mejor manera:
9.13. Selección de dispositivos.
31
X. Resultados Obtenidos
En la realización de este proyecto se logró hacer un manual de lenguaje
ensamblador para el PIC18F252, el cual cuenta con 4 ejemplos paso a paso de
su elaboración, además de imágenes y diagramas que ayudan a la
comprensión. Se logró realizar distintos tipos de programas, abarcando gran
parte de las instrucciones utilizadas frecuentemente. También se llevó a cabo la
simulación de los programas, pero la programación del PIC no se logró del todo,
ya que el programador con el software de programación no tuvieron
compatibilidad
lo
cual
provocaba
errores
al
cargar
el
archivo
al
Microcontrolador.
XI. Análisis de Riesgos
Los impedimentos de que este proyecto no pueda ser realizado
son:

Falta de equipo como computadora, Microcontrolador y programador.

Falta de software de programación y simulación.

Realización de ejemplos que no funcionen.

Falta de tiempo para entender el lenguaje o para desarrollar el manual.
32
XII. Conclusiones
En la realización del manual se saca como conclusión que siempre que
se utilice algún Microcontrolador para programar es necesario tener a la mano
la hoja de datos, ya que esta brinda ayuda técnica que servirá para el desarrollo
del programa, otra cosa que se encontró fue que para realizar un manual hay
que saber de lo que se habla, es decir conocer el tema y redactarlo de la forma
que te hubiera gustado a ti que te lo explicaran, en mi caso la información
obtenida era muy técnica, lo que provocaba confusión, es por eso que se
realiza un manual que intenta explicar de manera muy detallada cada paso y
con ejemplos funcionales.
XIII. Recomendaciones
Después de la culminación del proyecto proseguiría hacer un curso,
donde se enseñe el lenguaje ensamblador tomando el manual como fuente de
consulta, el curso deberá contar con tres distintos niveles, principiante,
intermedio y avanzado.
33
XIV. Referencia Bibliográfica
Hyde, Randall . El arte de la programación en lenguaje ensamblador, Primera
Edición. Editorial Peter Kitson.
Bartlett, Jonathan. Programación desde las bases, Tercera Edición. Editorial
Peter Kitson .
También se consultó:
http://www.microchip.com
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=
1406&dDocName=en019469&part=SW007002
34
ANEXO 1
35
MANUAL DE
PROGRAMACIÓN DE
LENGUAJE
ENSAMBLADOR PARA
EL PIC18F252
NIVEL BÁSICO
36
Introducción
El muestra de manera detallada ejemplos de programación en lenguaje
ensamblador, estos fueron realizados para el PIC18F252, además que cuenta
con marco teórico que ayudara al lector la comprensión de algunos términos y
operaciones usadas dentro del manual. Cabe resaltar que este manual es para
nivel básico o principiantes.
Objetivo:

Dar a conocer al lector los alcances de un Microcontrolador como
dispositivo de control.

Saber reconocer las características necesarias para programar un
Microcontrolador.

Enseñar con base ejemplos sencillos.
37
Marco teórico
En este parte da a conocer conocimientos necesarios para el completo
entendimiento del manual, estas definiciones ayudan al mejor entendimiento
para personas que desconocen del tema.
Sistemas
digitales:
Un
sistema
digital
como
cualquier
sistema
de
procesamiento de información en el cual la información se encuentre
representada por medio de señales que se hayan restringidas que sólo pueden
asumir valores discretos. La principal ventaja de los sistemas digitales respecto
a los analógicos es que son más fáciles de diseñar, de implementar y de
depurar, ya que las técnicas utilizadas en cada una de esas fases están bien
establecidas. Las operaciones digitales también son mucho más precisas y la
transmisión de señales dentro del circuito y entre circuitos es más fiable porque
utilizan un conjunto discreto de valores, fácilmente discernibles entre sí, lo que
reduce la probabilidad de cometer errores de interpretación.

Sistemas digitales combinacionales: Aquellos en los que sus salidas
sólo depende del estado de sus entradas en un momento dado. Por lo
tanto, no necesita módulos de memoria, ya que las salidas no dependen
de los estados previos de las entradas.

Sistemas digitales secuenciales: Aquellos en los que sus salidas
dependen además del estado de sus entradas en un momento dado, de
38
estados previos. Esta clase de sistemas necesitan elementos de
memoria que recojan la información de la 'historia pasada' del sistema.
Para la implementación de los circuitos digitales, se utilizan puertas
lógicas (AND, OR y NOT), construidas generalmente a partir de transistores.
Estas puertas siguen el comportamiento de algunas funciones del Álgebra de
Boole.
Bit y Byte: Un bit es una señal electrónica que puede estar encendida (1) o
apagada (0). Es la unidad más pequeña de información que utiliza un
ordenador. Son necesarios 8 bits para crear un byte.
Compuertas Digitales: Las computadoras digitales se utilizan el sistema de
números binarios, que tiene dos dígitos 0 y 1.
Utilizando diversas técnicas de codificación los grupos de bits pueden hacerse
que representen no solamente números binarios sino también otros símbolos,
tales como dígitos decimales o letras de alfabeto. Utilizando arreglos binarios y
diversas técnicas de codificación, los dígitos binarios o grupos de bits pueden
utilizarse para desarrollar conjuntos completos de instrucciones para realizar
diversos tipos de cálculos.
39
Compuerta AND: Cada compuerta tiene dos variables de entrada designadas
por A y B y una salida binaria designada por X. La compuerta AND produce
UNA multiplicación lógica.
Compuerta AND
Compuerta OR: La compuerta OR hace la función sumar. Las compuertas OR
pueden tener más de dos entradas y por definición la salida es 1 si cualquier
entrada es 1.
Compuerta OR
40
Compuerta NOT: El circuito NOT es un inversor que invierte el nivel lógico de
una señal binaria, también llamada función complementaria. Si la variable
binaria posee un valor 0, la compuerta NOT cambia su estado al valor 1 y
viceversa.
Compuerta NOT
Compuerta NAND: Es el complemento de la función AND, como se indica por
el símbolo gráfico, que consiste en una compuerta AND seguida por un
pequeño círculo (quiere decir que invierte la seña, una NOT. Las compuertas
NAND pueden tener más de dos entradas, y la salida es siempre el
complemento de la función AND.
Compuerta NAND
41
Compuerta NOR: La compuerta NOR es el complemento de la compuerta OR
y utiliza el símbolo de la compuerta OR seguido de un círculo pequeño. Las
compuertas NOR pueden tener más de dos entradas, y la salida es siempre el
complemento de la función OR.
Compuerta NOR
Sistema Decimal: El sistema decimal es un sistema de numeración donde se utiliza
la base diez, por lo que se compone de diez cifras diferentes: 0, 1, 2, 3, 4, 5, 6, 7, 8 y 9.
Sistema Binario: En el sistema Binario o de base 2, cuanta solamente con dos
dígitos el 0 y el 1, empezamos con el 0 y después el 1, y para formar un número
más grande, se van añadiendo 0 y 1 la izquierda del número que ya tenemos.
En el sistema binario sólo puede haber dos valores para cada dígito: un 0=
desactivado ó un 1= activado.
Sistema Hexadecimal: Este sistema es de base 16, lo que significa que para
cada columna es posible escoger uno de entre 16 dígitos. Éstos son 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, A, B, C, D, E y F. Para contar en el sistema hexadecimal se
42
inicia en la primera columna a la izquierda del punto hexadecimal y se cuenta
desde 0 hasta F
Sistemas numéricos
Lenguaje ensamblador: El
lenguaje
ensamblador
es
un
lenguaje
de
programación de bajo nivel para las computadoras, microprocesadores,
Microcontroladores, y otros circuitos integrados programables.
Características del lenguaje ensamblador: El código escrito en lenguaje
ensamblador posee una cierta dificultad de ser entendido ya que su estructura
se acerca al lenguaje máquina, es decir, es un lenguaje de bajo nivel.
Con el lenguaje ensamblador se tiene un control muy preciso de las
tareas realizadas por un microprocesador por lo que se pueden crear
segmentos de código difíciles y/o muy ineficientes de programar en un lenguaje
43
de alto nivel, ya que, entre otras cosas, en el lenguaje ensamblador se dispone
de instrucciones del CPU que generalmente no están disponibles en los
lenguajes de alto nivel
Arquitectura interna de un Microcontrolador: Un microcontrolador es un
dispositivo complejo, formado por otros más sencillos. A continuación se
analizan algunos de los aspectos más importantes.
Procesador: Es la parte encargada del procesamiento de las instrucciones. La
arquitectura von Neumann se caracterizaba porque la CPU se conectaba con
una memoria única, donde coexistían datos e instrucciones, a través de un
sistema de buses.
Arquitectura von Neumann
En la arquitectura Harvard son independientes la memoria de
instrucciones y la memoria de datos y cada una dispone de su propio sistema
de buses para el acceso. Esta dualidad, además de propiciar el paralelismo,
permite la adecuación del tamaño de las palabras y los buses a los
requerimientos específicos de las instrucciones y de los datos.
44
Arquitectura Harvard
Memoria de programa: El Microcontroladores está diseñado para que en su
memoria de programa se almacenen todas las instrucciones del programa de
control. Como éste siempre es el mismo, debe estar grabado de forma
permanente.
Memoria
de
datos:
Los datos que manejas
los
programas varían
continuamente, y esto exige que la memoria que los contiene debe ser de
lectura y escritura, por lo que la memoria RAM estática (SRAM) es la más
adecuada, aunque sea volátil. Hay microcontroladores que disponen como
memoria de datos una de lectura y escritura no volátil, del tipo EEPROM. De
esta forma, un corte en el suministro de la alimentación no ocasiona la pérdida
de la información, que está disponible al reiniciarse el programa.
Líneas de E/S: A excepción de dos pines destinadas a recibir la alimentación,
otras dos para el cristal de cuarzo, que regula la frecuencia de trabajo, y una
más para provocar el Reset, los restantes pines de un microcontrolador sirven
45
para soportar su comunicación con los periféricos externos que controla. Las
líneas de E/S que se adaptan con los periféricos manejan información en
paralelo y se agrupan en conjuntos de ocho, que reciben el nombre de Puertas.
El lenguaje ensamblador cuenta con un juego de instrucciones y estas se
pueden dividir en grupos:

CISC (Complex Instruction Set Computer): Juego de Instrucciones
Complejo, más de 80 instrucciones

RISC (Reduced Instruction Set Computer): Juego de Instrucciones
Reducido, unas 35 instrucciones. Los Microcontroladores PICmicro son
de este tipo.

SISC (Specific Instruction Set Computer): Juego de Instrucciones
Específico, para una mejor presentación las instrucciones se pueden
clasificar según la función que desempeñan en un programa.
46
CONOCE EL MICROCONTROLADOR
Para poder programar es necesario saber que vas a programar, para
esto es necesario elegir el PIC a utilizar y saber sus características básicas. En
este caso se utilizara un PIC18F252 para los ejemplos de programación. Los
datos son obtenidos de la datasheet del propio componente, esta es obtenida
de la página del fabricante Microchip.
Diagrama de pines
Se debe tomar en cuenta otras caracteristicas del microcontrolador,
como la frecuencia de operación, la memoria, entradas analogicas, las
intrucciones, entre otras; las caracteristicas se muestran en la siguiente tabla:
Características
PIC18F252
Frecuencia de Operación
DC-40Hz
Memoria de Programa (Bytes)
32K
Memoria de Programa (Instrucciones)
16384
Memoria de Datos (Bytes)
1536
Memoria de Datos EEPROM (Bytes)
256
47
Fuentes de Interrupciones
17
Puertos de Entrada/Salida
Ports A, B, C
Timers
4
Captura, Comparación/Módulos PWM
2
Comunicación Serial
MSSP, Addessable, USAR
Módulo de10-bit Analógico a Digital
5 canales de entrada
RESERT (y retardos)
POR, BOR, Instructions de RESET, Stack
Full, Stack Underflow (PWRT, OST)
Características PIC18F252
Otro factor que se debe tomar en cuenta es el diagrama de bloques de la
arquitectura del microcontrolador, ya que ayudara a comprender un poco mejor
el uncionamiento de este
.
48
El lenguaje ensamblador cuenta con instrucciones, etiquetas, operando y
comentarios, todo esto facilita tanto la escritura como el entendimiento de este,
a continuación se muestra la manera en que cada uno se acomoda.
Etiqueta Instrucción Operando Comentario
Inicio
Movlw
0xf0
Movwf
TRISCA
Goto
Inicio
;Mueve 0xf0 a W
;TRISA toma el valor de W
;Regresa a la dirección Inicio
Tabla de Campos
El campo del código de operación es el único que nunca puede estar
vacío; éste siempre contiene una instrucción o una directiva del assembler. El
campo del operando o dirección puede contener una dirección o un dato, o
puede estar en blanco. El campo del comentario o de etiquetas es opcional. El
programador asignará una etiqueta a una línea de instrucción o agregará un
comentario según su conveniencia: normalmente, para hacer más fácil el uso y
la lectura; por ejemplo si va a retomar el trabajo dentro de tres semanas.
Los Registros
Un registro es un lugar dentro del PIC que puede ser escrito, leído o
ambas cosas. Piensa en un registro como si fuese un trozo de papel donde tú
puedes ver la información o escribirla.
49
La figura de más abajo muestra el mapa de registros del interior del
PIC18F252. La figura es solo para mostrar donde están los diferentes bits y
piezas dentro del PIC, y ayudará a explicar unos cuantos comandos.
50
La primera cosa que notarás es que está dividido en Bancos. El Banco 1
es utilizado para controlar las propias operaciones del PIC, por ejemplo para
decirle al PIC cuales bits del Puerto A son entradas y cuales son salidas. El
Banco 0 se utiliza para manipular los datos. Un ejemplo es el siguiente:
Digamos que queremos poner un bit del puerto A en nivel alto. Lo primero que
necesitamos hacer es ir al Banco 1 para poner ese bit o pin en particular en el
puerto A como salida. Después volvemos al Banco 0 y enviamos un 1 lógico a
ese pin.
Los registros que se van a usar más frecuentemente en el Banco 1 son
STATUS, TRISA, TRISB y TRISC. El primero permite ir de un banco a otro, los
TRIS permiten establecer los pines que serán de entrada y de salida con
respecto al puerto.

STATUS
Para cambiar del Banco 0 al Banco 1 utilizamos el registro STATUS.
Hacemos esto poniendo el bit 5 del registro STATUS a 1. Para cambiar de
nuevo al Banco 0, ponemos el bit 5 del registro STATUS a 0. El registro
STATUS se localiza en la dirección D8h (la 'h' significa que el número es
hexadecimal).

TRISA, TRISB y TRISC
51
Están localizados en las direcciones 92h, 93h y 94h respectivamente
para este PIC. Para programar que un pin sea una salida o una entrada,
simplemente enviamos un 0 o un 1 al bit en cuestión en el registro

PORTA, PORTB y PORTC
Para poner uno de nuestros pines de salida a nivel alto, simplemente
ponemos un 1 el bit correspondiente en nuestro registro PORTA, PORTB y
PORTC. El formato es el mismo que para los registros TRISA, TRISB y TRISC.
Para leer si un pin está a nivel alto o nivel bajo en los pines del puerto, se
ejecutar un chequeo para ver si el bit en particular correspondiente esta puesto
a nivel alto (1) o está puesto a nivel bajo (0). Antes de dar algún ejemplo es
necesario también explicar lo que es el registro W.
El registro W es un registro de propósito genera, es decir, es al cual le
puedes asignar cualquier valor que se desee. Una vez que se haya asignado un
valor a ese registro, puedes sumarle cualquier otro valor, o moverlo. Si le
asignas otro valor a W, su contenido es sobrescrito.
A continuación se mostrará un ejemplo: de cómo utilizar las instrucciones
anteriores, esto es solamente para inicializar los puertos, si se intenta compilar
en este momento probablemente marque un error. Vamos configurar el puerto
B, sus entradas y salidas.
52
PASO 1. Lo primero, necesitamos cambiar del banco 0 al banco 1. Hacemos
esto modificando el registro STATUS, que está en la dirección D8h, poniendo el
bit 5 a 1.
BSF
D8h,5
La instrucción BSF significa en ingles "Bit Set F" (Poner a 1 un bit de la
Memoria). La letra F significa que se va a utilizar una posición de memoria, o un
registro en memoria. Se van utilizar dos números después de esta instrucción,
estos números están en hexadecimal– D8h, el cual se refiere a la dirección del
registro STATUS, y el número 5 que corresponde al número de bit. Por lo tanto,
la instrucción dice: "pon a 1 el bit 5 de la dirección de memoria 03h", esto en
palabras.
PASO 2. Ahora ya estamos en el banco 1 ponemos el valor binario en nuestro
W, este valor se puede escribir en hexadecimal o binario.
MOVLW
b'00000110'
MOVLW
06h
Cualquiera de las dos funcionará. La instrucción MOVLW significa en
inglés "Move Literal Value into W", en español, mover un valor literal
directamente al registro W.
53
PASO 3. Ahora necesitamos poner este valor en el registro TRISB para
configurar el puerto:
MOVWF
93h
Esta instrucción significa "poner los contenidos de W en el registro cuya
dirección viene a continuación", en este caso la dirección 93h, que apunta a
TRISB.
Nuestro registro TRISB ahora tiene el valor 00000110 o mostrado gráficamente:
Pin del Puerto B RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
Valor Binario
0
0
0
0
0
1
1
0
Entrada/Salida
S
S
S
S
S
E
E
S
PASO 4. Ahora tenemos que configurar los pines del Puerto B, y para ello
necesitamos volver al banco 0 para manipular cualquier dato.
BCF
D8h, 5
Esta instrucción hace lo contrario a BSF. Significa en ingles "Bit Clear F"
que quiere decir “poner a 0 un bit de la memoria”. Los dos números que le
siguen son la dirección del registro, en este caso del registro STATUS, y el
54
número de bit, es este caso el 5. Así que lo que hemos hecho ahora es poner a
0 el bit 5 del registro STATUS. Ahora ya se está de vuelta en el banco 0.
Aquí está el código en un solo bloque:
BSF
MOVLW
MOVWF
BCF
D8h, 5
06h
93h
D8h, 5
; Ve al banco 1
; Pon 0000 0110 en W
; Mueve lo que tiene W a TRISB
; Vuelve al Banco 0
Ahora, entendiendo lo anterior, se puede realizar un programa sencillo,
que encienda y apague un LED. Lo primero que se tiene que hacer es definir
qué puerto y que bit del puerto será el que este parpadeando, para esto
utilizamos lo anteriormente aprendido, usaremos el bit 1 del puerto B.
bsf
movlw
movwf
bcf
D8h,5
00h
93h
D8h,5
;Ir al Banco 1
;Pone 00000000 en W
;Todo el puerto a como salida
;volver al Banco 0
Teniendo configurado el puerto que vamos a utilizar, solo falta mandar la
señal al LED, esto lo se hace poniendo en alto o bajo el bit que se desea
encender, en este caso el bit 2 del puerto B.
movlw
02h
; Escribe en W 0000 0001, poniendo el bit 1 en alto y los
;demás en su estado bajo
movwf
81h
; EL puerto B toma el valor de W, el puerto B está en la
;dirección 81h
En este punto el LED va a estar encendido, lo que se quiere ahora es
apagarlo y esto se hace poniendo el puerto B en 0000 0000.
55
movlw
movwf
00h
81h
; Escribe 00h en el registro W. Esto pone a 0 todos los pines.
; Apaga el puerto B
Lo que se hizo fue encender y apagar el LED una vez, lo que se quiere
es hacerlo pero manera continua, es para esto que se usa un GOTO y una
etiqueta, el GOTO, te manda a la etiqueta que se le indique, y si se pone la
etiqueta al inicio del programa y el GOTO después de apagar el LED lo que se
obtendrá será un ciclo continuo del LED encendiendo y apagando.
INICIO movlw
movwf
movlw
movwf
goto
01h
81h
00h
81h
INICIO
;Regresa a la etiqueta de inicio
Como se logra notar el programa sin las etiquetas es bastante confuso,
porque solamente se aprecian letras y números, existe una función llamada
EQU, que nos sirve para declarar con nombres a los números, esta instrucción
no es del propio PIC, sino del lenguaje ensamblador.
STATUS EQU
TRISB
EQU
PORTB EQU
D8h
93h
81h
; Este asigna a la palabra STATUS el valor D8h
; Este asigna a la palabra TRISA el valor 93h
; Este asigna a la palabra PORTB el valor de 81h
Ahora será más fácil entender el programa aunque no se usen muchas
etiquetas, y con esta nueva instrucción el programa quedara de la siguiente
manera:
STATUS EQU
TRISB
EQU
PORTB EQU
D8h
93h
81h
; Este asigna a la palabra STATUS el valor D8h
; Este asigna a la palabra TRISA el valor 93h
; Este asigna a la palabra PORTB el valor de 81h
56
bsf
movlw
movwf
bcf
INICIO movlw
movwf
movlw
movwf
goto
STATUS,5
00h
TRISB
STATUS,5
02h
PORTB
00h
PORTB
INICIO
En teoría se tiene un programa que prende y apaga un LED, el
programa comprende de 5 instrucciones y si tomamos en cuenta que cada una
dura un ciclo de instrucción, entonces el tiempo de encendido y apagado será
muy rápido para distinguirlo o verlo. La fórmula para determinar un ciclo de
instrucción es la siguiente:
(
)*4= CI
Entonces, si tenemos un cristal de 20MHz un ciclo de maquina dura .2
microsegundos y si tenemos 5 instrucciones quiere decir que prendera y
apagara el LED en 1 microsegundo, lo cual es imposible de ver para el ojo
humano, es por eso que se deben de crear retardos o delays para hacer que
tarde más tiempo en la realización de una operación
El principio para retardo es el de contar hacia atrás o hacia adelante
desde un número previamente establecido y cuando llegue a cero, paramos de
contar. El valor cero indica el fin del retardo y continuamos nuestro camino a
través del programa. Así que lo primero que se necesita hacer es definir una
57
constante que se usara como contador. La llamaremos CONTADOR. Lo
siguiente se necesita decidir el tamaño del número desde el que contador y se
debe considerar que el número mayor que se puede tener es 255 o FFh en
hexadecimal. Ahora, como hemos mencionado en el apartado anterior, la
instrucción EQU asigna una palabra a una localización de un registro de
memoria. Esto significa que cualquiera que sea el número que asignemos a
CONTADOR, será igual al contenido de un registro.
Si se prueba y asignamos el valor FFh, el compilador entenderá que se
está asignando la dirección de memoria FFh a la constante, y se obtendrá un
error cuando se vaya a compilar el programa. Esto es debido a que la
localización FFh está reservada, y por tanto no se puede acceder a ella.. Si se
asigna a nuestro CONTADOR, por ejemplo, a la dirección 08h, este apuntará a
un registro de propósito general. Las posiciones de memoria tienen un valor por
defecto de FFh. De este modo, si CONTADOR apunta a 08h, tendrá un valor de
FFh la primera vez que lo se asigne. Si queremos que CONTADOR tenga un
valor de 93h, no podemos decir 'CONTADOR EQU 93h' porque esta es la
localización del registro del puerto B (TRISB). Lo que hacemos es esto:
movlw
93h
; Primero, ponemos el valor 93h en el registro W.
movwf
08h
; Ahora lo movemos a nuestro registro 08h.
58
Ahora, se puede decir 'CONTADOR equ 08h', CONTADOR será igual al valor
93h.
Así que lo primero definimos nuestra constante:
CONTADOR equ 08h
A continuación es necesario disminuir este CONTADOR en 1 hasta que
alcance cero. Este lenguaje cuenta con una instrucción que hace el decremento
y con ayuda de otra llamada GOTO, hacemos que el proceso se repita hasta
que llegue el valor a 0.
decfsz
CONTADOR,1
Esta instrucción dice "resta 1 al registro (en esta caso CONTADOR). Si
llegamos a cero, salta 2 lugares hacia delante, si no llega a cero se ira a la
instrucción GOTO que lo llevara nuevamente a realizar el decremento.
CONTADOR
equ
ETIQUETA
decfsz CONTADOR,1
goto
08h
ETIQUETA
;Continua por aquí.
Lo que se hizo fue primero poner nuestra constante CONTADOR a 255.
La siguiente línea pone una etiqueta, llamada ETIQUETA seguida de nuestra
59
instrucción decfsz. La instrucción decfsz CONTADOR,1 disminuye el valor de
CONTADOR en 1, y almacena el resultado de vuelta en CONTADOR. También
comprueba si CONTADOR tiene un valor de 0. Si no lo tiene, hace que el
programa salte a la siguiente línea. Aquí tenemos una instrucción de 'goto' que
nos envía de vuelta a nuestra instrucción decfsz. Si el valor de CONTADOR es
igual a cero, entonces la instrucción decfsz hace que el programa salte dos
lugares hacia adelante, y se sitúe donde se ha escrito "Continua por aquí". Así
que, como se puede ver, se ha hecho que el programa permanezca en un lugar
durante un tiempo predeterminado antes de seguir adelante. Esto se llama
bucle de retardo. Si necesitamos un retardo mayor, podemos poner un bucle
detrás de otro. Cuantos más bucles pongamos, mayor será el retardo. Nosotros
vamos a necesitar por lo menos dos, si queremos ver parpadear al LED.
Vamos a poner estos bucles de retardo en nuestro programa, y
terminaremos haciendo un programa real añadiendo los comentarios:
;*****Establecimiento constantes ****
STATUS
equ
D8h
; Dirección del registro STATUS
TRISA
equ
85h
; Dirección del registro Puerto B
PORTA
equ
05h
; Dirección del Puerto A.
CONTADOR1 equ
08h
; Primer contador retardo.
CONTADOR2 equ
09h
; Segundo contador para retardo.
;
;****Configuración del Puerto****
bsf
STATUS,5
; Cambiamos al banco 1Switch to Bank 1
movlw 00h
; Ponemos los pines del puerto A ...
movwf TRISB
; como salidas.
bcf
STATUS,5
; Volvemos al Banco 0.
;
;****Encendido del LED ****
60
Inicio movlw
02h
; Encendemos el LED poniendo
primero el valor
movwf PORTB
; en el registro w y después al puerto
;
;****Inicio del retardo 1****
Bucle1 decfsz CONTADOR1,1
; Restamos 1 a 255.
goto
Bucle1
; Si CONTADOR es cero, continuamos.
decfsz CONTADOR2,1
; Restamos 1 a 255
goto
Bucle1
; Volvemos al inicio de nuestro bucle
; Este retardo cuenta hacia atrás ...
;.desde 255 a 0, 255 veces.
;
;****Retardo terminado, ahora apagamos el LED ****
movlw 00h
; Apaga el LED poniendo primero el valor ...
movwf PORTB
; en el registro w y después al puerto
;
;****Añadimos otro retardo****
Bucle2 decfsz CONTADOR1,1 ; Este segundo bucle mantiene el LED
goto
Bucle2
; apagado el tiempo suficiente
decfsz CONTADOR2,1
; para que lo veamos
goto
Bucle2
;
;****Ahora volvemos al inicio del programa
goto
Inicio
; Vuelve al principio y enciende el LED...
;de nuevo.
;****Termina el Programa****
end
; Algunos compiladores necesitan esta instrucción.
;y también por si acaso olvidamos poner...
;la instrucción 'goto'.
Para hacer un retardo con un tiempo específico en necesario saber
la frecuencia del cristal, ya que con este se determina el tiempo de un ciclo de
instrucción, esto es igual a (1/cristal)x4, exceptuando aquellas que como CALL,
RETURN, GOTO, RETLW, BTFSC, INCFSZ, DECFSZ, que duran el doble, otro
factor que determina la duración del retardo es el valor que tenga la variable,
este está comprendido de 0 a 255, y también tomar en cuenta si se decrementa
61
o incrementar la variable, por ejemplo si tenemos un cristal de 20MHz, la
variable tiene un valor de 125 y se decrementa.
Un ciclo de instrucción (CI) = (1/20Mhz)x4 = .2µs
movlw
.125
movwf
CONTADOR
Bucle
decfsz
CONTADOR, 1
Goto
Bucle
;Continua con el programa
Entonces, el tiempo es determinado por el Ciclo de instrucción
multiplicado por el valor de la variable (tomando en cuenta si a la variable se
decrementa o incrementa) y a su vez esto multiplicado por la suma de la
cantidad de ciclos de instrucción de las instrucciones dentro del dentro del
retardo.
CI x CONTADOR x (2+1)= Tiempo1
(.2µs)x(125)x3 = .075ms
Si se requiriera un valor mayor de tiempo, esto se hace metiendo este
bucle o ciclo dentro de un segundo, y si el tiempo aun no fuera suficiente, se
puede repetir el proceso N veces hasta alcanzar tiempo requerido.
Bucle2
Bucle1
movlw
movwf
movlw
movwf
decfsz
Goto
.100
CONTADOR2
.125
CONTADOR1
CONTADOR1, 1
Bucle1
62
decfsz
CONTADOR2, 1
Goto
Bucle2
;Continua con el programa
Para
esto
se
tiene
la
siguiente
formula
(Tiempo1)x(CONTADOR2)+(2CIxCONTADOR2)= Tiempo2, y para determinar
el
tiempo
de
un
tercer
bucle
o
anidamiento
seria
(Tiempo2)x(CONTADOR3)+(2CIxCONTADOR3)= Tiempo3, y así N veces.
Anteriormente se realizó un programa que hace el parpadeo de un LED,
ahora se verá la manera de encender y apagar un LED usando un interruptor,
para esto es necesario leer los puertos, para esto es necesario configurar los
puertos o al menos un bit de un puerto como entrada, la cual será leída.
bsf
movlw
movwf
bcf
STATUS,5
07h
TRISA
STATUS,5
; Va al Banco 1.
; Para configurar el pin 7 del Puerto B
; como entrada.
; Vuelve al Banco 0.
Ahora hemos puesto el bit 0 del puerto A como entrada. Lo que
necesitamos hacer ahora es comprobar si el pin está a nivel alto o a nivel bajo.
Para ello, podemos usar una de estas dos instrucciones: BTFSC y BTFSS. La
instrucción BTFSC significa "Haz una comprobación de bit en el registro y bit
que especificamos. Si es un 0, entonces sáltate la siguiente instrucción". La
instrucción BTFSS significa "Haz una comprobación de bit en el registro y bit
que especificamos. Si es un 1, entonces sáltate la siguiente instrucción".
63
La que se use dependerá de cómo se quiera que nuestro programa
reaccione cuando lea la entrada. Por ejemplo, si simplemente se está
esperando que la entrada sea 1, entonces se podría utilizar la instrucción
BTFSS de este modo:
;Aquí el código
BTFSS
Goto
PORTB, 7
Inicio
;Continua por aquí
Entonces es muy sencillo hacer un programa que prenda un LED con un
interruptor externo, como siempre es necesaria la configuración de los puertos.
bsf
movlw
movwf
bcf
STATUS,5
1000 0000
TRISB
STATUS,5
; Va al Banco 1
; Para configurar el bit 7 del Puerto B
; como entrada
; Vuelve al Banco 0
Aquí se está poniendo el bit 7 del puerto B como entrada, y todos los
demás se quedan como salidas, ahora preguntamos si el bit 7 está en alto o en
bajo, para prender o apagar el LED, para esto se utiliza el BTFSS para que
cuando este activo el bit 7 salte a la opción de encender, mientras tanto que se
mantenga apagado.
CHECA
Btfss
goto
PORTB, 7
CHECA
;Puerto B bit 7 Activado?
;si no lo está sigue preguntando
64
Bsf
PORTB,0
Cuando está activo enciende el bit 0 del
;puerto B
Y así de sencillo es una manera de leer la entrada de los puertos y con
respecto al estado de esta señal, sea en alto o en bajo, tomar una decisión,
saltar a otra parte del programa, hacer una interrupción, realizar alguna
operación, etc.
Operadores Aritméticos

ADD
Esta función lo que hace es sumar dos números. Si el resultado de
sumar dos números excede de 8 bits o de 255, entonces se activará un flag
llamado CARRY, el CARRY se trata de 1 bit que se ubica en un registro en
concreto de la memoria del PIC, el CARRY está localizado en el bit 0 de la
dirección de memoria 03h. Si este bit se activa, quiere decir que la suma de los
2 números excedió los 255. Si es 0, entonces el resultado queda dentro de los 8
bits. También, el PIC nos da dos modalidades de ADD, que son ADDLW y
ADDWF. Como puedes suponer, es muy similar a la función anterior. ADDLW
añade los contenidos del registro W con un número que le especifiquemos.
ADDWF añadirá los contenidos del registro W y cualquier otro registro que le
especifiquemos.

SUB
65
La instrucción SUB es una substracción o resta. Una vez más el PIC da dos
modalidades: SUBLW y SUBWF. La sintaxis es exactamente la misma que para
la función ADD.
Ahora se mostrara como hacer un convertidor de BCD a 7 segmentos
utilizando las instrucciones SUB y ADD, es decir, hacer una conversión de 8 bits
y desplegar el número en decimal en tres displays, para esto es necesario
seleccionar un puerto como como entradas, otro puerto para los displays y 3
salidas más para multiplexar. La multiplexación consiste en elegir el display que
se va a activar, más adelante se entenderá mejor, empezaremos configurando
los puertos:
;;;;;;;;;;;Configuración de puertos;;;;;;;;;;;;;
bsf
clrf
clrf
movlw
movwf
bcf
STATUS,5
TRISC
TRISA
b'11111111'
TRISB
STATUS,5
;Se mueve el Banco 1
;Puerto C como salida de displays
;Puerto A como salida de multiplexar
;1111 1111 movidos a W
;Puerto B como entrada de 8 bits
;Regresa al Banco 0
La conversión se hará de la siguiente manera, se adquiere el dato del
puerto B, a este dato en decimal equivale a 255, entonces se empezara
sacando centenas, decenas y unidades, también debemos tomar en cuenta que
el lenguaje ensamblador no hace divisiones, por lo que se harán restas. Primero
se guarda el valor del puerto en una variable y se le hará una resta de 100, si el
66
valor es mayor a 100 se incrementara el valor de otra variable llamada cent, de
no ser así se provocara un acarreo o CARRY y se volverá a sumar los 100 para
regresarlo a su valor original y pasara a determinar el número de centenas que
tiene y se hará lo mismo que en las centenas, solamente que en lugar de
substraer 100 se substraerá 10 y se irán guardando en otra variable llamada
dec, se entenderá mejor con la siguiente parte del código.
;;;;;;;;;;;;;;Adquisición de dato;;;;;;;;;;;;;;
movf
PORTB,0
;coloca lo que está en el puerto B en W
movwf DIVIDENDO
;Lo q esta en W lo mueve a DIVIDENDO
;;;;;;;;;;;;;;Obtener Centenas;;;;;;;;;;;;;;;;;
CENTENAS
movlw .100
;W toma el valor de 100d valor en decimal
subwf DIVIDENDO,f
;se hace la resta de k-w, es decir,
;DIVIDENDO - 100
btfss
STATUS,0
;Pregunta por el carry, si se produjo
goto
SUMA_100
;el número dio negativo se suma lo q se resto
incf
cent,f
; incrementa en 1 la varia de centenas
goto
CENTENAS
;repite el proceso hasta q ya no se puedan
;extraer centenas
SUMA_100
movlw .100
addwf DIVIDENDO,f
;se suman los 100 que se le restaron
;para regresar a su valor y devolver el carry
;;;;;;;;;;;;;;Obtener centenas;;;;;;;;;;;;;;;;;
DECENAS
movlw .10
;W tomo el valor de 10d
subwf DIVIDENDO,f
;y se la substrayendo al DIVIDENDO
btfss
STATUS,0
;pregunta si se produjo el CARRY
goto
SUMA_10
;Va a la rutina para devolver los 10
incf
dec,f
;si no se incrementa en 1 las decenas
goto
DECENAS
;y se repite el ciclo hasta q ya no entre
SUMA_10
movlw .10
addwf DIVIDENDO,f
;si al hacer la resta dio un numero negativo
;se produce un carry?
67
goto
UNIDADES
;y se le hace una suma devolviendo al valor
;anterior
;;;;;;;;;;;;;;Obtener Unidades;;;;;;;;;;;;;;;;;
UNIDADES
movf
DIVIDENDO,0
movwf uni
;el valor que queda al DIVIDENDO
;se pone en las unidades
Hasta aquí ya se han sacado las centenas, decenas y unidades del
puerto B, que se ha llamado DIVIDENDO, ahora hay que mandarlas a los
display, hay que recordar que los 3 display están conectados a la mismas
salidas, entonces si se mandan las centenas y los display están activos, los 3
desplegaran el mismo número, es por eso que se usa la multiplexación, cuando
se quieran mandar las decenas se manda un pulso del puerto A al display de
las centenas y al mismo tiempo se manda el valor de las centenas, lo mismo
para las decenas y unidades y así cada uno mostrara el número
correspondiente.
;;;;;;;;;MANDAR CENTENAS;;;;;;;;;;;;;
movf
cent,0
;Guarda una copia de cent en W
movwf COMPARA
;adquiere el valor q tiene W (cent)
bSf
PORTA,0
;Activa el bit 0 del puerto A (para multiplexar)
call
NUMEROS
;Se mueve a la tabla para comparar el valor q
;tenia cent
bCf
PORTA,0
;Desactiva el bit 0 de las centenas
;;;;;;;;;MANDAR DECENAS;;;;;;;;;;;;;
movf dec,0
;Guarda en W una copia de dec
Movwf COMPARA
;mueve el valor de dec a compara
bSf
PORTA,1
;activa bit 1 del puert0 A para el display de decenas
68
call
NUMEROS
;Compara el dato con una tabla
bCf
PORTA,1
;Regresa y apaga el display de decenas
;;;;;;;;;MANDAR UNIDADES;;;;;;;;;;;;;
movf uni,0
;lo que vale uni lo guarda en W
movwf COMPARA
;W se guarda en COMPARA
bSf
PORTA,2
;Activa el bit 2 del puerto A para las unidades
call
NUMEROS
;llama a una tabla y verifica el numero q es
bCf
PORTA,2
;regresa y desactiva las unidades
Se tiene que crear una tabla de comparación, esta tabla sirve dentro de
nuestro programa para comparar las centenas, decenas y unidades y con
respecto al número que se tenga mandar a activar los bits necesarios para
hacer el número correspondiente en el display, la comparación se hace en
binario, es por eso que debemos de saber que bit son necesarion poner en alto
o bajo (dependiendo del tipo de display) obtener el numero deseado, en la
siguiente imagen se muestra como están conectados los display con el
microcontrolador:
69
Así que lograr los de manera gráfica en el display el numero esta la
siguiente tabla representativa para un cátodo común.
Número
Valor del Puerto C
1
b'01000001' = 41h
2
b'00111011' = 3Bh
3
b'01101011' = 6Bh
4
b'01001101' = 4Dh
5
b'01101110' = 6Eh
6
b'01111110' = 7Eh
Display
70
7
b'01000011' = 43h
8
b'01111111' = 7Fh
9
b'01101111' = 6Fh
0
b'01110111' = 77h
Para poder comparar el valor del número obtenido con respecto al
número que se tiene que desplegar en el display es necesario utilizar las
instrucciones anteriores, y con respecto al resultado tomar la decisión de
mandar el número o seguir buscando a cual corresponde.
;;;;;;;;;;Tabla De Comparación;;;;;;;
NUMEROS
;;;;;;;;;;CERO;;;;;;;;;;;
MOVF COMPARA,0
SUBLW
b'00000'
BTFSC
STATUS,2
CALL CERO
;W igual al Puerto B
;Se resta COMPRAR con 0
;Si el resultado es CERO manda
;llamar al numero
;en este caso a CERO, sino, brinca a
;comparar otro numero
71
;;;;;;;;;;UNO;;;;;;;;;;
MOVF COMPARA,0
SUBLW
b'00001'
; Este número binario equivale a
;número en decimal
BTFSC
STATUS,2
CALL UNO
Y se repite prácticamente las mismas instrucciones para cada una de las
comparaciones, solamente cambia el valor contra el cual compara.
;;;;;;;;;;OCHO;;;;;;;;;;
MOVF COMPARA,0
SUBLW
b'01000'
BTFSC
STATUS,2
CALL OCHO
;;;;;;;;;;NUEVE;;;;;;;;;;
MOVF COMPARA,0
SUBLW
b'01001'
BTFSC
STATUS,2
CALL NUEVE
Solamente falta la dichosa falta de los números que desplegara en el
diplsay, la cual viene a continuación
;;;;;;;;;Tabla de Numeros;;;;;;;;;;;;;;
CERO
UNO
MOVLW
MOVWF
RETURN
MOVLW
MOVWF
RETURN
b'01110111
PORTC
b'01000001'
PORTC
Y este proceso se repite hasta el número nueve, cambiando los
bits que se activaran en el Puerto C, este número se muestra en la tabla
mostrada anteriormente.
OCHO
NUEVE
MOVLW
MOVWF
RETURN
MOVLW
b’01111111
PORTC
b'01101111
72
MOVWF
RETURN
PORTC
Y con esto se tiene se tiene el programa terminado de conversión. Claro
que existen más funciones y mejores formas de realizar los programas, aquí
solo se muestra de una manera sencilla el alcance que puede tener, la limitante
ahora es el Microcontrolador y el programador.
El LCD
La pantalla de cristal líquido o LCD (Liquid Crystal Display) es un
dispositivo
microcontrolado de visualización grafico para la presentación de caracteres o
símbolos, en este caso dispone de 2 filas de 16 caracteres cada una, y cada
carácter dispone de una matriz de 5x7 puntos (pixels).
Características principales:

Pantalla de caracteres ASCII, además de los caracteres Kanji y Griegos.

Desplazamiento de los caracteres hacia la izquierda o la derecha.

Memoria de 40 caracteres por línea de pantalla.

Movimiento del cursor y cambio de su aspecto.

Permite que el usuario pueda programar 8 caracteres.

Conexión a un procesador usando un interfaz de 4 u 8 bits
73
El LCD cuanta con pines, y además un juego de instrucciones y
comandos utilizados para configurar el LCD, adelante se muestra una tabla con
los pines.
Clear Display
Borrar y colocar el cursor en la primera posición (dirección 0). Pone el bit
I/D a 1 por defecto.
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2
DB1
DB0
0
0
0
0
0
0
0
0
0
1
Home
74
Colocar el cursor en la posición de inicio (dirección 0) y hacer que el
display comience a desplazarse desde la posición original. El contenido de la
memoria RAM de datos de visualización (DD RAM) permanece invariable.
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2
DB1
DB0
0
0
0
0
0
0
0
0
1
X
Entry Mode Set
Establecer la dirección de movimiento del cursor y especificar si la
visualización se desplaza a la siguiente posición de la pantalla o no.. Para
visualizar normalmente se debe poner el bit S=0.
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2
DB1
DB0
0
0
0
0
0
0
0
1
I/D
S
Display ON/OFF Control
Activar o desactivar poniendo en ON/OFF tanto el LCD (D) como el
cursor (C) y establecer si este último debe o no parpadear (B).
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2
DB1
DB0
0
0
0
0
0
0
1
D
C
B
Cursor or Display Shift
Mover el cursor y desplazar el LCD sin cambiar el contenido de la
memoria de datos de visualización DD RAM.
75
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2
DB1
DB0
0
0
0
0
0
1
S/C
R/L
X
X
Function Set
Establecer el tamaño de interface con el bus de datos (DL), número de
líneas del LCD (N) y tipo de carácter (F).
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2
DB1
DB0
0
0
0
0
1
DL
N
F
X
X
Set the CG RAM Address
El módulo LCD además de tener definidos todo el conjunto de caracteres
ASCII permite al usuario definir 4 u 8 caracteres. La composición de estos
caracteres se va guardando en una memoria llamada CG RAM con capacidad
para 64 bytes. Cada carácter definido por el usuario se compone de 16 u 8
bytes que se almacenan en consecutivas en posiciones de la CG RAM.
Mediante esta instrucción se establece la dirección de memoria CG RAM a
partir de la cual se irán almacenando los bytes que definen un carácter.
Ejecutando este comando todos los datos que se lean o escriban
posteriormente lo harán desde esta memoria CG RAM.
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2
0
0
0
1
Dirección de la CG RAM
DB1
DB0
76
Set the DD RAM Address
Los caracteres o datos a visualizar se almacenan en una memoria
llamada DD RAM para luego pasar a la pantalla. Mediante esta instrucción se
establece la dirección de la memoria DD RAM a partir de la cual se
almacenarán los datos a visualizar. Ejecutando este comando todos los datos
que se escriban o lean posteriormente lo harán desde esta memoria DD RAM.
Las direcciones 80h a 8Fh corresponden a los 16 caracteres del primer renglón
y las direcciones C0h a CFh a los 16 caracteres del segundo renglón, para este
modelo de LCD.
RS
R/W
DB7
DB6
DB5
DB4
DB3
0
0
1
Dirección de la DD RAM
DB2
DB1
DB0
Read Busy Flag and Address
El módulo LCD tarda un cierto tiempo para ejecutar las instrucciones,
tiempo en que no se debe enviar otra instrucción. Para ello dispone de un flag
BUSY (ocupado) que indica que se está ejecutando una instrucción. Esta
instrucción de lectura informa del estado de dicho flag además de proporcionar
el valor del contador de direcciones de la CG RAM o de la DD RAM según la
última que se haya empleado.
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2
0
1
BF
Dirección de la CG RAM o DD RAM
DB1
DB0
Writ
77
e data to CG or DD RAM
Comando para escribir en la memoria DD RAM los datos que se quieren
presentar en pantalla, en código ASCII. Igualmente se escribe en la memoria
CG RAM los bytes para generar caracteres definidos por el usuario.
Previamente se direcciona la memoria DD RAM o la memoria CG RAM en la
que se quiere escribir datos.
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2
1
0
Código ASCII o byte del carácter gráfico
DB1
DB0
Read Data from CG RAM or DD RAM
Comando para leer los datos almacenados en la memoria DD RAM, en
código ASCII. Igualmente se lee de la memoria CG RAM los bytes de los
caracteres definidos por el usuario. Previamente se direcciona la memoria DD
RAM o la memoria CG RAM de la que se quiere leer los datos.
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2
1
1
Código ASCII o byte del carácter gráfico
DB1
DB0
Para comenzar a trabajar con un LCD es necesario hacer una
configuración inicial, definiendo los parámetros del cursor, su posición inicial, la
manera de desplegar los datos, el tamaño del dato y la manera de recibirlo, esto
usando las instrucciones anteriormente mencionadas, bueno sin olvidar las
78
configuraciones iniciales que debe llevar todo programa en lenguaje
ensamblador, que son la definición de puertos de entrada y salida y variables.
La configuración de los puertos se muestra a continuación:
RS
Equ 0x04
;El registro de control es toma el valor de 04
RW Equ 0x06
;El modo lectura/escritura tomo el valor de 06
E
Equ 0x07
;El Habilitador o Enable toma el valor de 07
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Facilitara La escritura y comprensión del programa;;;;;;;;;;;
ORG 0X00
;;;;;;;;Configuración De Puerto;;;;;;;;
BSF
STATUS,5 ;Cambia al banco 1
CLRF
TRISB
;Puerto B como salida
BCF
STATUS,5 ; Regresa banco 0
CLRF
PORTB
;Pone el Puerto B en Cero
Los parámetros que se configuran habitualmente son el CLEAR
DISPLAY, SET DISPLAY SHITF, SET DISPLAY CHARACTER MODE y SET
DISPLAY ON/OFF AND CURSOS COMMAND, lo más recomendable en este
orden:
79
La parte del código que corresponde a la inicialización de configuración
del LCD es la siguiente:
;;;;;;;;;;;;;;;;RUTINA PARA CONFIGURAR LCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CONF_LCD
CALL LCD_BUSY
call LCD_Clr
;Borra el display
call DELAY_2MS
movlw 0x20
;0010 0000
call LCD_Cmd
call DELAY_40us
movlw 0x28
;0010 1000 Set display shift
call LCD_Cmd
call DELAY_40us
movlw 0x06
;0000 0110 Set display character mode
call LCD_Cmd
call DELAY_40us
movlw 0x0c
;0000 1100 Set display on
call LCD_Cmd
;Set cursor off
call DELAY_40us
call LCD_Clr
;clear display
call DELAY_2MS
retlw 0x00
Cabe aclarar que en esta parte del programa aparecen subrutinas
que aún no se han nombrado, como LCD_Cmd que se encarga de enviar el
dato, los retardos y el LCD_BUSY.
El LCD_Busy es la manera de revisar que el LCD no esté realizando
alguna otra operación, tanto como de escritura o lectura, para realizar esta
revisión se debe a leer el bit 7 de datos del LCD y habilitar el Enable (E) y
preguntar si está en estado alto o bajo, si está en estado alto quiere decir que
está realizando una operación y entonces se queda esperando hasta que haya
terminado, cuando termina regresa el Enable a esta do bajo y se regresa al
80
modo de escritura y al modo de control, con el siguiente diagrama de flujo se
entenderá mejor:
Entonces la parte de este código quedaría de la siguiente manera:
LCD_BUSY
bsf
clrf
bcf
bcf
bsf
call
OCUPADO btfsc
goto
bcf
bsf
STATUS,5
TRISB
STATUS,5
PORTB, RS
PORTB, RW
PULSE_E
MEMORIA2, 7
OCUPADO
PORTB, RW
STATUS,
5
;banco 1
;Puerto como salida
;regresa al banco 0
;modo registro de control
;modo lectura
;Deja entra salir los datos
; bit 7 activo?
;checa hasta q se desocupe
;se desocupa y habilita modo lectura
;banco 1
81
movlw 0x00
movwf TRISB
bcf
STATUS,
return
;configura como salida puerto b
5
;regresa banco 0
La manera de enviar datos aria con respecto si se configuro de un
bus de 4 bits o uno de 8 bits, la manera más cómoda seria de 8 bits, pero la
manera más práctica es de un bus de 4 bits, ya que se dejan pines disponibles
del Microcontrolador, este programa está configurado para un bus de 4 bits,
para un bus de 4 bits es necesario primero poner R/W en modo de escritura, RS
va a variar dependiendo si se quiere mandar un dato o un comando o
instrucción de configuración, un 1 para datos y 0 para comando, después
revisar con el LCD_Busy si está ocupado el LCD o no, activar el Enable y
posteriormente dividir este dato o comando, según sea el caso, en dos, para así
mandar primero los niveles bajos y después los niveles altos. La parte de este
programa corresponde a las siguientes líneas:
;;;;;;;;;;;;RUTINA PARA CARACTER DE 4 BITS;;;;;;;;;;;;;;;;;;;;;
LCD_Char
call LCD_BUSY
movwf MEMORIA1
swapf MEMORIA1,w
andlw 0x0f
movwf PORTB
bsf
PORTB, RS
call PULSO_E
movf MEMORIA1,w
andlw 0x0f
movwf PORTB
bsf
PORTB, RS
call PULSO_E
;GUARDA EL VALOR DE MEMORIA1 A W
;CAMBIA LOS NIVELES ALTOS
;BORRA LOS VALORES ALTOS
;MANDA LOS BITS BAJOS
;PONE EL REGISTRO DE CONTROL
;MANDA UN PULSO PARA LEER
;MANDAR NIVELES BAJOS
;BORRA LOS NIVELES ALTOS
;Y LOS MANDA POR EL PUERTO B
;RS line to 1
;HABILITA UN PULSO DE ENABLE
82
call LCD_BUSY
retlw 0x00
;;;;;;;;;;;;;;;; RUTINA PARA MANDAR COMANDOS;;;;;;;;;;;;;;;;;;;;;
LCD_Cmd
call LCD_BUSY
movwf MEMORIA1
swapf MEMORIA1,w
andlw 0x0f
movwf PORTB
bcf
PORTB, RS
call PULSO_E
movf MEMORIA1,w
andlw 0x0f
movwf PORTB
bcf
PORTB, RS
call PULSO_E
call LCD_BUSY
retlw 0x00
;GUARDA EL VALOR DE MEMORIA1 A W
;CAMBIA LOS NIVELES ALTOS
;BORRA LOS VALORES ALTOS
;MANDA LOS BITS BAJOS
;Modo de comandos
;MANDA UN PULSO PARA LEER
;Manda los niveles bajos
;Borra los 4 bit más significativos
;Manda niveles bajos por el Puerto B
;RS line to 0
;Activa la entrada de datos
;revisa que no este ocupado el LCD
;regresa con el valor de 0
Ya se tiene la parte de la configuración del PIC, el LCD_Busy que revisa
que no este ocupado, la forma de mandar datos y comandos, solo falta la parte
central del programa que depende directamente de todo lo anterior:
;;;;;;;;;;;;;; PROGRAMA ;;;;;;;;;;;;;;;;
clrf
CONTADOR
;PONE EN 0 EL CONTADOR
MENDAJE
movf CONTADOR, w
call TEXTO
xorlw 0x00
btfsc STATUS, 2
goto fin
call LCD_Char
incf CONTADOR, f
goto MENSAJE
fin
goto fin
;;;;;;;;;;;;;;;;TEXTO;;;;;;;;;;;;;;;;;;;
TEXTO
addwf PCL, f
;PONE EL VALOR DEL CONTADOR EN W
;VA A LA TABLA DONDE ESTA EL TEXTO
;ES IGUAL A 0?
;pregunta por el resultado de la operación
;si es cero termina, sino…
;Va a la rutina para insertar carácter
;incrementa en 1 el contador
;Regresa para adquirir el mensaje
;termina
83
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
b'00010100'
b'01100100'
b'00011100'
b'00010100'
b'00010100'
b'00101110'
b'00010100'
b'00100100'
b'00010100'
b'00100100'
b'00010100'
b'00100100'
b'01000001'
b'01000010'
b'01000001'
0x00
;Los caracteres son ingresados
;mediante código binario
;este valor es sacado de la tabla de caracteres
;aunque también puede escribirse la letra
;y el programa generare el código binario
;correspondiente
Lo que hace el programa es que lleva una cuenta de la veces que se
repite el ciclo, para que cuando mande a la subrutina TEXTO este valor de
CONTADOR va a ser los renglones que va a saltar hacia abajo, y así ira
escribiendo las letras previamente cargadas, también compara el valor 0x00
para determinar si ya se terminó la tabla, y manda el dato con la subrutina
LCD_Char.
Recomendaciones:
La única manera de aprender a programar, es programando, con la
práctica encontraras las particularidades de cada micro y desarrollarlas tu
propia forma de la resolución y análisis de problemas, la única limitante en el
desarrollo de programas el que los realiza, es decir la imaginación que se tiene
para solucionar los problemas.
84
Descargar