Sie sind auf Seite 1von 196

ELABORADO POR:

FRANCISCO TERÁN ARÉVALO


Enero 2017

ÍNDICE:
Prologo……………………………………………………………………………..4

Reglamento para estudiantes……………………………………………………5

Competencias previas……………………………………………………………6

Competencias a desarrollar………………………………………………………6

Practica 1 INTERMITENCIA ASM………………………………………………8

Practica 2…ROTA ASM…………..………………………………………………25

Practica 3…MENU ROTA ASM……………………………………………………30

Practica 3A…MENU CUENTA ASM…………………………………………….. Practica


3A Menu de contadores36
Practica 4…..INT RB0 ASM………………………………………………………47

Practica 5….INT RB ASM……..KEYBOARD……………………………………53

Practica 6….TIMER 0 ASM.………………………………………………………69

Practica 7….TIMER 1 ASM.………………………………………………………81

Practica 8…TIMER 2 ASM..………………………………………………………86


Practica 9……ADC ASM…………………………………………………………92

Practica 10…PUERTO SERIE ASM..……………………………………….….98

Practica 11…INTERMITENCIA C……………………………………………….104

Practica 12…ROTA C…………….………………………………………………107

Practica1 3…MENU ROTA C……………………………………………………111

Practica 14…INTERRUPCION RB0 C…………………………………………117

Practica 15…INTERRUPCION RB KEYBOARD C..…………………………122

Practica 16……TIMER 0 C………….……………………………………………126

Practica 17……TIMER 1 C..………………………………………………………134

Practica 18……TIMER 2 C..………………………………………………………139

Practica 19……ADC C………………………………………………………………144

Practica 20……RS232 C………………………………………………………….…182

Practica 21 ….LCD C ……………………………………………………………….136

Practica 22 …..PWM…………………………………………………………………146

Practica 23 Ultrasonido……………………………………………………………..148

Practica 24 Reloj de Tiempo Real RTC…………………………………………….152

Practica 25 EEPROM………………………………………………………………….160

Practica 26 Generador de tonos………………………………………………………167

Practica 27 Matriz de leds……………………………………………………………183

Proyecto Integrador………………………………………………………………….PROYECTO
+

Prologo:
El desarrollo de la tecnología digital se encuentra en un nivel donde la mayoría de las
aplicaciones que antes se realizaban con electrónica analógica hoy día se resuelven con
en el formato digital.
Los microprocesadores han revolucionado la solución de problemas para múltiples
aplicaciones los vemos cotidianamente en aplicaciones del hogar tales como lavadoras
hornos de microondas electrodomésticos en general, en aplicaciones automotrices para
el control de velocidad del vehículo, para el monitoreo del motor para asistentes en
frenos, tracción, clima etc. Los vehículos actualmente cuentan con diez o más
subsistemas de control basados en sistemas digitales.

La materia Microprocontroladores de la retícula de Ingeniería Electrónica se refiere a:

Esta asignatura aporta al perfil del Ingeniero electrónico el desarrollo de habilidades


para diseñar, analizar y construir equipos o sistemas electrónicos para la solución de
problemas en el entorno, aplicando normas técnicas y estándares nacionales e
internacionales, así como crear, innovar, adaptar, y transferir tecnología en el ámbito
de la ingeniería electrónica mediante la aplicación de métodos y procedimientos
científicos, tomando en cuenta el desarrollo sustentable del entorno.
Además permite gestionar proyectos de investigación y/o desarrollo tecnológico, así
como ejercer actividades emprendedoras de liderazgo y adquirir habilidades para la
toma de decisiones en su ámbito profesional.
En diversas aplicaciones, el uso de la electrónica hace necesario el conocimiento del
diseño basado en sistemas digitales, y el uso de circuitos de alta escala de integración,
como son los microcontroladores, hace algunas aplicaciones más simples, eficientes o
versátiles. Por lo que es conveniente que los alumnos de la carrera de ingeniería
electrónica adquieran dominio en el uso de estos dispositivos.
La materia consiste en el conocimiento de la estructura interna y externa del
microcontrolador, así como la configuración y programación en lenguaje
ensamblador y lenguaje C, de los periféricos integrados y aplicaciones típicas de
microcontroladores.
La asignatura requiere que el estudiante cuente con bases sólidas en diseño digital y
analógico, así como nociones de programación, por lo tanto se relaciona con las
asignaturas de mediciones eléctricas, programación estructurada, fundamentos de
investigación, diseño digital y diseño digital con VHDL, y todas aquellas en las que se
realicen aplicaciones, tales como electrónica de potencia, instrumentación,
amplificadores operacionales, entre otras.
Reglamento para Estudiantes:
1.- El uso de los sistemas de cómputo es exclusivo para la realización de las prácticas
asignadas.

2.- Los equipos utilizados en las practicas deberán utilizarse si se tiene el conocimiento
previo de su manejo. Solicite asistencia al maestro en caso contrario.

3.- No se permite bebidas o alimentos en el interior del laboratorio.

4.- Realizar su práctica lo más individual posible favor de no copiar al compañero.


Solicite asesoría.

Competencias previas:
La asignatura requiere que el estudiante cuente con bases sólidas en diseño digital y
analógico, así como nociones de programación, por lo tanto se relaciona con las asignaturas
de mediciones eléctricas, programación estructurada, fundamentos de investigación, diseño
digital y diseño digital con VHDL, y todas aquellas en las que se realicen aplicaciones, tales
como electrónica de potencia, instrumentación, amplificadores operacionales, entre otras.

Competencias a desarrollar:

Competencias Especificas:
Conocer y explicar el funcionamiento interno y externo del microcontrolador, realizar
programas en lenguaje ensamblador y lenguaje C, utilizando todos los recursos del
microcontrolador, para resolver problemas específicos en el ámbito de la aplicación de la
ingeniería electrónica y en el desarrollo de aplicaciones y de equipo electrónico, para lo cual
el estudiante realizará actividades de investigación, análisis, reflexión, observación, y diseño,
apoyándose en el uso de herramientas computacionales.

Competencias genéricas:
Competencias instrumentales
� Capacidades cognitivas, la capacidad de comprender y manipular ideas y pensamientos.
� Capacidades metodológicas para manipular el ambiente: ser capaz de organizar el tiempo
y las estrategias para el aprendizaje, tomar decisiones o resolver problemas.

� Destrezas tecnológicas relacionadas con el uso de maquinaria, destrezas de


computación; así como, de búsqueda y manejo de información.

� Destrezas lingüísticas tales como la comunicación oral y escrita o


conocimientos de una segunda lengua
Práctica No.1 Intermitencia (ASM).

VIDEO BASICO MPLAB


Objetivo: Que el alumno realice un pequeño programa de prueba en ensamblador para empezar a familiarizarse tanto con el
software como con el hardware.

Introducción: Esta práctica ayudará al alumno a familiarizarse con el software Mplab y al utilizar el simulador le ayudará a
entender como funciona la arquitectura del microcontrolador. En el simulador(MPLABSIM) se pueden ver los movimientos
en los registros, la memoria de datos, la memoria de programa, el registro de estado,etc. Se recomienda abrir una ventana
con los registros utilizados en el programa y correr paso a paso la simulación. Además aprenderá como realizar la conexión
básica del microcontrolador para que funcione correctamente.

El programa funciona de la siguiente manera:


Al energizar el sistema, el led conectado en el pin RB0 encenderá por algunos milisegundos y después se apagará y durará el
mismo tiempo apagado que encendido. Este ciclo se repetirá indefinidamente. Al presionar el pushbotton conectado al pin
MCLR el microcontrolador se reinicia, es decir volverá a comenzar desde el principio.

Esta práctica se correlaciona con el Tema 2.1 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC18F4550
1 Cristal 20 Mhz
2 Capacitores de 22pf o 15pf
2 Leds
1 Resistencia de 10 Kohms
2 Resistencia de 220 ohms
1 Push Button
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
Opcional Tarjeta de desarrollo para practicas DV08
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics

Metodología:

1- Utilice el software MPLAB para editar el programa intermitencia.asm que se muestra mas adelante.
2- Enamble, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido al ensamblar) en el PIC
NOTA: En este primer ejemplo se utiliza la librería para el PIC 16F874 es necesario poner entonces las siguientes
directivas:
LIST P=PIC16F874
#include p16f874.inc

Pero si usted esta utilizando otro microcontrolador ejemplo el PIC 18F4550 entonces la librería cambiaria así:
LIST P=PIC18F4550
#include p18f4550.inc
Si su programador no cuenta con la opción de poner la palabra de configuración , entonces es necesario agregar la
configuración por software con la directiva (__config) de la siguiente forma:

LIST P=PIC16F874
#include p16f874.inc
__config _XT_OSC & _PWRTE_OFF & _WDT_OFF & _CP_OFF & _LVP_OFF & _WRT_ENABLE_OFF

Para el PIC18F4455 se utiliza la directiva (CONFIG) de la siguiente forma:


LIST P=PIC18F4550
#include p18f4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF

Observe que en esta configuración se selecciona la oscilación XT porque el cristal a utilizar es de 4 MHZ y todas
las opciones están en OFF.

4- Arme el circuito de acuerdo al diagrama de conexión.


5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice alguna de las siguientes opciones(el maestro decidirá cual):
a) Cuando prenda el LED en RB0 apague un LED conectado en el pin RC0, realice un retardo de tiempo y luego
prenda el LED en RC0 y apague el LED en RB0, este ciclo lo deberá realizar indefinidamente.
b) Simular las luces de un semáforo asignando al pin RB0 un led de color verde, al pin RB1 un led de color
amarillo y al pin RB2 un led de color rojo. Asigne los tiempos de retardo tal como un semáforo real.
c) Dejar al alumno que utilice su creatividad.
d) Dejar que el maestro ponga una opción diferente a estas.

7- Reporte sus resultados.

Creación de un proyecto usando MPLAB


Paso 1 Localice el programa MPLAB en su computadora con el icono

O en la carpeta de Microchip localizada en la ruta mostrada


Paso 2 Abrir el programa
Mostrará esta ventana: Seleccionar Project para crear un proyecto nuevo.

Paso 3 Seleccione Project Wizard (Asistente de proyecto)


Paso 4 seleccionar dispositivo PIC18F4550 y presione siguiente:

Paso 5 Seleccione ensamblador o compilador a usar (Compilador para programas en C)


Si aparece una tacha Roja significa que no esta en la ruta dada usar el Browser para localizar la ruta correcta.
Paso 6 Crear un proyecto (es buena practica cada proyecto ponerlo en una carpeta.

Queda así:
Paso 7 si tiene un programa en ensamblador para este proyecto agregarlo aquí, si no presione siguiente.
Paso 8 Finalizar:
Paso 9 agregar el archivo fuente (source File)

Copiar el programa listado abajo Intermitencia.asm seleccionando en la pestaña File New y abrirá una ventana
Untilted, copiar ahí como se muestra:

Paso 10 guardar archivo en la carpeta del proyecto: con la extensión .asm


Aparecerá asi:

Paso 11 Agregarlo a la carpeta Source File usando botón derecho del ratón
Aparecerá así:

Paso 11 Ensamblar presionar el icono Build All


Nota:Absolute es cuando lo quiere solo en su computadora y Reloctable cuando quiere cambiarlo de
computadora.
Paso 12 asegure que no hay errores
Ya tenemos nuestro primer programa: visualizar los archivos que se generaron en nuestro proyecto:

El archivo Intermitencia.HEX es el ejecutable puede usarlo en un micro o en un simulador como proteus o


en el mismo simulador MPLABSIM,

Se abrirá esta ventana:


1 Correr
2 Detener
3 Correr animadamente
4 Correr por pasos
5 Reset
B Para Breakpoints (otra forma es poner cursor la li

Abrir una ventana para visualizar las variables y los registros del PIC
Seleccionar en la pestaña view la función Watch.

Se pueden abrir multiples ventanas o las que necesite para visualizar que hace el programa
Ventana de program Memory viualiza las instrucciones, dirección donde se encuentran, código de operación
etiquetas y las instrucciones
Ventana del Harware stock visualiza la posición del apuntador de stack cuando hay subrutinas y la dirección
donde se llamo.
La ventana de File Registers visualiza las variables que se declararon su contenido y dirección
La ventana Watch visualiza al igual que la ventana File Registers lo que el usuario le agregue a la ventana.
Al ejecutarse o correrse paso a paso se verán reflejados los cambios de las variables o registros según la
instrucción que se ejecutó .

Correr animadamente y ver como cambian las variables……


Correr paso a paso y ver como se ejecuta el programa………
Inserar un punto de roptura (Breakpoint) en la instruccion call delay poniendo el cursor antes de la letra D y
dar doble click al mouse aparecerá una B en un circulo rojo en esa instrucción , y correr el programa con el
triangulo verde. (Run) esto ejecutara todo hasta encontrar otro Breakpoint.
Programa fuente:
;**************************************
;* intermitencia.asm *
;* Este programa configura RD0 como salida *
;* y genera una intermitencia en dicha salida *
;* *
;* Rev A: By Ing. Jorge Aguirre
;* Rev B: F. Teran PIC 18F4550 *
;**************************************
;La siguiente configuración solo se utiliza si usamos alguna librería ejemplo:

LIST P=PIC18F4550
#include p18F4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF

CUENTA1 EQU 20H ;las variables que usemos siempre a


;partir de la dirección 20Hh
CUENTA2 EQU 21H
CUENTA3 EQU 23H

F EQU 1 ;Constantes del programa


w EQU 0

ORG 1000H ;Inicia en la dirección 00H de la memoria de


;si se carga a proteus o a un micro sin bootloader
;Si se usa bootloader usar la dirección 1000H
programa
BSF STATUS,5 ;banco 1
BCF TRISD,0 ;RB0 como salida
BCF STATUS,5 ;banco 0
INICIO
BSF PORTD,0 ;Pone a "1" RD0 (enciende)
CALL DELAY ;Llama a la subrutina de retardo
BCF PORTD,0 ;Cuando vuelve del retardo pone
;a "0" RD0 (apaga)
CALL DELAY ;llama a la subrutina de retardo
GOTO INICIO ;cuando vuelve del retardo
;repite el ciclo

;=======================
;= DELAY: Subrutina de retardo =
;= Modifica los siguientes registros: =
;= CUENTA1 =
;= CUENTA2 =
;=======================
;(Conviene hacerse un pequeño resumen de lo que
;hace cada subrutina, puede sernos muy útil para
;usarla en otros programas)
;Subrurtina hecha con 3 lazos anidados

DELAY MOVLW 05cH ;Carga el acumulador W con el valor


;de 05CH (92 en decimal)
MOVWF CUENTA3

ACA3 MOVLW 0ffH ;Carga el acumulador W con el valor


;de FFH (255 en decimal)
MOVWF CUENTA1 ;Mueve el contenido del acumulador
;a CUENTA1
ACA1 MOVLW 0FFH ;Carga CUENTA2 con el valor FFH
MOVWF CUENTA2

ACA DECFSZ CUENTA2,F ;Decrementa CUENTA2, guarda el resultado


;en f(CUENTA2), y si es cero se salta la
;siguiente instrucción
GOTO ACA ;Vuelve a decrementar mientras
;CUENTA2 no sea cero
DECFSZ CUENTA1,F ;Se decrementa CUENTA1 cada vez que
;CUENTA2 llega a cero
GOTO ACA1

DECFSZ CUENTA3,F ;Se decrementa CUENTA3 cada vez que


;CUENTA1 llega a cero
GOTO ACA3

;mientras CUENTA3 no llegue a cero recarga


;CUENTA1 y y CUENTA2 repite el proceso
RETURN ;retorna al programa principal

;= =
;= FIN DE LA SUBRUTINA DELAY =
;===========================

END ;Fin del programa

Diagrama de conexión:
Sugerencias Didácticas:
1.- Por ser el primer programa se le sugiere al maestro de ensamblar y correr el programa de prueba junto con el alumno en
la sala de computo, e ir explicando los pasos requeridos en el MPLAB para editar un programa, realizar un
proyecto(projet), ensamblar(MPASM) y simular (MPLABSIM). Aproveche para enseñar al alumno el ambiente del
MPLAB así como algunas opciones del MPLABSIM.
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Práctica No.2 Rotación del Puerto RD (ASM).


Objetivo: Que el alumno aprenda a manipular los puertos del Microcontrolador en lenguaje Ensamblador.

Introducción:
Esta práctica le ayudará al alumno a conocer la distribución de los puertos y aprenderá a manejarlos. Además de manejar
saltos condicionados e incondicionados y aprenderá a insertar subrutinas en el programa.
El programa funciona de la siguiente manera:
Al energizar el sistema el led que está en el bit RD0 encenderá por un tiempo de aproximádamente de 250 milisegundos,
después de esto se apagará y procederá a encender el led siguiente en el bit RD1, este también durará encendido por un
tiempo de aproximádamente de 250 milisegundos y se apagará. Esta operación se repetirá con todos los demás leds hasta
llegar al último led en el bit RD7. Después de esto este ciclo se repetirá indefinidamente.

Esta práctica se correlaciona con los Temas del 2.2.1 al 2.2.5 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC18F4550
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
8 Leds
1 Resistencia de 10 Kohms
8 Resistencias de 220 ohms
1 Push Button
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics

Metodología:

1- Utilice el software MPLAB para editar el programa rota.asm que se muestra mas adelante.
2- Ensamble, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en la compilación) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice alguna de las siguientes opciones (el maestro decidirá cual):
a) Realice una rotación a la derecha del puerto RD.
b) Realice una rotación a la izquierda y al llegar al bit 7 realizar una rotación a la
derecha hasta el bit 0. Repita el ciclo indefinidamente.
c) Realice una rotación a la izquierda involucrando el puerto RD y RC.
d) Dejar al alumno que utilice su creatividad para hacer los movimientos que
desee de los puertos.
e) Dejar que el maestro ponga una opción diferente a estas.

7- Reporte sus resultados.

NOTA: Para utilizar el programa fuente con el PIC18F4550 sustituya las siguientes directivas:
LIST P=PIC18F4550
#include p18f4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF

Programa fuente:
;************************************************
;* rota.asm *
;* Este programa configura PORTD como salida *
;* y genera una rotacion a la izquierda hasta llegar *
;* al bit 7 enseguida repite de nuevo el ciclo *
;* Rev A: By Ing. Jorge Aguirre *
;* Rev B: Adaptado al 4550 y tarjeta de desarrollo *
;* F. Teran
;************************************************
LIST P=PIC18F4550
#include p18F4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF

CUENTA1 EQU 20H


CUENTA2 EQU 21H
CUENTA3 EQU 22H

F EQU 1
w EQU 0

ORG 1000H
CLRF TRISD ;Puerto RD como salida

INICIO
BCF STATUS,0 ;Limpia el bit 0 del registro STATUS
MOVLW 01H
MOVWF PORTD ;Saca un 01H por el puerto RD

REPETIR
CALL DELAY ;Llama a la subrutina de retardo
RLF PORTD,F ;Rota a la izquierda el puerto RD
BTFSC STATUS,0 ;
GOTO INICIO
GOTO REPETIR ;Brinca a la etiqueta REPETIR

;===========================
; DELAY: Subrutina de retardo
;Rutina de aprox. 250 msegundos
;===========================
DELAY
MOVLW 01H ;Carga el W con el valor 01H
MOVWF CUENTA3 ;Carga CUENTA3 con el valor del W

LAZO3 MOVLW 0F9H ;Carga el W con el valor F9H


MOVWF CUENTA2 ;Carga CUENTA2 con el valor del W
LAZO2 MOVLW 0FAH ;Carga el W con el valor FAH
MOVWF CUENTA1 ;Carga CUENTA1 con el valor del W

LAZO1 NOP
DECFSZ CUENTA1,F ;Decrementa CUENTA1 y sigue en el
GOTO LAZO1 ;lazo1 mientras no sea 0

DECFSZ CUENTA2,F ;Decrementa CUENTA2 y sigue en el


GOTO LAZO2 ;lazo2 mientras no sea 0

DECFSZ CUENTA3,F ;Decrementa CUENTA3 y sigue en el


GOTO LAZO3 ;lazo3 mientras no sea 0

RETURN ;retorna al programa principal

;===========================
;= FIN DE LA SUBRUTINA DELAY =
;===========================

END ;Fin del programa

Diagrama de conexión:

U1
C2 2
RA0/AN0 RC0/T1OSO/T1CKI
15
22p 3 16
RA1/AN1 RC1/T1OSI/CCP2/UOE
4 17
RA2/AN2/VREF-/CVREF RC2/CCP1/P1A
X1 5
RA3/AN3/VREF+ RC4/D-/VM
23
CRYSTAL 6 24
RA4/T0CKI/C1OUT/RCV RC5/D+/VP
7 25
RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK U2
C1 14
RA6/OSC2/CLKO RC7/RX/DT/SDO
26
RN1
13 d1 1 20
22p OSC1/CLKI
a1 16 d1 d22 19
33 19 a b2 15 d2 d33 18
RB0/AN12/INT0/FLT0/SDI/SDA RD0/SPP0
34 20 b c3 14 d3 d44 17
RB1/AN10/INT1/SCK/SCL RD1/SPP1
35 21 c d4 13 d4 d55 16
RB2/AN8/INT2/VMO RD2/SPP2
36 22 d e5 12 d5 d66 15
RB3/AN9/CCP2/VPO RD3/SPP3
37 27 e f6 11 d6 d77 14
RB4/AN11/KBI0/CSSPP RD4/SPP4
38 28 f g7 10 d7 d88 13
RB5/KBI1/PGM RD5/SPP5/P1B
39 29 g h8 9 d8 9 12
RB6/KBI2/PGC RD6/SPP6/P1C
40 30 h 10 11
RB7/KBI3/PGD RD7/SPP7/P1D
220
8 LED-BARGRAPH-GRN
RE0/AN5/CK1SPP
9
RE1/AN6/CK2SPP
10
RE2/AN7/OESPP
18 1
VUSB RE3/MCLR/VPP
PIC18F4550
PROGRAM=p3rota.cof

NOTA:
Sugerencias Didácticas:
1.- Se le sugiere al maestro de ensamblar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Enfocarse en enseñar en el
simulador como esta construida la subrutina de retardo usando las opciones del debugger:
Settings.- Poner la velocidad de ejecución a 4Mhz (por default es de 20Mhz).
StopWatch.- Nos ayudará a verificar el tiempo de retardo de la subrutina.
Set Breakpoint.- Poner punto de paro en el programa en la línea donde se desea que el programa detenga su ejecución,
ejemplo: Poner el cursor en la línea donde se llama a la subrutina DELAY (call DELAY),presionar el botón derecho del
mouse y aparecerá una ventana con varias opciones, seleccione la opción Set-Breakpoint. Realice lo mismo para poner
otro punto de paro en la siguiente instrucción(RLF PORTB,F), de esta forma se puede correr el programa y se detendrá
en la instrucción Call DELAY se pone a zero el Stop wtach se vuelve a correr desde ahí el programa y se detendrá en la
siguiente instrucción mostrándonos en el Stop Watch el tiempo transcurrido en la subrutina DELAY.
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte:
1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] http://www.microchip.com
Práctica No.3 Menú de rotas (ASM).
Objetivo: Que el alumno aprenda a elaborar un menú de opciones en Lenguaje Ensamblador.

Introducción: Esta práctica le ayudará al alumno a conocer la distribución de los puertos y aprenderá a manejarlos para leer
o escribir en ellos. Además de aprender como realizar un menú de opciones en lenguaje ensamblador.
Este programa lee una opción por el puerto C y la muestra por el puerto B.

Esta práctica se correlaciona con el Tema 2.2.5 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC18F4550
1 Cristal 20 Mhz
2 Capacitores de 22pf o 15pf
8 Leds
4 Resistencia de 10 Kohms
8 Resistencias de 220 ohms
1 Push Button
1 Dip Switch (3 o 4 switch)
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics

Metodología:

1- Utilice el software MPLAB para editar el programa Menu.asm que se muestra mas adelante y termínelo para
que tenga 7 opciones de rotas. Las 7 opciones se introducirán en binario por el puerto “C” (opcional-puede
usar un dip switch para introducir la opción) de la siguiente forma:

0000 0000 - No realiza nada


0000 0001 - Rota1
0000 0010 - Rota2
0000 0011 - Rota3
0000 0100 - Rota4
0000 0101 - Rota5
0000 0110 - Rota6
0000 0111 - Rota7

2- Ensamble, Simule y entienda el funcionamiento del programa.


3- Grabe el archivo (.HEX obtenido en el ensamble) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6.-Se puede modificar el programa para que el menú de opciones pueda ser de otras opciones diferentes, el maestro
puede sugerir las opciones o dejar que el alumno utilice su creatividad.
Puede ser por ejemplo que el programa lea un número del puerto C y otro del puerto D y las opciones podrían ser
las operaciones aritméticas (suma, resta, etc.) y/o las operaciones lógicas(And , Or, etc.). El resultado de la
operación que la muestre por el puerto B.
Otro ejemplo sería que lea un número en binario por el puerto C y lo muestre en BCD en un display de 7
segmentos colocado por el puerto B.
7- Reporte sus resultados.

NOTA: Para utilizar el programa fuente con el PIC18F4550 sustituya las siguientes directivas:
LIST P=PIC18F4550
#include p18f4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF

Programa Fuente:
;Programa Fuente:
;***********************************************
;* menurota.asm *
;* Este programa configura PORTD como salida y el *
;* PORTB como entrada. Lee la opción deseada por el PORTB *
;* de un menú de opciones *
;* Rev A: By Ing. Jorge Aguirre *
;* Rev B: F. Teran
;***********************************************
LIST P=PIC18F4550
#include p18f4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF

;Declaración de variables en la memoria


CUENTA1 EQU 20H
CUENTA2 EQU 21H
CUENTA3 EQU 22H
OPCION EQU 23H

F EQU 1
w EQU 0

ORG 1000H

CLRF TRISD ;Puerto RD como salida


MOVLW 0FFH
MOVWF TRISB ;Puerto RB como entrada
BCF INTCON2,7 ;RESISTENCIAS DE PULL-UP EN RB
MOVLW 0FH
MOVWF ADCON1 ;BITS 0-4 DE RB DIGITALES

INICIO
BCF STATUS,0 ;Limpia el bit 0 del registro STATUS

MOVF PORTB,W ;LEER PUERTO C


MOVWF OPCION ;PONER CONTENIDO DE RC EN OPCION

OPCION1 ;Checa si es la opción 1


MOVLW 01H
SUBWF OPCION,W
BTFSC STATUS,2
CALL ROTA1

OPCION2 ;Checa si es la opción 2


MOVLW 02H
SUBWF OPCION, W ;Si la opción =02h al restarlo con W =02h el resultado
BTFSC STATUS,2 ;es cero por lo tanto se levanta la bandera z que esta
CALL ROTA2 ;en el registro STATUS y por lo tanto llama a ROTA2

OPCION3 ;Checa si es la opción 3


MOVLW 03H
SUBWF OPCION,W
BTFSC STATUS,2
CALL ROTA3

; Aquí continué poniendo mas opciones

GOTO INICIO
;===========================
; SUBRUTINA ROTA1
;===========================
ROTA1
BCF STATUS,0 ;BORRA LA BANDERA CARRY
MOVLW 01H
MOVWF PORTD ;Saca un 01H por el puerto RD
REPETIR
CALL DELAY ;Llama a la subrutina de retardo
RLCF PORTD, F ;Rota a la izquierda el puerto RD
BTFSS STATUS,0 ;Salta si el carry es 1 a REURN
GOTO REPETIR ;Brinca a la etiqueta REPETIR
RETURN

;===========================
; SUBRUTINA ROTA2
;===========================
ROTA2
BCF STATUS,0 ;BORRA LA BANDERA CARRY
MOVLW 80H
MOVWF PORTD ;Saca un 80H por el puerto RD
REPETIR2
CALL DELAY ;Llama a la subrutina de retardo
RRCF PORTD, F ;Rota a la derecha el puerto RD
BTFSS STATUS,0 ;Salta si el carry es 1 a REURN
GOTO REPETIR2 ;Brinca a la etiqueta REPETIR2
RETURN

;===========================
; SUBRUTINA ROTA3
;===========================
ROTA3 ;Esta rutina no hace nada solo es de demostración
NOP
RETURN

;===========================
; DELAY: Subrutina de retardo
;Rutina de aprox. 600 milisegundos
;===========================
DELAY
MOVLW 01DH ;Carga el W con el valor 01H
MOVWF CUENTA3 ;Carga CUENTA3 con el valor del W

LAZO3 MOVLW 0F9H ;Carga el W con el valor F9H


MOVWF CUENTA2 ;Carga CUENTA2 con el valor del W
LAZO2 MOVLW 0FAH ;Carga el W con el valor FAH
MOVWF CUENTA1 ;Carga CUENTA1 con el valor del W
LAZO1 NOP
DECFSZ CUENTA1,F ;Decrementa CUENTA1 y sigue en el
GOTO LAZO1 ;lazo1 mientras no sea 0
DECFSZ CUENTA2,F ;Decrementa CUENTA2 y sigue en el
GOTO LAZO2 ;lazo2 mientras no sea 0

DECFSZ CUENTA3,F ;Decrementa CUENTA3 y sigue en el


GOTO LAZO3 ;lazo3 mientras no sea 0

RETURN ;retorna al programa principal

;===========================
;= FIN DE LA SUBRUTINA DELAY =
;===========================

END ;Fin del programa

Diagrama de conexión:

U1
C2 2
RA0/AN0 RC0/T1OSO/T1CKI
15
22p 3 16
RA1/AN1 RC1/T1OSI/CCP2/UOE
4 17
RA2/AN2/VREF-/CVREF RC2/CCP1/P1A
X1 5
RA3/AN3/VREF+ RC4/D-/VM
23
R3
CRYSTAL 6 24
RA4/T0CKI/C1OUT/RCV RC5/D+/VP
7 25
RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK R4
220R
C1 14
RA6/OSC2/CLKO RC7/RX/DT/SDO
26
13
22p OSC1/CLKI R5
220R
33 19
34
RB0/AN12/INT0/FLT0/SDI/SDA RD0/SPP0
20
R6
220R
RB1/AN10/INT1/SCK/SCL RD1/SPP1
35 21
1 36
RB2/AN8/INT2/VMO RD2/SPP2
22
R7
220R
RB3/AN9/CCP2/VPO RD3/SPP3
37 27
0 38
RB4/AN11/KBI0/CSSPP RD4/SPP4
28
R8
220R
RB5/KBI1/PGM RD5/SPP5/P1B
39 29
0 40
RB6/KBI2/PGC RD6/SPP6/P1C
30
R9
220R
RB7/KBI3/PGD RD7/SPP7/P1D
220R
8 R10
RE0/AN5/CK1SPP
9
RE1/AN6/CK2SPP
10
0 18
RE2/AN7/OESPP
1
220R
SW1 VUSB RE3/MCLR/VPP
PIC18F4550 R2
PROGRAM=P5M_Rota.HEX
SW-SPDT 220R

SW2

SW-SPDT

SW3

SW-SPDT D3 D4 D5 D6 D7 D8 D9 D10
LED-GREEN LED-GREEN LED-GREEN LED-GREEN LED-GREEN LED-GREEN LED-GREEN LED-GREEN

NOTA: Agregue una resistencia de protección en serie de 220 Ohms a cada uno de los leds.

Sugerencias Didácticas:
1.- Se le sugiere al maestro de ensamblar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Enfocarse en enseñar en el
simulador como correr el programa paso a paso y ver como se realiza el llamado a una subrutina. Enseñar las opciones
del simulador MPLABSIM ( Step Into, Step Over y Step Out).
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte:
1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc.Graw Hill
[5] Apuntes del Maestro.
[6] http://www.microchip.com
Practica 3A Menu de contadores…..
;Programa Fuente:
;***********************************************
;* menucuenta.asm *
;* Este programa configura PORTD como salida y el *
;* PORTB como entrada. Lee la opción deseada por el PORTB *
;* de un menú de opciones para diferentes contadores de uno y dos digitos
;* y diferentes formas de decodificar a siete segmentos * *
;* Rev A: By F. TERAN *
;***********************************************
LIST P=PIC18F4550
#include p18f4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF

;Declaración de variables en la memoria


CUENTA1 EQU 20H
CUENTA2 EQU 21H
CUENTA3 EQU 22H
OPCION EQU 23H
VAR1 EQU 24H
VAR2 EQU 25H
TEMP EQU 26H
VAR17 EQU 27H
VAR27 EQU 29H
VARU EQU 28H
CONTADEC EQU 2AH
CONTADECU EQU 2BH
CONTADECD EQU 2CH

F EQU 1
w EQU 0

ORG 1000H

CLRF TRISD ;Puerto RD como salida


MOVLW 0FFH
MOVWF TRISB ;Puerto RB como entrada
BCF INTCON2,7 ;RESISTENCIAS DE PULL-UP EN RB
MOVLW 0FH
MOVWF ADCON1 ;BITS 0-4 DE RB DIGITALES

CLRF VAR2,F
movlw 55h
movwf PORTD ;ENVIAR UNOS ALTERNADOS AL PUERTO D PARA CHECAR SI ESTA
;INICIANDO EL PROGRAMA
INICIO

BCF STATUS,0 ;Limpia el bit 0 del registro STATUS

MOVF PORTB,W ;LEER PUERTO B


MOVWF OPCION ;PONER CONTENIDO DE RB EN OPCION

OPCION1 ;Checa si es la opción 1 Y EJECUTA EL CONTADOR UNO


MOVLW 01H
SUBWF OPCION,W
BTFSC STATUS,2
CALL CONTA1

OPCION2 ;Checa si es la opción 2 Y EJECUTA EL CONTADOR DOS


MOVLW 02H
SUBWF OPCION, W ;Si la opción =02h al restarlo con W =02h el resultado
BTFSC STATUS,2 ;es cero por lo tanto se levanta la bandera z que esta
CALL CONTA2 ;en el registro STATUS y por lo tanto llama a CONTA2

OPCION3 ;Checa si es la opción 3 Y EJECUTA EL CONTADOR TRES


MOVLW 03H
SUBWF OPCION,W
BTFSC STATUS,2
CALL CONTA3

OPCION4 ;Checa si es la opción 4 Y EJECUTA EL CONTADOR CUATRO


MOVLW 04H
SUBWF OPCION,W
BTFSC STATUS,2
CALL CONTA4

OPCION5 ;Checa si es la opción 5 Y EJECUTA EL CONTADOR CINCO


MOVLW 05H
SUBWF OPCION,W
BTFSC STATUS,2
CALL CONTA5

OPCION6 ;Checa si es la opción 6 Y EJECUTA EL CONTADOR SEIS


MOVLW 06H
SUBWF OPCION,W
BTFSC STATUS,2
CALL CONTA6

OPCION7 ;Checa si es la opción 7 Y EJECUTA EL CONTADOR SIETE


MOVLW 07H
SUBWF OPCION,W
BTFSC STATUS,2
CALL CONTA7

OPCION8 ;Checa si es la opción 7 Y EJECUTA EL CONTADOR SIETE


MOVLW 08H
SUBWF OPCION,W
BTFSC STATUS,2
CALL CONTA8

; Aquí continué poniendo mas opciones

GOTO INICIO

;===========================
; SUBRUTINA CUENTA8 DECIMAL ASCENDENTE EN DISPLAYS
;===========================

CONTA8
CLRF CONTADEC
MOVLW 3FH
MOVWF VAR17
MOVWF VAR27
MAS1 ; CALL DELAY2
MOVFF CONTADECU,TEMP
CALL CONV7
MOVWF VAR17,F
MOVFF CONTADECD,TEMP
CALL CONV7
MOVWF VAR27,F
MOVLW 0FH ;MASCARA UNIDADES
ANDWF CONTADEC,W
MOVWF CONTADECU
MOVLW 0F0H ;MASCARA P DECENAAS
ANDWF CONTADEC,W
MOVWF CONTADECD
SWAPF CONTADECD
MOVLW 01
ADDWF CONTADEC,W
DAW
MOVWF CONTADEC
MOVFF PORTB,OPCION
MOVLW 08
CPFSEQ OPCION
RETURN
GOTO MAS1

;===========================
; SUBRUTINA CUENTA1
;===========================
CONTA1
MOVLW 00H

MOVWF VAR1 ;Saca un 00H por el puerto RD


MOVLW 3FH
MOVWF PORTD
REPETIR
CALL DELAY ;Llama a la subrutina de retardo

INCF VAR1 ;INCREMENTA CONTADOR


MOVLW 01H
CPFSEQ VAR1 ;COMPARA CONTADOR CON 01 SI ES SACAR SU CODIGO EN 7 SEGM
GOTO DOS ;NO FUE UNO REVISA SI ES DOS
MOVLW 06H ;CODIGO DEL UNO
MOVWF PORTD ;SACAR AL DISPLAY
DOS
MOVLW 02H ;COMPARA SI FUE DOS Y SACA CODIGO DEL DOS
CPFSEQ VAR1 ;EN SIETE SEGMENTOS SI NO FUE CHECAR SI ES TRES
GOTO TRES
MOVLW 5BH
MOVWF PORTD
TRES
MOVLW 03H ;COMPARA SI FUE TRES Y SACA CODIGO DEL TRES
CPFSEQ VAR1 ;EN SIETE SEGM SI NO FUE CHECAR SI ES CUATRO
GOTO CUATRO
MOVLW 4FH
MOVWF PORTD
CUATRO
MOVLW 04H ;COMPARA SI FUE CUATRO Y SACA CODIGO DE CUATRO
CPFSEQ VAR1 ;EN SIETE SEGMENTOS SI NO FUE CHECAR EL CINCO
GOTO CINCO
MOVLW 66H
MOVWF PORTD
CINCO
MOVLW 05H ;COMPARA SI FUE CINCO Y SACA CODIGO DE CINCO
CPFSEQ VAR1 ;EN SIETE SEGMENTOS SI NO FUE CHECAR SEIS
GOTO SEIS
MOVLW 6DH
MOVWF PORTD
SEIS
MOVLW 06H ;COMPARA SI FUE SEIS Y SACA CODIGO DE SIES
CPFSEQ VAR1 ;EN SIETE SEGMENTOS SI NO FUE CHECAR SIETE
GOTO SIETE
MOVLW 7DH
MOVWF PORTD
SIETE
MOVLW 07H ;COMPARA SI FUE SIETE Y SACA CODIGO DE SIETE
CPFSEQ VAR1 ;EN SIETE SEGMENTOS SI NO FUE CHECAR OCHO
GOTO OCHO
MOVLW 07H
MOVWF PORTD
OCHO
MOVLW 08H ;COMPARA SI FUE OCHO Y SACA CODIGO DE OCHO
CPFSEQ VAR1 ;EN SIETE SEGMENTOS SO NO FUE CHECAR NUEVE
GOTO NUEVE
MOVLW 7FH
MOVWF PORTD
NUEVE
MOVLW 09H ;COMPARA SI FUE NUEVE Y SACA CODIGO DE NUEVE
CPFSEQ VAR1 ;EN SIETE SEGMENTOS SI NO FUE CHECAR "A"
GOTO DIEZ ;Y TERMINAR RUTINA
MOVLW 6FH
MOVWF PORTD
DIEZ

MOVLW 0AH
CPFSEQ VAR1
GOTO REPETIR ;Brinca a la etiqueta REPETIR
RETURN

;===========================
; SUBRUTINA CUENTA2
;===========================
;SUBRUTINA CONTADOR DE NUEVE A CERO
CONTA2
MOVLW 09H

MOVWF VAR1 ;Saca un 09H por el puerto RD


MOVLW 6FH
MOVWF PORTD
REPETIR2
CALL DELAY ;Llama a la subrutina de retardo

DECF VAR1 ;DECREMENTA CONTADOR


MOVLW 01H
CPFSEQ VAR1 ;CHECA SI FUE UNO Y SACA SU CODIGO
GOTO DOS2 ;SI NO FUE CHECAR SI ES DOS
MOVLW 06H
MOVWF PORTD
DOS2
MOVLW 02H
CPFSEQ VAR1 ;CHECA SI FUE DOS Y SACA SU CODIGO
GOTO TRES2 ;SI NO FUE CHECAR SI ES TRES
MOVLW 5BH
MOVWF PORTD
TRES2
MOVLW 03H
CPFSEQ VAR1 ;CHECA SI FUE TRES Y SACA SU CODIGO
GOTO CUATRO2 ;SI NO FUE CHECAR SI ES CUATRO
MOVLW 4FH
MOVWF PORTD
CUATRO2
MOVLW 04H
CPFSEQ VAR1 ;CHECA SI FUE CUATRO Y SACA SU CODIGO
GOTO CINCO2 ;SI NO FUE CHECAR SI ES CINCO
MOVLW 66H
MOVWF PORTD
CINCO2
MOVLW 05H
CPFSEQ VAR1 ;CHECA SI FUE CINCO Y SACA SU CODIGO
GOTO SEIS2 ;SI NO FUE CHECAR SI ES SEIS
MOVLW 6DH
MOVWF PORTD
SEIS2
MOVLW 06H
CPFSEQ VAR1 ;CHECA SI FUE SEIS Y SACA SU CODIGO
GOTO SIETE2 ;SI NO FUE CHECAR SI ES SIETE
MOVLW 7DH
MOVWF PORTD
SIETE2
MOVLW 07H
CPFSEQ VAR1 ;CHECA SI FUE SIETE Y SACA SU CODIGO
GOTO OCHO2 ;SI NO FUE CHECAR SI ES OCHO
MOVLW 07H
MOVWF PORTD
OCHO2
MOVLW 08H
CPFSEQ VAR1 ;CHECA SI FUE OCHO Y SACA SU CODIGO
GOTO NUEVE2 ;SI NO FUE CHECAR SI ES NUEVE
MOVLW 7FH
MOVWF PORTD
NUEVE2
MOVLW 00H
CPFSEQ VAR1 ;CHECA SI FUE CERO Y SACA SU CODIGO
GOTO DIEZ2 ;SI NO FUE CHECAR SI ES 0FFH
MOVLW 3FH
MOVWF PORTD
DIEZ2

MOVLW 0FFH
CPFSEQ VAR1
GOTO REPETIR2 ;Brinca a la etiqueta REPETIR
RETURN

;===========================
; SUBRUTINA CUENTA3
;===========================
CONTA3 ;Esta rutina cuenta de cero al nueve
MOVLW 00
MOVWF VAR1 ;variable que lleva la cuenta inicializar en cero
OTRO
MOVFF VAR1,TEMP ;se lleva a temp para convertirla en 7 segmentos
CALL CONV7 ;llama conversion a siete segentos
MOVWF PORTD ; saca 7 segm por puerto D
CALL DELAY ; llama retraso de tiempo ,5 seg aprox
INCF VAR1 ;incrementa variable contador
MOVLW 10H ;checa si la lleva diez cuentas
CPFSEQ VAR1
GOTO OTRO ;no lleva diez genera otro

CLRF VAR1 ;ya llego a 10 inicializa contador en cero


RETURN

;===========================
; SUBRUTINA CUENTA4
;===========================
;esta rutina cuenta de 00-FF hexadecimal multiplexa en delay2
CONTA4
CLRF VAR1 ;inicializa en cero la cuenta
OTRO2
MOVFF VAR1,VARU ;llevamos la cuenta a la variable VARU
MOVLW 0FH ;elimina la parte alta de VARU
ANDWF VARU,W
MOVWF TEMP ;lleva parte baja de cuenta a temp. para
CALL CONV7 ;convertir en siete sementos el resulatdo queda en W
; MOVWF PORTD
MOVWF VAR17,F ;se guarda parte baja del conta en 7 segm en VAR17
MOVFF VAR1,VARU ;se lleva contador a VARU
SWAPF VARU ;se intercambia primer digito del segundo digito de contador
MOVLW 0FH ;se elimina la parte alta
ANDWF VARU,W

MOVWF TEMP ; se lleva a temp para su conversion


CALL CONV7 ; a siete segmentos
; MOVWF PORTD
MOVWF VAR27,F ; se guarda la conversion en VAR27
CALL DELAY2 ;llama delay2 para multiplexar y esperar un tiempo
INCF VAR1 ;incrementa contador
MOVLW 00H
CPFSEQ VAR1 ;compara contgador con cero p' checar si ya dio vuelta
GOTO OTRO2 ;no ha terminado de dar vuelta continua
; CLRF VAR1
; INCF VAR2
; MOVLW 10H
; CPFSEQ VAR2
; CLRF VAR2
RETURN
;===========================
; SUBRUTINA CUENTA5
;===========================
;CONTADOR DE CERO A 99
CONTA5
CLRF VAR1 ;inicializa en cero la cuenta
OTRO25
MOVFF VAR1,VARU ;llevamos la cuenta a la variable VARU
MOVLW 0FH ;elimina la parte alta de VARU
ANDWF VARU,W
MOVWF TEMP ;lleva parte baja de cuenta a temp. para
CALL CONV7 ;convertir en siete sementos el resulatdo queda en W
; MOVWF PORTD
MOVWF VAR17,F ;se guarda parte baja del conta en 7 segm en VAR17
MOVFF VAR1,VARU ;se lleva contador a VARU
SWAPF VARU ;se intercambia primer digito del segundo digito de contador
MOVLW 0FH ;se elimina la parte alta
ANDWF VARU,W

MOVWF TEMP ; se lleva a temp para su conversion


CALL CONV7 ; a siete segmentos
; MOVWF PORTD
MOVWF VAR27,F ; se guarda la conversion en VAR27
CALL DELAY2 ;llama delay2 para multiplexar y esperar un tiempo
; INCF VAR1 ;incrementa contador
MOVF VAR1,W ;LLEVAR CONTADOR A W
ADDLW 01 ;INCREMENTAR CONTADOR
DAW ;AJUSTAR A DECIMAL
MOVWF VAR1,F ;REGRESAR CONTADOR EN DECIMAL A VAR1
MOVLW 00H
CPFSEQ VAR1 ;compara contador con cero p' checar si ya dio vuelta
GOTO OTRO25 ;no ha terminado de dar vuelta continua
RETURN

;===========================
; SUBRUTINA CUENTA6
;===========================

;CONTADOR DE CERO A 59
CONTA6
CLRF VAR1 ;inicializa en cero la cuenta
OTRO26
MOVFF VAR1,VARU ;llevamos la cuenta a la variable VARU
MOVLW 0FH ;elimina la parte alta de VARU
ANDWF VARU,W
MOVWF TEMP ;lleva parte baja de cuenta a temp. para
CALL CONV7 ;convertir en siete sementos el resulatdo queda en W
; MOVWF PORTD
MOVWF VAR17,F ;se guarda parte baja del conta en 7 segm en VAR17
MOVFF VAR1,VARU ;se lleva contador a VARU
SWAPF VARU ;se intercambia primer digito del segundo digito de contador
MOVLW 0FH ;se elimina la parte alta
ANDWF VARU,W

MOVWF TEMP ; se lleva a temp para su conversion


CALL CONV7 ; a siete segmentos

MOVWF VAR27,F ; se guarda la conversion en VAR27


CALL DELAY2 ;llama delay2 para multiplexar y esperar un tiempo

MOVF VAR1,W ;LLEVAR CONTADOR A W


ADDLW 01 ;INCREMENTAR CONTADOR
DAW ;AJUSTAR A DECIMAL
MOVWF VAR1,F ;REGRESAR CONTADOR EN DECIMAL A VAR1
MOVLW 60H
CPFSEQ VAR1 ;compara contador con SESENTA p' checar si ya dio vuelta
GOTO OTRO26 ;no ha terminado de dar vuelta continua
RETURN

RETURN

;===========================
; SUBRUTINA CUENTA7
;===========================

;CONTADOR DE CERO A 99
CONTA7
CLRF VAR1 ;inicializa en cero la cuenta
OTRO27
MOVFF VAR1,VARU ;llevamos la cuenta a la variable VARU
MOVLW 0FH ;elimina la parte alta de VARU
ANDWF VARU,W
MOVWF TEMP ;lleva parte baja de cuenta a temp. para
CALL CONV7 ;convertir en siete sementos el resulatdo queda en W
; MOVWF PORTD
MOVWF VAR17,F ;se guarda parte baja del conta en 7 segm en VAR17
MOVFF VAR1,VARU ;se lleva contador a VARU
SWAPF VARU ;se intercambia primer digito del segundo digito de contador
MOVLW 0FH ;se elimina la parte alta
ANDWF VARU,W

MOVWF TEMP ; se lleva a temp para su conversion


CALL CONV7 ; a siete segmentos
; MOVWF PORTD
MOVWF VAR27,F ; se guarda la conversion en VAR27
CALL DELAY2 ;llama delay2 para multiplexar y esperar un tiempo
; INCF VAR1 ;incrementa contador
MOVF VAR1,W ;LLEVAR CONTADOR A W
ADDLW 01 ;INCREMENTAR CONTADOR
DAW ;AJUSTAR A DECIMAL
MOVWF VAR1,F ;REGRESAR CONTADOR EN DECIMAL A VAR1
MOVLW 00H
CPFSEQ VAR1 ;compara contador con cero p' checar si ya dio vuelta
GOTO OTRO27 ;no ha terminado de dar vuelta continua
RETURN
RETURN
;=================================
;= INICIA LA SUBRUTINA CONV_7_SEGM = EL NUMERO A CONVERTIR ESTA EN TEMPORAL Y REGRESA
EN W
;=================================
CONV7 ;RUTINA DE CONVERSION A 7 SEGMENTOS
MOVF TEMP,W
ADDWF TEMP,W
MOVFF PCL, 01H ;HACE UN RESPALDO DEL PCL
ADDWF PCL, F ;SUMA EL REGISTRO W CON PCL EL RESULTADO SE ALMACENA EN
;PCL Y BRINCA DEACUERDO AL DATO REQUERIDO
RETLW 3Fh ;CODIGO DE 7 SEGMENTOS P'CERO 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 06h ;CODIGO DE 7 SEGM P'UNO 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 5Bh ;CODIGO DE 7 SEGM P'DOS 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 4Fh ;CODIGO DE 7 SEGM P'TRES 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 66h ;CODIGO DE 7 SEGM P'CUATRO 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 6Dh ;CODIGO DE 7 SEGM P'CINCO 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 7Dh ;CODIGO DE 7 SEGM P'SEIS 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 07h ;CODIGO DE 7 SEGM P'SIETE 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 7Fh ;CODIGO DE 7 SEGM P'OCHO 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 6Fh ;CODIGO DE 7 SEGM P'NUEVE 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 77h ;CODIGO DE 7 SEGMENTOS P'A 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 7Ch ;CODIGO DE 7 SEGMENTOS P'B 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 39h ;CODIGO DE 7SIETE SEGM P'C 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 5Eh ;CODIGO DE 7 SEGMENTOS P'D 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 79h ;CODIGO DE 7 SEGMENTOS P'E 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 71h ;CODIGO DE 7 SEGMENTOS P'F 0gfedcba <--MENOS SIGNIFICATIVO

;=======================================
;= FIN DE LA SUBRUTINA CONVERSION 7 SEGM =
;=======================================

;===========================
; DELAY: Subrutina de retardo
;Rutina de aprox. 250 milisegundos
;===========================
DELAY
; return
MOVLW 012H ;Carga el W con el valor 01H
MOVWF CUENTA3 ;Carga CUENTA3 con el valor del W

LAZO3 MOVLW 0F9H ;Carga el W con el valor F9H


MOVWF CUENTA2 ;Carga CUENTA2 con el valor del W
LAZO2 MOVLW 0FAH ;Carga el W con el valor FAH
MOVWF CUENTA1 ;Carga CUENTA1 con el valor del W
LAZO1 NOP
DECFSZ CUENTA1,F ;Decrementa CUENTA1 y sigue en el
GOTO LAZO1 ;lazo1 mientras no sea 0

DECFSZ CUENTA2,F ;Decrementa CUENTA2 y sigue en el


GOTO LAZO2 ;lazo2 mientras no sea 0

DECFSZ CUENTA3,F ;Decrementa CUENTA3 y sigue en el


GOTO LAZO3 ;lazo3 mientras no sea 0

RETURN ;retorna al programa principal

;===========================
;= FIN DE LA SUBRUTINA DELAY =
;===========================

;===========================
; DELAY: Subrutina de retardo
;Rutina de aprox. 250 milisegundos
;===========================
DELAY2
MOVLW 10H ;Carga el W con el valor 01H
MOVWF CUENTA3 ;Carga CUENTA3 con el valor del W

LAZO32 MOVLW 0F9H ;Carga el W con el valor F9H


MOVWF CUENTA2 ;Carga CUENTA2 con el valor del W
LAZO22 MOVLW 0FAH ;Carga el W con el valor FAH
MOVWF CUENTA1 ;Carga CUENTA1 con el valor del W
LAZO12
MOVFF VAR17,PORTD
;CALL DELAY3
MOVF VAR27,W
MOVLW 80H
ADDWF VAR27,W
MOVWF PORTD
DECFSZ CUENTA1,F ;Decrementa CUENTA1 y sigue en el
GOTO LAZO12 ;lazo1 mientras no sea 0

DECFSZ CUENTA2,F ;Decrementa CUENTA2 y sigue en el


GOTO LAZO22 ;lazo2 mientras no sea 0

DECFSZ CUENTA3,F ;Decrementa CUENTA3 y sigue en el


GOTO LAZO32 ;lazo3 mientras no sea 0

RETURN

;===========================
; DELAY: Subrutina de retardo
;Rutina de aprox. 250 milisegundos
;===========================
DELAY3
MOVLW 01H ;Carga el W con el valor 01H
MOVWF CUENTA3 ;Carga CUENTA3 con el valor del W

LAZO33 MOVLW 09H ;Carga el W con el valor F9H


MOVWF CUENTA2 ;Carga CUENTA2 con el valor del W
LAZO23 MOVLW 0AH ;Carga el W con el valor FAH
MOVWF CUENTA1 ;Carga CUENTA1 con el valor del W
LAZO13 NOP
; MOVFF VAR1_7,PORTD
; CALL DELAY3
; MOVF VAR1_7,W
; MOVLW 80H
; ADDWF VAR1_7,W
; MOVWF PORTD
DECFSZ CUENTA1,F ;Decrementa CUENTA1 y sigue en el
GOTO LAZO13 ;lazo1 mientras no sea 0

DECFSZ CUENTA2,F ;Decrementa CUENTA2 y sigue en el


GOTO LAZO23
;lazo2 mientras no sea 0

DECFSZ CUENTA3,F ;Decrementa CUENTA3 y sigue en el


GOTO LAZO33 ;lazo3 mientras no sea 0

RETURN

END ;Fin del programa

Práctica No.4 Interrupción Externa INTRB0 (ASM).


Objetivo: Desarrollar una rutina de servicio para la interrupción externa INTRB0 en Lenguaje Ensamblador

Introducción:
Con el desarrollo de esta práctica el alumno comprenderá como el programa se interrumpe cuando se provoca una
interrupción por el pin RB0 (un cambio de estado en el pin RB0) y brincará a la localidad 04H de la memoria de programa
para ejecutar la rutina de servicio que atiende dicha interrupción. La rutina de servicio de interrupción invierte el estado del
bit RD0 cada vez que se presione el push botton (dispositivo que provoca la interrupción), dicho cambio de estado se
mostrará por el pin RD0 a través de un Led.

Esta practica se correlaciona con el Tema 2.2 y principalmente con el subtema 2.2.5.4 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC18F4550
1 Cristal 20 Mhz
2 capacitores de 22pf o 15pf
1 Led
2 Push Button
1 Resistencia de 10k
1 Resistencia de 220 Ohms
1 Resistencia de 1 Mhoms
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics

Metodología:
1- Utilice el software MPLAB para editar el programa intrb0.asm que se muestra mas adelante.
2- Ensamble, simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en el ensamble) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice una tarea diferente en la rutina de servicio de interrupción puede
ser alguna de las siguientes:
a) Que vaya incrementando un contador cada vez que se presione el push botton y que dicha cuenta la muestre en
binario por el puerto C a través de 8 leds.
b) Que vaya incrementando un contador cada vez que se presione el push botton y que dicha cuenta la muestre en
BCD a través de un display doble de 7 segmentos conectados por el puerto C.
c) Que realice una rotación hacia la izquierda de unos leds conectados por el puerto C cuando se presione por
primera vez el push botton y que cambie el sentido las siguientes veces que se vuelva a presionar el push
boton.
d) Se puede dejar libre al alumno para que utilice su creatividad.
e) Dejar que el maestro ponga una opción diferente a estas.
7- Reporte sus resultados.

NOTA: Para utilizar el programa fuente con el PIC18F4550 sustituya las siguientes directivas:
LIST P=PIC18F4550
#include p18f4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF
Cambiar la dirección de la rutina de servicio de interrupción : (ORG 04H) por (ORG 08H)

Puesto que el pin RB0 es por default canal análogo AN12 ponga las siguientes instrucciones para hacerlo digital:
MOVLW 0FH ;Estas 2 instrucciones Solo poner para el
MOVWF ADCON1 ;PIC18F4550 (Pone todos los ANx a Digitales)
;Programa fuente:

;*******************************************
;* intrb0.asm *
;* Este programa CUENTA EN BINARIO EN PORTD cada *
;* vez que se modifica el estado del pin RB0 *
;* Para ello se habilita la interrupción INTRB0 *
;* Rev A: By Ing. Jorge Aguirre *
;* Rev B: By Ing. F. Teran adaptado al 4550 *
;*******************************************
LIST P=PIC18F4550
#include p18f4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF

CUENTA1 EQU 22H


CUENTA2 EQU 23H
CUENTA3 EQU 24H
CUENTA4 EQU 25H
CUENTA5 EQU 26H
ACUM EQU 20H ;Variable localizada en la dirección 20H
STAT EQU 21H ;Variable localizada en la dirección 21H

F EQU 1
w EQU 0

ORG 1000H
GOTO INICIO ;ponemos este GOTO al principio para poder poner
;el subprograma de las interrupciones a partir de
;la dirección 08h
;Comienza la interrupción:
;=========================

ORG 1008H ;El pic salta a esta dirección cuando se produce


;una interrupción EN LA TARJETA DE DESARROLLO
BCF INTCON,4 ;DESHABILITAMOS INT0 PARA EVITAR REBOTE
CALL DELAYC ;DELAY DE 10 mS APROX TIEMPO DEL REBOTE
; CALL DELAYC ;UN MILISEGUNDO CADA CALL APROX.
; CALL DELAYC
; CALL DELAYC
; CALL DELAYC
; CALL DELAYC
; CALL DELAYC
; CALL DELAYC
BSF INTCON,4 ;HABILITAMOS INTERRUPCION TO
; BSF INTCON3,3 ;HABILITAMOS INTERRUPCION T1
BCF INTCON,1 ;bit que indica un cambio en RB0, recuerda que
;hay que ponerlo a "0" por programa
; BCF INTCON3,0 ;bit que indica un cambio en RB1, recuerda que
;hay que ponerlo a "0" por programa
;comenzamos guardando el contenido del acumulador
;y del STATUS para restaurarlos antes de salir de
;la interrupción (es recomendable hacer esto
;siempre que se usen interrupciones)

MOVWF ACUM ;Copia el acumulador W al registro ACUM


MOVF STATUS, W ;Guarda STATUS en el acumulador
;programa principal salta la interrupción
;Por si acaso, nunca se sabe en que parte de
;programa principal salta la interrupción
MOVWF STAT ;Copia el acumulador al registro STAT

;============================
INCF PORTD ;INCREMENTA PUERTOD CADA VEZ QUE SE PRESIONA RB0
;===================================
;ahora hay que restaurar los valores del STATUS y
;del acumulador antes de salir de la interrupción:

MOVF STAT, W ;Guarda el contenido de STAT en el acumulador


MOVWF STATUS ;Restaura el STATUS
SWAPF ACUM, F ;Da la vuelta al registro ACUM
SWAPF ACUM, W ;Vuelve a dar la vuelta al registro ACUM y restaura
;el acumulador (Con la instrucción SWAPF para no
;alterar el STATUS, la instrucción MOVF altera el
;bit 2 del STATUS)
RETFIE ;fin de la interrupción

INICIO

MOVLW 00H ;Todos los bits del acumulador a "0"


MOVWF TRISD ;Configuramos todo el puerto D como salidas
BCF INTCON2,7 ;RESISTENCIAS DE PULL-UP EN RB

MOVLW 0FFH ;Todos los bits del acumulador a "1"


MOVWF TRISB ;Configuramos todo el puerto B como entradas

MOVLW 0FH ;Estas 2 instrucciones Solo poner para el


MOVWF ADCON1 ;PIC18F4550 (Pone todos los ANx a Digitales)
BSF INTCON2,5 ;SELECCIONA EL RAISING EDGE PARA LA INTERRUPCION T0
; BSF INTCON2,6 ;SELECCIONA EL RAISING EDGE PARA LA INTERRUPCION T1
;====================================
;Configuración de las interrupciones:

BSF INTCON,7 ;Habilita las interrupciones globalmente


;BSF INTCON3,3 ;Habilita la interrupción por cambio en RB1
BSF INTCON,4 ;Habilita la interrupción por cambio en RB0
CLRF PORTD
;====================================
;ya están configuradas las interrupciones, a
;partir de ahora cuando haya un cambio en RB0
;saltará a la dirección 04h del programa
NADA

GOTO NADA ;NO HACE NADA

DELAYC ;RETRAZO DE TIEMPO DE 960 MICROSEGUNDOS


; RETURN
MOVLW 0FH
MOVWF CUENTA4
OTRO21
MOVLW 0FFH
MOVWF CUENTA5
OTRO5
DECFSZ CUENTA5
GOTO OTRO5
DECFSZ CUENTA4
GOTO OTRO21

RETURN
END ;FIN DE PROGRAMA

Diagrama de conexión:
U1
C2 2
RA0/AN0 RC0/T1OSO/T1CKI
15
22p 3 16
RA1/AN1 RC1/T1OSI/CCP2/UOE
4 17
RA2/AN2/VREF-/CVREF RC2/CCP1/P1A
X1 5
RA3/AN3/VREF+ RC4/D-/VM
23
CRYSTAL 6 24
RA4/T0CKI/C1OUT/RCV RC5/D+/VP
7 25
RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK U2
C1 14
RA6/OSC2/CLKO RC7/RX/DT/SDO
26
RN1
13 d1 1 20
22p OSC1/CLKI
a1 16 d1 d22 19
33 19 a b2 15 d2 d33 18
RB0/AN12/INT0/FLT0/SDI/SDA RD0/SPP0
34 20 b c3 14 d3 d44 17
RB1/AN10/INT1/SCK/SCL RD1/SPP1
35 21 c d4 13 d4 d55 16
RB2/AN8/INT2/VMO RD2/SPP2
36 22 d e5 12 d5 d66 15
RB3/AN9/CCP2/VPO RD3/SPP3
37 27 e f6 11 d6 d77 14
1 38
RB4/AN11/KBI0/CSSPP
RB5/KBI1/PGM
RD4/SPP4
RD5/SPP5/P1B
28 f g7 10 d7 d88 13
39 29 g h8 9 d8 9 12
RB6/KBI2/PGC RD6/SPP6/P1C
40 30 h 10 11
RB7/KBI3/PGD RD7/SPP7/P1D
220
8 LED-BARGRAPH-GRN
RE0/AN5/CK1SPP
9
RE1/AN6/CK2SPP
10
RE2/AN7/OESPP
18 1
VUSB RE3/MCLR/VPP
PIC18F4550
PROGRAM=p3rota.cof

Sugerencias Didácticas:
1.- Se le sugiere al maestro de ensamblar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Correr el programa paso a paso y
ver como se genera la interrupción al cambiar el estado del pin RB0, como brinca a la dirección 08H de la memoria de
programa y enfatizar que lo primero que hay que hacer es borrar la bandera que indica que hubo en cambio en RB0 (bit 1
del registro INTCON). Indicar la importancia de guardar el acumulador(W) y el registro de estado en memoria RAM antes
de hacer algo en la rutina de interrupción y después antes de regresarse de la interrupción recuperar nuevamente lo que
tenia el acumulador(W) y el registro de estado antes de la interrupción.
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte:
1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] http://www.microchip.com
Práctica No.5 Interrupción del puerto RB (ASM).
Objetivo: Desarrollar una rutina de servicio para la interrupción externa por el puerto RB(pines RB7,RB6,RB5 y RB4) en
Lenguaje Ensamblador.

Introducción:
Con el desarrollo de esta práctica el alumno comprenderá como el programa se interrumpe cuando se provoca una
interrupción por el puerto RB (específicamente cuando cambia de estado alguno de los pines RB7,RB6,RB5 y RB4) y
brincará a la localidad 08H de la memoria de programa para ejecutar la rutina de servicio que atiende dicha interrupción. La
rutina de servicio de interrupción invierte el estado del bit RC0 cada vez que se presione alguno de los push botton
(dispositivo que provoca la interrupción) conectados a los pines RB7,RB6,RB5 y RB4, dicho cambio de estado se mostrara
por el pin RD0 a través de un Led.

Esta práctica se correlaciona con el Tema 2.2 y principalmente con el subtema 2.2.5.4 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC18F4550
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
1 Led
5 Push Button
1 Resistencia de 1k
4 Resistencias de 1 Mohm
1 Resistencia de 220 Ohms
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics

Metodología:

1- Utilice el software MPLAB para editar el programa intRB.asm que se muestra mas adelante.
2- Ensamble, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en el ensamble) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice una tarea diferente en la rutina de servicio de interrupción puede
ser alguna de las siguientes:
f) Que vaya incrementando un contador cada vez que se presione cualquiera de los push button y que dicha
cuenta la muestre en binario por el puerto C a través de 8 leds.
g) Que vaya incrementando un contador cada vez que se presione cualquiera de los push button y que dicha
cuenta la muestre en BCD a través de un display doble de 7 segmentos conectados por el puerto C.
h) Que realice una rotación hacia la izquierda de unos leds conectados por el puerto C cuando se presione por
primera vez el push button y que cambie el sentido las siguientes veces que se vuelva a presionar el push
button.
i) Se puede dejar libre al alumno para que utilice su creatividad.
j) Dejar que el maestro ponga una opción diferente a estas.

7- Reporte sus resultados.

NOTA: Para utilizar el programa fuente con el PIC18F4550 sustituya las siguientes directivas:
LIST P=PIC18F4550
#include p18f4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF
Cambiar la dirección de la rutina de servicio de interrupción : (ORG 04H) por (ORG 08H)
Puesto que el pin RB0 es por default canal análogo AN12 ponga las siguientes instrucciones para hacerlo digital:
MOVLW 0FH ;Estas 2 instrucciones Solo poner para el
MOVWF ADCON1 ;PIC18F4550 (Pone todos los ANx a Digitales)

Programa fuente:
;*******************************************
;* intrb.asm *
;* Este programa invierte el estado del pin RC0 cada *
;* vez que se modifica el estado del pin RB7,RB6,RB5 *
;* o RB4 Para ello se habilita la interrupción RB *
;* Rev A: By Ing. Jorge Aguirre *
;********************************************
LIST P=PIC18F4550
#include p18f4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF

CUENTA1 EQU 20H ;variables a partir de la dirección 20H


CUENTA2 EQU 21H
CUENTA3 EQU 22H

ACUM EQU 23H ;Variable localizada en la dirección 20H


STAT EQU 24H ;Variable localizada en la dirección 21H
LEIDO EQU 25H

F EQU 1 ;Constantes
w EQU 0

ORG 1000H
GOTO INICIO ;ponemos este GOTO al principio para poder poner
;el subprograma de las interrupciones a partir de
;la dirección 04h

;Comienza la interrupción:
;=========================

ORG 1008H ;El pic salta a esta dirección cuando se produce


;una interrupción
BCF INTCON,0 ;bit que indica un cambio en RB, recuerda que
;hay que ponerlo a "0" por programa
;comenzamos guardando el contenido del acumulador
;y del STATUS para restaurarlos antes de salir de
;la interrupción (es recomendable hacer esto
;siempre que se usen interrupciones)
MOVFF PORTB,LEIDO
MOVWF PORTB ;LEER PUERTO B P PODER BORRAR BANDERA

MOVWF ACUM ;Copia el acumulador W al registro ACUM


MOVF STATUS, W ;Guarda STATUS en el acumulador
BANCO0 ;Por si acaso, nunca se sabe en que parte de
;programa principal salta la interrupción
MOVWF STAT ;Copia el acumulador al registro STAT

;============================

BTFSC PORTD,0 ;si RB0 es "0" se salta la siguiente instrucción


GOTO ESUNO ;brinca a la etiqueta “ESUNO”
BSF PORTD,0 ;Pon a "1" RC0 (porque era "0")
GOTO HECHO ;ya está invertido RD0, brinca a “HECHO”
ESUNO
BCF PORTD,0
;Pone un "0" en RD0 (Porque era "1")
;Ya se ha invertido el estado de RD0
;===================================

;ahora hay que restaurar los valores del STATUS y


;del acumulador antes de salir de la interrupción:

HECHO
CALL DELAY ;Se puso un pequeño retardo para eliminar rebote
MOVF STAT, W ;Guarda el contenido de STAT en el acumulador
MOVWF STATUS ;Restaura el STATUS
SWAPF ACUM,F ;Da la vuelta al registro ACUM
SWAPF ACUM, W ;Vuelve a dar la vuelta al registro ACUM y restaura
;el acumulador (Con la instruccion SWAPF para no
;alterar el STATUS, la instrucción MOVF altera el
;bit 2 del STATUS)
BCF INTCON,0 ;se limpia la bandera de int. RB antes de regresar
RETFIE ;fin de la interrupción

;======================

INICIO
BANCO1
MOVLW 00H ;Todos los bits del acumulador a "0"
MOVWF TRISD ;Configuramos todo el puerto C como salidas

MOVLW 0FFH ;Todos los bits del acumulador a "1"


MOVWF TRISB ;Configuramos todo el puerto B como entradas
BANCO0
MOVLW 0FH ;Estas 2 instrucciones Solo poner para el
MOVWF ADCON1 ;PIC18F4455 (Pone todos los ANx a Digitales)

;====================================
;Configuración de las interrupciones:
BSF INTCON,7 ;Habilita las interrupciones globalmente
BSF INTCON,3 ;Habilita la interrupción por cambio en
; RB7,RB6,RB5 y RB4
;====================================
;ya están configuradas las interrupciones, a
;partir de ahora cuando haya un cambio en RB7,RB6,
;RB5 y RB4 saltará a la dirección 04h del programa

NADA GOTO NADA ;En este ejemplo no se hace nada en el programa


;principal, simplemente se espera a que salte la
;interrupción.

;===========================
; DELAY: Subrutina de retardo
;Rutina de aprox. 250 msegundos
;===========================
DELAY
MOVLW 01CH ;Carga el W con el valor 01H
MOVWF CUENTA3 ;Carga CUENTA3 con el valor del W

LAZO3 MOVLW 0F9H ;Carga el W con el valor F9H


MOVWF CUENTA2 ;Carga CUENTA2 con el valor del W
LAZO2 MOVLW 0FAH ;Carga el W con el valor FAH
MOVWF CUENTA1 ;Carga CUENTA1 con el valor del W

LAZO1 NOP
DECFSZ CUENTA1,F ;Decrementa CUENTA1 y sigue en el
GOTO LAZO1 ;lazo1 mientras no sea 0

DECFSZ CUENTA2,F ;Decrementa CUENTA2 y sigue en el


GOTO LAZO2 ;lazo2 mientras no sea 0

DECFSZ CUENTA3,F ;Decrementa CUENTA3 y sigue en el


GOTO LAZO3 ;lazo3 mientras no sea 0

RETURN ;retorna al programa principal

;===========================

END ;FIN DE PROGRAMA

PROGRAMA MODIFICADO:
;Programa fuente:
;*******************************************
;* intrb.asm *
;* Este programa invierte el estado del pin RC0 cada *
;* vez que se modifica el estado del pin RB7,RB6,RB5 *
;* o RB4 Para ello se habilita la interrupción RB *
;* Rev A: By Ing. Jorge Aguirre
;* DECODICA UN TECLADO MATRICIAL DE 4X4 *
;* REV B F.TERAN
;********************************************
LIST P=PIC18F4550
#include p18f4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF

CUENTA1 EQU 20H ;variables a partir de la dirección 20H


CUENTA2 EQU 21H
CUENTA3 EQU 22H
MASK EQU 23H
LEIDO EQU 24H
UNID EQU 25H
DECE EQU 26H
CENTE EQU 27H
UMILL EQU 28H

ACUM EQU 29H ;Variable localizada en la dirección 29H


STAT EQU 2AH ;Variable localizada en la dirección 2AH

F EQU 1 ;Constantes
w EQU 0

;ORG 00H ; PARA SIMULAR EN PROTEOUS O CORRER SIN BOOTLOADER


ORG 1000H
GOTO INICIO ;ponemos este GOTO al principio para poder poner
;el subprograma de las interrupciones a partir de
;la dirección 08h

;Comienza la interrupción:
;=========================
;ORG 08H ; PARA SIMULAR EN PROTEOUS O CORRER SIN BOOTLOADER
ORG 1008H ;El pic salta a esta dirección cuando se produce
;una interrupción

MOVFF PORTB,LEIDO
MOVWF PORTB ;LEER PUERTO B P PODER BORRAR BANDERA
BCF INTCON,3 ;DESHabilita la interrupción por cambio en
CERO4 ; RB7,RB6,RB5 y RB4
BTFSS PORTB,4
GOTO CERO4
nop
nop
CERO5 ; RB7,RB6,RB5 y RB4
BTFSS PORTB,5
GOTO CERO5
nop
nop
CERO6 ; RB7,RB6,RB5 y RB4
BTFSS PORTB,6
GOTO CERO6
nop
nop
CERO7 ; RB7,RB6,RB5 y RB4
BTFSS PORTB,7
GOTO CERO7
nop
nop
BCF INTCON,0 ;bit que indica un cambio en RB, recuerda que
;hay que ponerlo a "0" por programa

MOVWF ACUM ;Copia el acumulador W al registro ACUM


MOVF STATUS, W ;Guarda STATUS en el acumulador

;============================
CALL DECOD

HECHO
CALL DELAY ;Se puso un pequeño retardo para eliminar rebote
MOVF STAT, W ;Guarda el contenido de STAT en el acumulador
MOVWF STATUS ;Restaura el STATUS
SWAPF ACUM,F ;Da la vuelta al registro ACUM
SWAPF ACUM, W ;Vuelve a dar la vuelta al registro ACUM y restaura
;el acumulador (Con la instruccion SWAPF para no
;alterar el STATUS, la instrucción MOVF altera el
;bit 2 del STATUS)
MOVWF PORTB ;LEER PUERTO B P PODER BORRAR BANDERA
nop
BCF INTCON,0 ;se limpia la bandera de int. RB antes de regresar
RETFIE ;fin de la interrupción

;======================

INICIO

MOVLW 00H ;Todos los bits del acumulador a "0"


MOVWF TRISC ;Configuramos todo el puerto C como salidas
MOVWF TRISD ;CONFIGURA EL PUERTO D COMO SALIDA
MOVWF TRISB
MOVWF MASK ;INICILIZAMOS MASK EN CERO
MOVWF PORTB ;INICILIZAMOS PUERTO B EN CERO

MOVLW 0F0H ;Todos los bits del acumulador a "11110000"


MOVWF TRISB ;Configuramos b0-b3 salida y b4-b7 como entrada del puerto B

MOVLW 0FH ;Estas 2 instrucciones Solo poner para el


MOVWF ADCON1 ;PIC18F4455 (Pone todos los ANx a Digitales)

;====================================
;Configuración de las interrupciones:
BSF INTCON,7 ;Habilita las interrupciones globalmente
BSF INTCON,3 ;Habilita la interrupción por cambio en
; RB7,RB6,RB5 y RB4
BCF INTCON2,7 ;HABILITA LAS RESISTENCIAS DE PULL-UP
;====================================
;ya están configuradas las interrupciones, a
;partir de ahora cuando haya un cambio en RB7,RB6,
;RB5 y RB4 saltará a la dirección 04h del programa

MOVLW 5BH
MOVWF UNID ;INICIALIZA UNIDADES
MOVLW 3FH
MOVWF DECE ;INICIALIZA DECENAS
MOVLW 06H
MOVWF CENTE ;INICIALIZA CENTENAS
MOVLW 7FH
MOVWF UMILL ;INICIALIZA UNIDADES MILLAR

MOVLW 18H ;RUTINA DE INICIO PARA VERIFICAR SI EL MICRO ESTA


MOVWF PORTD ;OPERANDO SACA DOS BIT CONSECUTIVOS DEL DISPLAY PARA
;DAR VUELTA LOS ENCENDIDOS......
CALL DELAY
MOVLW 0cH
MOVWF PORTD
CALL DELAY

MOVLW 03H
MOVWF PORTD
CALL DELAY
MOVLW 30H
MOVWF PORTD
CALL DELAY

MOVLW 18H
MOVWF PORTD
CALL DELAY
MOVLW 0cH
MOVWF PORTD
CALL DELAY
MOVLW 03H
MOVWF PORTD
CALL DELAY
MOVLW 30H
MOVWF PORTD
CALL DELAY

MOVLW 18H
MOVWF PORTD
CALL DELAY
MOVLW 0cH
MOVWF PORTD
CALL DELAY

MOVLW 03H
MOVWF PORTD
CALL DELAY
MOVLW 7fH
MOVWF PORTD
CALL DELAY ;TERMINA LA ROTACION DE DOS BITS POR EL DISPLAY

NADA ;Escaneo de bits CON ceros en RB0,RB1,RB2 y RB3


;SALIDA EN PUERTO B RB3 RB2 RB1 RB0
; 1 1 1 0
; 1 1 0 1
; 1 0 1 1
; 0 1 1 1
; SE REPITE CONTINUAMENTE
BSF INTCON,3 ;Habilita la interrupción por cambio en
; RB7,RB6,RB5 y RB4
MOVLW 0FH
MOVWF MASK ;PONER EN CERO-F LA MASCARA

BCF MASK,0 ;BORRAR PUERTO B b0


MOVFF MASK,PORTB
NOP
NOP
BSF MASK,0 ;FIJAR b0 DE MASCARA

NOP
NOP
NOP

BCF MASK,1 ;BORRAR PUERTO B b1


MOVFF MASK,PORTB
NOP
NOP
BSF MASK,1 ;FIJAR b1 DE MASCARA

NOP
NOP
NOP

BCF MASK,2 ;BORRAR PUERTO B b2


MOVFF MASK,PORTB
NOP
NOP
BSF MASK,2 ;FIJAR b2 DE MASCARA

NOP
NOP
NOP

BCF MASK,3 ;BORRAR PUERTO B b3


MOVFF MASK,PORTB
NOP
NOP
BSF MASK,3 ;FIJAR b3 DE MASCARA

GOTO NADA ;TERMINA LA GENERACION DE CEROS EN LOS BITS CERO UNO DOS TRES
;DEL PUERTO B PARA EFECTUAR CAMBIOS EN FUNCION DEL TIEMPO
;Y FORMAR UNA MATRIZ ENTRE LOS BITS 4-7 DEL PUERTO B

;===========================
; DELAY: Subrutina de retardo
;Rutina de aprox. 250 msegundos
;===========================
DELAY
NOP
;RETURN
MOVLW 05H ;Carga el W con el valor 01H
MOVWF CUENTA3 ;Para 20 MHz T=.25

LAZO3 MOVLW 0ffH ;Carga el W con el valor F9H


MOVWF CUENTA2 ;Carga CUENTA2 con el valor del W
LAZO2 MOVLW 0ffH ;Carga el W con el valor FAH
MOVWF CUENTA1 ;Carga CUENTA1 con el valor del W

LAZO1 NOP
DECFSZ CUENTA1,F ;Decrementa CUENTA1 y sigue en el
GOTO LAZO1 ;lazo1 mientras no sea 0

DECFSZ CUENTA2,F ;Decrementa CUENTA2 y sigue en el


GOTO LAZO2 ;lazo2 mientras no sea 0

DECFSZ CUENTA3,F ;Decrementa CUENTA3 y sigue en el


GOTO LAZO3 ;lazo3 mientras no sea 0

RETURN ;retorna al programa principal

;===========================

;RUTINA DECODER PARA SABER CUAL INTERRUPTOR DE LA MATRIZ SE ACTIVO


;LOS PRIMEROS CUATRO BITS DE RB SE ESCANEA CON UN CERO CONTINUAMENTE
;=============================
DECOD
BTFSS LEIDO,4 ;SELECCIONAR COLUMNA
GOTO COL1 ;COLUMNA UNO

BTFSS LEIDO,5 ;SELECCIONAR COLUMNA


GOTO COL2 ;COLUMNA DOS

BTFSS LEIDO,6 ;SELECCIONAR COLUMNA


GOTO COL3 ;COLUMNA TRES

BTFSS LEIDO,7 ;SELECCIONAR COLUMNA


GOTO COL4 ;COLUMNA CUATRO

COL1
BTFSS LEIDO,0 ;SELECCIONAR COLUMNA
GOTO CERO ;NUMERO CERO

BTFSS LEIDO,1 ;SELECCIONAR COLUMNA


GOTO UNO ;NUMERO UNO

BTFSS LEIDO,2 ;SELECCIONAR COLUMNA


GOTO DOS ;NUMERO DOS

BTFSS LEIDO,3 ;SELECCIONAR COLUMNA


GOTO TRES ;NUMERO TRES

COL2
BTFSS LEIDO,0 ;SELECCIONAR COLUMNA
GOTO CUATRO ;NUMERO CUATRO

BTFSS LEIDO,1 ;SELECCIONAR COLUMNA


GOTO CINCO ;NUMERO CINCO

BTFSS LEIDO,2 ;SELECCIONAR COLUMNA


GOTO SEIS ;NUMERO SEIS

BTFSS LEIDO,3 ;SELECCIONAR COLUMNA


GOTO SIETE ;NUMERO SIETE
COL3
BTFSS LEIDO,0 ;SELECCIONAR COLUMNA
GOTO OCHO ;NUMERO OCHO

BTFSS LEIDO,1 ;SELECCIONAR COLUMNA


GOTO NUEVE ;NUMERO NUEVE

BTFSS LEIDO,2 ;SELECCIONAR COLUMNA


GOTO A1 ;NUMERO "A"

BTFSS LEIDO,3 ;SELECCIONAR COLUMNA


GOTO B1 ;NUMERO "B"

COL4
BTFSS LEIDO,0 ;SELECCIONAR COLUMNA
GOTO C1 ;NUMERO "C"

BTFSS LEIDO,1 ;SELECCIONAR COLUMNA


GOTO D1 ;NUMERO "D"

BTFSS LEIDO,2 ;SELECCIONAR COLUMNA


GOTO E1 ;NUMERO "E"

BTFSS LEIDO,3 ;SELECCIONAR COLUMNA


GOTO F1 ;NUMERO CERO

UNO
MOVLW 39H
MOVWF PORTD ;CODIGO DE 1 EN 7 SEGMENTOS
RETURN

DOS
MOVLW 7CH
MOVWF PORTD ;CODIGO DE 2 EN 7 SEGMENTOS
RETURN

TRES
MOVLW 77H
MOVWF PORTD ;CODIGO DE 3 EN 7 SEGMENTOS
RETURN

CUATRO
MOVLW 79H
MOVWF PORTD ;CODIGO DE 4 EN 7 SEGMENTOS
RETURN

CINCO
MOVLW 4FH
MOVWF PORTD ;CODIGO DE 5 EN 7 SEGMENTOS
RETURN
SEIS
MOVLW 7DH
MOVWF PORTD ;CODIGO DE 6 EN 7 SEGMENTOS
RETURN

SIETE
MOVLW 6FH
MOVWF PORTD ;CODIGO DE 7 EN 7 SEGMENTOS
RETURN

OCHO
MOVLW 3FH
MOVWF PORTD ;CODIGO DE 8 EN 7 SEGMENTOS
RETURN

NUEVE
MOVLW 5BH
MOVWF PORTD ;CODIGO DE 9 EN 7 SEGMENTOS
RETURN

A1
MOVLW 6DH
MOVWF PORTD ;CODIGO DE A EN 7 SEGMENTOS
RETURN

B1
MOVLW 7FH
MOVWF PORTD ;CODIGO DE B EN 7 SEGMENTOS
RETURN

C1
MOVLW 71H
MOVWF PORTD ;CODIGO DE C EN 7 SEGMENTOS
RETURN

D1
MOVLW 06H
MOVWF PORTD ;CODIGO DE D EN 7 SEGMENTOS
RETURN

E1
MOVLW 66H
MOVWF PORTD ;CODIGO DE E EN 7 SEGMENTOS
RETURN

F1
MOVLW 07H
MOVWF PORTD ;CODIGO DE F EN 7 SEGMENTOS
RETURN
CERO
MOVLW 5EH
MOVWF PORTD ;CODIGO DE CERO EN 7 SEGMENTOS
RETURN

END ;FIN DE PROGRAMA

Diagrama de conexión:
+5vdc
S1

+5vdc +5vdc
sw2
1Mohms R3

11,32
R1
10k
S1 +5vdc
1 S1

VDD
13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39 sw3
2 RB6 38 1Mohms R4
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35 +5vdc
Y1 6 RA3/AN3 RB2 34 S1
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0/INT
9 RE0/AN5 sw4
C2 22pf 10 RE1/AN6 1Mohms R5
R2 RE2/AN7
+5vdc 15 30
16 RC0 RD7 29 +5vdc
220 D? 17 RC1 RD6 28 S1
18 RC2 RD5 27
23 RC3 RD4 22
24 RC4 RD3 21 sw5
25 RC5 RD2 20 1Mohms R6
26 RC6 RD1 19
RC7 RD0
VSS

U1
12,31

PIC16F874

U1
C2 2
RA0/AN0 RC0/T1OSO/T1CKI
15
22p 3 16
RA1/AN1 RC1/T1OSI/CCP2/UOE
4 17
RA2/AN2/VREF-/CVREF RC2/CCP1/P1A
X1 5
RA3/AN3/VREF+ RC4/D-/VM
23
R3
CRYSTAL 6 24
RA4/T0CKI/C1OUT/RCV RC5/D+/VP
C1 7
RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK
25
R4
220R
22p 14 26
RA6/OSC2/CLKO RC7/RX/DT/SDO
13
OSC1/CLKI R5
220R
33 19
34
RB0/AN12/INT0/FLT0/SDI/SDA RD0/SPP0
20
R6
220R
RB1/AN10/INT1/SCK/SCL RD1/SPP1
35 21
36
RB2/AN8/INT2/VMO RD2/SPP2
22
R7
220R
RB3/AN9/CCP2/VPO RD3/SPP3
37 27
38
RB4/AN11/KBI0/CSSPP RD4/SPP4
28
R8
220R
RB5/KBI1/PGM RD5/SPP5/P1B
39 29
40
RB6/KBI2/PGC RD6/SPP6/P1C
30
R9
220R
RB7/KBI3/PGD RD7/SPP7/P1D
220R
8
RE0/AN5/CK1SPP
9
R10
RE1/AN6/CK2SPP
10
RE2/AN7/OESPP 220R
18 1
VUSB RE3/MCLR/VPP
PIC18F4550 R2
PROGRAM=P9AKEY.HEX
220R

A 7 8 9
B 4 5 6
C 1 2 3
ON
D
C 0 = +
1

4
Sugerencias Didácticas:
1.- Se le sugiere al maestro de ensamblar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Correr el programa paso a paso y
ver como se genera la interrupción al cambiar el estado de cualquiera de los pines RB4,RB5,RB6 y RB7. Observar como
brinca a la dirección 04H de la memoria de programa y enfatizar que lo primero que hay que hacer es borrar la bandera
que indica que hubo un cambio en RB (bit 0 del registro INTCON) y antes de regresar de la interrupción, además indicar
que se le agregó un pequeño retardo para eliminar el rebote.
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte:
1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] http://www.microchip.com
Práctica No.6 Temporizador TMRO (ASM).
Objetivo: Aprender a configurar y programar el TMR0, en Lenguaje Ensamblador.

Introducción:
Con el desarrollo de esta práctica el alumno aprenderá a configurar el timer 0 para generar retardos de tiempo. En esta
práctica en particular se configura el prescaler con un factor de división de 1/256. Esto quiere decir que debido al cristal de
4Mhz cada 256 microsegundos se genera una cuenta en el registro contador TMR0, por tal razón se inicializa el TMR0 con
un 12 al inicio para que cada 244 cuentas se desborde el TMR0 y provoque una interrupción. Dentro de la rutina de servicio
de interrupción se tiene un contador que detectara cuando el microcontrolador se haya interrumpido 16 veces obteniendo una
cuenta de aproximadamente de 1 segundo de la siguiente forma:
256*244*16= 999,424 Microseg.
Por lo tanto el led permanece prendido aproximadamente por 1 segundo y permanece apagado por el mismo tiempo teniendo
a la salida del pin RB0 una onda cuadrada perfecta que se puede verificar con un osciloscopio.

Esta práctica se correlaciona con el subtema 2.2.5.4 y 2.2.6 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 capacitores de 22pf o 15pf
1 Resistencia de 220 Ohms
1 Resistencia de 10k
1 Push Button
1 Led
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Osciloscopio

Metodología:

1- Utilice el software MPLAB para editar el programa Tmr0.asm que se muestra mas adelante.
2- Ensamble, simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en el ensamble) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice una tarea diferente en la rutina de servicio de interrupción puede
ser alguna de las siguientes:
a) Hacer que el tiempo de encendido del led sea aproximadamente de medio segundo y el apagado sea de medio
segundo también.
b) Hacer que el tiempo de encendido del led sea de 1 y el apagado sea de medio segundo.
c) Realizar un rota utilizando la interrupción del TMR0. . La rotación la debe realizar dentro de la rutina de
servicio de interrupción.
d) Realizar un reloj con segundos, minutos y horas. Sacar el resultado por display de 7 segmentos conectados en
los puertos siguientes: Segundos por RB, Minutos por RC y Horas por RD.
e) Dejar al alumno que utilice su creatividad.
f) Dejar que el maestro ponga una opción diferente a estas.
7- Verifique sus resultados con un osciloscopio.
8- Reporte sus resultados.

NOTA: Para utilizar el programa fuente con el PIC18F4455 sustituya las siguientes directivas:
LIST P=PIC18F4455
#include p18f4455.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF
Cambiar la dirección de la rutina de servicio de interrupción : (ORG 04H) por (ORG 08H)
Puesto que el pin RB0 es por default canal análogo AN12 ponga las siguientes instrucciones para hacerlo digital:
MOVLW 0FH ;Estas 2 instrucciones Solo poner para el
MOVWF ADCON1 ;PIC18F4455 (Pone todos los ANx a Digitales)
Cambie el registro TMR0 por TMR0L ya que es el que se utiliza en el PIC18F4455
La configuración del TMR0 se hace en el registro T0CON en lugar del OPTION como lo hace el PIC16F874
MOVLW 0C7H ;T0CON=1100 0111, Prescaler 1/256,Asignamos
MOVWF T0CON ;prescaler a TMR0,lo configuramos a 8 bits
;Entrada interna de TMR0
Programa fuente
;**********************************************
;Tmr0.asm
; Este programa configura el TMR0 para interrumpirse aproximadamente cada segundo. En la rutina de
; interrupción solo prende y apaga un led conectado en el pin RB0.
;REV: A Ing. Jorge Aguirre
;***********************************************

;ESTE PROGRAMA ES TARA EL PIC16F874 ADELANTE ESTA PARA EL 4550


LIST P=PIC16F874
#include p16f874.inc

__config _XT_OSC & _PWRTE_OFF & _WDT_OFF & _CP_OFF & _LVP_OFF & _WRT_ENABLE_OFF

CONTADOR EQU 20H ;Registro para guardar el Estado

#DEFINE BANCO0 BCF STATUS,5 ;Definición del Banco 0


#DEFINE BANCO1 BSF STATUS,5 ;Definición del Banco 1

ORG 00H ;Dirección 00H de la memoria de programa


GOTO INICIO ;Brinca al inicio del programa

;=========================
ORG 04H ;Dirección 04H de la memoria de programa
BCF INTCON,2 ;bit que indica desbordamiento de TMR0, recuerda
;que hay que ponerlo a "0" por programa, este es
;el momento

MOVLW 0CH ;Carga con un 12 al TMR0 cada vez que se


MOVWF TMR0 ;interrumpe cada 244 cuentas
DECFSZ CONTADOR
GOTO HECHO
SEGUNDO MOVLW 10H ;Carga un 16 el CONTADOR para
MOVWF CONTADOR ;realizar 16 cuentas
;256*244*16= 999,424 Microseg.

BTFSC PORTB,0 ;si RB0 es "0" se salta la siguiente instrucción


GOTO ESUNO ;brinca a la etiqueta “ESUNO”
BSF PORTB,0 ;Pon a "1" RB0 (porque era "0")
GOTO HECHO ;ya está invertido RB0, brinca a “HECHO”

ESUNO
BCF PORTB,0 ;Pone un "0" en RB0 (Porque era "1")
;Ya se ha invertido el estado de RB0
HECHO
RETFIE ;fin de la interrupción
;======================
INICIO
BANCO1
BCF TRISB,0 ;RB0 como salida

BSF OPTION_REG,0 ;\
BSF OPTION_REG,1 ; }Prescaler a 1/256
BSF OPTION_REG,2 ;/
BCF OPTION_REG,3 ;Asignamos el prescaler a TMR0
BCF OPTION_REG,5 ;Entrada de TMR0 por ciclo de
BANCO0 ;instrucción interna (se pone a contar)
;====================================
MOVLW 10H ;Carga un 16 en CONTADOR para
MOVWF CONTADOR ;realizar 16 cuentas
MOVLW 0CH ;carga un 12 en TMR0 para generar cuentas
MOVWF TMR0 ;de 246 ciclos y desbordarse.

BSF INTCON,7 ;Habilita las interrupciones globalmente


BSF INTCON,5 ;Habilita la interrupción del TMR0
BSF PORTB,0 ;Pone un 1 en el pin RB.0, prende el LED
;====================================
;ya están configuradas las interrupciones, a partir de ahora cuando se
;desborde el TMR0 saltará a la dirección 04h del programa.

NADA GOTO NADA


;En este ejemplo no se hace nada en el programa
;principal, simplemente se espera a que salte a la
;dirección 04h.

END ;FIN DE PROGRAMA

Diagrama de conexión:
+5vdc
+5vdc

11,32
R1
10k
S1
1

VDD
13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35
Y1 6 RA3/AN3 RB2 34 R1 D1
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5 220 LED
C2 22pf 10 RE1/AN6
RE2/AN7
15 30
16 RC0 RD7 29
17 RC1 RD6 28
18 RC2 RD5 27
23 RC3 RD4 22
24 RC4 RD3 21
25 RC5 RD2 20
26 RC6 RD1 19
RC7 RD0
VSS

U1
12,31

PIC16F874

;PROGRAMA RELOJ CON TIMER CERO CON PIC 18F4550

;Programa fuente
;**********************************************
;Tmr0.asm
; Este programa configura el TMR0 para interrumpirse aproximadamente cada segundo. En la rutina de
; interrupción CUENTA LOS SEGUNDOS EN EL DISPLAY.
;REV: B F. TERAN
;***********************************************

LIST P=PIC18F4550
#include p18f4550.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF
CONTADOR EQU 20H ;Registro para guardar el Estado
CUENTA_S EQU 21H ;SEGUNDOS
CUENTA_M EQU 22H ;MINUTOS
CUENTA_H EQU 23H ;HORAS
SEGU7 EQU 24H ;SEGUNDOS UNIDADES EN 7 SEGMENTOS
SEGD7 EQU 25H ;SEGUNDOS DECENAS EN 7 SEGMENTOS
MINU7 EQU 26H ;MINUTOS UNIDADES EN SIETE SEGMENTOS
MIND7 EQU 27H ;MINUTOS DECENAS EN 7 SEGMENTOS
HRSU7 EQU 28H ;HORAS UNIDADES EN 7 SEGMENTOS
HRSD7 EQU 29H ;HORAS DECENAS EN 7 SEGMENTOS
CUENTA_X EQU 2AH ;CUENTA TEMPORAL
CUENTA_XU EQU 2BH ;CUENTA TEMPORAL UNIDADES
CUENTA_XD EQU 2CH ;CUENTA TEMPORAL DECENAS
CONTAX EQU 2DH ;CONTADOR TEMPORAL
DEL1 EQU 2EH
DEL2 EQU 2FH

ORG 000H ;Dirección 00H de la memoria de programa


GOTO INICIO ;Brinca al inicio del programa

;=========================
ORG 008H ;Dirección 08H de la memoria de programa
BCF INTCON,2 ;bit que indica desbordamiento de TMR0, recuerda
;que hay que ponerlo a "0" por programa, este es
;el momento

MOVLW 08H ;Carga con un 12 al TMR0 cada vez que se


MOVWF TMR0L ;interrumpe cada 244 cuentas
DECFSZ CONTADOR
GOTO HECHO
SEGUNDO
MOVLW 0C0H ;Carga un 16 x 12 =192 =0C0H el CONTADOR para
MOVWF CONTADOR ;realizar 16 cuentas
;256*244*16= 999,424 Microseg.

; BTFSC PORTD,0 ;si RB0 es "0" se salta la siguiente instrucción


; GOTO ESUNO ;brinca a la etiqueta “ESUNO”
; BSF PORTD,0 ;Pon a "1" RB0 (porque era "0")
; GOTO HECHO ;ya está invertido RB0, brinca a “HECHO”

;ESUNO
; BCF PORTD,0 ;Pone un "0" en RB0 (Porque era "1")
;Ya se ha invertido el estado de RB0
;HECHO
;MINU GOTO SMINU
MOVF CUENTA_S,W ;INCREMENTA SEGUNDOS
ADDLW 1
DAW ;AJUSTA DECIMAL
MOVWF CUENTA_S ;SEE GUARDA EN CUENTA_S
MOVWF CUENTA_X ;SE GUARDA EN TEMPORAL P CONVERTIR A 7 SEGMENTOS
CALL CONVERT ;LLAMAR RUTINA CONVERSION 7 SEGM.
MOVFF CUENTA_XU,SEGU7 ;GUARDAR SEGUNDOS UNIDADES 7 SEGM EN SEGU7
MOVFF CUENTA_XD,SEGD7 ;GUARDAR SEGUNDOS DEC 7 SEGM EN SEGD7
MOVLW 59H ;CHECAR SI YA ES MAYOR QUE 59 SEGUNDOS
CPFSGT CUENTA_S
GOTO SIGUE ;NO FUE MAYOR QUE 59 CONTINUAR
CLRF CUENTA_S ;SI FUE 60 INICIALIZAR EN CERO
SMINU
MOVF CUENTA_M,W ;INCREMENTAR MINUTOS
ADDLW 1
DAW ;AJUSTAR DECIMAL
MOVWF CUENTA_M ;GUARDAR MINUTOS EN CUENTA_M
MOVWF CUENTA_X ;MINUTOS A TEMPORAL CUENTA_X
CALL CONVERT ;CONVERTIR A SIETE SEGMENTOS
MOVFF CUENTA_XU,MINU7 ;MINUTOS UNIDAD 7 SEGM A MINU7
MOVFF CUENTA_XD,MIND7 ;DECENAS MINUTOS 7 SEGM A MIND_7
MOVLW 59H ;CHECA SI ES MAYOR QUE 59 MINUTOS
CPFSGT CUENTA_M

GOTO SIGUE ;NO ES MAYOR CONTINUA


CLRF CUENTA_M ;SI ES MAYOR INICIALIZA MINUTOS EN CERO

MOVF CUENTA_H,W;INCREMENTA HORAS


ADDLW 01
DAW ;AJUSTA DECIMAL
MOVWF CUENTA_H
MOVWF CUENTA_X
CALL CONVERT ;CONVIERTE A 7 SEGMENTOS UNIDADES Y DECENAS
MOVFF CUENTA_XU,HRSU7
MOVFF CUENTA_XD,HRSD7
MOVLW 23H ;COMPARA HORAS SI ES MAYOR QUE 23
CPFSGT CUENTA_H

GOTO SIGUE ;NO ES MAYOR A 23 CONTINUA


CLRF CUENTA_H ;SI ES MAYOR A 23 INICIALIZA EN CERO

SIGUE NOP
HECHO NOP
RETFIE ;fin de la interrupción
;======================
INICIO

CLRF TRISD ;RD como salida


CLRF TRISA ;RA COMO SALIDA
MOVLW 0FH ;Estas 2 instrucciones Solo poner para el
MOVWF ADCON1 ;PIC18F4455 (Pone todos los ANx a Digitales)

MOVLW 0C7H ;T0CON=1100 0111, Prescaler 1/1,Asignamos


MOVWF T0CON ;prescaler a TMR0,lo configuramos a 8 bits
;instrucción interna (se pone a contar)
;====================================
MOVLW 010H ;Carga un 16 en CONTADOR para
MOVWF CONTADOR ;realizar 16 cuentas
MOVLW 0CH ;carga un 12 en TMR0 para generar cuentas
MOVWF TMR0L ;de 244 ciclos y desbordarse.

BSF INTCON,7 ;Habilita las interrupciones globalmente


BSF INTCON,5 ;Habilita la interrupción del TMR0 BSF PORTB,0 ;Pone un 1 en el pin RB.0,
prende el LED
;====================================
;ya están configuradas las interrupciones, a partir de ahora cuando se
;desborde el TMR0 saltará a la dirección 08h del programa.

CLRF CUENTA_S ;INICIALIZA SEGUNDOS EN CERO


CLRF CUENTA_M ;INICIALIZA MINUTOS EN CERO
CLRF CUENTA_H ;INICIALIZA HORAS EN CERO
MOVLW 3FH ;INICIALIZAR VALORES DE NUMS 7 SEGMENTOS
MOVWF SEGU7 ;EN CERO
MOVLW 06H ;INICIALIZAR VALORES DE NUMS 7 SEGMENTOS
MOVWF SEGD7
MOVLW 5BH ;INICIALIZAR VALORES DE NUMS 7 SEGMENTOS
MOVWF MINU7
MOVLW 4FH ;INICIALIZAR VALORES DE NUMS 7 SEGMENTOS
MOVWF MIND7
MOVLW 66H ;INICIALIZAR VALORES DE NUMS 7 SEGMENTOS
MOVWF HRSU7
MOVLW 6DH ;INICIALIZAR VALORES DE NUMS 7 SEGMENTOS
MOVWF HRSD7

NADA ;SACA POR PUERTO D NUMEROS EN SIETE SEGM


NOP ;Y POR EL PUERTO A SELECCIONA EL DISPLAY
NOP
MOVLW 00
MOVWF PORTA ;SE APAGAN LOS DISPALYS CON 00 EN A
NOP
NOP
MOVF SEGU7,W
MOVWF PORTD
MOVLW 01
MOVWF PORTA ;SEG UNIDADES SE SELECCIONA CON 01 EN PUERTO A
CALL DEL5
NOP
NOP

NOP
NOP
MOVLW 00
MOVWF PORTA ;APAGA DISPLAYS
NOP
NOP
MOVF SEGD7,W
MOVWF PORTD
MOVLW 02
MOVWF PORTA ;DECENAS SEGUNDOS CON 02 EN PUERTO A
CALL DEL5
NOP
NOP

NOP
NOP
MOVLW 00
MOVWF PORTA ;APAGA DISPAYS P EVITAR FANTASMA
NOP
NOP
MOVF MINU7,W
MOVWF PORTD
MOVLW 04
MOVWF PORTA ;UNIDADES MINUTO CON 04 EN PUERTO A
CALL DEL5
NOP
NOP

NOP
NOP
MOVLW 00
MOVWF PORTA ;APAGA DISPAYS P EVITAR FANTASMA
NOP
NOP
MOVF MIND7,W
MOVWF PORTD
MOVLW 08
MOVWF PORTA ;DECENAS MINUTOS CON PUERTOA =08
CALL DEL5
NOP
NOP

NOP
NOP
MOVLW 00
MOVWF PORTA ;APAGA DISPAYS P EVITAR FANTASMA
NOP
NOP
MOVF HRSU7,W
MOVWF PORTD
MOVLW 010H
MOVWF PORTA ;UNIDADES HORAS CON PORTA =10H
CALL DEL5
NOP
NOP

NOP
NOP
MOVLW 00
MOVWF PORTA ;APAGA DISPAYS P EVITAR FANTASMA
NOP
NOP
MOVF HRSD7,W
MOVWF PORTD
MOVLW 020H
MOVWF PORTA ;DECENAS HORAS CON PORTA = 20H
CALL DEL5
NOP
NOP

GOTO NADA
;En este ejemplo no se hace nada en el programa
;principal, simplemente se espera a que salte a la
;dirección 04h.

CONVERT ;CONVIERTE VARIABLE TEMPORAL A SIETE SEGM

MOVF CUENTA_X,W
ANDLW 0FH ;SEPARA UNIDAES
CALL CONV7 ;CONVIERTE UNIDADES A SIETE SEGM
MOVWF CUENTA_XU ;GUARDA UNIDADES SIETE SEGMENTOS

SWAPF CUENTA_X,F ;INTERCAMBIA UNIDADES DE DECENAS


MOVF CUENTA_X,W
ANDLW 0FH ;ELIMINA UNIDADES
CALL CONV7 ;CONVIERTE A SIETE SEGMENTOS
MOVWF CUENTA_XD ;GUARDA DECENAS EN TEMPORAL

RETURN

CONV7 ;RUTINA DE CONVERSION A 7 SEGMENTOS EL RESULTADO QUEDA


;EN EL REG W.
; return
MOVWF CONTAX ;VARIABLE A CONVERTIR
ADDWF CONTAX,W ;DUPLICA EL VALOR DE LA VARIABLE
MOVFF PCL, 00H ;HACE UN RESPALDO DEL PCL
ADDWF PCL, F ;SUMA EL REGISTRO W CON PCL EL RESULTADO SE ALMACENA EN
PCL Y BRINCA DEACUERDO AL DATO REQUERIDO
RETLW 3Fh ;CODIGO DE SIETE SEGMENTOS P'CERO 0gfedcba <--MENOS
SIGNIFICATIVO
RETLW 06h ;CODIGO DE SIETE SEGMENTOS P'UNO 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 5Bh ;CODIGO DE SIETE SEGMENTOS P'DOS 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 4Fh ;CODIGO DE SIETE SEGMENTOS P'TRES 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 66h ;CODIGO DE SIETE SEGMENTOS P'CUATRO 0gfedcba <--MENOS
SIGNIFICATIVO
RETLW 6Dh ;CODIGO DE SIETE SEGMENTOS P'CINCO 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 7Dh ;CODIGO DE SIETE SEGMENTOS P'SEIS 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 07h ;CODIGO DE SIETE SEGMENTOS P'SIETE 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 7Fh ;CODIGO DE SIETE SEGMENTOS P'OCHO 0gfedcba <--MENOS SIGNIFICATIVO
RETLW 6Fh ;CODIGO DE SIETE SEGMENTOS P'NUEVE 0gfedcba <--MENOS
SIGNIFICATIVO

;======================

DEL5 ;DELAY UN MILISEGUNDO


MOVLW 10H
MOVWF DEL2
AQUI1 DECFSZ DEL1
GOTO AQUI1
DECFSZ DEL2
GOTO AQUI1
RETURN
END ;FIN DE PROGRAMA
Sugerencias Didácticas:
1.- Se le sugiere al maestro de ensamblar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Enfocarse en enseñar en el
simulador como esta construida la rutina de interrupción del TMR0 usando las opciones del debugger:
Settings.- Poner la velocidad de ejecución a 4Mhz (por default es de 20Mhz).
StopWatch.- Nos ayudará a verificar el tiempo de retardo de cada interrupción.
Set Breakpoint.- Poner punto de paro en el programa en la línea donde se desea que el programa detenga su ejecución,
ejemplo: Poner el cursor en la línea donde esta la etiqueta SEGUNDO, presionar el botón derecho del mouse y aparecerá
una ventana con varias opciones, seleccione la opción Set-Breakpoint. Correr el programa hasta que se detenga en la
etiqueta SEGUNDO, poner a cero el Stop wtach y volver a correr desde ahí el programa y se detendrá nuevamente en la
misma etiqueta mostrándonos en el Stop Watch el tiempo transcurrido de aproximadamente 1 segundo(256*244*16=
999,424 Microsegundos).
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] http://www.microchip.com
Práctica No.7 Temporizador TMR1 (ASM).
Objetivo: Aprender a configurar y programar el TMR1, en Lenguaje Ensamblador.

Introducción:
Con el desarrollo de esta práctica el alumno aprenderá a configurar el timer 1 para generar retardos de tiempo. En esta
practica en particular se configura el prescaler con un factor de división de 1/2. Esto quiere decir que debido al cristal de
4Mhz cada 2 microsegundos se genera una cuenta en el registro contador TMR1, por tal razón se inicializa el TMR1 con una
cuenta de 15,536 al inicio para que cada 50,000 cuentas se desborde el TMR1 y provoque una interrupción. Dentro de la
rutina de servicio de interrupción se tiene un contador que detectara cuando el microcontrolador se haya interrumpido 10
veces obteniendo una cuenta de aproximadamente de 1 segundo de la siguiente forma: 2*50000*10= 1,000,000
Microsegundos.

El objetivo por lo tanto es prender el led por aproximadamente 1 segundo para después apagarlo por el mismo tiempo
teniendo a la salida del pin RB0 una onda cuadrada perfecta que se puede verificar con un osciloscopio.

Esta práctica se correlaciona con el subtema 2.2.5.4 y 2.2.6 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
2 Resistencia de 220 Ohms
1 Resistencia de 10k
1 Push Button
2 Led
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Osciloscopio

Metodología:
1- Utilice el software MPLAB para editar el programa Tmr1.asm que se muestra mas adelante.
2- Ensamble, simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en el ensamble) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice una tarea diferente en la rutina de servicio de interrupción puede
ser alguna de las siguientes:
g) Realizar un reloj con segundos, minutos y horas. Sacar el resultado por display de 7 segmentos conectados en
los puertos siguientes: Segundos por RB, Minutos por RC y Horas por RD.
h) Dejar al alumno que utilice su creatividad.
i) Dejar que el maestro ponga una opción diferente a estas.

7- Verifique sus resultados con un osciloscopio.


8- Reporte sus resultados.
8- Reporte sus resultados.

NOTA: Para utilizar el programa fuente con el PIC18F4455 sustituya las siguientes directivas:
LIST P=PIC18F4455
#include p18f4455.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF
Cambiar la dirección de la rutina de servicio de interrupción : (ORG 04H) por (ORG 08H)
Puesto que el pin RB0 es por default canal análogo AN12 ponga las siguientes instrucciones para hacerlo digital:
MOVLW 0FH ;Estas 2 instrucciones Solo poner para el
MOVWF ADCON1 ;PIC18F4455 (Pone todos los ANx a Digitales)

Programa fuente:

;**********************************************
;TMR1.asm
;REV:A By Ing. Jorge Aguirre
; Temporizador de 16 bits para el PIC16F874
;***********************************************

LIST P=PIC16F874
#include p16f874.inc

__config _XT_OSC & _PWRTE_OFF & _WDT_OFF & _CP_OFF & _LVP_OFF & _WRT_ENABLE_OFF

CONTADOR EQU 20H ;Registro para guardar el Estado

#DEFINE BANCO0 BCF STATUS,5 ;Definición del Banco 0


#DEFINE BANCO1 BSF STATUS,5 ;Definición del Banco 1

ORG 00H ;Dirección 00H de la memoria de programa


GOTO INICIO ;Brinca al inicio del programa

;=========================
;ORG 08H ;Solo para el PIC18Fxxx
ORG 04H ;Dirección 04H de la memoria de programa
BCF PIR1,0 ;(TMR1IF)bit que indica desbordamiento de TMR1
;recuerda que hay que ponerlo a "0" por programa
;este es el momento

MOVLW 0B0H ;carga un 3CB0H = 15536 para generar


MOVWF TMR1L ;65536-15536= 50,000 cuentas para
MOVLW 3CH ;el sobreflujo
MOVWF TMR1H ;En teoria 2*50000*10=1,000,000 Microseg

DECFSZ CONTADOR
GOTO HECHO
SEGUNDO MOVLW 0AH ;Carga un 10 el CONTADOR para
MOVWF CONTADOR ;realizar 10 cuentas
;2*50000*10= 1,000,000 Microsegundos

BTFSC PORTB,0 ;si RB0 es "0" se salta la siguiente instrucción


GOTO ESUNO ;brinca a la etiqueta “ESUNO”
BSF PORTB,0 ;Pone a "1" RB0 (porque era "0")
BSF PORTB,1 ;Pone a "1" RB1
GOTO HECHO ;ya está invertido RB0, brinca a “HECHO”

ESUNO
BCF PORTB,0 ;Pone un "0" en RB0 (Porque era "1")
;Ya se ha invertido el estado de RB0
HECHO
RETFIE ;fin de la interrupción

;Fin de la interrupción
;======================

INICIO
BANCO1
BCF TRISB,0 ;RB0 como salida
BANCO0
;MOVLW 0FH ;Estas 2 instrucciones Solo poner para el
;MOVWF ADCON1 ;PIC18F4455 (Pone todos los ANx a Digitales)

BCF T1CON ,0 ;Deshabilitada la interrupción por TMR1


BCF T1CON ,1 ; T1_Interno
BSF T1CON ,4 ;} Preescaler 1/2
BCF T1CON ,5 ;Entrada de TMR0 por ciclo de
;instrucción interna (se pone a contar)
;Configuración de las interrupciones:
;====================================
MOVLW 0AH ;Carga un 10 en CONTADOR para
MOVWF CONTADOR ;realizar 10 cuentas
MOVLW 0B0H ;carga un 3CB0H = 15536 para generar
MOVWF TMR1L ;65536-15536= 50,000 cuentas para
MOVLW 3CH ;el sobreflujo
MOVWF TMR1H ;En teoría 2*50000*10=1,000,000 Microsegundos

BSF INTCON,6 ;Habilita las interrupciones Periféricas


BANCO1
BSF PIE1,0 ;(TMR1IE)Habilita la interrupción del TMR1
BANCO0
BSF INTCON,7 ;Habilita las interrupciones globalmente
BSF T1CON,0 ;(TMR1ON)Inicia la cuenta en el TMR1
BSF PORTB,0 ;Pone un 1 en el pin RB.0, prende el LED
;====================================
;ya están configuradas las interrupciones, a partir de ahora cuando se ;desborde el TMR0 saltará a la dirección 04h del
programa.

NADA GOTO NADA


;En este ejemplo no se hace nada en el programa
;principal, simplemente se espera a que salte a la
;dirección 04h.

END ;FIN DE PROGRAMA

Diagrama de conexión:
+5vdc
+5vdc
11,32

R1
10k
S1
1
VDD

13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38 R3 D2
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35 220 LED
Y1 6 RA3/AN3 RB2 34 D1
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5 R2 220 LED
C2 22pf 10 RE1/AN6
RE2/AN7
15 30
16 RC0 RD7 29
17 RC1 RD6 28
18 RC2 RD5 27
23 RC3 RD4 22
24 RC4 RD3 21
25 RC5 RD2 20
26 RC6 RD1 19
RC7 RD0
VSS

U1
12,31

PIC16F874
Sugerencias Didácticas:
1.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Enfocarse en enseñar en el
simulador como esta construida la rutina de interrupción del TMR1 usando las opciones del debugger:
Settings.- Poner la velocidad de ejecución a 4Mhz (por default es de 20Mhz).
StopWatch.- Nos ayudará a verificar el tiempo de retardo de cada interrupción.
Set Breakpoint.- Poner punto de paro en el programa en la línea donde se desea que el programa detenga su ejecución,
ejemplo: Poner el cursor en la línea donde esta la etiqueta SEGUNDO, presionar el botón derecho del mouse y aparecerá
una ventana con varias opciones, seleccione la opción Set-Breakpoint. Correr el programa hasta que se detenga en la
etiqueta SEGUNDO, poner a zero el Stop wtach y volver a correr desde ahí el programa y se detendrá nuevamente en la
misma etiqueta mostrándonos en el Stop Watch el tiempo transcurrido de aproximadamente 1 segundo(2*50000*10=
1,000,000 Microsegundos).
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] http://www.microchip.com
Práctica No.8 Temporizador TMR2 (ASM).
Objetivo: Aprenderá a configurar y programar el TMR2, en Lenguaje Ensamblador.

Introducción:
Con el desarrollo de esta práctica el alumno aprenderá a configurar el timer 2 para generar retardos de tiempo. En esta
práctica en particular se configura el prescaler con un factor de división de 1/16. Esto quiere decir que debido al cristal de
4Mhz cada 16 microsegundos se genera una cuenta en el registro contador TMR2, por tal razón se inicializa el TMR2 con
una cuenta de 12 al inicio para que cada 244 cuentas se desborde el TMR2 y provoque una interrupción. Dentro de la rutina
de servicio de interrupción se tiene un contador que detectara cuando el microcontrolador se haya interrumpido 256 veces
obteniendo una cuenta de aproximadamente de 1 segundo de la siguiente forma: 16*244*256= 999,424
Microsegundos.

El objetivo por lo tanto es prender el led por aproximadamente 1 segundo para después apagarlo por el mismo tiempo
teniendo a la salida del pin RB0 una onda cuadrada perfecta que se puede verificar con un osciloscopio.

Esta práctica se correlaciona con el subtema 2.2.5.4 y 2.2.6 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
3 Resistencia de 220 Ohms
1 Resistencia de 10k
1 Push Button
3 Led
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Osciloscopio

Metodología:

1- Utilice el software MPLAB para editar el programa Tmr2.asm que se muestra mas adelante.
2- Ensamble, simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en el ensamble) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice una tarea diferente en la rutina de servicio de interrupción puede
ser alguna de las siguientes:
j) Realizar un reloj con segundos, minutos y horas. Sacar el resultado por display de 7 segmentos conectados en
los puertos siguientes: Segundos por RB, Minutos por RC y Horas por RD.
k) Dejar al alumno que utilice su creatividad.
l) Dejar que el maestro ponga una opción diferente a estas.

7- Verifique sus resultados con un osciloscopio.


8- Reporte sus resultados.

NOTA: Para utilizar el programa fuente con el PIC18F4455 sustituya las siguientes directivas:
LIST P=PIC18F4455
#include p18f4455.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF
Cambiar la dirección de la rutina de servicio de interrupción : (ORG 04H) por (ORG 08H)
Puesto que el pin RB0 es por default canal análogo AN12 ponga las siguientes instrucciones para hacerlo digital:
MOVLW 0FH ;Estas 2 instrucciones Solo poner para el
MOVWF ADCON1 ;PIC18F4455 (Pone todos los ANx a Digitales)

Programa fuente:

;**********************************************
;TMR2.asm
; Temporizador de 8 bits para el PIC16F87X
;REV:A By Ing. Jorge Aguirre
;***********************************************
LIST P=PIC16F874
#include p16f874.inc
__config _XT_OSC & _PWRTE_OFF & _WDT_OFF & _CP_OFF & _LVP_OFF & _WRT_ENABLE_OFF

CONTADOR EQU 20H ;Registro para guardar el Estado

#DEFINE BANCO0 BCF STATUS,5 ;Definición del Banco 0


#DEFINE BANCO1 BSF STATUS,5 ;Definición del Banco 1

ORG 00H ;Dirección 00H de la memoria de programa


GOTO INICIO ;Brinca al inicio del programa

;=========================
;ORG 08H ;Solo para el PIC18Fxxx
ORG 04H ;Dirección 04H de la memoria de programa
BCF PIR1,1 ;(TMR2IF)bit que indica desbordamiento de TMR2
;recuerda que hay que ponerlo a "0" por programa
;este es el momento

MOVLW 0CH ;carga un 12 al TMR2 para que se


MOVWF TMR2 ;interrumpa cada 244 cuentas

DECFSZ CONTADOR
GOTO HECHO
SEGUNDO MOVLW 0FFH ;Carga un 255 el CONTADOR para
MOVWF CONTADOR ;realizar 256 cuentas
;16*244*256=999,424 Microsegundos

BTFSC PORTB,0 ;si RB0 es "0" se salta la siguiente instrucción


GOTO ESUNO ;brinca a la etiqueta “ESUNO”
BSF PORTB,0 ;Pon a "1" RB0 (porque era "0")
BSF PORTB,1 ;Pone a "1" RB1
BSF PORTB,2 ;Pone a "1" RB2
GOTO HECHO ;ya está invertido RB0, brinca a “HECHO”

ESUNO
BCF PORTB,0 ;Pone un "0" en RB0 (Porque era "1")
;Ya se ha invertido el estado de RB0
HECHO
RETFIE ;fin de la interrupción

;======================

INICIO
BANCO1
BCF TRISB,0 ;RB0 como salida
BANCO0
;MOVLW 0FH ;Estas 2 instrucciones Solo poner para el
;MOVWF ADCON1 ;PIC18F4455 (Pone todos los ANx a Digitales)
BSF T2CON ,0 ;} Preescaler 1/16
BSF T2CON ,1 ; T2CON=0000 0011
BCF T2CON ,2 ;Deshabilitada la interrupción por TMR2
;====================================
MOVLW 0FFH ;Carga un 255 CONTADOR para
MOVWF CONTADOR ;realizar 256 cuentas
MOVLW 0CH ;carga un 12 en TMR2 para generar
MOVWF TMR2 ;cuentas de 244 ciclos y desbordarse
;16*244*256=999,424 Microsegundos

BSF INTCON,6 ;Habilita las interrupciones Periféricas


BANCO1
BSF PIE1,1 ;(TMR2IE)Habilita la interrupción del TMR2
BANCO0
BSF INTCON,7 ;Habilita las interrupciones globalmente
BSF T2CON,2 ;(TMR2ON)Inicia la cuenta en el TMR2 (T2CON=0000 0111)
BSF PORTB,0 ;Pone un 1 en el pin RB.0, prende el LED
;====================================
;ya están configuradas las interrupciones, a partir de ahora cuando se
;desborde el TMR0 saltará a la dirección 04h del programa.

NADA GOTO NADA


;En este ejemplo no se hace nada en el programa
;principal, simplemente se espera a que salte a la
;dirección 04h.

END ;FIN DE PROGRAMA

Diagrama de conexión:
+5vdc
+5vdc

11,32
R1
10k D3
S1
1

VDD
13 MCLR R4 220 LED
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38 R3 D2
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35 220 LED
Y1 6 RA3/AN3 RB2 34 D1
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5 R2 220 LED
C2 22pf 10 RE1/AN6
RE2/AN7
15 30
16 RC0 RD7 29
17 RC1 RD6 28
18 RC2 RD5 27
23 RC3 RD4 22
24 RC4 RD3 21
25 RC5 RD2 20
26 RC6 RD1 19
RC7 RD0
VSS

U1
12,31

PIC16F874

Sugerencias Didácticas:
1.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Enfocarse en enseñar en el
simulador como esta construida la rutina de interrupción del TMR2 usando las opciones del debugger:
Settings.- Poner la velocidad de ejecución a 4Mhz (por default es de 20Mhz).
StopWatch.- Nos ayudará a verificar el tiempo de retardo de cada interrupción.
Set Breakpoint.- Poner punto de paro en el programa en la línea donde se desea que el programa detenga su ejecución,
ejemplo: Poner el cursor en la línea donde esta la etiqueta SEGUNDO, presionar el botón derecho del mouse y aparecerá
una ventana con varias opciones, seleccione la opción Set-Breakpoint. Correr el programa hasta que se detenga en la
etiqueta SEGUNDO, poner a cero el Stop wtach y volver a correr desde ahí el programa y se detendrá nuevamente en la
misma etiqueta mostrándonos en el Stop Watch el tiempo transcurrido de aproximadamente 1
segundo(16*244*256=999,424 Microsegundos).
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] http://www.microchip.com
+-hPráctica No.9 Convertidor Análogo(ASM).

Objetivo: Programar el convertidor A/D en lenguaje Ensamblador.

Introducción:
Con el desarrollo de esta práctica el alumno aprenderá a configurar el convertidor A/D para realizar lecturas de voltaje en
cualquiera de los convertidores/análogos del PIC, estos se seleccionan con los bits 3, 4 y 5 del registro ADCON0 de acuerdo
a la siguiente tabla:
Bits 5 4 3 de ADCON0
0 0 0 para seleccionar la lectura por RA0
0 0 1 para seleccionar la lectura por RA1
0 1 0 para seleccionar la lectura por RA2
0 1 1 para seleccionar la lectura por RA3
1 0 0 para seleccionar la lectura por RA5
1 0 1 para seleccionar la lectura por RE0
1 1 0 para seleccionar la lectura por RE1
1 1 1 para seleccionar la lectura por RE2

Se sugiere correr y probar el programa justificando primero a la izquierda para que los 8 bits mas altos queden en el registro
ADRESH y se puedan sacar directo por el puerto RB(es como si tuviéramos la resolución a 8 bits). Después correr y probar
el programa justificando a la derecha de esta manera tenemos los 8 bits mas bajos en ADRESL y los mostramos por el
puerto RB y los 2 bits mas altos quedarían en ADRESL y los mostramos por el puerto RC(Resolución a 10 bits).
El justificado a la izquierda lo configuramos poniendo un 0 en el bit 7(ADFM) del registro ADCON1 y el justificado a la
derecha lo configuramos poniendo un 1 en ese mismo bit.
Comprobar que en la resolución de 8 bits los incrementos de cada bit corresponden a incrementos de 20mv(5v/255) y que en
la resolución de 10 bits los incrementos de cada bit son de 4mv(5v/1024).

Esta práctica se correlaciona con el subtema 2.2.8 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
1 Resistencia de 10k
1 Push Button
10 Leds
10 Resistencia de 220 Ohms
1 Potenciómetro de 100k
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Voltímetro

Metodología:

1- Utilice el software MPLAB para editar el programa ADC.asm que se muestra mas adelante.
2- Ensamble, simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en la compilación) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice una tarea diferente en la rutina de servicio de interrupción puede
ser alguna de las siguientes:
m) Conecte 2 display de 7 segmentos en el puerto B, ahora muestre la lectura obtenida por el display pero
mostrando el correspondiente voltaje leído en el potenciómetro(realice la conversión para mostrar el voltaje
con un entero y un decimal ). Verifique la lectura obtenida en el display poniendo un voltímetro a la entrada de
RA0/AN0. realice una tabla comparativa entre su lectura y la del voltímetro varíe el potenciómetro para que
realice lecturas cada 500mv.
n) Conecte un display de 7 segmentos por el puerto RC para mostrar la parte entera del voltaje leído y 2 display
de 7 segmentos en el puerto RB para mostrar 2 decimales.
o) Conecte 1 potenciómetro en cada uno de los pines RA0,RA1,RA2 del pic y muestre su lectura por un display
doble de 7 segmentos conectados al puerto RB. Utilice los pines del puerto RC para seleccionar cual de los 3
canales se desea leer. Conecte 1 display de 7 segmentos por el puerto RD para indicar cual de los canales
análogos se esta leyendo.
p) Poner un sensor de temperatura o cualquier otro tipo de sensor(presión, flujo, etc.) en alguno de los
convertidores análogos y mostrar la lectura por un display(puede ser un LCD).
q) Dejar al alumno que utilice su creatividad.
r) Dejar que el maestro ponga una opción diferente a estas.

7- Verifique sus resultados con un voltímetro.


8- Reporte sus resultados.

NOTA: Para utilizar el programa fuente con el PIC18F4455 sustituya las siguientes directivas:

LIST P=PIC18F4455
#include p18f4455.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF

Para configurar el convertidor análogo digital se utilizan los siguientes registros:


;MOVLW 01H ;configuramos el ADCON0=01H
;MOVWF ADCON0 ;Selecciona el canal AN0, A/D Encendido.
;MOVLW 0EH ;Estas 2 instrucciones Solo poner para el
;MOVWF ADCON1 ;PIC18F4455 (Pone todos los ANx a Digitales)
;MOVLW 01H ;Justificado a la izquierda,FOsc/8
;MOVWF ADCON2 ;;Selecciona el canal AN0, A/D Encendido.

Programa fuente:

;**********************************************
;ADC.asm
;REV:A By Ing. Jorge Aguirre
;***********************************************
LIST P=PIC16F874
#include p16f874.inc

__config _XT_OSC & _PWRTE_OFF & _WDT_OFF & _CP_OFF & _LVP_OFF & _WRT_ENABLE_OFF

CUENTA1 EQU 20H ;las variables que usemos siempre a partir de la dirección 20Hh
CUENTA2 EQU 21H
#DEFINE BANCO0 BCF STATUS,5 ;Definición del Banco 0
#DEFINE BANCO1 BSF STATUS,5 ;Definición del Banco 1

F EQU 1 ;Constantes del programa


w EQU 0

ORG 00H ;Dirección 00H de la memoria de programa


INICIO
BANCO1
MOVLW 00H ;Cargamos W=00H
MOVWF TRISB ;Puerto RB como salida
MOVWF TRISC ;Puerto RC como salida
MOVWF ADCON1 ;Todos los pines Analogos
;justificado a la Izquierda para tener los 8 bits mas altos en ARDES
BANCO0
MOVLW 41H
MOVWF ADCON0 ;FOsc/8, A/D Encendido.

REPITE
CALL DELAY ;Hacemos un retardo de tiempo

;REGISTRO ADCON1
;bit 7-6 Unimplemented: Read as ‘0’
;bit 5-2 CHS3:CHS0: Analog Channel Select bits
;0000 = Channel 0 (AN0)
;0001 = Channel 1 (AN1)
;0010 = Channel 2 (AN2)
;0011 = Channel 3 (AN3)
;0100 = Channel 4 (AN4)
;0101 = Channel 5 (AN5)(1,2)
;0110 = Channel 6 (AN6)(1,2)
;0111 = Channel 7 (AN7)(1,2)
;1000 = Channel 8 (AN8)
;1001 = Channel 9 (AN9)
;1010 = Channel 10 (AN10)
;1011 = Channel 11 (AN11)
;1100 = Channel 12 (AN12)
;1101 = Unimplemented(2)
;1110 = Unimplemented(2)
;1111 = Unimplemented(2)
;bit 1 GO/DONE: A/D Conversion Status bit
;When ADON = 1:
;1 = A/D conversion in progress
;0 = A/D Idle
;bit 0 ADON: A/D On bit
;1 = A/D converter module is enabled
;0 = A/D converter module is disabled
;Note 1: These channels are not implemented on 28-pin devices.
;2: Performing a conversion on unimplemented channels will return a floating input measurement.
BSF ADCON0,01H ;Arrancamos una conversion del A/D
CICLO
BTFSC ADCON0,01H ;Checamos si ya termino la conversion
GOTO CICLO ;Si no ha terminado volvemos a checar

MOVF ADRESH,W ;Al terminar la conversion cargamos ADRESH al W


MOVWF PORTB ;Mostramos el resultado por el Puerto RB
GOTO REPITE
;========================================
;= DELAY: Subrutina de retardo =
;= Modifica los siguientes registros: =
;= CUENTA1 =
;= CUENTA2 =
;========================================
;Subrurtina hecha con 2 lazos anidados

DELAY MOVLW 0ffH ;Carga el acumulador W con el valor


;de FFH (255 en decimal)
MOVWF CUENTA1 ;Mueve el contenido del acumulador
;a CUENTA1
ACA1 MOVLW 0FFH ;Carga CUENTA2 con el valor FFH
MOVWF CUENTA2
ACA DECFSZ CUENTA2,F ;Decrementa CUENTA2, guarda el resultado
;en f(CUENTA2), y si es cero se salta la
;siguiente instrucción
GOTO ACA ;Vuelve a decrementar mientras
;CUENTA2 no sea cero
DECFSZ CUENTA1,F ;Se decrementa CUENTA1 cada vez que
;CUENTA2 llega a cero
GOTO ACA1 ;mientras CUENTA1 no llegue a cero recarga
;CUENTA2 y repite el proceso
RETURN ;retorna al programa principal

;= FIN DE LA SUBRUTINA DELAY =


;===========================

END ;FIN DE PROGRAMA

Diagrama de conexión:
+5vdc
+5vdc

11,32
R1
10k
S1
1

VDD
13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35
Y1 6 RA3/AN3 RB2 34
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5
LED
C2 22pf 10 RE1/AN6
RE2/AN7
+5Vdc 15 30
16 RC0 RD7 29
17 RC1 RD6 28
P1 18 RC2 RD5 27
23 RC3 RD4 22
100K 24 RC4 RD3 21
25 RC5 RD2 20
26 RC6 RD1 19
RC7 RD0
VSS

U1
12,31

PIC16F874

NOTA: Conecte una resistencia de 220 ohms en serie con cada uno de los leds.

Sugerencias Didácticas:
1.- Se le sugiere al maestro de ensamblar y correr el programa de prueba junto con el alumno en la sala de computo.
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] http://www.microchip.com
Práctica No.10 Puerto Serie(Ensamblador)..
Objetivo: Realizar una comunicación serie entre 2 Microcontroladores ( Ensamblador).

Introducción:
Con el desarrollo de esta práctica el alumno aprenderá a configurar el puerto serie(UART) para realizar comunicaciones en
serie con cualquier dispositivo que maneje comunicación serial. Se requiere revisar los siguientes registros que se utilizan
para la comunicación serie:
PIR1, PIE1, TXSTA , RCSTA, SPBRG, TXREG.

Esta práctica se correlaciona con el subtema 2.2.7 de la Unidad 2.

Material y Equipo utilizado:


2 Microcontrolador PIC16F874
2 Cristal 4 Mhz
4 Capacitores de 22pf o 15pf
20 Resistencia de 10k
4 Push Button
16 Leds
16 Resistencia de 220 Ohms
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Voltímetro

Metodología:
1- Utilice el software MPLAB para editar el programa Serie.asm que se muestra mas adelante.
2- Ensamble, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX ) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el funcionamiento del programa poniendo el dato a trasmitir por el puerto serie en el puerto RD (Dip-
Switch) del Microcontrolador 1 y una vez puesto presionar el PushButton 2 conectado en el pin RC0. Observe que
el dato trasmitido se mostrara por los leds conectados en el puerto RB del microcontrolador 2. Cambie el dato varias
veces en el Dip-switch y vuelva a trasmitir, confirme que lo que manda es realmente lo que se muestra en los leds.
Ahora trasmita el dato del Microcontrolador 2 hacia el Microcontrolador 1.
6- Ahora modifique el programa para que realice una tarea diferente puede ser alguna de las siguientes:
s) Conecte 2 display de 7 segmentos en el puerto RB de cada uno de los microcontroladores, ahora muestre la
lectura obtenida por el display . Los datos que ponga en el Dip-Switch tendrán que estar en BCD para que se
puedan mostrar en los display. Ejemplo ponga un 31H en el Dip-Switch para poder ver un 31 decimal en los
display.
t) Conecte 1 potenciómetro en el pin RA0 del Microcontrolador 1(configurado para leer su voltaje Análogo) y
muestre su lectura por un display doble de 7 segmentos conectados al puerto RB del Microcontrolador 2.
u) Poner un sensor de temperatura o cualquier otro tipo de sensor(presión, flujo, etc.) en lugar del potenciómetro
del inciso b) y mostrar la lectura por un display(puede ser un LCD) conectado en el Microcontrolador 2.
v) Dejar al alumno que utilice su creatividad.
w) Dejar que el maestro ponga una opción diferente a estas.

7- Reporte sus resultados, incluya como quedaron configurados los registros para lograr la
comunicación serie e incluya una breve explicación.
NOTA: Para utilizar el programa fuente con el PIC18F4455 sustituya las siguientes directivas:
LIST P=PIC18F4455
#include p18f4455.inc
CONFIG FOSC = XT_XT,PWRT = OFF, WDT = OFF, LVP=OFF

Cambiar la dirección de la rutina de servicio de interrupción : (ORG 04H) por (ORG 08H)
Puesto que el pin RB0 es por default canal análogo AN12 ponga las siguientes instrucciones para hacerlo digital:
MOVLW 0FH ;Estas 2 instrucciones Solo poner para el
MOVWF ADCON1 ;PIC18F4455 (Pone todos los ANx a Digitales)

Programa fuente:
;**********************************************************
;* Serie.asm *
;* Este programa realiza una Comunicacion serie entre *
;* 2 Microcontroladores, trasmitiendo el dato leido por *
;* el puerto RD del Microcontrolador 1 al Microcontrolador*
;* 2 y este al recibirlo lo muestra por el puerto RB. *
;* Tambien trasmite del Microcontrolador 2 al 1 *
;* Rev A: By Ing. Jorge Aguirre *
;**********************************************************
LIST P=PIC16F874
#include p16f874.inc

__config _XT_OSC & _PWRTE_OFF & _WDT_OFF & _CP_OFF & _LVP_OFF & _WRT_ENABLE_OFF

CUENTA1 EQU 20H ;Variable localizada en la dirección 20H


CUENTA2 EQU 21H ;Variable localizada en la dirección 21H
CUENTA3 EQU 22H ;Variable localizada en la dirección 22H

F EQU 1
w EQU 0

#DEFINE BANCO0 BCF STATUS,5


#DEFINE BANCO1 BSF STATUS,5

ORG 00H
GOTO INICIO ;ponemos este GOTO al principio para poder poner
;el subprograma de las interrupciones a partir de
;la dirección 04h

;Comienza la interrupción:
;=========================

ORG 04H ;El pic salta a esta dirección cuando se produce una
;interrupcion por el puerto serie
BTFSS PIR1, 0x5 ;Checa si se interrumpio por recepcion
GOTO REGRESA ;si no fue hacia regresa de la interrupcion
BCF PIR1,5 ;Si fue por recepcion limpia la bandera
MOVF RCREG,W ;Lee lo que llego por recepcion y lo carga al W
MOVWF PORTB ;Muestra lo que se recibio por el puerto RB

REGRESA
RETFIE ;fin de la interrupción

;======================
INICIO
BANCO1 ;Pasamos al banco 1
MOVLW 00H ;RC=0000 0000
MOVWF TRISB ;Configuramos todo el puerto C como salidas

MOVLW 0BFH ;RC=1011 1111


MOVWF TRISC ;Configuramos Tx=0(salida), Rx=1(entrada)
MOVLW 0FFH ;Todos los bits del acumulador a "1"
MOVWF TRISD ;Configuramos todo el puerto D como entradas

BANCO0 ;Volvemos al banco 0

BSF PORTB,0 ;Prende el led conectado al PORTB.0


CALL DELAY ;Retardo de tiempo
BCF PORTB,0 ;Apaga el led conectado al PORTB.0
;====================================
BANCO1
BSF PIE1,5 ;Habilita la interrupción para el puerto serie
MOVLW 24H ;BRGH=1, TXEN=1(hablita la interrupción por TX)
MOVWF TXSTA ;configuración del puerto serie
MOVLW 19H ;VELOCIDAD A 9600 BAUDS, BRGH=1 4MHZ
MOVWF SPBRG ;Se carga la configuración en el Registro SPBRG
BANCO0
MOVLW 90H ;SPEN=1, CREN=1(hablita la interrupción por RX)
MOVWF RCSTA ;Se carga la configuracion en el registro RCSTA

BSF INTCON,6 ;Habilita la interrupción de periféricos


BSF INTCON,7 ;Habilita las interrupciones globalmente
;====================================
CICLO BTFSC PORTC, 0 ;Espera que se presione el push-bottom conectado
GOTO CICLO ;en el pin PORTC.0

BSF PORTB,0 ;Prende el led conectado al PORTB.0


CALL DELAY ;Retardo de tiempo
BCF PORTB,0 ;Apaga el led conectado al PORTB.0

MOVF PORTD,W ;carga el dato del Puerto RD al W


CICLO2 BTFSS PIR1, 0x4 ;Verifica que el bufer de trasmisión este vacío
GOTO CICLO2 ;si no es así espera hasta que se vacie
MOVWF TXREG ;trasmite el dato cargando W al TXREG
GOTO CICLO ;Salta a Ciclo para esperar otro dato a trasmitir

;===========================
; DELAY: Subrutina de retardo
;Rutina de aprox. 250 msegundos
;===========================
DELAY
MOVLW 01H ;Carga el W con el valor 01H
MOVWF CUENTA3 ;Carga CUENTA3 con el valor del W

LAZO3 MOVLW 0F9H ;Carga el W con el valor F9H


MOVWF CUENTA2 ;Carga CUENTA2 con el valor del W
LAZO2 MOVLW 0FAH ;Carga el W con el valor FAH
MOVWF CUENTA1 ;Carga CUENTA1 con el valor del W
LAZO1 NOP
DECFSZ CUENTA1,F ;Decrementa CUENTA1 y sigue en el
GOTO LAZO1 ;lazo1 mientras no sea 0
DECFSZ CUENTA2,F ;Decrementa CUENTA2 y sigue en el
GOTO LAZO2 ;lazo2 mientras no sea 0
DECFSZ CUENTA3,F ;Decrementa CUENTA3 y sigue en el
GOTO LAZO3 ;lazo3 mientras no sea 0

RETURN ;retorna al programa principal


;===========================
END ;FIN DE PROGRAMA

Diagrama de conexión:
+5vdc
+5vdc

11,32
R1
10k
S1
1

VDD
13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35
Y1 6 RA3/AN3 RB2 34
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5
LED
C2 22pf 10 RE1/AN6 S1
R2 10k RE2/AN7
+5Vdc 15 30 9 8
16 RC0 RD7 29 10 7
17 RC1 RD6 28 11 6
18 RC2 RD5 27 12 5
S2 sw2 23 RC3 RD4 22 13 4
24 RC4 RD3 21 14 3
TX 25 RC5 RD2 20 15 2
26 RC6 RD1 19 16 1
RX RC7 RD0
VSS

SW DIP-8
U1
12,31

PIC16F874 10K 10K 10K 10K 10K 10K 10K 10K

+5vdc
+5vdc +5Vdc
11,32

R3
10k
S3
1
VDD

13 MCLR
sw3 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C3 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35
Y2 6 RA3/AN3 RB2 34
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5
LED
C4 22pf 10 RE1/AN6 S2
R3 10k RE2/AN7
+5Vdc 15 30 9 8
16 RC0 RD7 29 10 7
17 RC1 RD6 28 11 6
18 RC2 RD5 27 12 5
S4 sw4 23 RC3 RD4 22 13 4
24 RC4 RD3 21 14 3
TX 25 RC5 RD2 20 15 2
26 RC6 RD1 19 16 1
RX RC7 RD0
VSS

SW DIP-8
U2
12,31

PIC16F874 10K 10K 10K 10K 10K 10K 10K 10K

+5Vdc

NOTA: Conecte una resistencia de 220 ohms (puede ser de 330 ohms)en serie con cada uno de los leds.

Sugerencias Didácticas:
1.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de computo.
2.- Investigar la configuración requerida para la comunicación serie para el PIC.
3.- Formar equipos de trabajo.
4.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
5.- Propiciar la investigación.
6.- Estimular la participación en las prácticas.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:
[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003
[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] http://www.microchip.com
Practica # 11 Intermitencia en lenguaje C
Programa Fuente:

/*********************************************************/
// PROGRAMA: Intermitencia.C
// Este programa configura RB0 como salida *
// y genera una intermitencia en dicha salida *
// Rev A: By Ing. Jorge Aguirre
/*********************************************************/
#if defined(__PCM__)
#include <16F874.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#elif defined(__PCH__)
#include <18F4455.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#endif

#use Delay(Clock=4000000)

// *********************************
void main(void){
set_tris_b(0b00000000); // Configura el puerto RB como salidas
while(1){ // Lazo infinito
output_b(0b00000001); // Pone un 1 en el bit 0 del pto B
delay_ms( 250 ); // Retardo de 250 msegundos
output_b(0b00000000); // Pone un 0 en el bit 0 del pto B
delay_ms( 250 );
}
}
Diagrama de conexión:
U2
7805
1 2 + 5Vdc
IN OUT
GND

9 Vdc Pila
3

+5vdc
+5vdc
11,32

R1
10k
S1
1
VDD

13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35
Y1 6 RA3/AN3 RB2 34 R1 D1
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5 220 LED
C2 22pf 10 RE1/AN6
R2 RE2/AN7
+5vdc 15 30
16 RC0 RD7 29
220 D2 17 RC1 RD6 28
18 RC2 RD5 27
23 RC3 RD4 22
24 RC4 RD3 21
25 RC5 RD2 20
26 RC6 RD1 19
RC7 RD0
VSS

U1
12,31

PIC16F874

Sugerencias Didácticas:
1.- Por ser el primer programa en “C” se le sugiere al maestro de compilar y correr el programa de prueba junto con el
alumno en la sala de computo, e ir explicando los pasos requeridos en el MPLAB para editar un programa, realizar un
proyecto(projet), Compilar(CCS) y simular (MPLABSIM). Aproveche para enseñar al alumno el ambiente del MPLAB así
como algunas opciones del MPLABSIM.
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] Manual de usuario del compilador PCW de CCS
[7] http://www.microchip.com

#use Delay(Clock=48000000) //Instrucciones para tarjetas con bootloader

#build(reset=0x1000)
#build(interrupt=0x1008)
#org 0,0x0FFF void bootloader() {} //
Práctica No.12 Rotación del Puerto RB (Lenguaje “C”).
Objetivo: Que el alumno aprenda a manipular los puertos del Microcontrolador en lenguaje “C”.

Introducción:
Esta práctica le ayudará al alumno a conocer la distribución de los puertos y aprenderá a manejarlos. Además aprenderá a
utilizar las función set_tris_b(configuración) para configurar si los pines del puerto RB son de entrada o de salida (0-
salida, 1- Entrada). La función output_b(dato) se utiliza para sacar el dato por el puerto RB. De la misma forma tendríamos
las siguientes funciones para los demás puertos:
set_tris_a( byte ); output_a( byte );
set_tris_b( byte ); output_b( byte );
set_tris_c( byte ); output_c( byte );
set_tris_d( byte ); output_d( byte );
set_tris_e( byte ); output_e( byte );

En lenguaje “C” el byte se puede expresar en código hexadecimal con (0x) o en binario con (0b). Ejemplo:
Si queremos sacar el numero 0F Hex por el puerto RB seria de la siguiente forma:

En hexadecimal: Output_b(0x0F)
En binario: Output_b(0b00001111)

Esta práctica se correlaciona con los Temas del 2.2.1 al 2.2.5 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
8 Leds
1 Resistencia de 10 Kohms
8 Resistencias de 220 ohms
1 Push Button
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics

Metodología:

1- Utilice el software MPLAB para editar el programa rota.c que se muestra mas adelante.
2- Compile, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en la compilación) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice una de las siguientes opciones: (el maestro decidirá cual):
a). Realice una Rotación a la Derecha del Puerto B.
b). Realice una rotación a la izquierda y al llegar al bit 7 realizar una rotación a la
derecha hasta el bit 0. Repita el ciclo indefinidamente.
c). Realice una rotación a la izquierda involucrando el puerto B y C.
d). Dejar al alumno que utilice su creatividad para hacer los movimientos que
desee de los puertos.
e) Dejar que el maestro ponga una opción diferente a estas.

7- Reporte sus resultados.

Programa fuente:

/*********************************************************/
// PROGRAMA: ROTA1.C
// Rotación del puerto B de izquierda a derecha
// Rev A: ING. JORGE AGUIRRE
/*********************************************************/
#if defined(__PCM__)
#include <16F874.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#elif defined(__PCH__)
#include <18F4455.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#endif

#use Delay(Clock=4000000)

// *********************************

void main(void){
set_tris_b(0b00000000);
while(1){

output_b(0b00000001);
delay_ms( 250 );
output_b(0b00000010);
delay_ms( 250 );
output_b(0b00000100);
delay_ms( 250 );
output_b(0b00001000);
delay_ms( 250 );
output_b(0b00010000);
delay_ms( 250 );
output_b(0b00100000);
delay_ms( 250 );
output_b(0b01000000);
delay_ms( 250 );
output_b(0b10000000);
delay_ms( 250 );

}
}

Diagrama de conexión:
+5vdc
+5vdc

11,32
R?
10k
S?
1

VDD
13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35
Y? 6 RA3/AN3 RB2 34
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5
LED
C2 22pf 10 RE1/AN6
RE2/AN7
15 30
16 RC0 RD7 29
17 RC1 RD6 28
18 RC2 RD5 27
23 RC3 RD4 22
24 RC4 RD3 21
25 RC5 RD2 20
26 RC6 RD1 19
RC7 RD0
VSS

U?
12,31

PIC16F874

NOTA: Agregue una resistencia en serie de 220 Ohms a cada uno de los leds.

Sugerencias Didácticas:
1.- Formar equipos de trabajo.
2.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
3.- Propiciar la investigación.
4.- Estimular la participación en las prácticas.
5.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de computo.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] Manual de usuario del compilador PCW de CCS
[7] http://www.microchip.com
Práctica No.13 Menú de rotas (Lenguaje “C”).

Objetivo: Que el alumno aprenda a elaborar un menú de opciones en Lenguaje “C”


Introducción: Esta práctica le ayudará al alumno a conocer la distribución de los puertos y aprenderá a manejarlos en
lenguaje C . Además de aprender a utilizar la sentencia del Lenguaje “C” (SWITCH – CASE) para la realización de un menú
de opciones.
Este programa lee una opción por el puerto C y la muestra por el puerto B.

Esta práctica se correlaciona con el Tema 2.2.5 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
8 Leds
1 Resistencia de 10 Kohms
8 Resistencias de 220 ohms
1 Push Button
1 Dip Switch (3 o 4 switch)
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Compilador CCS

Metodología:

1- Utilice el software MPLAB para editar el programa Menu.c que se muestra mas adelante y termínelo para que
tenga 7 opciones de rotas. Las 7 opciones se introducirán en binario por el puerto “C” (opcional-puede usar un
dip switch para introducir la opción) de la siguiente forma:

0000 0000 - No realiza nada


0000 0001 - Rota1
0000 0010 - Rota2
0000 0011 - Rota3
0000 0100 - Rota4
0000 0101 - Rota5
0000 0110 - Rota6
0000 0111 - Rota7

2- Compile, Simule y entienda el funcionamiento del programa.


3- Grabe el archivo (.HEX obtenido en la compilación) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6.-Se puede modificar el programa para que el menú de opciones pueda ser de otras opciones diferentes, el maestro
puede sugerir las opciones o dejar que el alumno utilice su creatividad.
Puede ser por ejemplo que el programa lea un número del puerto C y otro del puerto D y las opciones podrían ser
las operaciones aritméticas (suma, resta, etc.) y/o las operaciones lógicas(And , Or, etc.). El resultado de la
operación que la muestre por el puerto B.
Otro ejemplo sería que lea un número en binario por el puerto C y lo muestre en BCD en un display de 7
segmentos colocado por el puerto B.
7- Reporte sus resultados.

Programa Fuente:

#if defined(__PCM__)
#include <16F874.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#elif defined(__PCH__)
#include <18F4455.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#endif

#use Delay(Clock=4000000)

// *********************************

// Definiciones de usuario
#byte PORTB = 0x06
#byte TRISB = 0x86
#byte TRISC = 0x87
#byte PORTC = 0x07

//Declaración de funciones
void espera_seg(void); //declara la function de retardo de un segundo
void ROTA1(void); //declara la function rota 1
void ROTA2(void); //declara la function rota 2
void ROTA3(void); //declara la function rota 3
void ROTA4(void); //declara la function rota 4
void ROTA5(void); //declara la function rota 5
void ROTA6(void); //declara la function rota 6
void ROTA7(void); //declara la function rota 7

//Declaración de variables
int i;

void main(){
TRISB=0x00; //Configura el puerto B como salidas
PORTB=0x00; //Pone en ceros al puerto B para empezar con los leds apagados
TRISC=0xFF; //Configura el puerto C como entradas

while(1){ //se establece un lazo infinito


espera_seg(); //llama a la rutina de espera un segundo
switch (PORTC){ //evalúa las entradas en el Puerto c
case 0x00:break; //en caso de que la entrada sea cero no hace nada
case 0x01:ROTA1();break;// en caso de que la entrada sea 1 llama a la rutina de rota 1
case 0x02:ROTA2();break;// en caso de que la entrada sea 2 llama a la rutina de rota 2
case 0x03:ROTA3();break;// en caso de que la entrada sea 3 llama a la rutina de rota 3
case 0x04:ROTA4();break;;//en caso de que la entrada sea 4 llama a la rutina de rota 4
case 0x05:ROTA5();break;// en caso de que la entrada sea 5 llama a la rutina de rota 5
case 0x06:ROTA6();break;// en caso de que la entrada sea 6 llama a la rutina de rota 6
case 0x07:ROTA7();break;// en caso de que la entrada sea 7 llama a la rutina de rota 7
default:PORTC=0; //Default: pone el Puerto ‘C” en ceros
}
}
}

void ROTA1(void) //Función rota 1


{
PORTB=0b00000001; //enciende el bit 0 del Puerto B
espera_seg( ); //llama a la función de retardo de 1 segundo.
while(PORTB !=0x80){ //checa si ya prendió el bit 7 del puerto B.
PORTB<<=1; //Rota el puerto B 1 vez a la izquierda
espera_seg(); //llama a la función de retardo de 1 segundo
}
}

void ROTA2(void) //Función rota 2


{
}

void ROTA3(void) //Función rota 3


{
}

void ROTA4(void) //Función rota 4


{
}

void ROTA5(void) //Función rota 5


{
}

void ROTA6(void) //Función rota 6


{
}

void ROTA7(void) //Función rota 7


{
}

void espera_seg(void)
{
int i;
for(i=0; i<4; i++);
delay_ms( 250 );
/* 250 milisegundos */
}

Diagrama de conexión:
+5vdc
+5vdc

11,32
R1
10k
S1
1

VDD
13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35
Y1 6 RA3/AN3 RB2 34
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5
LED
C2 22pf 10 RE1/AN6
RE2/AN7
S1
1 6 15 30
2 5 16 RC0 RD7 29
3 4 17 RC1 RD6 28
18 RC2 RD5 27
23 RC3 RD4 22
SW
24 RC4 RD3 21
25 RC5 RD2 20
R2 R3 R4 26 RC6 RD1 19
10k 10k 10k RC7 RD0
VSS

U1
12,31

PIC16F874
+5Vdc

NOTA: Agregue una resistencia en serie de 220 Ohms a cada uno de los leds.

Sugerencias Didácticas:
1.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Enfocarse en enseñar en el
simulador como correr el programa paso a paso y ver como se realiza el llamado a una subrutina. Enseñar las opciones del
simulador MPLABSIM ( Step Into, Step Over y Step Out). Checar la función espera_seg(); con el Stop Watch.
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte:
1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc.Graw Hill
[5] Apuntes del Maestro.
[6] Manual de usuario del compilador PCW de CCS
[7] http://www.microchip.com

Práctica No.14 Interrupción Externa INTRB0 (Lenguaje “C”).


Objetivo: Desarrollar una rutina de servicio para la interrupción externa INTRB0 en Lenguaje “C”.

Introducción:
Con el desarrollo de esta práctica el alumno comprenderá como el programa se interrumpe cuando se provoca una
interrupción por el pin RB0 (un cambio de estado en el pin RB0) y brincará a la localidad 04H de la memoria de programa
para ejecutar la rutina de servicio que atiende dicha interrupción. La rutina de servicio de interrupción invierte el estado del
bit RC0 cada vez que se presione el push botton (dispositivo que provoca la interrupción), dicho cambio de estado se
mostrara por el pin RC0 a través de un Led.

Esta práctica se correlaciona con el Tema 2.2 y principalmente con el subtema 2.2.5.4 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
2 Leds
1 Resistencia de 10 Kohms
1 Resistencia de 220 Ohms
1 Resistencia de 1 M0hms
2 Push Button
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Compilador CCS

Metodología:
1- Utilice el software MPLAB para editar el programa intrb0.c que se muestra mas adelante.
2- Compile, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en la compilación) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice una tarea diferente en la rutina de servicio de interrupción puede
ser alguna de las siguientes:
k) Que vaya incrementando un contador cada vez que se presione el push botton y que dicha cuenta la muestre en
binario por el puerto C a través de 8 leds.
l) Que vaya incrementando un contador cada vez que se presione el push botton y que dicha cuenta la muestre en
BCD a través de un display doble de 7 segmentos conectados por el puerto C.
m) Que realice una rotación hacia la izquierda de unos leds conectados por el puerto C cuando se presione por
primera vez el push botton y que cambie el sentido las siguientes veces que se vuelva a presionar el push
boton.
n) Se puede dejar libre al alumno para que utilice su creatividad.
o) Dejar que el maestro ponga una opción diferente a estas.
7- Reporte sus resultados.

Programa fuente:
#if defined(__PCM__)
#include <16F874.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#elif defined(__PCH__)
#include <18F4455.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#endif

#use Delay(Clock=4000000)

// *********************************
// Declaracion de variables
int PORTC_0;

// *********************************

#INT_EXT //Interrupcion por el Puerto B


void intext_isr() {

if(PORTC_0==1){ //checa si PORTC_0=1


PORTC_0=0; //Si es verdadero cambia a PORTC_0=0
output_c(0b00000000); // pone un 0 en el bit 0 del Pto C
}
else {
PORTC_0=1; //Si no es verdadero cambia a PORTC_0=1
output_c(0b00000001); // pone un 1 en el bit 0 del Pto C
}
}

void main() {

set_tris_c(0x00); // Todo el Pto. C como salidas


set_tris_b(0x0FF); // Todo el Pto. B como entradas

output_c(0b00000001); // pone un 1 en el bit 0 del Pto C

ENABLE_INTERRUPTS(GLOBAL | INT_EXT);// b7 ;Habilita las interrupciones globalmente


// b4 ;Habilita la interrupción por el bit RB0
while(1){ }; // Lazo infinito, no hace nada
}

Diagrama de conexión:
+5vdc +5vdc

11,32
R1
10k
S1
1

VDD
13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35 +5vdc
Y1 6 RA3/AN3 RB2 34 S1
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0/INT
9 RE0/AN5 sw1
C2 22pf 10 RE1/AN6 1Mohms R3
R2 RE2/AN7
+5vdc 15 30
16 RC0 RD7 29
220 D? 17 RC1 RD6 28
18 RC2 RD5 27
23 RC3 RD4 22
24 RC4 RD3 21
25 RC5 RD2 20
26 RC6 RD1 19
RC7 RD0
VSS

U?
12,31

PIC16F874

Sugerencias Didácticas:
1.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Correr el programa paso a paso y
ver como se genera la interrupción al cambiar el estado del pin RB0, como brinca a la dirección 04H de la memoria de
programa y enfatizar que lo primero que hay que hacer es borrar la bandera que indica que hubo en cambio en RB0 (bit 1
del registro INTCON). En lenguaje C no hay que preocuparse por guardar el contenido del acumulador(W), ni el registro
de estado, el compilador CCS lo hace automáticamente.
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte:
1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] Manual de usuario del compilador PCW de CCS
[7] http://www.microchip.com
Práctica No.15 Interrupción del puerto RB (Lenguaje “C”).
Objetivo: Desarrollar una rutina de servicio para la interrupción externa por el puerto RB(pines RB7,RB6,RB5 y RB4) en
Lenguaje “C”.

Introducción:
Con el desarrollo de esta práctica el alumno comprenderá como el programa se interrumpe cuando se provoca una
interrupción por el puerto RB (específicamente cuando cambia de estado alguno de los pines RB7,RB6,RB5 y RB4) y
brincará a la localidad 04H de la memoria de programa para ejecutar la rutina de servicio que atiende dicha interrupción. La
rutina de servicio de interrupción invierte el estado del bit RC0 cada vez que se presione alguno de los push button
(dispositivo que provoca la interrupción) conectados a los pines RB7,RB6,RB5 y RB4, dicho cambio de estado se mostrara
por el pin RC0 a través de un Led.

Esta práctica se correlaciona con el Tema 2.2 y principalmente con el subtema 2.2.5.4 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
1 Led
5 Push Button
1 Resistencia de 1k
4 Resistencias de 1 Mohm
1 Resistencia de 220 Ohms
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Compilador CCS

Metodología:

1- Utilice el software MPLAB para editar el programa intRB.c que se muestra mas adelante.
2- Compile, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en la compilación) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice una tarea diferente en la rutina de servicio de interrupción puede
ser alguna de las siguientes:
p) Que vaya incrementando un contador cada vez que se presione cualquiera de los push button y que dicha
cuenta la muestre en binario por el puerto C a través de 8 leds.
q) Que vaya incrementando un contador cada vez que se presione cualquiera de los push button y que dicha
cuenta la muestre en BCD a través de un display doble de 7 segmentos conectados por el puerto C.
NOTA: Se le puede agregar a estas practicas que además de mostrar la cuenta también indique cual fue el pin que
interrumpió por medio de 4 leds.
r) Que realice una rotación hacia la izquierda de unos leds conectados por el puerto C cuando se presione por
primera vez el push button y que cambie el sentido las siguientes veces que se vuelva a presionar el push
button.
s) Se puede dejar libre al alumno para que utilice su creatividad.
t) Dejar que el maestro ponga una opción diferente a estas.

7- Reporte sus resultados.

Programa fuente:

#if defined(__PCM__)
#include <16F874.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#elif defined(__PCH__)
#include <18F4455.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#endif

#use Delay(Clock=4000000)

// *********************************

// Declaracion de variables
int PORTC_0;

//Declaración de funciones
void espera_seg(void);

// *********************************

#INT_RB //Interrupt por el Puerto B


void intext_isr() {

if(PORTC_0==1){
PORTC_0=0;
output_c(0b00000000); // pone un 0 en el bit 0 del Pto C
}
else {
PORTC_0=1; //Si no es verdadero cambia a PORTC_0=1
output_c(0b00000001); // pone un 1 en el bit 0 del Pto C
}
espera_seg();
}

void main() {

set_tris_c(0x00); // Todo el Pto. C como salidas


set_tris_b(0x0FF); // Todo el Pto. B como entradas
output_c(0b00000001); // pone un 1 en el bit 0 del Pto C
ENABLE_INTERRUPTS(GLOBAL | INT_RB); // b7 ;Habilita las interrupciones globalmente
// b3 ;Habilita la interrupción por RB
while(1){ }; // Lazo infinito, no hace nada
}

// Funcion de retardo de 1 segundo


void espera_seg(void)
{
int i;
for(i=0; i<4; i++);
delay_ms( 250 );
/* 250 milisegundos */
}

Diagrama de conexión:
+5vdc
S1

+5vdc +5vdc
sw2
1Mohms R3
11,32

R1
10k
S1 +5vdc
1 S1
VDD

13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39 sw3
2 RB6 38 1Mohms R4
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35 +5vdc
Y1 6 RA3/AN3 RB2 34 S1
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0/INT
9 RE0/AN5 sw4
C2 22pf 10 RE1/AN6 1Mohms R5
R2 RE2/AN7
+5vdc 15 30
16 RC0 RD7 29 +5vdc
220 D? 17 RC1 RD6 28 S1
18 RC2 RD5 27
23 RC3 RD4 22
24 RC4 RD3 21 sw5
25 RC5 RD2 20 1Mohms R6
26 RC6 RD1 19
RC7 RD0
VSS

U1
12,31

PIC16F874

Sugerencias Didácticas:
1.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Correr el programa paso a paso
y ver como se genera la interrupción al cambiar el estado de cualquiera de los pines RB4,RB5,RB6 y RB7. Observar
como brinca a la dirección 04H de la memoria de programa y enfatizar que lo primero que hay que hacer es borrar la
bandera que indica que hubo un cambio en RB (bit 0 del registro INTCON) y antes de regresar de la interrupción,
además indicar que se le agregó un pequeño retardo para eliminar el rebote.
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte:
1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] Manual de usuario del compilador PCW de CCS
[7] http://www.microchip.com
Práctica No.16 Temporizador TMRO (Lenguaje “C”).
Objetivo: Aprender a configurar y programar el TMR0, en Lenguaje “C”.

Introducción:
Con el desarrollo de esta práctica el alumno aprenderá a configurar el timer 0 para generar retardos de tiempo. En esta
práctica en particular se configura el prescaler con un factor de división de 1/256. Esto quiere decir que debido al cristal de
4Mhz cada 256 microsegundos se genera una cuenta en el registro contador TMR0, por tal razón se inicializa el TMR0 con
un 12 al inicio para que cada 244 cuentas se desborde el TMR0 y provoque una interrupción. Dentro de la rutina de servicio
de interrupción se tiene un contador que detectara cuando el microcontrolador se haya interrumpido 16 veces obteniendo una
cuenta de aproximadamente de 1 segundo de la siguiente forma: 256*244*16= 999,424 Microsegundos.

En teoría esto parece estar bien pero debido a que el compilador de “C” inserta código antes de entrar a la rutina de servicio
de interrupción y después de terminar la rutina de servicio de interrupción , tenemos que tomar en cuenta este código en las
cuentas del tiempo. Por lo tanto se recomienda utilizar el simulador y poner un breakpoint en la instrucción donde se reinicia
la cuenta del contador a cero dentro de la rutina de servicio de interrupción (contador = 0; ) y verificar el tiempo que se tarda
con la opción del stopwatch (localizado en el submenú debugger) correr el programa con la opcion RUN y esperar que se
detenga. Al detenerse observar la cuenta en el stopwatch poner a zero y volver a correr con el RUN. Con esto observaremos
que el tiempo transcurrido en el stopwatch es de 1.000032 segundos.

El objetivo por lo tanto es prender el led por aproximadamente 1 segundo para después apagarlo por el mismo tiempo
teniendo a la salida del pin RB0 una onda cuadrada perfecta que se puede verificar con un osciloscopio.
NOTA: Debido a que el TMR0 del microcontrolador 18F4455 es de 16 bits(65536 cuentas para el sobreflujo) entonces la
cuenta de inicio seria de 65292 para que cada 244 cuentas se desborde el TMR0 y provoque una interrupción. La formula
quedaría de la siguiente manera: 256*244*16= 999,424 Microsegundos.

Esta practica se correlaciona con el subtema 2.2.5.4 y 2.2.6 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 capacitores de 22pf o 15pf
1 Resistencia de 220 Ohms
1 Resistencia de 10k
1 Push Button
1 Led
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Compilador CCS
1 Osciloscopio

Metodología:

1- Utilice el software MPLAB para editar el programa Tmr0.c que se muestra mas adelante.
2- Compile, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en la compilación) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice una tarea diferente en la rutina de servicio de interrupción puede
ser alguna de las siguientes:
x) Hacer que el tiempo de encendido del led sea aproximadamente de medio segundo y el apagado sea de medio
segundo también.
y) Hacer que el tiempo de encendido del led sea de 1 y el apagado sea de medio segundo.
z) Realizar un rota utilizando la interrupción del TMR0. La rotación la debe realizar dentro de la rutina de
servicio de interrupción.
aa) Realizar un reloj con segundos, minutos y horas. Sacar el resultado por display de 7 segmentos conectados en
los puertos siguientes: Segundos por RB, Minutos por RC y Horas por RD.
bb) Dejar al alumno que utilice su creatividad.
cc) Dejar que el maestro ponga una opción diferente a estas.
7- Verifique sus resultados con un osciloscopio.
8- Reporte sus resultados.

Programa fuente:

#if defined(__PCM__)
#include <16F874.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#define cuenta 12 //TMR0-8bits 256-12=244cuentas para sobreflujo
//256*244*16=999,424 microseg

#elif defined(__PCH__)
#include <18F4455.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#define cuenta 65292 //TMR0-16bits 65536-65292=244cuentas para sobreflujo
//256*244*16=999,424 microseg
#endif
//*******************************************
#use delay(clock=4000000)

//*******************************************
// declaracion variables globales
int contador,flag=0;

//*******************************************
// Rutina de servicio de interrupcion
#INT_RTCC
void clock_isr() {
set_timer0(cuenta);
contador=contador+1;

if(contador>15){
contador=0;
if(flag == 1){
flag=0;
output_high(PIN_B0);
}
else{
flag=1;
output_low(PIN_B0);
}
}
}

void main(void) {
contador=0;
set_tris_b(0x00);
SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_256);
SET_TIMER0(cuenta);

ENABLE_INTERRUPTS(GLOBAL | INT_TIMER0 );
output_b(0);
output_high(PIN_B0);

while(1){ };
}

Otra forma de hacer el programa con el mismo objetivo pero ahora la rutina de prender y apagar el led no esta dentro de la
rutina de servicio.

#if defined(__PCM__)
#include <16F874.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#define cuenta 12 //TMR0-8bits 256-12=244cuentas para sobreflujo
//256*244*16=999,424 microseg
#elif defined(__PCH__)
#include <18F4455.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#define cuenta 65292 //TMR0-16bits 65536-65292=244cuentas para sobreflujo
//256*244*16=999,424 microseg
#endif
//*******************************************
#use delay(clock=4000000)

//*******************************************
// declaracion variables globales
int contador,flag=0;

//*******************************************
// Rutina de servicio de interrupcion
#INT_RTCC
void clock_isr() {
set_timer0(cuenta);
contador=contador+1;
}

void main() {
contador=0;
set_tris_b(0x00);
SETUP_TIMER_0(RTCC_DIV_256);
set_timer0(cuenta);

enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);
output_b(0);
output_high(PIN_B0);
while(1){
if(contador>15){
contador=0;
if(flag == 1){
flag=0;
output_high(PIN_B0);
}
else{
flag=1;
output_low(PIN_B0);
}
}
}
}
Diagrama de conexión:

+5vdc
+5vdc

11,32
R1
10k
S1
1

VDD
13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35
Y1 6 RA3/AN3 RB2 34 R1 D1
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5 220 LED
C2 22pf 10 RE1/AN6
RE2/AN7
15 30
16 RC0 RD7 29
17 RC1 RD6 28
18 RC2 RD5 27
23 RC3 RD4 22
24 RC4 RD3 21
25 RC5 RD2 20
26 RC6 RD1 19
RC7 RD0
VSS

U1
12,31

PIC16F874

PROGRAMA ALTERNO

//***********************************************************
//******PROGRAMA PARA LA TARJETA TEC BLANCA CON DISPLAYS CATODO COMUN**********
// USO DEL TIMER CERO PARA GENERAR UN SEGUNDO OPERANDO EN 16 BITS
// INICIALIZANDOLO EN 18661 PARA QUE CUENTE 46875
// CADA VEZ QUE TIMER CERO INTERRUMPE SE INCREMENTAN SEGUNDOS
// MINUTOS Y HORAS LUEGO SE VISUALIZAN EN LOS DISPLAYS DE
// SIETE SEGMENTOS (DOS) EN FUNCION DE LA VARIABLE CUENTA
// SE SACAN LOS SEGUNDOS LOS MINUTOS O LAS HORAS
//*********************************************************

#include <18F4550.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#define cuenta 18661 //TMR0-16bits 65536-18661=46875cuentas para sobreflujo
//256*46875*4=48,000,000 Hz

//*******************************************
#use delay(clock=48000000)
#build(reset=0x1000)
#build(interrupt=0x1008)
#org 0,0x0FFF void bootloader() {} //

//*******************************************
// declaracion variables globales
int contador,flag=0,seg=0,min=0,hr=0,segu=0,segd=0;
int minu=0,mind=0,hru=0,hrd=0,cont=0,uni=0,dec=0;

//***********************************************************
// Rutina de servicio de interrupcion EXTERNA T0 PARA SELECCIONAR
// QUE SALE POR EL DISPLAY : CONT=0 --> SEGUNDOS CONT=1 --> MINUTOS
// CONT=2 --> HORAS
//************************************************************
#int_EXT
void intext_isr()
{
disable_interrupts(INT_EXT);
delay_ms(20);
enable_interrupts(INT_EXT);
cont=cont+1;
if (cont>=3) cont=0;

//**********************************************************
// INTERRUPCION TIMER CERO INTERRUMPE CADA SEGUNDO
//**********************************************************

#INT_RTCC
void clock_isr() {
set_timer0(cuenta);
seg=seg+1; //RELOJ HORAS MINUTOS Y SEGUNDOS
if (seg==60)
{ Seg=0;
min=min+1;
}
if (min==60)
{hr=hr+1;
if (hr==24) hr=0;
}
}

void main (void) {


contador=0;
set_tris_d(0x00);
SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_256);
SET_TIMER0(cuenta);
enable_interrupts(INT_EXT);
ENABLE_INTERRUPTS(GLOBAL | INT_TIMER0 );
ext_int_edge(L_TO_H);

set_tris_d(0x00);
set_tris_b(0xFF);

port_b_pullups(TRUE);
int tabla[10]={0x3F,0x06,0x5B,0x4F,0X66, 0X6D,0X7D,0x07,0x7F,0X67};
int i;
//SEPARA UNIDADES Y DECENAS DE SEGUNDOS
//MINUTOS Y HORAS
while(1){
segd=seg/10;
segu=seg-segd*10;;
mind=min/10;
minu=min-mind*10;
hrd=hr/10;
hru=hr-hrd*10;
if (cont==0){
uni=segu;
dec=segd;
}
if (cont==1){
uni=minu;
dec=mind;
}
if (cont==2){
uni=hru;
dec=hrd;
}

//SACA A DOS DISPLAYS

for(i=0;i<=10;++i){
output_d(tabla[uni]);
delay_ms(5);
output_d(tabla[dec]+0X80);
delay_ms(5);
}
if (cont==1){
if (~input(pin_b1)){
min=min+1;
if (min>=60) min=0;

delay_ms(500);
}
}
if (cont==2){
if (~input(pin_b1)){
hr=hr+1;
if (hr>=24) hr=0;

delay_ms(500);
}
}
}
}

Sugerencias Didácticas:
1.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Enfocarse en enseñar en el
simulador como esta construida la rutina de interrupción del TMR0 usando las opciones del debugger:
Settings.- Poner la velocidad de ejecución a 4Mhz (por default es de 20Mhz).
StopWatch.- Nos ayudará a verificar el tiempo de retardo de cada interrupción.
Set Breakpoint.- Poner punto de paro en el programa en la línea donde se desea que el programa detenga su ejecución,
ejemplo: Poner el cursor en la primer línea de la rutina de interrupción ISR[ set_timer0(cuenta)] , presionar el botón
derecho del mouse y aparecerá una ventana con varias opciones, seleccione la opción Set-Breakpoint. Correr el programa
hasta que se detenga en la misma línea, poner a zero el Stop wtach y volver a correr desde ahí el programa y se detendrá
nuevamente en la misma etiqueta mostrándonos en el Stop Watch el tiempo transcurrido de aproximadamente 1
segundo(256*244*16= 999,424 Microseg).
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] Manual de usuario del compilador PCW de CCS
[7] http://www.microchip.com
Práctica No.17 Temporizador TMR1 (Lenguaje “C”).
Objetivo: Aprender a configurar y programar el TMR1, en Lenguaje “C”.

Introducción:
Con el desarrollo de esta práctica el alumno aprenderá a configurar el timer 1 para generar retardos de tiempo. En esta
práctica en particular se configura el prescaler con un factor de división de 1/2. Esto quiere decir que debido al cristal de
4Mhz cada 2 microsegundos se genera una cuenta en el registro contador TMR1, por tal razón se inicializa el TMR1 con una
cuenta de 15,536 al inicio para que cada 50,000 cuentas se desborde el TMR1 y provoque una interrupción. Dentro de la
rutina de servicio de interrupción se tiene un contador que detectara cuando el microcontrolador se haya interrumpido 10
veces obteniendo una cuenta de aproximadamente de 1 segundo de la siguiente forma: 2*50000*10= 1,000,000
Microsegundos.

En teoría esto parece estar bien pero debido a que el compilador de “C” inserta código antes de entrar a la rutina de servicio
de interrupción y después de terminar la rutina de servicio de interrupción, tenemos que tomar en cuenta este código en las
cuentas del tiempo. Por lo tanto se recomienda utilizar el simulador y poner un breakpoint en la instrucción donde se reinicia
la cuenta del contador a cero dentro de la rutina de servicio de interrupción (contador = 0; ) y verificar el tiempo que se tarda
con la opción del stopwatch (localizado en el submenú debugger) correr el programa con la opción RUN y esperar que se
detenga. Al detenerse observar la cuenta en el stopwatch poner a cero y volver a correr con el RUN. Con esto observaremos
que el tiempo transcurrido en el stopwatch es de 1.000460 segundos.

El objetivo por lo tanto es prender el led por aproximadamente 1 segundo para después apagarlo por el mismo tiempo
teniendo a la salida del pin RB0 una onda cuadrada perfecta que se puede verificar con un osciloscopio.

Esta práctica se correlaciona con el subtema 2.2.5.4 y 2.2.6 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
2 Resistencia de 220 Ohms
1 Resistencia de 10k
1 Push Button
2 Led
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Compilador CCS
1 Osciloscopio
Metodología:

1- Utilice el software MPLAB para editar el programa Tmr1.c que se muestra mas adelante.
2- Compile, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en la compilación) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice una tarea diferente en la rutina de servicio de interrupción puede
ser alguna de las siguientes:
dd) Realizar un reloj con segundos, minutos y horas. Sacar el resultado por display de 7 segmentos conectados en
los puertos siguientes: Segundos por RB, Minutos por RC y Horas por RD.
ee) Dejar al alumno que utilice su creatividad.
ff) Dejar que el maestro ponga una opción diferente a estas.

7- Verifique sus resultados con un osciloscopio.


8- Reporte sus resultados.

Programa fuente:

#if defined(__PCM__)
#include <16F874.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#elif defined(__PCH__)
#include <18F4455.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#endif

#use Delay(Clock=4000000)

// *********************************
int contador,PORTB_0;

#INT_TIMER1 //Rutina de servicio de interrupción


void clock_isr(void) {
SET_TIMER1(15559); //Ajuste de 15535 a 15559 para aproximarlo al 1 seg
contador=contador+1; //Utilice el StopWatch en el simulador para verificarlo
if(contador==10){
contador=0; //<-- Ponga aquí el Breakpoint para checar
if(PORTB_0==1){
PORTB_0=0;
output_b(0b00000010);
}
else {
PORTB_0=1;
output_b(0b00000011);

}
}
}

void main(void) {
contador=0;
set_tris_b(0x00);

SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_2);
SET_TIMER1(15536); //65536-15536=50000 cuentas para el sobreflujo
//En teoria 2*50000*10=1,000,000 Microseg
ENABLE_INTERRUPTS(INT_TIMER1);
ENABLE_INTERRUPTS(GLOBAL );

while(1){ };
}

Diagrama de conexión:
+5vdc
+5vdc
11,32

R1
10k
S1
1
VDD

13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38 R3 D2
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35 220 LED
Y1 6 RA3/AN3 RB2 34 D1
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5 R2 220 LED
C2 22pf 10 RE1/AN6
RE2/AN7
15 30
16 RC0 RD7 29
17 RC1 RD6 28
18 RC2 RD5 27
23 RC3 RD4 22
24 RC4 RD3 21
25 RC5 RD2 20
26 RC6 RD1 19
RC7 RD0
VSS

U1
12,31

PIC16F874

PROGRAMA ALTERNO PARA TARJETA TEC (SEGUNDERO)

#include <18F4550.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use Delay(Clock=48000000)
//#build(reset=0x1000)
//#build(interrupt=0x1008)
//#org 0,0x0FFF void bootloader() {} //
// *********************************
int contador,PORTD_0,uni=0,dec=0;

#INT_TIMER1 //Rutina de servicio de interrupción


void clock_isr(void) {
SET_TIMER1(5536); //Ajuste de 15535 a 15559 para aproximarlo al 1 seg
contador=contador+1; //Utilice el StopWatch en el simulador para verificarlo
if(contador==50){
contador=0; //<-- Ponga aquí el Breakpoint para checar
// if(PORTD_0==1){
// PORTD_0=0;
// output_d(0b00000010);
// }
// else {
// PORTD_0=1;
// output_d(0b00000001);

++uni;
if(uni>9)
{
uni=0;
++dec;
if(dec>5)
{
dec=0;
}
}

}
}

void main(void) {
int tabla[10]={0x3F,0x06,0x5B,0x4F,0X66, 0X6D,0X7D,0x07,0x7F,0X67};
int i;
contador=0;
set_tris_d(0x00);

SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_4);
SET_TIMER1(15536); //65536-15536=50000 cuentas para el sobreflujo
//En teoria 2*50000*10=1,000,000 Microseg
ENABLE_INTERRUPTS(INT_TIMER1);
ENABLE_INTERRUPTS(GLOBAL );

while(1){
for(i=0;i<=100;++i){
output_d(tabla[uni]);
delay_ms(5);
output_d(tabla[dec]+0X80);
delay_ms(5);
}
};
}

Sugerencias Didácticas:
1.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Enfocarse en enseñar en el
simulador como esta construida la rutina de interrupción del TMR1 usando las opciones del debugger:
Settings.- Poner la velocidad de ejecución a 4Mhz (por default es de 20Mhz).
StopWatch.- Nos ayudará a verificar el tiempo de retardo de cada interrupción.
Set Breakpoint.- Poner un punto de paro en el programa en la línea donde se desea que el programa detenga su ejecución,
ejemplo: Poner el cursor en esta línea que esta dentro de la rutina de interrupción:
[ contador=0 //<-- Ponga aquí el Breakpoint ]
Presionar el botón derecho del mouse y aparecerá una ventana con varias opciones, seleccione la opción Set-Breakpoint.
Correr el programa hasta que se detenga nuevamente en la misma línea, poner a cero el Stop wtach y volver a correr desde
ahí el programa y se detendrá nuevamente en la misma línea mostrándonos en el Stop Watch el tiempo transcurrido de
aproximadamente 1 segundo(2*50000*10= 1,000,000 Microseg.).
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.
Reporte del Alumno (Resultados):
1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.
Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] Manual de usuario del compilador PCW de CCS
[7] http://www.microchip.com
Práctica No.18 Temporizador TMR2 (Lenguaje “C”)..
Objetivo: Aprender a configurar y programar el TMR2, en Lenguaje “C”.

Introducción:
Con el desarrollo de esta práctica el alumno aprenderá a configurar el timer 2 para generar retardos de tiempo. En esta
práctica en particular se configura el prescaler con un factor de división de 1/16. Esto quiere decir que debido al cristal de
4Mhz cada 16 microsegundos se genera una cuenta en el registro contador TMR2, por tal razón se inicializa el TMR2 con
una cuenta de 12 al inicio para que cada 244 cuentas se desborde el TMR2 y provoque una interrupción. Dentro de la rutina
de servicio de interrupción se tiene un contador que detectara cuando el microcontrolador se haya interrumpido 256 veces
obteniendo una cuenta de aproximadamente de 1 segundo de la siguiente forma: 16*244*256= 999,424
Microsegundos.

En teoría esto parece estar bien pero debido a que el compilador de “C” inserta código antes de entrar a la rutina de servicio
de interrupción y después de terminar la rutina de servicio de interrupción, tenemos que tomar en cuenta este código en las
cuentas del tiempo. Por lo tanto se recomienda utilizar el simulador y poner un breakpoint en la instrucción donde se reinicia
la cuenta del contador a cero dentro de la rutina de servicio de interrupción (contador = 0; ) y verificar el tiempo que se tarda
con la opción del stopwatch (localizado en el submenú debugger) correr el programa con la opción RUN y esperar que se
detenga. Al detenerse observar la cuenta en el stopwatch poner a cero y volver a correr con el RUN. Con esto observaremos
el tiempo real transcurrido en el stopwatch .

El objetivo por lo tanto es prender el led por aproximadamente 1 segundo para después apagarlo por el mismo tiempo
teniendo a la salida del pin RB0 una onda cuadrada perfecta que se puede verificar con un osciloscopio.

Esta práctica se correlaciona con el subtema 2.2.5.4 y 2.2.6 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
3 Resistencia de 220 Ohms
1 Resistencia de 10k
1 Push Button
3 Led
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Osciloscopio

Metodología:
1- Utilice el software MPLAB para editar el programa Tmr2.asm que se muestra mas adelante.
2- Compile, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en la compilación) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el buen funcionamiento del programa.
6- Ahora modifique el programa para que realice una tarea diferente en la rutina de servicio de interrupción puede
ser alguna de las siguientes:
gg) Realizar un reloj con segundos, minutos y horas. Sacar el resultado por display de 7 segmentos conectados en
los puertos siguientes: Segundos por RB, Minutos por RC y Horas por RD.
hh) Dejar al alumno que utilice su creatividad.
ii) Dejar que el maestro ponga una opción diferente a estas.

7- Verifique sus resultados con un osciloscopio.


8- Reporte sus resultados.
Programa fuente:

#if defined(__PCM__)
#include <16F874.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#elif defined(__PCH__)
#include <18F4455.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#endif

#use Delay(Clock=4000000)

// *********************************
int contador,PORTB_0;

#INT_TIMER2 //Rutina de servicio de interrupción


void clock_isr(void) {
SET_TIMER2(12); //TMR2=12 para que de 256-12=244 ciclos para que
//se desborde el TMR2
contador=contador+1; //Utilice el StopWatch en el simulador para verificarlo
if(contador==256){ //y ajustarlo 16*244*256=999,424 Microsegundos
contador=0; //<-- Ponga aquí el Breakpoint para checar
if(PORTB_0==1){
PORTB_0=0;
output_b(0b00000110);
}
else {
PORTB_0=1;
output_b(0b00000111);

}
}
}

void main(void) {
contador=0;
set_tris_b(0x00); //Puerto B de salida

SETUP_TIMER_2(0x07,255,1); //T2CON=0x07 Prescaler 16 y bit TMR2ON=1


//Period=255, 1 Reset para la interrupción
SET_TIMER2(12); //256-12= 244 cuentas para el sobreflujo
//En teoria 16*244*256= 999.424 Microseg
ENABLE_INTERRUPTS(INT_TIMER2);//Habilita la interrupción del TMR2IE=1 en PIE1
//y habilita la Ints. Perifericas PEIE=1
ENABLE_INTERRUPTS(GLOBAL ); //INTCON=1100 0000 habilita la interrupción Global

while(1){ };
}
Diagrama de conexión:
+5vdc
+5vdc

11,32
R1
10k D3
S1
1

VDD
13 MCLR R4 220 LED
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38 R3 D2
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35 220 LED
Y1 6 RA3/AN3 RB2 34 D1
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5 R2 220 LED
C2 22pf 10 RE1/AN6
RE2/AN7
15 30
16 RC0 RD7 29
17 RC1 RD6 28
18 RC2 RD5 27
23 RC3 RD4 22
24 RC4 RD3 21
25 RC5 RD2 20
26 RC6 RD1 19
RC7 RD0
VSS

U1
12,31

PIC16F874

Sugerencias Didácticas:
1.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de computo.
Aproveche para seguir enseñando al alumno mas opciones del simulador (MPLABSIM). Enfocarse en enseñar en el
simulador como esta construida la rutina de interrupción del TMR2 usando las opciones del debugger:
Settings.- Poner la velocidad de ejecución a 4Mhz (por default es de 20Mhz).
StopWatch.- Nos ayudará a verificar el tiempo de retardo de cada interrupción.
Set Breakpoint.- Poner un punto de paro en el programa en la línea donde se desea que el programa detenga su ejecución,
ejemplo: Poner el cursor en esta línea que esta dentro de la rutina de interrupción:
[ contador = 0 //<-- Ponga aquí el Breakpoint ]
Presionar el botón derecho del mouse y aparecerá una ventana con varias opciones, seleccione la opción Set-Breakpoint.
Correr el programa hasta que se detenga nuevamente en la misma línea, poner a cero el Stop wtach y volver a correr desde
ahí el programa y se detendrá nuevamente en la misma línea mostrándonos en el Stop Watch el tiempo transcurrido de
aproximadamente 1 segundo (16*244*256=999,424 Microsegundos) .
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.
Bibliografía Preliminar:

[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003


[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] Manual de usuario del compilador PCW de CCS
[7] http://www.microchip.com
Práctica No.19 Convertidor Análogo(Lenguaje “C”)..
Objetivo: Programar el convertidor A/D en Lenguaje “C”.

Introducción:
Con el desarrollo de esta práctica el alumno aprenderá a configurar el convertidor A/D para realizar lecturas de voltaje en
cualquiera de los convertidores/análogos del PIC, estos se seleccionan con la función: set_adc_channel( X ), en donde X
corresponde al canal analógico que deseamos utilizar de acuerdo a la siguiente tabla:
X=0 ; para seleccionar la lectura por RA0
X=1 ; para seleccionar la lectura por RA1
X=2 ; para seleccionar la lectura por RA2
X=3 ; para seleccionar la lectura por RA3
X=4 ; para seleccionar la lectura por RA5
X=5 ; para seleccionar la lectura por RE0
X=6 ; para seleccionar la lectura por RE1
X=7 ; para seleccionar la lectura por RE2

Se sugiere correr y probar el programa con la resolución de 8 bits del convertidor análogo y después hacer lo mismo pero
con la resolución a 10 bits. Esto con el fin de que comprueben que en la resolución de 8 bits los incrementos de cada bit
corresponden a incrementos de 20mv(5v/255) y que en la resolución de 10 bits los incrementos de cada bit son de
4mv(5v/1024). Para poner la resolución en el programa se hace con la directiva: #device adc=X (en donde X es un 8 si la
resolución que quieren es de 8 bits o 10 si la resolución de que quieren es de 10 bits).

Esta práctica se correlaciona con el subtema 2.2.8 de la Unidad 2.

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
1 Resistencia de 10k
1 Push Button
10 Leds
10 Resistencia de 220 Ohms
1 Potenciómetro de 100k
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Voltímetro

Metodología:
1- Utilice el software MPLAB para editar el programa ADC.C que se muestra mas adelante.
2- Compile, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en la compilación) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el funcionamiento del programa con la resolución de 8 bits( comente la directiva //#device adc=10) y
después cambie la resolución para 10 bits( ahora comente la directiva //#device adc=8).
6- Ahora modifique el programa para que realice una tarea diferente puede ser alguna de las siguientes:
jj) Conecte 2 display de 7 segmentos en el puerto B, ahora muestre la lectura obtenida por el display pero
mostrando el correspondiente voltaje leído en el potenciómetro(realice la conversión para mostrar el voltaje
con un entero y un decimal ). Verifique la lectura obtenida en el display poniendo un voltímetro a la entrada de
RA0/AN0. realice una tabla comparativa entre su lectura y la del voltímetro varíe el potenciómetro para que
realice lecturas cada 500mv.
kk) Conecte un display de 7 segmentos por el puerto RC para mostrar la parte entera del voltaje leído y 2 display
de 7 segmentos en el puerto RB para mostrar 2 decimales.
ll) Conecte 1 potenciómetro en cada uno de los pines RA0,RA1,RA2 del pic y muestre su lectura por un display
doble de 7 segmentos conectados al puerto RB. Utilice los pines del puerto RC para seleccionar cual de los 3
canales se desea leer. Conecte 1 display de 7 segmentos por el puerto RD para indicar cual de los canales
análogos se esta leyendo.
mm) Poner un sensor de temperatura o cualquier otro tipo de sensor(presión, flujo, etc.) en alguno de los
convertidores análogos y mostrar la lectura por un display(puede ser un LCD).
nn) Dejar al alumno que utilice su creatividad.
oo) Dejar que el maestro ponga una opción diferente a estas.

7- Verifique sus resultados con un voltímetro.


8- Reporte sus resultados.

Programa fuente:

// Programa ADC.C

#if defined(__PCM__)
#include <16F874.h>
//#device adc=8 //Resolución del convertidor análogo de 8 bits
#device adc=10 //Resolución del convertidor análogo de 10 bits
#fuses XT,NOWDT,NOPROTECT,NOLVP

#elif defined(__PCH__)
#include <18F4455.h>
#device adc=10
#fuses XT,NOWDT,NOPROTECT,NOLVP
#endif

#use Delay(Clock=4000000)

// *********************************
long int longdato; // Variable de 2 bytes para guardar un dato de 10 bits
char dato; // Variable de 1 byte para guardar un dato de 8 bits

void main(){
set_tris_b(0x00); // Se configura el Puerto RB de salida
set_tris_c(0x00); // Se configura el Puerto RC de salida
setup_adc_ports(ALL_ANALOG); // Todos los puertos como Análogos
setup_adc(ADC_CLOCK_DIV_8); // Se divide la entrada del reloj del ADC entre 8
set_adc_channel(0); // Se selecciona el canal 0 (RA0)

/* VDD and VSS references */


while(1){
delay_ms(200);
longdato= read_adc(); // Se lee el canal 0 y se guarda en la variable longdato(10 bits)
dato=(char)longdato; // Se guarda solo los 8 bits menos significativos en la variable dato
output_b(dato); // Se muestran los 8 bits menos significativos por el puerto RB

dato=(char)((longdato>>8)); // Se rotan 8 bits a la derecha del dato de 10 bits para quedarnos solo
// con los 2 bits mas significativos
output_c(dato); // Se muestran los 2 bits mas significativos por el puerto RC

}
}

Diagrama de conexión:
+5vdc
+5vdc
11,32

R1
10k
S1
1
VDD

13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35
Y1 6 RA3/AN3 RB2 34
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5
LED
C2 22pf 10 RE1/AN6
RE2/AN7
+5Vdc 15 30
16 RC0 RD7 29
17 RC1 RD6 28
P1 18 RC2 RD5 27
23 RC3 RD4 22
100K 24 RC4 RD3 21
25 RC5 RD2 20
26 RC6 RD1 19
RC7 RD0
VSS

U1
12,31

PIC16F874
NOTA: Conecte una resistencia de 220 ohms en serie con cada uno de los leds.

Sugerencias Didácticas:
1.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de computo.
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:
[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003
[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] Manual de usuario del compilador PCW de CCS
[7] http://www.microchip.com

Práctica No.20 Puerto Serie(Lenguaje “C”)..


Objetivo: Realizar una comunicación serie entre 2 Microcontroladores ( Lenguaje “C”).

Introducción:
Con el desarrollo de esta práctica el alumno aprenderá a configurar el puerto serie(UART) para realizar comunicaciones en
serie con cualquier dispositivo que maneje comunicación serial. Aprenderá el uso de la siguiente directiva para configurar el
puerto serie:
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)

También la forma de indicar la rutina de servicio de interrupción por el puerto serie:


#INT_RDA //Rutina de servicio de Interrupción por RX
void serial_isr()
{ }

Como habilitar la interrupción por recepción en el puerto serie:


enable_interrupts(INT_RDA); //Habilitamos la interrupción por RX
Esta práctica se correlaciona con el subtema 2.2.7 de la Unidad 2.

Material y Equipo utilizado:


2 Microcontrolador PIC16F874
2 Cristal 4 Mhz
4 Capacitores de 22pf o 15pf
20 Resistencia de 10k
4 Push Button
16 Leds
16 Resistencia de 220 Ohms
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Voltímetro

Metodología:
1- Utilice el software MPLAB para editar el programa Serie.C que se muestra mas adelante.
2- Compile, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en la compilación) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el funcionamiento del programa poniendo el dato a trasmitir por el puerto serie en el puerto RD (Dip-
Switch) del Microcontrolador 1 y una vez puesto presionar el PushButton 2 conectado en el pin RC0. Observe que
el dato trasmitido se mostrara por los leds conectados en el puerto RB del microcontrolador 2. Cambie el dato varias
veces en el Dip-switch y vuelva a trasmitir, confirme que lo que manda es realmente lo que se muestra en los leds.
Ahora trasmita el dato del Microcontrolador 2 hacia el Microcontrolador 1.
6- Ahora modifique el programa para que realice una tarea diferente puede ser alguna de las siguientes:
pp) Conecte 2 display de 7 segmentos en el puerto RB de cada uno de los microcontroladores, ahora muestre la
lectura obtenida por el display . Los datos que ponga en el Dip-Switch tendrán que estar en BCD para que se
puedan mostrar en los display. Ejemplo ponga un 31H en el Dip-Switch para poder ver un 31 decimal en los
display.
qq) Conecte 1 potenciómetro en el pin RA0 del Microcontrolador 1(configurado para leer su voltaje Análogo) y
muestre su lectura por un display doble de 7 segmentos conectados al puerto RB del Microcontrolador 2.
rr) Poner un sensor de temperatura o cualquier otro tipo de sensor(presión, flujo, etc.) en lugar del potenciómetro
del inciso b) y mostrar la lectura por un display(puede ser un LCD) conectado en el Microcontrolador 2.
ss) Dejar al alumno que utilice su creatividad.
tt) Dejar que el maestro ponga una opción diferente a estas.

7- Reporte sus resultados.

Programa fuente:
// Programa Serie.C

#if defined(__PCM__)
#include <16F874.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#elif defined(__PCH__)
#include <18F4455.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#endif

#use Delay(Clock=4000000) //Cristal de 4MHz


#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)//Config. del puerto serie

char dato; //Variable Global

//*************** PUERTO SERIE *******************


#INT_RDA //Rutina de servicio de Interrupcion por RX
void serial_isr()
{
dato=getc(); //Se lee el dato recibido por el puerto serie
output_b(dato); /Se muestra por el puerto RB

}
//*************************************************
void main(){
set_tris_b(0x00); //Todo el puerto RB de salida
set_tris_c(0xBF); //RC= 1011 1111, Tx=0(salida),Rx=1(entrada)
set_tris_d(0xFF); //Todo el puerto RD de entrada

output_b(0x00); //Apagamos todos los leds


output_high(PIN_B0); //Prendemos el Led 0
delay_ms(1000); //Retardo de 1 segundo
output_low(PIN_B0); //Apagamos el Led 0
delay_ms(1000);

enable_interrupts(INT_RDA); //Habilitamos la interrupcion por RX


enable_interrupts(GLOBAL); //Habilitamos el bit Global

while(1){ //Lazo infinito


delay_ms(1000); //Retardo de 1 segundo
if (!input(PIN_C0)){ //Si el bit 0 del Puerto C es 0 se hace trasmisión
output_high(PIN_B0); //Prendemos el Led 0
delay_ms(1000); //Retardo de 1 segundo
output_low(PIN_B0); //Apagamos el Led 0
dato= input_d(); //Leemos el puerto RD
putchar(dato); //trasmitimos el dato
}
}
}
Diagrama de conexión:
+5vdc
+5vdc

11,32
R1
10k
S1
1

VDD
13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35
Y1 6 RA3/AN3 RB2 34
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5
LED
C2 22pf 10 RE1/AN6 S1
R2 10k RE2/AN7
+5Vdc 15 30 9 8
16 RC0 RD7 29 10 7
17 RC1 RD6 28 11 6
18 RC2 RD5 27 12 5
S2 sw2 23 RC3 RD4 22 13 4
24 RC4 RD3 21 14 3
TX 25 RC5 RD2 20 15 2
26 RC6 RD1 19 16 1
RX RC7 RD0
VSS

SW DIP-8
U1
12,31

PIC16F874 10K 10K 10K 10K 10K 10K 10K 10K

+5vdc
+5vdc +5Vdc
11,32

R3
10k
S3
1
VDD

13 MCLR
sw3 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C3 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35
Y2 6 RA3/AN3 RB2 34
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5
LED
C4 22pf 10 RE1/AN6 S2
R3 10k RE2/AN7
+5Vdc 15 30 9 8
16 RC0 RD7 29 10 7
17 RC1 RD6 28 11 6
18 RC2 RD5 27 12 5
S4 sw4 23 RC3 RD4 22 13 4
24 RC4 RD3 21 14 3
TX 25 RC5 RD2 20 15 2
26 RC6 RD1 19 16 1
RX RC7 RD0
VSS

SW DIP-8
U2
12,31

PIC16F874 10K 10K 10K 10K 10K 10K 10K 10K

+5Vdc

NOTA: Conecte una resistencia de 220 ohms (puede ser de 330 ohms)en serie con cada uno de los leds.

Sugerencias Didácticas:
1.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de computo.
2.- Formar equipos de trabajo.
3.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
4.- Propiciar la investigación.
5.- Estimular la participación en las prácticas.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:
[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003
[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] Manual de usuario del compilador PCW de CCS
[7] http://www.microchip.com

PRACTICA 21 LCD C

Conectando un Display al Microcontrolador.

Objetivo: Conectar un display al Microcontrolador para futuras aplicaciones.

Introducción:
Con el desarrollo de esta práctica el alumno aprenderá a conectar el display LCD por el puerto RD y aprenderá
cual es la librería y las funciones que puede utilizar para el manejo del display:
Librería #include <lcd.c>
Funciones:
lcd_init; inicializa el display
lcd_putc( ); imprime un carácter en el display LCD
printf(lcd_putc,”resultado= %d”, variable); imprime una cadena de caracteres con formato.
gotoxy(x, y); pone el cursor del display LCD en el renglón x y columna y).
lcd_getc(x, y); regresa las coordenadas del renglón y la columna donde esta el cursor.

Esta práctica se correlaciona con circuitos de soporte de la Unidad 3 .

Material y Equipo utilizado:


1 Microcontrolador PIC16F874
1 Cristal 4 Mhz
2 Capacitores de 22pf o 15pf
1 Resistencia de 10k
1 Push Button
1 Potenciómetro de 5K
1 Display LCD
1 Fuente de +5 VDC (Opcional: 1 Pila Cuadrada de +9Vdc, 1 Reg. 7805)
-------------------------------------
1 Software de MPLAB
1 Grabador de Pics
1 Voltímetro

Metodología:
1- Utilice el software MPLAB para editar el programa Lcd.C que se muestra mas adelante.
2- Compile, Simule y entienda el funcionamiento del programa.
3- Grabe el archivo (.HEX obtenido en la compilación) en el PIC
4- Arme el circuito de acuerdo al diagrama de conexión.
5- Pruebe el funcionamiento del programa observando que en el display LCD se muestra un reloj con horas,
minutos y segundos. El reloj deberá de iniciar por default con cuenta en 05:57:00, espere hasta que cambie de
hora de 5 a 6 para lo cual deberá esperar 3 minutos.
6- Ahora modifique el programa para que realice una tarea diferente, puede ser alguna de las siguientes:
uu) Agréguele al reloj un circuito para ajustar las horas y los minutos a través de interrupciones.
vv) Agréguele al reloj para que a cierta hora encienda un led transcurra un tiempo y luego lo apague.
Puede sustituir el led por algún otro dispositivo por ejemplo: Focos o lámparas de 12Vdc o de
120VAC, motores a través de relevadores.
ww) Dejar al alumno que utilice su creatividad.
xx) Dejar que el maestro ponga una opción diferente a estas.

7- Reporte sus resultados.

Programa fuente:
// Programa LCD.C

// LCD.C
// Rev A by Ing. Jorge Aguirre

//**************************************************
// Conexion de los pines del LCD:
// NC VSS (pin 1 del LCD) conectar a GND
// NC VDD (pin 2 del LCD) conectar a +5Vdc
// NC VEE (pin 3 del LCD) conectar a un potenciometro ya que
// es para el contraste del LCD

// D0 enable (pin 6 del LCD)


// D1 rs (pin 4 del LCD)
// D2 rw (pin 5 del LCD)
// D4 D4 (pin 11 del LCD)
// D5 D5 (pin 12 del LCD)
// D6 D6 (pin 13 del LCD)
// D7 D7 (pin 14 del LCD)
// NOTA: Los pines 7,8,9 y 10 del LCD no se conectan porque la
// conexion es a 4 bits
//*****************************************************
#if defined(__PCM__)
#include <16F874.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#elif defined(__PCH__)
#include <18F4455.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#endif

#use Delay(Clock=4000000) //Cristal de 4MHz

#include <lcd.c> //Libreria del LCD

void main() {

int seg=0,min=57,hr=5; // Parametros de inicializacion

lcd_init(); // Inicializa el LCD


delay_ms(6); // Retardo de 6 ms

while(TRUE) // ciclo infinito


{
seg++; // incrementa los segundos
if(seg==60){ // Checa si ya paso un minuto
seg=0;
min++; //Incrementa los minutos
if(min==60){ //Checa si ya paso una hora
min=0;
hr++; //Incrementa las horas
if(hr==24) hr=0; //Checa si ya paso un Dia
}
}
printf(lcd_putc,"\fReloj: %d:%d:%d ",hr,min,seg); // \f limpia pantalla
delay_ms(1000); //Retardo de 1 segundo
}
}

Diagrama de conexión:
+5vdc
+5vdc

11,32
R1
10k
S1
1

VDD
13 MCLR
sw1 14 OSC1 40
OSC2 RB7 39
2 RB6 38
C1 22pf 3 RA0/AN0 RB5 37
4 RA1/AN1 RB4 36
5 RA2/AN2 RB3 35
Y1 6 RA3/AN3 RB2 34
7 RA4 RB1 33
4MHZ 8 RA5/AN4 RB0
9 RE0/AN5
C2 22pf 10 RE1/AN6
RE2/AN7
15 30
16 RC0 RD7 29
17 RC1 RD6 28
18 RC2 RD5 27
23 RC3 RD4 22
24 RC4 RD3 21
25 RC5 RD2 20
26 RC6 RD1 19
RC7 RD0
VSS

4 5 6 11 12 13 14
U1
12,31

PIC16F874

2 3 1

+5Vdc

5K
P1

Sugerencias Didácticas:
1.- Formar equipos de trabajo.
2.- Estimular al alumno al desarrollo de su pensamiento lógico y creativo.
3.- Propiciar la investigación.
4.- Estimular la participación en las prácticas.
5.- Se le sugiere al maestro de compilar y correr el programa de prueba junto con el alumno en la sala de
computo.

Reporte del Alumno (Resultados):


1.- El diagrama de flujo.
2.- El diagrama de conexión.
3.- El programa fuente obtenido.
4.- Conclusiones del Equipo.

Bibliografía Preliminar:
[1] Microchip Technology Inc., “PIC16F873/874/876/877 Data Sheet”, 2003
[2] Microchip Technology Inc., “PIC18F2455/2550/4455/4550 Data Sheet”, 2009
[3] Tópicos del Help en el MPLAB(MPLAB-IDE, MPLAB- Editor, MPLAB-SIM)
[4] E. Martín Cuenca. Microcontroladores PIC. Diseño práctico de aplicaciones Ed. Mc. Graw Hill
[5] Apuntes del Maestro.
[6] Manual de usuario del compilador PCW de CCS
[7] http://www.microchip.com

CODIGO PARA TARJETA INVDISA


#include <18F4550.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#define LCD_RS_PIN PIN_E0


#define LCD_RW_PIN PIN_E1
#define LCD_ENABLE_PIN PIN_E2 //// #define LCD_RW_PIN PIN_E2
////
#define LCD_DATA4 PIN_D4 ////
#define LCD_DATA5 PIN_D5 ////
#define LCD_DATA6 PIN_D6 ////
#define LCD_DATA7 PIN_D7

#use Delay(Clock=48000000) //Frec. interna de 48MHz


#build(reset=0x1000)
#build(interrupt=0x1008)
#org 0,0x0FFF void bootloader() {} //

#include <lcd.c> //Libreria del LCD

void main() {

int seg=0,min=57,hr=5,entero=2,decimal=6; // Parametros de inicializacion


//char seg=0,min=57,hr=5;

lcd_init(); // Inicializa el LCD


delay_ms(6); // Retardo de 6 ms

while(TRUE) // ciclo infinito


{
seg++; // incrementa los segundos
if(seg==60){ // Checa si ya paso un minuto
seg=0;
min++; //Incrementa los minutos
if(min==60){ //Checa si ya paso una hora
min=0;
hr++; //Incrementa las horas
if(hr==24) hr=0; //Checa si ya paso un Dia
}
}
// printf(lcd_putc,"\fReloj: %d:%d:%d ",hr,min,seg); // \f limpia pantalla
printf(lcd_putc,"\fReloj %02u:%02u:%02u",hr,min,seg);

// lcd_gotoxy(1,2);
// printf(lcd_putc,"Voltaje= %d.%d", entero, decimal);
delay_ms(1000); //Retardo de 1 segundo
}
}

Practica 22 PWM

OBJETIVO:
Obtener una onda de frecuencia constante con ancho de pulso variable modificado cada vez que se presiona
RB0.

//#include <PWM.h>

#fuses XT,NOWDT,NOPROTECT,NOLVP,CPUDIV1
#use Delay(Clock=20000000)
//0#build(reset=0x1000)
//#build(interrupt=0x1008)
//#org 0,0x0FFF voidbootloader() {}
int x=0;
#Int_ext
void incremento()
{
x+=5;
if(x>=255)
{
x=0;
}
}

void main()
{
set_tris_b(0xFF); // Todo el Pto. B como entradas
port_b_pullups(TRUE); // habilita resistencias pullup
set_tris_c(0x00);
setup_timer_2(T2_DIV_BY_16,255,1);
setup_ccp2(CCP_PWM);
setup_ccp1(CCP_PWM);
enable_interrupts(int_ext);
enable_interrupts(GLOBAL);
while(1)
{
set_pwm2_duty(x);
set_pwm1_duty(255-x);
}

DIAGRAMA:
Practica 23 Sensor ultrasonido

Objetivo: Entender el funcionamiento de un sensor ultrasonido para mediciones de distancia:

Teoria de operación:
The Timing diagram is shown below. You only need to supply a short 10uS
pulse to the trigger input to start the ranging, and then the module will send out
an 8 cycle burst of ultrasound at 40 kHz and raise its echo. The Echo is a
distance object that is pulse width and the range in proportion .You can
calculate the range through the time interval between sending trigger signal and
receiving echo signal. Formula: uS / 58 = centimeters or uS / 148 =inch; or: the
range = high level time * velocity (340M/S) / 2; we suggest to use over 60ms
measurement cycle, in order to prevent trigger signal to the echo signal.
Calculo de tiempo: Partiendo de una frecuencia de operación de 48 MHz. Dividir entre 8 para operar el timer1 a
6 MHz, como el timer cuenta cada cuatro ciclos de reloj entonces cada cuenta se realiza en 1/1,500,000
segundos asi que este numero lo dividimos entre 1.5 por programa para obtener un microsegundo por cada
cuenta del timer1. Asi que lo que cuente el timer1 sera el tiempo en microsegundos de ida y vuelta de la señal
enviada. La distancia se calcula con la formula de velocidad = distancia/tiempo
Por lo que distancia es velocidad*tiempo. Tomando la velocidad del sonido como 340 m/s.
Programa:

#include <Ultrasonido.h>

#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=48000000)

#define LCD_RS_PIN PIN_E0


#define LCD_RW_PIN PIN_E1 //Definicion de pines
#define LCD_ENABLE_PIN PIN_E2 //para LCD en puerto E control ////
#define LCD_RW_PIN PIN_E2 ////
#define LCD_DATA4 PIN_D4 ////
#define LCD_DATA5 PIN_D5 //// PUERTO D PARA DATOS
#define LCD_DATA6 PIN_D6 ////
#define LCD_DATA7 PIN_D7

#build(reset=0x1000)
#build(interrupt=0x1008)
#org 0,0x0FFF void bootloader() {} //

#include <lcd.c> //Libreria del LCD

int16 distancia, tiempo;


#define trig pin_A4
#define echo pin_A5
#USE standard_io(b)

void main()
{
lcd_init();
printf(LCD_PUTC, "\f Iniciando.");
delay_ms(500);
printf(LCD_PUTC, "\f Iniciando..");
delay_ms(500);
printf(LCD_PUTC, "\f Iniciando...");
delay_ms(500);

setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //Frecuencia reloj 48 Mhz Dividida entre 8 y entre 4 (Ciclos por


instruccion) 1.5 Mhz
SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_256);
while(TRUE)
{
output_high(trig); //disparar inicio del sensor durante 50 useg
delay_us(50);
output_low(trig);
while(!input(echo)) //Ciclar aquí hasta recibir la señal de eco.
{}
set_timer1(0);
set_timer0(0);
while(input(echo))
{}
tiempo=get_timer1(); //Tiempo de ida y vuelta dos veces la distancia donde choca
tiempo=(tiempo*2)/3; //Dividir entre 1.5 para obtener 1 Mhz o sea un microsegundo por cuenta
distancia=((tiempo)*(340))/2;

printf(LCD_PUTC, "\fTiempo :%Lu us \nDist = %Lu cm",tiempo,distancia);


delay_ms(500);
}
}

Probar el programa propuesto y verificar las distancias medidas.

Modificar el programa para avisar a un conductor que va de reversa que se aproxima a un objeto. (como para
estacionarse)

Programa 24 RTC Reloj de Tiempo Real

Objetivo: Entender la operación del reloj de tiempo real DS1307 como una aplicación de comunicación serie I2C
. Programarlo para poner a tiempo y dejarlo en operación. Mejorar el programa para que genere tiempos de
encendido y apagado de dispositivos tales como alarmas, focos , sistemas de riego etc.

Teoria de operación:

FEATURES
Real time clock counts seconds, minutes,
hours, date of the month, month, day of the
week, and year with leap year compensation
valid up to 2100
56 byte nonvolatile RAM for data storage
2-wire serial interface
Programmable squarewave output signal
Automatic power-fail detect and switch
circuitry
Consumes less than 500 nA in battery backup
mode with oscillator running
Optional industrial temperature range
-40°C to +85°C
Available in 8-pin DIP or SOIC
CONECTAR EL SDA Y SCK DEL RELOJ AL SDA Y SCK DEL MICRO CON UN PAR DE CABLES DUPONT
COMO SE MUESTRA EN LA FOTO:

SDA ES EL BLANCO Y SE CONECTA A LA PATA 33 DEL MICRO, SCK ES EL NEGRO Y SE CONECTA A LA


PATA 34 DEL MICRO.
Programa:

PARA PONER A TIEMPO PRESIONE EL BOTON b2 Y SOSTÉNGALO UN MOMENTO LUEGO LIBÉRELO EL


CONTADOR DE AÑO INICIA EN AUMENTO PRESIONE DE NUEVO b2 PARA FIJARLO, ESTO PASARA
AHORA AL MES HACER LA MISMA OPERACIÓN DE PRESIONAR Y SOLTAR SEGUIRÁ EL DÍA Y ASÍ
SUCESIVAMENTE. NOTA: NO SE PASE DEL NUMERO A PROGRAMAR O TENDRA QUE INICIAR DE
NUEVO.
SI QUIERE QUE EL TIEMPO NO SE PIERDA AUNQUE DESCONECTE EL PIC PONER UNA BATERIA
CR2032 COMO SE MUESTRA.
//*******PROGRAMACION DEL RELOJ DE TIEMPO REAL***************
//*******

#include <18F4550.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=48000000)
#include <DS1307.C>

#define LCD_RS_PIN PIN_E0


#define LCD_RW_PIN PIN_E1 //Definicion de pines
#define LCD_ENABLE_PIN PIN_E2 //para LCD en puerto E control ////
#define LCD_RW_PIN PIN_E2 ////
#define LCD_DATA4 PIN_D4 ////
#define LCD_DATA5 PIN_D5 //// PUERTO D PARA DATOS
#define LCD_DATA6 PIN_D6 ////
#define LCD_DATA7 PIN_D7

#use Delay(Clock=48000000) //Frec. interna de 48MHz


#build(reset=0x1000)
#build(interrupt=0x1008)
#org 0,0x0FFF void bootloader() {} //

#include <lcd.c> //Libreria del LCD

BYTE sec=12; //DEFINICION DE VARIABLES


BYTE min=13;
BYTE hrs=14;
BYTE day=1;
BYTE month=1;
BYTE yr=10;
BYTE dow=2; //DIA DE LA SEMANA (NUMERO)

int secu,secd;

VOID PONER_time() //FUNCION P PONER A TIEMPO USANDO EL SWITCH


{ //CONECTADO A B2 PRESIONAR B2 PARA INICIAR CON
delay_ms(20); // EL YEAR EN CUANTO SE SUELTE B2 SE INCREMENTA
sec=00; //LA VARIABLE AL LLEGAR AL NUMERO DESEADO
min=00; //PRESIONAR DE NUEVO POR APROX UN SEGUNDO LUEGO
hrs=00; //LIBERAR PARA CONTINUAR CON EL MES Y REPETIR EL
day=01; //PROCESO SEGUIRA EL DIA LUEGO HORAS, MINUTOS
month=01; //DESPUES DE AJUSTAR TODAS LAS VARIABLES PRESIONAR
yr=10; //DE NUEVO Y REGRESA AL PROGRAMA PRINCIPAL DONDE LEE
ds1307_set_date_time(day,month,yr,dow,hrs,min,sec); //Y MUESTRA RELOJ Y FECHA
lcd_gotoxy(1,1); //GRABA CONDICIONES INICIALES P PONER A TIEMPO
printf(lcd_putc,"Clock %02u:%02u:%02u",hrs,min,sec); //MUESTRA EN DISPLAY RELOJ
lcd_gotoxy(1,2);
printf(lcd_putc,"FECHA %02u:%02u:%02u",DAY,month,yr); //MUESTRA EN DISPLAY FECHA
delay_ms(1000);
while(~INPUT(pin_B2)) //CICLO PARA PONER A TIEMPO YEAR
{ //SE QUEDA AQUI HASTA QUE SE LIBERE EL SWITCH B2

delay_ms(100);

delay_ms(1000);
while(INPUT(pin_B2)) //CICLO PARA CUANDO EN BOTON ESTA LIBERADO
{
//SE INCREMENTA YEAR (yr) Y SE MUESTRA AL DISPLAY
//SE INCREMENTA CADA SEGUNDO HASTA PRESIONAR B2

yr=yr+1;
lcd_gotoxy(1,1);
printf(lcd_putc,"Clock %02u:%02u:%02u",hrs,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"FECHA %02u:%02u:%02u",DAY,month,yr);
delay_ms(1000);

ds1307_set_date_time(day,month,yr,dow,hrs,min,sec);
delay_ms(1000); //SE GUARDA EL VALOR MODIFICADO DE YR

while(~INPUT(pin_B2)) //CICLO PARA MODIFICAR MONTH


{

delay_ms(100);

delay_ms(1000);
while(INPUT(pin_B2))
{

month=month+1;
lcd_gotoxy(1,1);
printf(lcd_putc,"Clock %02u:%02u:%02u",hrs,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"FECHA %02u:%02u:%02u",DAY,month,yr);
delay_ms(1000);

ds1307_set_date_time(day,month,yr,dow,hrs,min,sec);
delay_ms(1000);

while(~INPUT(pin_B2)) //CICLO PARA MODIFICAR DAY


{

delay_ms(100);

delay_ms(1000);
while(INPUT(pin_B2))
{

day=day+1;
lcd_gotoxy(1,1);
printf(lcd_putc,"Clock %02u:%02u:%02u",hrs,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"FECHA %02u:%02u:%02u",DAY,month,yr);
delay_ms(1000);

ds1307_set_date_time(day,month,yr,dow,hrs,min,sec);
delay_ms(1000);

while(~INPUT(pin_B2)) //CICLO PARA MODIFICAR HRS


{

delay_ms(100);

}
delay_ms(1000);
while(INPUT(pin_B2))
{

hrs=hrs+1;
lcd_gotoxy(1,1);
printf(lcd_putc,"Clock %02u:%02u:%02u",hrs,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"FECHA %02u:%02u:%02u",DAY,month,yr);
delay_ms(1000);

ds1307_set_date_time(day,month,yr,dow,hrs,min,sec);
delay_ms(1000);

while(~INPUT(pin_B2)) //CICLO PARA MODIFICAR MIN


{

delay_ms(100);

delay_ms(1000);
while(INPUT(pin_B2))
{

min=min+1;
lcd_gotoxy(1,1);
printf(lcd_putc,"Clock %02u:%02u:%02u",hrs,min,sec);
lcd_gotoxy(1,2);
printf(lcd_putc,"FECHA %02u:%02u:%02u",DAY,month,yr);
delay_ms(1000);

ds1307_set_date_time(day,month,yr,dow,hrs,min,sec);
delay_ms(3000);
}

void main() // LEE RELOJ Y FECHA Y LOS MUESTRA AL DISPLAY


{ //REVIZA SI B2 SE PRESIONO PARA PONER A TIEMPO

port_b_pullups(TRUE); //Resist de pull_up

lcd_init(); // Inicializa el LCD


delay_ms(6); // Retardo de 6 ms

while(1)
{
if (~INPUT(pin_B2)) //LLAMA FUNCION PONER_time AL PRESIONAR B2
{
PONER_time();
}
delay_ms(200);
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);

lcd_gotoxy(1,1);
printf(lcd_putc,"Clock %02u:%02u:%02u",hrs,min,sec);

lcd_gotoxy(1,2);
printf(lcd_putc,"FECHA %02u:%02u:%02u",DAY,month,yr);

delay_ms(20);

[pSi lo quiere simular en proteus recuerde comentar las instrucciones de Build reset y de build int
(Las tres líneas que usamos para el bootloader)
Practica 25 EEPROM 24C04

Objetivo: Leer y escribir en una EEPROM . Correr programa que se proporciona para esta practica.
Modificarlo para que opere como un sitema de riego. Ej se riega Lunes Miercoles y viernes de las 6:00 PM a las
7:30 PM. Esto en conjunto con el reloj de tiempo real.

Teoria de operación:
DIAGRAMA UTILIZADO:
Programa:

//Modificar programa para teclado 4x4

#INCLUDE <18F4550.h>
#USE DELAY(CLOCK=4000000)
#FUSES XT,NOPROTECT,NOWDT,NOLVP
#DEFINE USE_PORTB_LCD TRUE
#DEFINE USE_PORTB_KBD //Manejar teclado en puerto B por defecto
// esta en el puerto D

#INCLUDE<KBD.C> //Driver para teclado telefonico

#INCLUDE<LCD.C>
#BYTE PORTC= 0XF82
#BYTE PORTB= 0XF81
#DEFINE LED1 PORTC,4
#DEFINE LED2 PORTC,7
#BYTE WPUB= 0X95 //DECLARAR REGISTRO OPCION
#BYTE OPTION_REG= 0X81
INT CONT;
BYTE J=16;
CHAR K;
INT MIL,CEN,DEC,UNI,VAL;
long int contra=9999; //Variable entera para almacenar clave
int sinal; //variable para saber si esta la contrasena de defecto

VOID TECLADO()
{
k=kbd_getc();//llamada a funcion leer teclado ;almacenar en k
//si no se oprime la tecla se retorna un caracter nulo

WHILE(K=='\0') //SI NO SE OPRIME NINGUNA TECLAB SIGUE LLAMANDO AL TECLADO


{
K=kbd_getc();
}
IF ( (K!='\0'))
{
IF(K=='0') //Si k es igual a cero
VAL=0; //VAL es igual a cero
IF(K== '1')
VAL=1;
IF(K== '2')
VAL=2;
IF(K== '3')
VAL=3;
IF(K== '4')
VAL=4;
IF(K== '5')
VAL=5;
IF(K== '6')
VAL=6;
IF(K== '7')
VAL=7;
IF(K== '8')
VAL=8;
IF(K== '9')
VAL=9;
}
}

//Rutina para pedir la clave


void pedir_clave (void)
{
TECLADO();
IF((K!='#')&&(K!='*'))
{
lcd_putc('*');
MIL=VAL;
}
IF(K=='*')
return;
TECLADO();
IF((K!='#')&&(K!='*'))
{
lcd_putc('*');
CEN=VAL;
}
IF(K=='*')
return;
TECLADO();

IF((K!='#')&&(K!='*'))
{
lcd_putc('*');
DEC=VAL;
}
IF(K=='*')
return;
TECLADO();
IF((K!='#')&&(K!='*'))
{
lcd_putc('*');
UNI=VAL;
}
IF(K=='*')
return;

int validar_clave(void)

{
long int clave=0,M,C,D,U;
M=MIL*1000;//convierte miles a numero
C=CEN*100; //Convierte centenas a numeero

D=DEC*10; //Convierte deceas a numero


U=UNI;

clave=M+C+D+U;
if(clave==contra) //sila clave es igual a la contraseña
return(1);
else
return(0);
}

void cambio_clave(void)
{
int bandera=0;
long clave=0,M,C,D,U;
LCD_PUTC("\f");
LCD_GOTOXY(1,1);
LCD_PUTC("CLAVE ACTUAL");
LCD_GOTOXY(1,2);
pedir_clave(); //llama funcion pedir la clave
bandera=validar_clave();
if(bandera==1)
{
LCD_PUTC("\f");
LCD_GOTOXY(1,1);
LCD_PUTC("CLAVE NUEVA");
LCD_GOTOXY(1,2);
TECLADO();
IF((K!='#')&&(K!='*'))
{
lcd_putc('*');
MIL=VAL;
}

TECLADO();
IF((K!='#')&&(K!='*'))
{
lcd_putc('*');
CEN=VAL;
}

TECLADO();
IF((K!='#')&&(K!='*'))
{
lcd_putc('*');
DEC=VAL;
}

TECLADO();
IF((K!='#')&&(K!='*'))
{
lcd_putc('*');
UNI=VAL;
}

M=MIL*1000;//convierte miles a numero


C=CEN*100; //Convierte centenas a numeero

D=DEC*10; //Convierte deceas a numero


U=UNI;

clave=M+C+D+U;

contra=clave;
WRITE_EEPROM(0,MIL); //GUARDA EN MEMORIA CONTRASENA
WRITE_EEPROM(1,CEN);
WRITE_EEPROM(2,DEC);
WRITE_EEPROM(3,UNI);
WRITE_EEPROM(4,12); //INDICADOR QUE SE HA CAMBIADO LA CONTRASENA

}
else
{
LCD_PUTC("\f");
LCD_GOTOXY(1,2);
LCD_PUTC(" CLAVE INVALIDA");
BIT_SET(LED2);
DELAY_MS(4000);
BIT_CLEAR(LED2);
LCD_PUTC("\f");
}
}
VOID MAIN()
{
long M,C,D,U;
OPTION_REG =0;
WPUB=0B11111111;//SELECCIONA PULLUPS PUERTO B
SET_TRIS_C(0X00);
lcd_init(); //INICIALIZA DRIVER DEL TECLADO

kbd_init();
PORTC=0;

sinal = READ_EEPROM(4); // BANDERA DE INICIO


if (sinal!=12)
contra=9999;
else
{
M=READ_EEPROM(0);
C=READ_EEPROM(1);
D=READ_EEPROM(2);
U=READ_EEPROM(3);

M=M*1000;
C=C*100;

D=D*10;

contra=M+C+D+U;
}

WHILE(TRUE)
{
LCD_PUTC("\f");
LCD_GOTOXY(1,1);

LCD_PUTC(" DIGITE CLAVE");


LCD_GOTOXY(1,2);
DELAY_MS(1000);

pedir_clave(); //Llama funcion pedir clave


IF(K=="*")
cambio_clave();
else
{
WHILE((K!="#"))
{
TECLADO();
IF(K=="*")
cambio_clave();
}
IF(validar_clave()==1) //Aqui se compara si los
//numeros digitados
//estan correctos
{
LCD_PUTC("\f"); //BOORA LCD
LCD_GOTOXY(1,1); //LOCALIZA CURSOR LCD
LCD_PUTC(" CLAVE CORRECTA ");
BIT_SET(LED1);
DELAY_MS(2000);
BIT_CLEAR(LED1);
}
ELSE
{
LCD_PUTC("\f");
LCD_GOTOXY(1,2);
LCD_PUTC(" CLAVE INVALIDA ");
BIT_SET(LED2);
DELAY_MS(4000);
BIT_CLEAR(LED2);
}
}
}
}

Practica 26 tonos

Objetivo: Aprender a usar la librería tones y llevar una melodía a la bocina.


Teoria:
El driver de tones.c genera tonos de las notas en dos octavas, y se le puede asignar
la duración del tono le provee el listado del driver.
Programa : El programa listado genera una melodía usando la librería tones.C

#include <cucaracha.h>

/////////////////////////////////////////////////////////////////////////
//// EX_TONES.C ////
//// ////
//// This example plays the song "La Cucaracha." ////
//// ////
//// Configure the CCS prototype card as follows: ////
//// Connect the positive wire of the speaker to pin B0 ////
//// Connect the negative wire of the speaker to Gnd ////

/////////////////////////////////////////////////////////////////////////

#use delay(clock=20000000)

//#build(reset=0x1000)
//#build(interrupt=0x1008)
//#org 0,0x0FFF void bootloader() {} //

#include <tones.c>

#define SIZE 34

const struct note


{
long tone;
long length;
} happy_bday[SIZE] = {
C_note[0],100, C_note[0],100, C_note[0],100,F_note[0],500, A_note[0],350,
C_note[0],100, C_note[0],100, C_note[0],100,F_note[0],500, A_note[0],350,
F_note[0],100, F_note[0],100, E_note[0],100,E_note[0],100, D_note[0],100,D_note[0],100,C_note[0],500,
C_note[0],100, C_note[0],100, C_note[0],100,E_note[0],500, G_note[0],350,
C_note[0],100, C_note[0],100, C_note[0],100,E_note[0],500, G_note[0],350,
C_note[1],350, D_note[1],100, C_note[1],100,Bb_note[0],100, A_note[0],100,G_note[0],100,F_note[0],350};

void main(void) {
int i;
set_tris_d(0b00000000); // Configura el puerto RB como salidas
// Lazo infinito
output_d(0b00000001); // Pone un 1 en el bit 0 del pto B
delay_ms( 1000 ); // Retardo de 250 msegundos
output_d(0b00000000); // Pone un 0 en el bit 0 del pto B
delay_ms( 1500 );

output_d(0b00000001); // Pone un 1 en el bit 0 del pto B


delay_ms( 1000 ); // Retardo de 250 msegundos
output_d(0b00000000); // Pone un 0 en el bit 0 del pto B
delay_ms( 1500 );

output_d(0b00000001); // Pone un 1 en el bit 0 del pto B


delay_ms( 1000 ); // Retardo de 250 msegundos
output_d(0b00000000); // Pone un 0 en el bit 0 del pto B
delay_ms( 1500 );

while(TRUE)
{
for(i=0; i<SIZE; ++i)
{
generate_tone(happy_bday[i].tone,happy_bday[i].length);
delay_ms(75);
}
}
}

Practica 27 Matriz de LEDs

Objetivo: Aprender a usar la librería del driver MAX7219 y controlar una matriz de LEDs de 8x8.

Teoria:
El driver de LEDs esta hecho para un circuito integrado MAX7219 para controlar el encendido o apagado de
un arreglo matricial de LEDs la hoja de datos muestra sus características:

General Description
The MAX7219/MAX7221 are compact, serial input/output
common-cathode display drivers that interface
microprocessors (μPs) to 7-segment numeric LED displays
of up to 8 digits, bar-graph displays, or 64 individual
LEDs. Included on-chip are a BCD code-B
decoder, multiplex scan circuitry, segment and digit
drivers, and an 8x8 static RAM that stores each digit.
Only one external resistor is required to set the segment
current for all LEDs. The MAX7221 is compatible
with SPI™, QSPI™, and Microwire™, and has slew-ratelimited
segment drivers to reduce EMI.
A convenient 3-wire serial interface connects to all
common μPs. Individual digits may be addressed and
updated without rewriting the entire display. The
MAX7219/MAX7221 also allow the user to select code-
B decoding or no-decode for each digit.
The devices include a 150μA low-power shutdown
mode, analog and digital brightness control, a scanlimit
register that allows the user to display from 1 to 8
digits, and a test mode that forces all LEDs on.
________________________Applications
Bar-Graph Displays
7-Segment Displays
Industrial Controllers
Panel Meters
LED Matrix Displays
____________________________Features
© 10MHz Serial Interface
© Individual LED Segment Control
© Decode/No-Decode Digit Selection
© 150μA Low-Power Shutdown (Data Retained)
© Digital and Analog Brightness Control
© Display Blanked on Power-Up
© Drive Common-Cathode LED Display
© Slew-Rate Limited Segment Drivers
for Lower EMI (MAX7221)
© SPI, QSPI, Microwire Serial Interface (MAX7221)
© 24-Pin DIP and SO Packages

MAX7219/MAX7221

+5V
19
9.53kΩ V+
18
ISET DIG 0–DIG 7
8 DIGITS

MOSI
1
DIN
MAX7219
MAX7221
μP I/O
12
LOAD (CS)
13 SEG A–G,
SCK CLK
SEG DP
9 8 SEGMENTS
GND
GND
4

( ) MAX7221 ONLY 8- DIGIT μP DISPLAY


Functional Diagram

CS tCSW
OR LOAD
tCSH
tCSS tCL tCH tCP tLDCK

CLK
tDH

tDS

DIN D15 D14 D1 D0

tDO

DOUT

Figure 1. Timing Diagram

Table 1. Serial-Data Format (16 Bits)


D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0

X X X X ADDRESS MSB MSBDATA LSB


Detailed Description
MAX7219/MAX7221 Differences
The MAX7219 and MAX7221 are identical except for
two parameters: the MAX7221 segment drivers are
slew-rate limited to reduce electromagnetic interference
(EMI), and its serial interface is fully SPI compatible.

Serial-Addressing Modes
For the MAX7219, serial data at DIN, sent in 16-bit
packets, is shifted into the internal 16-bit shift register
with each rising edge of CLK regardless of the state of
LOAD. For the MAX7221, CS must be low to clock data
in or out. The data is then latched into either the digit or
control registers on the rising edge of LOAD/CS.
LOAD/CS must go high concurrently with or after the
16th rising clock edge, but before the next rising clock
edge or data will be lost. Data at DIN is propagated
through the shift register and appears at DOUT 16.5
clock cycles later. Data is clocked out on the falling
edge of CLK. Data bits are labeled D0–D15 (Table 1).
D8–D11 contain the register address. D0–D7 contain
the data, and D12–D15 are “don’t care” bits. The first
received is D15, the most significant bit (MSB).
Digit and Control Registers
Table 2 lists the 14 addressable digit and control
registers. The digit registers are realized with an on-chip,
8x8 dual-port SRAM. They are addressed directly so that
individual digits can be updated and retain data as long
as V+ typically exceeds 2V. The control registers consist
of decode mode, display intensity, scan limit (number of
scanned digits), shutdown, and display test (all LEDs on).

Shutdown Mode
When the MAX7219 is in shutdown mode, the scan
oscillator is halted, all segment current sources are pulled
to ground, and all digit drivers are pulled to V+, thereby
blanking the display. The MAX7221 is identical, except
the drivers are high-impedance. Data in the digit and
control registers remains unaltered. Shutdown can be
used to save power or as an alarm to flash the display by
successively entering and leaving shutdown mode. For
minimum supply current in shutdown mode, logic inputs
should be at ground or V+ (CMOS-logic levels).

Typically, it takes less than 250µs for the MAX7219/


MAX7221 to leave shutdown mode. The display driver
can be programmed while in shutdown mode, and
shutdown mode can be overridden by the display-test
function.
;PROGRAMA

/*
******************************************************************************************************
* Chip : MAX7219
* Author : Burak HAN?ERL?
* Mail : bhancerli@gmail.com
* Description : MAX7219 LED Display Driver Routines - v1.1
*
*
* The Maxim MAX7219 is a led display driver. It can control up to 64 individual leds or eight
* 7-segment-display.
*
* Max7912 uses 3-wire to communicate with microcontroller.
* - DATA : Used to transmit data.
* - CLOCK : Used to generate clock signal which is required for transmitting each bite of data.
* - LOAD : Used to load data to the Max7913's Dual-Port SRam.
*
*
*
* Advantages of Max7219 :
* - Adjustable intensity. (More or less bright leds)
* - Shutdown mode (much less power consumption)
* - Test mode (To see if digits are working or not)
* - Adjustable digit number. (1 to 8 seven-segment-display)
* - Changeable decode mode. (codeB-decode-mode or no-decode-mode)
* (Look over datasheet for more detailed information)
*
*
* DESCRIPTION OF USER FUNCTIONS
* -------------------------------
* init7219() : Required for initialize MAX7219. This function have has to be called before calling
any function.
* write7219(digit, data) : Writes data to the specified digit number. If Decimal Point needed on any
digit, just add
128 to the data.
For example : write7219(1,3) = writes "3" to first digit.
write7219(1,131) = writes "3." to first digit.
* shutdown7219(operatingMode) : Set operatingMode = 0 to Shutdown mode
* Set operatingMode = 1 to Normal mode
* decode7219(decodeMode) : Sets digit-decode mode. code-B or no-decode mode. Look up
datasheet for detailed instructions.
* For example, if user sets decodeMode = 4, (4=0b00000100), then 3. digit will be
* decoded as code-B algorithm, but other pins don't have any decode mode.
* brightness7219(brightnessLevel) : Sets brightness level of digits.
* brightnessLevel = 0 ; minimum brightness level
* brightnessLevel = 15 ; maximum brigthness level
*
* scanLimit7219(totalDigitNumber) : Sets number of connected digits to the MAX7219. When init7912()
function is called,
number of digit will be setted to 4 as default.

186
MANUAL DE PRACTICAS MICROCONTROLADORES

* test7219(testMode) : Sets 7-segment-display test-mode on or off.


testMode = 0 ; normal operation mode
testMode = 1 ; display test mode

** THIS LIBRARY CAN BE USED, DEVELOPED OR SHARED WITH REFERRING THE AUTHOR.
******************************************************************************************************/
#include <18F4550.h>
#device adc = 8
#fuses HS,NOWDT,NOPROTECT,NOLVP,CPUDIV1
#use Delay(Crystal=20000000)

// CONSTANTS //
// - Connection Pins (CHANGE THESE PINS AS YOU WISH)
#define CLK PIN_D7
#define LOAD PIN_D6 //cs chip select
#define SEND_DATA PIN_D5 //data in

// - Mode Selection
#define decode 0x09
#define brightness 0x02
#define scanLimit 0x0B
#define shutDown 0x0C
#define dispTest 0x0F

// Firt 4 bites (not used generally)


#define firstBites 0x0

// Wait function
#define wait delay_ms(1)

long serialData=0;

int
letra[31]={0X00,0X0,0X0,0X0,0X7F,0X08,0X08,0X08,0X7F,0X00,0X3E,0X41,0X41,0X41,0X3E,0X00,0X7F,
0X01,0X01,0X01,0X01,0X00,0X1F,0X28,0X48,0X28,0X1F,0X00,0X00,0X00,0X00};

void clock7219() // clock (CLK) pulse


{
output_low(CLK);
wait;
output_high(CLK);
}

void load7219() // load (LOAD) pulse


{
output_low(LOAD);
wait;
output_high(LOAD);
}

void send7219(long data) // send 16 bit data word to the 7219


{

int count;

187
MANUAL DE PRACTICAS MICROCONTROLADORES

for (count=0; count<16; ++count)


{
output_bit(SEND_DATA, shift_left(&data,2,0)); // set data (DIN) level
clock7219(); // clock data in
}
load7219(); // latch the last 16 bits clocked
}

void dataMaker(byte mode, int dataIncoming) // Standart data package function


{
serialData=firstBites;
serialData<<=4;
serialData|=mode;
serialData<<=8;
serialData|=dataIncoming;
send7219(serialData);
}

void write7219(byte digit, int data) // Send data to digits


{
dataMaker(digit, data);
}

void shutdown7219(int operatingMode)


{
dataMaker(shutDown,operatingMode);
}

void decode7219(int decodeMode)


{
dataMaker(decode, decodeMode);
}

void brightness7219(int brightnessLevel)


{
dataMaker(brightness, brightnessLevel);
}

void scanLimit7219(int totalDigitNumber)

{
dataMaker(scanLimit, totalDigitNumber);
}

void test7219(int testMode)


{
dataMaker(dispTest, testMode);
}

void init7219()
{
dataMaker(shutDown, 1); // No-Shutdown mode. Normal Operation mode.

188
MANUAL DE PRACTICAS MICROCONTROLADORES

dataMaker(decode, 0); // All digits are programmed as code-B decode mode.


dataMaker(scanLimit, 7); // Total digit number set to 4.
dataMaker(brightness, 5); // Full brightness.
}

void main()
{
init7219();
while(true)
{
int x;
write7219(0xf1,0xFF); //COL8 HOLA EN MARQUESINA
write7219(0xf2,letra[1]); //COL7 (RECORRIENDO)
write7219(0xf3,0x00); //COL6 PRIMERAS OCHO COLUMNAS
write7219(0xf4,0x00);
write7219(0xf5,0x00);
write7219(0x06,0x00);
write7219(0x07,0x00);
write7219(0x08,0x00);

delay_ms(250); //TIEMPO DE VISUALIZACION

write7219(0xf1,0x10); //COL8 // bbbb| RECORRIDO UNA


write7219(0xf2,0xFF); //COL7 // bbbb| COLUMNA
write7219(0xf3,0x00); //COL6 // bbbb|
write7219(0xf4,0x00); // bbbb|
write7219(0xf5,0x00); // bbbb|
write7219(0x06,0x00); // bbbb|
write7219(0x07,0x00); // bbbb|
write7219(0x08,0x00); // bbbb|

delay_ms(250); // VISUALIZA

write7219(0xf1,0x10); //COL8 RECORRIDO DOS COLUMNAS


write7219(0xf2,0x10); //COL7
write7219(0xf3,0xFF); //COL6
write7219(0xf4,0x00);
write7219(0xf5,0x00);
write7219(0x06,0x00);
write7219(0x07,0x00);
write7219(0x08,0x00);

delay_ms(250);

write7219(0xf1,0x10); //COL8
write7219(0xf2,0x10); //COL7
write7219(0xf3,0x10); //COL6
write7219(0xf4,0xFF);
write7219(0xf5,0x00);
write7219(0x06,0x00);
write7219(0x07,0x00);
write7219(0x08,0x00);

delay_ms(250);

189
MANUAL DE PRACTICAS MICROCONTROLADORES

write7219(0xf1,0x10); //COL8
write7219(0xf2,0x10); //COL7
write7219(0xf3,0x10); //COL6
write7219(0xf4,0x10);
write7219(0xf5,0xFF);
write7219(0x06,0x00);
write7219(0x07,0x00);
write7219(0x08,0x00);

delay_ms(250);
write7219(0xf1,0xFF); //COL8
write7219(0xf2,0x10); //COL7
write7219(0xf3,0x10); //COL6
write7219(0xf4,0x10);
write7219(0xf5,0x10);
write7219(0x06,0xFF);
write7219(0x07,0x00);
write7219(0x08,0x00);

delay_ms(250);
write7219(0xf1,0x00); //COL8
write7219(0xf2,0xFF); //COL7
write7219(0xf3,0x10); //COL6
write7219(0xf4,0x10);
write7219(0xf5,0x10);
write7219(0x06,0x10);
write7219(0x07,0xFF);
write7219(0x08,0x00);

delay_ms(250);

write7219(0xf1,0x00); //COL8
write7219(0xf2,0x00); //COL7
write7219(0xf3,0xFF); //COL6
write7219(0xf4,0x10);
write7219(0xf5,0x10);
write7219(0x06,0x10);
write7219(0x07,0x10);
write7219(0x08,0xFF);

delay_ms(250);

write7219(0xf1,0x38); //COL8
write7219(0xf2,0x00); //COL7
write7219(0xf3,0x00); //COL6
write7219(0xf4,0xFF);
write7219(0xf5,0x10);
write7219(0x06,0x10);
write7219(0x07,0x10);
write7219(0x08,0x10);

delay_ms(250);

write7219(0xf1,0x44); //COL8

190
MANUAL DE PRACTICAS MICROCONTROLADORES

write7219(0xf2,0x38); //COL7
write7219(0xf3,0x00); //COL6
write7219(0xf4,0x00);
write7219(0xf5,0xFF);
write7219(0x06,0x10);
write7219(0x07,0x10);
write7219(0x08,0x10);

delay_ms(250);
write7219(0xf1,0x82); //COL8
write7219(0xf2,0x44); //COL7
write7219(0xf3,0x38); //COL6
write7219(0xf4,0x00);
write7219(0xf5,0x00);
write7219(0x06,0xFF);
write7219(0x07,0x10);
write7219(0x08,0x010);

delay_ms(250);

write7219(0xf1,0x82); //COL8
write7219(0xf2,0x82); //COL7
write7219(0xf3,0x44); //COL6
write7219(0xf4,0x38);
write7219(0xf5,0x00);
write7219(0x06,0x00);
write7219(0x07,0xFF);
write7219(0x08,0x010);

delay_ms(250);
write7219(0xf1,0x44); //COL8
write7219(0xf2,0x82); //COL7
write7219(0xf3,0x82); //COL6
write7219(0xf4,0x44);
write7219(0xf5,0x38);
write7219(0x06,0x00);
write7219(0x07,0x00);
write7219(0x08,0xFF);

delay_ms(250);

write7219(0xf1,0x38); //COL8
write7219(0xf2,0x44); //COL7
write7219(0xf3,0x82); //COL6
write7219(0xf4,0x82);
write7219(0xf5,0x44);
write7219(0x06,0x38);
write7219(0x07,0x00);
write7219(0x08,0x00);

delay_ms(250);

write7219(0xf1,0x00); //COL8

191
MANUAL DE PRACTICAS MICROCONTROLADORES

write7219(0xf2,0x38); //COL7
write7219(0xf3,0x44); //COL6
write7219(0xf4,0x82);
write7219(0xf5,0x82);
write7219(0x06,0x44);
write7219(0x07,0x38);
write7219(0x08,0x00);

delay_ms(250);

write7219(0xf1,0x00); //COL8
write7219(0xf2,0x00); //COL7
write7219(0xf3,0x38); //COL6
write7219(0xf4,0x44);
write7219(0xf5,0x82);
write7219(0x06,0x82);
write7219(0x07,0x44);
write7219(0x08,0x38);

delay_ms(250);

write7219(0xf1,0xFF); //COL8
write7219(0xf2,0x00); //COL7
write7219(0xf3,0x00); //COL6
write7219(0xf4,0x38);
write7219(0xf5,0x44);
write7219(0x06,0x82);
write7219(0x07,0x82);
write7219(0x08,0x44);

delay_ms(250);

write7219(0xf1,0x01); //COL8
write7219(0xf2,0xFF); //COL7
write7219(0xf3,0x00); //COL6
write7219(0xf4,0x00);
write7219(0xf5,0x38);
write7219(0x06,0x44);
write7219(0x07,0x82);
write7219(0x08,0x82);

delay_ms(250);

write7219(0xf1,0x01); //COL8
write7219(0xf2,0x01); //COL7
write7219(0xf3,0xFF); //COL6
write7219(0xf4,0x00);
write7219(0xf5,0x00);
write7219(0x06,0x38);
write7219(0x07,0x44);
write7219(0x08,0x82);

delay_ms(250);

192
MANUAL DE PRACTICAS MICROCONTROLADORES

write7219(0xf1,0x01); //COL8
write7219(0xf2,0x01); //COL7
write7219(0xf3,0x01); //COL6
write7219(0xf4,0xFF);
write7219(0xf5,0x00);
write7219(0x06,0x00);
write7219(0x07,0x38);
write7219(0x08,0x44);

delay_ms(250);

write7219(0xf1,0x01); //COL8
write7219(0xf2,0x01); //COL7
write7219(0xf3,0x01); //COL6
write7219(0xf4,0x01);
write7219(0xf5,0xFF);
write7219(0x06,0x00);
write7219(0x07,0x00);
write7219(0x08,0x38);

delay_ms(250);

write7219(0xf1,0x00); //COL8
write7219(0xf2,0x01); //COL7
write7219(0xf3,0x01); //COL6
write7219(0xf4,0x01);
write7219(0xf5,0x01);
write7219(0x06,0xFF);
write7219(0x07,0x00);
write7219(0x08,0x00);

delay_ms(250);

write7219(0xf1,0x00); //COL8
write7219(0xf2,0x00); //COL7
write7219(0xf3,0x01); //COL6
write7219(0xf4,0x01);
write7219(0xf5,0x01);
write7219(0x06,0x01);
write7219(0x07,0xFF);
write7219(0x08,0x00);

delay_ms(250);

write7219(0xf1,0x00); //COL8
write7219(0xf2,0x00); //COL7
write7219(0xf3,0x01); //COL6
write7219(0xf4,0x01);
write7219(0xf5,0x01);
write7219(0x06,0x01);
write7219(0x07,0xFF);
write7219(0x08,0x00);

delay_ms(250);

193
MANUAL DE PRACTICAS MICROCONTROLADORES

write7219(0xf1,0x3F); //COL8
write7219(0xf2,0x00); //COL7
write7219(0xf3,0x00); //COL6
write7219(0xf4,0x01);
write7219(0xf5,0x01);
write7219(0x06,0x01);
write7219(0x07,0x01);
write7219(0x08,0xFF);

delay_ms(250);

write7219(0xf1,0x50); //COL8
write7219(0xf2,0x3F); //COL7
write7219(0xf3,0x00); //COL6
write7219(0xf4,0x00);
write7219(0xf5,0x01);
write7219(0x06,0x01);
write7219(0x07,0x01);
write7219(0x08,0x01);

delay_ms(250);

write7219(0xf1,0x90); //COL8
write7219(0xf2,0x50); //COL7
write7219(0xf3,0x3F); //COL6
write7219(0xf4,0x00);
write7219(0xf5,0x00);
write7219(0x06,0x01);
write7219(0x07,0x01);
write7219(0x08,0x01);

delay_ms(250);

write7219(0xf1,0x50); //COL8
write7219(0xf2,0x90); //COL7
write7219(0xf3,0x50); //COL6
write7219(0xf4,0x3F);
write7219(0xf5,0x00);
write7219(0x06,0x00);
write7219(0x07,0x01);
write7219(0x08,0x01);

delay_ms(250);

write7219(0xf1,0x3F); //COL8
write7219(0xf2,0x50); //COL7
write7219(0xf3,0x90); //COL6
write7219(0xf4,0x50);
write7219(0xf5,0x3F);
write7219(0x06,0x00);
write7219(0x07,0x00);
write7219(0x08,0x01);

194
MANUAL DE PRACTICAS MICROCONTROLADORES

delay_ms(250);

write7219(0xf1,0x00); //COL8
write7219(0xf2,0x3F); //COL7
write7219(0xf3,0x50); //COL6
write7219(0xf4,0x90);
write7219(0xf5,0x50);
write7219(0x06,0x3F);
write7219(0x07,0x00);
write7219(0x08,0x00);

delay_ms(250);

write7219(0xf1,0x00); //COL8
write7219(0xf2,0x00); //COL7
write7219(0xf3,0x3F); //COL6
write7219(0xf4,0x50);
write7219(0xf5,0x90);
write7219(0x06,0x50);
write7219(0x07,0x3F);
write7219(0x08,0x00);

delay_ms(250);

} //REPITE EN EL WHILE

CONEXIONES CONECTE LA MATRIZ DE LEDS EN LOS BITS :

#define CLK PIN_D7


#define LOAD PIN_D6 //cs chip select
#define SEND_DATA PIN_D5 //data in

PROYECTO

Proyecto Integrador:

Proyecto Integrador 2

Proyecto Integrador 3

195
MANUAL DE PRACTICAS MICROCONTROLADORES

196

Das könnte Ihnen auch gefallen