You are on page 1of 297

PIC18F4550 Asembler

Programacin del PIC18F4550 con


nuestro Programador USB
4 November 2016
Ahora en este artculo se muestra como se programo el PIC18F4550 con nuestro programador USB
de PICs.

Familia PIC18F de Microchip

La familia PIC18F de la empresa Microchip, tiene microcontroladores que van de las 18 hasta las 80
terminales, muchos de ellos compatibles con la popular familia PIC16F, a diferencia de esta, la
arquitectura de estos PICs esta optimizada para la programacin en lenguaje C, adems de
velocidades de reloj de hasta 48 MHz y por supuesto mas memoria de programa. Uno de estos PICs
es el PIC18F4550, es el usado en este artculo, para demostrar como nuestro programador USB es
capaz de programar algn PIC de la familia PIC18F.

PIC18F4550

Es un microcontrolador con arquitectura de 8 bits, pero con 32K de memoria de programa, entre sus
perifricos ms llamativos esta el puerto USB 2.0 tambin incluye un mdulo serial (I2C, SPI, UART),
ADC, etc. es de 40 pines lo hacen llamativo para proyectos donde se requieren muchas entradas o
salidas, en la siguiente imagen en amarillo se muestran sus caractersticas resumidas de este
microcontrolador.

La siguiente imagen muestra una foto del PIC18F4550

Y enseguida se muestra un diagrama de terminales


Ms detalles exhaustivos de este microcontrolador lo encuentras en su hoja de datos: Datasheet

Puedes ver el precio de este microcontrolador desde nuestra tienda online dando clic aqu.

Enseguida se muestra una serie de pasos para programar este microcontrolador.

Programacin del PIC16F1824

Igual que en los ejemplos de los artculos pasados, para mostrar cmo se programa este PIC usando
nuestro programador USB, se realiz un simple programa que enciende y apaga un LED cada 100
mS, conectado en este PIC al pin, se uso el PIC C Compiler para generar el archivo .HEX. Se usar
el oscilador interno para minimizar las conexiones y generar los retardos de 100 mS, el cdigo fuente,
es bien simple, an as se puede descargar desde nuestro
repositorio: https://github.com/TecdigitaldelBajio/Programador-USB-de-PICs-

Paso #1 Diagrama esquemtico

La figura siguiente muestra el diagrama esquemtico del circuito que se armar en una protoboard,
para programar este PIC. No es necesaria ninguna fuente de voltaje, pues se toma del programador
como los ejercicios anteriores.
Paso #2 Alambrado en la protoboard.

La imagen siguiente muestra el alambrado del diagrama esquemtico anterior en la protoboard, la


imagen muestra la conexin necesaria para el programa de muestra.

Despus de esto se conecta el programador usando los cables dupont que se proveen con el
programador, recuerde identificar las terminales requeridas por el programador: MCLR, PGC
(ICSPDAT), PGD(ICSPCLK). La imagen siguiente muestra esta conexin:
Con esa conexin se puede programar "en sistema" el microcontrolador, por lo que no es necesario
remover el microcontrolador de la protoboard.

Paso #3 Programar usando el software PiCkit 2

Ahora nos aseguramos que el cable USB este conectado al programador y a la computadora
personal, se abre el software PICkit 2, al hacerlo si las conexiones fueron las correctas se detectar
automticamente el PIC18F4550 como lo muestra en la pantalla.

Ahora solo basta con importar el archivo HEX, y programar dando clic en el botn "write", este proceso
y el LED "parpadeando" cada 100 mS, se ven en el siguiente video.
Bienvenidos
Posted on June 30, 2012by need4bits
Te sugiero que leas cada parrafo de los post, te ser de mucha ayuda

Comenzamos este blog compartiendo una sencilla prctica en ASM para el PIC18F4550,
algo tan prctico como el tpicoHello World! para las computadoras pero en este caso
encenderemos un LED.

Si entraste a este blog posiblemente tengas relacin con el mundo de la tecnologa y


debes tener una idea de la programacin de computadoras, en el caso de que alguna vez
hayas programado posiblemente lo hayas hecho en un lenguaje de programacin de alto
nivel; es decir te result demasiado fcil escribir un programa dada la sintaxis de los
comandos y lo familiar que es al utilizar mnemonicos, sin embargo al final este lenguaje
de alto nivel termina compilando el cdigo y pasandolo a un lenguaje de bajo nivel para
que la computadora lo pueda ensamblar y posteriormente interpretar.

Al hablar de un microcontrolador tambin hablamos de una computadora, pues tiene


los bloques necesarios para ser considerado como tal. De esta manera debemos
programar nuestro microcontrolador para que pueda realizar diferentes funciones, en
este caso enender un LED.

Por qu trabajar con el PIC18F4550?


Microchip es la empresa que comercializa estos microcontroladores y la mayora de ellos
son muy comunes debido a la extensa bibliografa de que disponen, adems de que el
fabricante proporciona el software para su programacin.

Material:
PIC18F4550
Resistencia 1k, 330
Un Botn
2 Capacitores de .22pF
1 Cristal de 4MHz, es opcional y servir para futuras prcticas, pero ahorita se puede
omitir.
1 LED
1 Fuente de +5V
1 Programador
MPLAB IDE de Microchip
Pickit 2
Introduccin
El PIC18F4550 tiene puertos que podemos configurar como entradas o salidas, el
manejo de estos puertos es a travs de los registros PORTA, PORTB, PORTC, PORTD,
etc; sin embargo no todos los puertos pueden configurarse como entradas digitales y ese
es el caso del Puerto A, aunque sus pines pueden configurarse como entradas digitales
debemos tener en cuenta que estn orientados a entradas analgicas.
Adems un puerto puede configurarse como entradas y salidas y para ello modificamos
los valores del TRISA, TRISB, TRISC, PORTD, etc; donde el valor tiene una longitud de
8 bits y puede introducirse en decimal (anteponiendo un . Punto y el valor .12 ), en
binario (con el valor entre comillas simples y anteponiendo una b00001100) o en
hexadecimal 0x0C, existen otras formas de introducir valores en ensamblador pero
estas son las ms comunes. En un principio establecer las entradas y salidas en binario,
es decir, poner 0 si el pin de un determinado puerto se quiere configurar como salida y
un 1 si se quiere utilizar como entrada, una vez hecho esto puede pasarse el valor a
hexadecimal y modificar los TRIS_

Es importante ver la hoja de especificaciones del Microcontrolador para conocer las


funciones disponibles, su funcionamiento, sus partes internas y de esta manera pensar
en sus posibles aplicaciones.

La tecnologa nos permite simular circuitos elctricos en computadora y ahora es


posible simular el cdigo de un PIC virtualmente sin necesidad de grabar el
microcontrolador y probarlo fsicamente.

Para comenzar a programar debemos descargar el software apropiado y existe un editor


de Microchip para esta tarea.

El el siguiente post MPLAB IDE te explicamos cmo bajar MPLAB IDE y usarlo,
conforme subimos ms prcticas irmos explicando otras funcionalidades de este
software.
Simulacin en MPLAB IDE
Posted on June 30, 2012by need4bits
La simulacin del cdigo de programa nos ayuda a ver el desarrollo de las instrucciones
as como los tiempos de ejecucin en determinados bloques o lneas y para ello
disponemos de la herramienta MPLAB SIM.

Describiremos la forma de utilizar MPLAB IDE para aquellos que comienzan a utilizar
microcontroladores de Microchip y necesitan hacer un seguimiento de la ejecucin del
programa.

Microchip te proporciona este software para programar sus dispositivos y tambin para
grabarlos, de manera que accediendo al rea de descargas de su pgina podremos
obtener dicho software. http://www.microchip.com/
Despus de instalar MPLAB IDE lo iniciamos y nos muestra una ventaja como la
siguiente (Figura 1)

Figura 1. Ventana principal MPLAB IDE

A estas alturas se deben conocer las partes de una ventana, de manera que crearemos un
nuevo proyecto desde el men Project Project Wizard, cabe mencionar que no es
la nica forma de crear un nuevo proyecto, tambin tenemos la opcin Project New,
pero el primer comando nos ofrece un asistente con los siguientes pasos:
1. Selecciona un Dispositivo (Figura 2)
Figura 2. Seleccionar Dispositivo

2. Selecciona una herramienta de lenguaje (Figura 3)

Figura 3. Seleccionar Compilador

3. Crear y guardar el archivo de proyecto (Figura 4)


Figura 4. Directorio para Crear y Guardar el Proyecto

4. Agregar archivos existentes al proyecto (Figura 5)

Figura 5. Agregar archivos y bibliotecas disponibles

5. Resumen de configuracin (Figura 6)


Figura 6. Informacin de configuracin y Finalizar

Ahora creamos un nuevo archivo presionando Ctrl+N , File New (Figura 7) , o en su


defecto, presionando el icono de la hoja en blanco (Figura 8) que aparece en la barra
de herramientas.

Figura 7. Archivo Nuevo

Figura 8. Icono Nuevo archivo

Se genera un documento en blanco sin ttulo ni formato que debemos guardar con la
extensin *.asm para poder compilar; para ello accedemos al men y ejecutamos el
comando Guardar como: File Save As
En la ventana Save As asignar el nombre del archivo y prestar mucha atencin en
asignar la extensin .asm al final; por ltimo activar la casilla de verificacin Add File
toProject (Agregar archivo al proyecto) y dar clic en guardar (Figura 9)
Figura 9. Guardar y agregar al proyecto

Una vez creado el archivo con extensin *.asm podemos introducir las lneas de cdigo y
estas se resaltaran de acuerdo a la sintaxis
(Directivas, Instrucciones, Direcciones, Variables, Comentarios), debemos comenzar
declarando la palabra de configuracin y posteriormente el programa.
Como buena prctica de programacin, podemos comenzar comentando el programa
con informacin bsica del mismo, para ello usamos punto y coma y lo que est
despus de ste smbolo sern comentarios, ejemplo:

;Esto es un comentario
;Informacin del Proyecto para su documentacin
;***********************************************
Posteriormente escribimos:

List P = 18F4550 ; Pic utilizado


Inclue <P18F4550.inc> ; Archivo con las directivas del Pic
Los archivos *.inc se encuentran en la carpeta de instalacin de MPLAB y contienen la
mayora de familias de microcontroladores de esta empresa.

La palabra de configuracin contiene las instrucciones de cmo debe configurarse el


PIC, para esta prctica utilizamos la palabra CONFIG con las siguientes opciones:

CONFIG FOSC = HS ; Tipo de Oscilador


CONFIG PWRT = ON ; Esperar a que el PIC se estabilice
CONFIG BOR = OFF ; Genera un reset cuando el voltaje disminuye
CONFIG WDT = OFF ; Perro Guardian
CONFIG MCLRF = ON ; Master Clear habilitado
CONFIG PBADEN = OFF ; Puerto B Analgico
CONFIG LVP = OFF ; Voltaje Bajo de Programacin
CONFIG DEBUG = OFF ; Depuracin Incircuit
CONFIG XINST = OFF ; Conjunto de instrucciones extendidas
Una vez escrita la palabra de configuracin se escribe el programa.

Como buena prctica de programacin es importante la indentacin (tabular) al escribir


el cdigo, pues permite una mejor lectura y comprensin de cada bloque, para ello
dejaremos a las etiquetas/banderas sin indentar, las instrucciones, direcciones,
variables y comentarios llevarn indentacin entre ellos, ejemplo:

; Correcto ******************************************
Bandera
MOVLW 0x0F ; Mover 0x0F -> W
MOVWF PORTB ; Mover W -> PORTB

;Incorrecto ****************************************
Bandera
MOVLW 0x0F ;Mover 0x0F -> W
MOVWF PORTB ;Mover W->PORTB

Posteriormente se construye el cdigo introducido y se verifican posibles errores;


ejecutamos los siguientes comandos:

Configure Select Device


Aqu elegimos el PIC con el que deseamos realizar la simulacin, el ensamblador puede
construir el cdigo sin problemas, pero esta opcin crea un archivo que permite una
simulacin posterior en programas como Proteus.

Project Set Active Project


Verificamos que est activo nuestro proyecto y no est en None(Quickbuild Mode) pues
no tenemos ms archivos *.asm
Project Build All
Una vez que el archivo.asm est creado y nuestro proyecto est activo nos aseguramos
que est compilado correctamente para ello ejecutamos el comando siguiente: Proyect
Build All o en su defecto presionando Ctrl + F10 (Figura 10)

Figura 10. Men Proyecto Construir todo (compilar todo)

Posteriormente se selecciona la herramienta para depurar/simular el cdigo, en este


caso elegir MPLAB SIM; para ello hacer clic en: Debugger Select Tool MPLAB
SIM (Figura 10)

Figura 10. MPLAB SIM


Despus de seleccionar MPLAB SIM, se activa un cuadro de herramientas
llamado Debug.
En caso de no haber construido todo el proyecto tambin se puede hacer con Project
Make y si se ha configurado el compilador previamente aparecer el siguiente cuadro
de herramientas antes mencionado:

De izquierda a derecha tenemos:

1. Botn para ejecutar el programa


2. Botn para detener la ejecucin
3. Botn para animar el programa, es decir, ejecutarlo automticamente lnea por lnea.
4. Ejecutar instruccin dentro (subrutinas)
5. Ejecutar instruccin sobre (subrutinas)
6. Ejecutar instruccin fuera (subrutinas)
7. Reset
8. Breakpoints para detener la ejecucin animada o resaltar una lnea de cdigo
A continuacin se mencionan las ventanas de programa donde se visualizan los eventos
de la simulacin.

Ventana Source
Es la ventana donde se edita el cdigo en ensamblador y al depurar aparece una
flecha verde que apunta a la siguiente instruccin a ejecutar:

Indicador de la siguiente instruccin a ejecutar

Ventana Special Function Registers


Muestra el estado de todos los registros de funciones especiales se activa en el
men: View Special Function Registers
Ventana Watch
Muestra el estado de algn registro en especial que el usuario ingrese en la columna
Symbol Name incluyendo los Registros de Funciones Especiales se activa en el
men View Watch

Ventana Stopwatch

Ventana Stimulus
Todas ellas son ventanas tiles sin embargo podemos omitir algunas de ellas del espacio
de trabajo, por ejemplo la ventana Special Function Registers la podemos quitar y dejar
a la ventana Watch; en caso de que nuestro programa no tenga entradas ni trabaje con
tiempos tambin podemos quitar la ventana Stimulus y Stopwatch respectivamente.

Para este caso crearemos un espacio de trabajo con las siguiente


ventanas: Source,Watch y Stimulus.
[En construccin: Ejecucin]

En otra publicacin explicaremos cmo grabar un el cdigo .hex en un microcontrolador


utilizando Pickit 2.
Simulacin en ISIS Proteus
Posted on August 2, 2012by need4bits

ISIS Proteus en un software de simulacin de circuitos elctricos que permite simular el


cdigo hexadecimal de un programa creado en Ensamblador o C.

Para realizar una simulacin seguir las siguientes indicaciones:

1. Una vez instalada la aplicacin, al ejecutarla aparecer la ventana principal (Figura 1)

Figura 1. Ventana Principal ISIS Proteus

2. Se da clic en la letra P junto a DEVICES para agregar los dispositivos en la hoja de


trabajo (Figura 2):

Figura 2. Seleccionar Dispositivos

3. Despus de dar clic se abrir la siguiente ventana (Figura 3):


Figura 3. Pick Devices

4. Del lado izquierdo hay un cuadro de texto con la etiqueta Keywords en el cual se
pueden los buscar componentes por su nombre, lo que facilita su bsqueda; aunque
tambin es posible buscar componentes por categoras pero resulta ms tardado.
(Figura 4):
Figura 4. Bsqueda por palabras clave

5. Una vez encontrado el componente, se agrega seleccionando su nombre en la ventana


de resultados y posteriormente presionando el botn OK . El componente aparecer
en el cuadro Devices y cada vez que se agregue un nuevo componente ir apareciendo en
este lugar (Figura 5):

Figura 5. Lista de componentes agregados

6. Posteriormente se selecciona el componente a insertar y se da clic en la hoja de


trabajo, tambin se puede arrastrar y soltar los componentes y mientras se hace esta
operacin el puntero del mouse cambiar a un lpiz verde y se podr visualizar la figura
(Figura 6):
Figura 6. Insercin de componentes

7. Dependiendo de la prctica se pueden agregar instrumentos de medicin como:


Osciloscopio, Multimetro, Generador de Seales, entre otros. En este caso al trabajar
con un PIC es necesario saber cmo importar el *.hex generado; para ello, una vez
agregado el PICXX, se da doble clic sobre este para editar sus propiedades o clic derecho
> Edit Properties, aparecer la siguiente ventana (Figura 7):

Figura 7. Importar el archivo *.hex

8. Dar clic en el icono de la carpeta para buscar el archivo e importarlo (Figura 8)

Figura 8. Importar el archivo *.hex

9. El botn anterior abre una ventana para buscar el archivo, seleccionarlo y poder
importarlo; para ello podemos importar archivos con extensin *.hex o *.cof. Una vez se
ha encontrado el archivo se da Abrir
10. Por ltimo se comienza la simulacin dando clic en el botn Play que se encuentra
en la parte inferior del lado izquierdo (Figura 10).
Figura 10. Iniciar simulacin

Si no existen errores Proteus comenzar a realizar las operaciones correspondientes al


circuito y al programa, de otra manera advertir en la barra de estado que hay errores
(Figura 11)

Figura 11. Mensajes y advertencias de errores

De esta manera se simula un circuito que emplea un PIC en ISIS Proteus.


1. Encender y Apagar un LED mediante un botn,
PIC18F4550 ASM
Posted on June 30, 2012by need4bits

Objetivo
Identificar y conocer las caractersticas de los microcontroladores de la familia
PIC18, en particular el PIC18F4550.
Ubicar los pines del PIC18F4550 e identificar sus funciones (Puertos, Oscilador, AD,
PWM, Tx, Rx).
Identificar los pines Vdd, Vss, ~MCLR, PGD y PGC para programar el
microcontrolador.
Conocer y manejar el software MPLAB para el desarrollo de proyectos, simular y
programar un microcontrolador.
Realizar un programa en ASM para encender y apagar un LED, conectado a RB0,
mediante un botn pulsador conectado a RB4.
Realizar la simulacin del circuito en ISIS Proteus, cargando el *.hex al PIC18F4550.
Programar el microcontrolador mediante Pickit2
Marco Terico
En el siguiente grfico (Figura 1) se muestran los puertos disponibles en el PIC18F4550,
sus ubicaciones y las posibles funciones de cada pin.

Figura1. Diagrama de los Pines del PIC18F4550


A continuacin se muestra el diagrama de Bloques de dicho microcontrolador (Figura 2)

figura 2. Diagrama de Bloques del PIC18F4550


Y por ltimo una tabla con funciones para su programacin (Figura 3)
Figura 3. Conjunto de instrucciones del PIC18F4550

Hemos mencionado que un microcontrolador puede ser considerado como una


computadora, pues posee una ALU (Unidad de Aritmtica y Lgica), registros, buses
y unidad de control, es decir tiene una CPU (Unidad Central de Procesamiento).

La mayora de los dispositivos de lgica secuencial, entre ellos los CPU, son de
naturaleza sncrona. Es decir, estn diseados y operan en funcin de una seal de
sincronizacin. Esta seal, conocida como seal de reloj, usualmente toma la forma de
una onda cuadrada peridica. Calculando el tiempo mximo en que las seales elctricas
pueden moverse en las varias bifurcaciones de los muchos circuitos de un CPU, los
diseadores pueden seleccionar un perodo apropiado para la seal de reloj.
Para el correcto funcionamiento del microcontrolador debemos definir la frecuencia del
oscilador pues determinar los ciclos de instruccin; podemos utilizar un oscilador
interno o externo, sin embargo es recomendable utilizar un oscilador de cristal externo
para evitar un mal funcionamiento frente a las variaciones de temparatura dentro del
microcontrolador.

A continuacin mostramos la tabla del registro de configuracin del oscilador (Figura 4)


Figura 4. Registro OSCCON para la Configuracin del Oscilador

Podemos ver que por default tiene cargado el valor: 0100 X000 que de acuerdo con los
valores de la tabla anterior corresponderan a la siguiente configuracin:

0 | El dispositivo entra en reposo/bajo consumo cuando se ejecuta la instruccin


Sleep.
100 | Frecuencia del oscilador interno: 1MHz
X | Depende del estado del bit IESO
0 | INTOSC La frecuencia del Oscilador Interno no es estable
00 | Oscilador primario, externo
Aunque el microcontrolador est configurado por defecto con 1MHz es necesario
especificarlo en la palabra de configuracin.
Para estas prcticas se utilizar una frecuencia de 4MHz y, como no es necesario
precisin en el tiempo, no pondremos ningn oscilador externo, de esta manera el valor
a cargar ser el siguiente:

0 110 0 0 00 => 0110 0000 => 0x60


Clculos
Dado que se configur el oscilador interno del microcontrolador a 4MHz, se tiene:

Ciclo de reloj:

Ciclo de instruccin:

Para limitar la corriente que circula por el LED se propone una resistencia de 330:

Y para limitar la corriente del pin de Reset y el botn pulsador a 0.5mA, utilizar una
resistencia de 10k.

Simulacin
Para simular el siguiente cdigo por favor revisar la publicacin de Cmo utilizar y
simular en MPLAB? y Cmo utilizar y simular en ISIS Proteus?, si sabes hacerlo
puedes seguir leyendo.
Creamos un proyecto nuevo y lo llamamos LedOn, como buena prctica de
programacin y para una mejor organizacin conviene que el archivo fuente del cdigo
lleve el mismo nombre del proyecto, es decir LedOn.asm este archivo con extensin
*.asm es de ensamblador.

1 ; ********************************************************

2 ; Desarrollo de Microcontroladores y DSPS

3 ; Encender un LED
4 ; Prctica 1

5 ;

; Fecha: 03/06/2012
6
; Notas: Encender un LED en RB4 al presionar un botn en RB0
7
;
8
; Autor: ek
9
; ************************************************************
10
LIST P = 18F4550
11
INCLUDE <P18F4550.INC>

12
;************************************************************

13 CONFIG FOSC = HS ;INTOSC_XT no disponible para simulacin, usar HS

14 CONFIG PWRT = ON

15 CONFIG BOR = OFF

16 CONFIG WDT = OFF

CONFIG MCLRE = ON
17

CONFIG PBADEN = OFF


18
CONFIG LVP = OFF
19
CONFIG DEBUG = OFF
20
CONFIG XINST = OFF
21
; CODE ******************************************************
22
#define Led PORTB, 4
23
24

25 ORG 0x00 ;Iniciar el programa en el registro 0x00

26

27 clrf PORTB ;Limpia los posibles valores actuales de PORTB

28 movlw 0x0F ;Entradas y Salidas para PORTB

movwf TRISB ;Configura TRISB <- W


29

30
INICIO
31
btfss PORTB, 0 ;Salta si RB0 = 1 presionado
32
goto LedOff ;RB0 = 0, continua apagado
33
bsf Led ;Encender Led
34
bra INICIO
35

36
LedOff
37
bcf Led ;Apagar Led

38
bra INICIO

39

40 END ;Fin de Programa

41

42

Una vez terminado contruimos el cdigo y si todo sale bien, nos deber aparecer en la
ventana output algo similar a esto:
Ahora abrimos Pickit 2 y grabamos el archivo
LedOn.hex generado.
Montamos el pic conforme el siguiente diagrama (Figura 5) y probamos.

Figura 5. Diagrama de Conexin del circuito.


2. Efecto de corrimiento con LEDs, PIC18F4550 ASM
Posted on August 12, 2012by need4bits

Introduccin
La disposicin de los puertos digitales nos permite hacer operaciones con un byte,
nibble o bit, por ejemplo intercambiar el nibble alto por el bajo o desplazar el valor de
un bit hacia la izquierda o derecha, algunas de estas operaciones estn disponibles en las
funciones de algunos PICs como el caso del 18F4550, gracias a estas funciones es posible
crear efectos de luces con LEDs al colocar ciertas configuraciones de 0 y 1 a la salida de
dichos puertos.

Objetivos
Identificar las caractersticas del PIC18F4550.
Utilizar el software MPLAB para crear un proyecto y simular el cdigo.
Realizar un programa en lenguaje ensamblador para controlar el encendido de 8
LEDs conectados a PORT B.
Mediante un pulsador en PD0 cambiar el sentido de encendido de derecha a
izquierda o viceversa al momento de presionar el botn.
El tiempo de transicin entre los LEDs ser de 300ms.
Realizar simulacin en MPLAB.
Realizar simulacin en ISIS Proteus.
Programar el microcontrolador utilizando Pickit 2
Marco Terico
En el siguiente grfico (Figura 1) se muestran los puertos disponibles en el PIC18F4550,
sus ubicaciones y las posibles funciones de cada pin.
Figura1. Diagrama de los Pines del PIC18F4550

A continuacin se muestra el diagrama de Bloques de dicho microcontrolador (Figura 2)


figura 2. Diagrama de Bloques del PIC18F4550

Y por ltimo una tabla con funciones para su programacin (Figura 3)


Figura 3. Conjunto de instrucciones del PIC18F4550

Hemos mencionado que un microcontrolador puede ser considerado como una


computadora, pues posee una ALU (Unidad de Aritmtica y Lgica), registros, buses
y unidad de control, es decir tiene una CPU (Unidad Central de Procesamiento).

La mayora de los dispositivos de lgica secuencial, entre ellos los CPU, son de
naturaleza sncrona. Es decir, estn diseados y operan en funcin de una seal de
sincronizacin. Esta seal, conocida como seal de reloj, usualmente toma la forma de
una onda cuadrada peridica. Calculando el tiempo mximo en que las seales elctricas
pueden moverse en las varias bifurcaciones de los muchos circuitos de un CPU, los
diseadores pueden seleccionar un perodo apropiado para la seal de reloj.
Para el correcto funcionamiento del microcontrolador debemos definir la frecuencia del
oscilador pues determinar los ciclos de instruccin; podemos utilizar un oscilador
interno o externo, sin embargo es recomendable utilizar un oscilador de cristal externo
para evitar un mal funcionamiento frente a las variaciones de temparatura dentro del
microcontrolador.

A continuacin mostramos la tabla del registro de configuracin del oscilador (Figura 4)


Figura 4. Registro OSCCON para la Configuracin del Oscilador

Podemos ver que por default tiene cargado el valor: 0100 X000 que de acuerdo con los
valores de la tabla anterior corresponderan a la siguiente configuracin:

0 | El dispositivo entra en reposo/bajo consumo cuando se ejecuta la instruccin


Sleep.
100 | Frecuencia del oscilador interno: 1MHz
X | Depende del estado del bit IESO
0 | INTOSC La frecuencia del Oscilador Interno no es estable
00 | Oscilador primario, externo
Aunque el microcontrolador est configurado por defecto con 1MHz es necesario
especificarlo en la palabra de configuracin.
Para estas prcticas se utilizar una frecuencia de 4MHz y, como no es necesario
precisin en el tiempo, no pondremos ningn oscilador externo, de esta manera el valor
a cargar ser el siguiente:

0 110 0 0 00 => 0110 0000 => 0x60


Clculos
Dado que se configur el oscilador interno del microcontrolador a 4MHz, se tiene:

Ciclo de reloj:

Ciclo de instruccin:

Para limitar la corriente que circular por los LEDs conectados al Puerto B, se proponen
resistencias de 330:

Y para limitar la corriente del pin de Reset y el botn pulsador a 0.5mA, utilizar una
resistencia de 10k.

Para generar el retardo se utilizarn tres registros de la memoria y se cargarn con los
siguientes valores, estos valores son calculados de acuerdo a un algoritmo que utiliza
ciclos.

Conta1 = 200
Conta2 = 100
Conta3 = 5

El contador 1 (Conta1) se encuentra dentro del ciclo de conteo del contador 2 (Conta2) y
ambos estn dentro del ciclo del contador 3 (Conta3). Tomando en cuenta que se
necesitan 3 ciclos de instruccin para ir decrementando los ciclos, la frmula queda
como sigue:

Simulacin
Antes de comenzar la simulacin es necesario leer lo siguiente: Cmo simular en
MPLAB? y Cmo simular en ISIS Proteus? en caso de saber cmo hacerlo se pueden
omitir los enlaces anteriores.
Desarrollar una simulacin en MPLAB con la finalidad de medir los tiempos de
ejecucin para los retardos y observar la ejecucin de cada instruccin.

1 ; ********************************************************

2 ; Desarrollo de Microcontroladores y DSPS

3 ; Barrido de LEDs bidireccional

4 ; Prctica 2

;
5
; Fecha: 08/06/2012
6
; Notas: Hacer el barrido de un LED
7
;
8
; Autor: ek
9
; ************************************************************
10
LIST P = 18F4550

11
INCLUDE <P18F4550.INC>

12
;************************************************************

13 CONFIG FOSC = HS

14 CONFIG PWRT = ON

15 CONFIG BOR = OFF

16 CONFIG WDT = OFF

CONFIG MCLRE = ON
17
18 CONFIG PBADEN = OFF

19 CONFIG LVP = OFF

CONFIG DEBUG = OFF


20
CONFIG XINST = OFF
21
; CODE ******************************************************
22

23
#define Conta 0x12
24
cblock
25
Conta1
26
Conta2

27
Conta3

28 Sweep

29 endc

30

31 #define Time1 0x00 ;Configuracin para 300ms 0x00

32 #define Time2 0x85 ;Configuracin para 300ms 0x85

33 #define Time3 0x02 ;Configuracin para 300ms 0x02

34

35 ORG 0x00 ;Iniciar el programa en el registro 0x00

36

37 clrf PORTB ;Limpia los posibles valores actuales de PORTB


38 clrf PORTD ;Limpia los posibles valores actuales de PORTD

39 clrf TRISB ;Configura TRISB movlw 0x01 ;Entrada RD0 de habilitaci

40 movwf TRISD ;Configura TRISD =>=>

call Retardo ;Esperar un tiempo


41
rrncf Sweep, F ;Rotar hacia la Derecha y Guardar en Sweep
42
movff Sweep, PORTB ;Mover el valor de Sweep a PORTB
43
btfss PORTD, 0 ;Salta si RD0 = 1, Cambio <== bra MoveRight ;Repe
44

45
MoveLeft
46
call Retardo ;Esperar un tiempo
47
rlncf Sweep, F ;Rotar hacia la izquierda y Guardar en Sweep
48
movff Sweep, PORTB ;Mover el valor de Sweep a PORTB

49
btfss PORTD, 0 ;Salta si RD0 = 1, Cambio ==> PRESIONAR Y SOLTAR

50
;btfsc PORTD, 0 ;Salta si RD0 = 0, Cambio ==> SLO AL PRESIONAR

51
bra MoveLeft ;Repetir Ciclo <=<=< bra MoveRight ;Direccin [

52

53
bra INICIO

54

55 ;****** Funciones *************************

56 Retardo

57 movlw Time1
58 movwf Conta1

59 movlw Time2

movwf Conta2
60
movlw Time3
61
movwf Conta3
62
Repeat
63
decfsz Conta1, F ;Salta cuando Conta1 llega a 0
64
bra Repeat ;Salta a Repeat para Decrementar Conta1
65

66
movlw Time1 ;Mover el valor de Conta1 -> W
67
movwf Conta1 ;W -> Conta1, reconfigurar el valor
68
decfsz Conta2, F ;Salta cuando Conta2 llega a 0

69
bra Repeat ;Salta a Repeat

70

71 decfsz Conta3

72 bra Repeat

73 Return

74

75 END ;Fin de Programa

76

77
78

79

Armar el siguientes circuito en ISIS Proteus y simularlo, de la misma manera ser el


circuito fsico (Figura 5).

Figura 5. Circuito
3. Control de un Motor a Pasos Bipolar, PIC18F4550 ASM
Posted on August 15, 2012by need4bits

Introduccin
En varios sistemas electrnicos nos encontramos con una parte mecnica que transmite
algn movimiento por palancas, levas, poleas, ejes de rotacin, entre otras, todas ellas
obtienen, en primera instancia, el movimiento de algn motor.

Existen diferentes tipos de motores, sin embargo para sistemas como: DVDs,
Grabadoras, Quemadores de discos, Impresoras, etc; se necesita un mejor control de las
vueltas que realiza el motor, de esta manera los motores a pasos resultan ser los ms
convenientes.

De igual manera disponemos de motores a pasos unipolares o bipolares, cada uno de


ellos tiene una combinacin a sus entradas que determina su posicin. Para controlar la
secuencia de estas combinaciones podemos utilizar un PIC.

Objetivo
Manipular un motor a pasos bipolar en dos direcciones mediante dos botones.

Objetivos especficos

Identificar las caractersticas del PIC18F4550.


Manejar el software MPLAB para crear un proyecto y simular su funcionamiento.
Realizar un programa en lenguaje ensamblador para controlar el sentido de giro de un motor
a pasos bipolar mediante dos botones pulsadores; un pulsador ubicado en RD0 controla el
sentido de giro hacia la derecha, mientras que el otro ubicado en RD1 lo hace hacia la
izquierda. El motor slo avanza un paso cada vez que se presiona uno de los dos botones, si
se presionan ambos o no se presiona ninguno el motor no deber avanzar.
Realizar la simulacin del cdigo en MPLAB.
Armar el circuito en ISIS Proteus y simularlo.
Programar el microcontrolador mediante el software Pickit2.
Armar el circuito fsico y realizar pruebas.
Marco Terico
En el siguiente grfico (Figura 1) se muestran los puertos disponibles en el PIC18F4550,
sus ubicaciones y las posibles funciones de cada pin.
Figura1. Diagrama de los Pines del PIC18F4550

A continuacin se muestra el diagrama de Bloques de dicho microcontrolador (Figura 2)


figura 2. Diagrama de Bloques del PIC18F4550

Y por ltimo una tabla con funciones para su programacin (Figura 3)


Figura 3. Conjunto de instrucciones del PIC18F4550

Hemos mencionado que un microcontrolador puede ser considerado como una


computadora, pues posee una ALU (Unidad de Aritmtica y Lgica), registros, buses
y unidad de control, es decir tiene una CPU (Unidad Central de Procesamiento).

La mayora de los dispositivos de lgica secuencial, entre ellos los CPU, son de
naturaleza sncrona. Es decir, estn diseados y operan en funcin de una seal de
sincronizacin. Esta seal, conocida como seal de reloj, usualmente toma la forma de
una onda cuadrada peridica. Calculando el tiempo mximo en que las seales elctricas
pueden moverse en las varias bifurcaciones de los muchos circuitos de un CPU, los
diseadores pueden seleccionar un perodo apropiado para la seal de reloj.
Para el correcto funcionamiento del microcontrolador debemos definir la frecuencia del
oscilador pues determinar los ciclos de instruccin; podemos utilizar un oscilador
interno o externo, sin embargo es recomendable utilizar un oscilador de cristal externo
para evitar un mal funcionamiento frente a las variaciones de temparatura dentro del
microcontrolador.

A continuacin mostramos la tabla del registro de configuracin del oscilador (Figura 4)


Figura 4. Registro OSCCON para la Configuracin del Oscilador

Podemos ver que por default tiene cargado el valor: 0100 X000 que de acuerdo con los
valores de la tabla anterior corresponderan a la siguiente configuracin:

0 | El dispositivo entra en reposo/bajo consumo cuando se ejecuta la instruccin Sleep.


100 | Frecuencia del oscilador interno: 1MHz
X | Depende del estado del bit IESO
0 | INTOSC La frecuencia del Oscilador Interno no es estable
00 | Oscilador primario, externo
Aunque el microcontrolador est configurado por defecto con 1MHz es necesario
especificarlo en la palabra de configuracin.
Para estas prcticas se utilizar una frecuencia de 4MHz y, como no es necesario
precisin en el tiempo, no pondremos ningn oscilador externo, de esta manera el valor
a cargar ser el siguiente:

0 110 0 0 00 => 0110 0000 => 0x60


Motor a Pasos Bipolar
Un motor a pasos es capaz de moverse ciertos grados cada vez que se le aplique un pulso
y se mueva un paso, este paso puede variar desde 90 hasta 1.8.

Estos motores poseen la ventaja de poder quedar enclavados en una sla posicin o bien
totalmente libres; si una o ms de sus bobinas esta energizada el motor permanecer en
la posicin correspondiente, o bien, si no hay flujo de corriente en las bobinas el eje del
motor estar libre.

Estos motores estn constituidos normalmente por un rotor sobre el que van aplicados
distintos imanes permanentes y por un cierto nmero de bobinas excitadoras en su
estator.

Para controlar un motor a pasos es necesario conocer su funcionamiento, disear la


etapa de potencia (transistores, diodos) y un circuito digital para la etapa de control
(Circuitos TTL, Microcontrolador PIC). (Figura 5)
Figura 5. Motor a Pasos Bipolar y puente H

Existen 2 tipos de motores a pasos:

1. Unipolares
2. Bipolares
Ambos soncontrolados mediante una secuencia de activacin especfica, pero se
diferencian en el modo en que estn conectadas sus bobinas. Debido a que se usar un
motor a pasos bipolar se caracterizar a continuacin.

Motor Bipolar
En este tipo de motores las bobinas del estator se conectar en serie formando solamente
dos grupos, que se montan sobre dos estatores. De acuerdo a la (Figura 5) se observa
que de este motor salen cuatro hilos que se conectan al circuito de control que realiza la
funcin de cuatro interruptores electrnicos dobles, que nos permiten variar la
polaridad de alimentacn de las bobinas.

Con la activacin y desactivacin adecuada de dichos interruptores dobles, podemos


obtener las secuencias adecuadas para que el motor pueda girar en un sentido o en otro.

Secuencia para manejar motores paso a paso Bipolares

Los motores a pasos Bipolares generalmente tienen 4 cables de salida. Se caracterizan


por tener dos bobinas independientes que al ser excitadas posicionan el eje del motor en
cierta posicin, estos motores necesitan la inversin de la corriente que circula en sus
bobinas en una secuencia determinada; Cada inversin de la polaridad provoca el
movimiento del eje en un paso, cuyo sentido de giro est determinado por la secuencia
siguiente (Figura 6):

Figura 6. Secuencia para un Motor a Pasos Bipolar

Motor Unipolar
Estos motores suelen tener 6 o 7 cables de salida, dependiendo de sus conexiones
internas. Este tipo se caracteriza por ser ms simple de controlar. En la (Figura 7)
podemos apreciar un ejemplo de conexionado para controlar un motor a pasos unipolar
mediante el uso de un ULN2803, el cual es un array de 8 transistores tipo darlington
capaz de manejar cargas de hasta 500mA. Las entradas de activacin (A, B, C y D)
pueden ser activadas por un microcontrolador.
Figura 7. Motor a Pasos Unipolar

Secuencia para manejar motores paso a paso Unipolares

Existen tres secuencias posibles para este tipo de motores, todas las secuencias
comienzan nuevamente por el paso 1 una vez alcanzao el paso final (4 u 8).

1. Secuencia normal: La descrita en la tabla de la (Figura 8).


2. Secuencia del tipo Wave drive: Slo activa una bobina a la vez.
3. Secuencia del tipo medio paso: Activa una bobina y despus dos.

Figura 8. Secuencia normal para motor a pasos unipolar

Para invertir el sentido de giro, simplemente se debe ejecutar las secuencias en modo
inverso.

Clculos
Dado que se configur el oscilador interno del microcontrolador a 4MHz, se tiene:

Ciclo de reloj:

Ciclo de instruccin:
Para limitar la corriente del pin de Reset y el botn
pulsador a 0.5mA, utilizar una resistencia de 10k.

Se emplea un retardo de 200 ms para verificar la secuencia de pulsos de los botones,


tomando en cuenta que es un tiempo considerable para pulsar y soltar un botn. Por lo tanto
se crean 2 variables quedando definidas de la siguiente manera:
Conta 1: 256
Conta 2: 256

El contador 1 se encuentra dentro del ciclo de conteo del contador 2. Tomando en


cuenta que se necesitan 3 ciclos de instruccin 3 us para la ejecucin de cada sustraccin
al contador 1. La frmula queda como sigue:

Simulacin
Antes de comenzar la simulacin es necesario leer lo siguiente: Cmo simular en
MPLAB? y Cmo simular en ISIS Proteus? en caso de saber cmo hacerlo se pueden
omitir los enlaces anteriores.
Simulacin en MPLAB

Para el desarrollo de esta prctica haremos uso de una librera que contendr las
funciones para los retardos, de manera que necesitaremos un archivo con extensin
*.inc y un *.asm, ste ltimo ser el archivo principal.

En primer lugar se realizar el cdigo correspondiente a los retardos, para ello creamos
un nuevo archivo File\New o Ctrl + N

Nos aparecer una ventana en blanco donde podemos comenzar a escribir el cdigo, sin
embargo la sintaxis no se resaltar hasta que tenga una extensin, para ello ejecutamos
el comando Guardar como mediante el men File\Save As En la ventana que
aparece asignar el nombre de la librera, en este caso le llamaremos Retardo y le
colocamos la extensin .inc de manera que antes de guardar deber aparecer en el
cuadro de texto Retardo.inc como se muestra en la (Figura 9)

Figura 9. Guardar Librera de la funcin Retardo

Despus de verificar la configuracin de la ventana Guardar como, damos clic en


Guardar y ahora nuestro archivo aparecer en la ventana de archivos de proyecto en
la carpeta Header Files (Figura 10). De este manera podemos insertar el cdigo que se
interpretar como una funcin incluida en una librera.
Figura 10. Archivo Fuente y para Librera

Ahora en el archivo Retardo.inc escribiremos el siguiente cdigo:

#define Conta
1

cblock
2
Conta1
3
Conta2
4
Conta3
5
endc
6

7
Retardo200ms

8
clrf Conta1

9
clrf Conta2

10 Repeat
11 decfsz Conta1, F ;Salta cuando Conta1 llega a 0

12 bra Repeat ;Salta a Repeat para Decrementar Conta1

13

decfsz Conta2, F ;Salta cuando Conta2 llega a 0


14

bra Repeat ;Salta a Repeat


15

16
Return
17

18

Se guardan los cambios y se continua editando el archivo fuente como sigue:

; ********************************************************
1

; Desarrollo de Microcontroladores y DSPS


2

; Control de un Motor a pasos Bipolar


3
; Prctica 3
4
;
5
; Fecha: 15/06/2012
6
; Notas: Control de un motor a pasos bipolar mediante
7
; dos botones que controlan su direccin

8
;

9
; Autor: ek

10 ; ************************************************************
11 LIST P = 18F4550

12 INCLUDE <P18F4550.INC>

;************************************************************
13

CONFIG FOSC = HS ;INTOSC_XT no disponible para simulacin, usar HS


14
CONFIG PWRT = ON
15
CONFIG BOR = OFF
16
CONFIG WDT = OFF
17
CONFIG MCLRE = ON
18
CONFIG PBADEN = OFF

19
CONFIG LVP = OFF

20
CONFIG DEBUG = OFF

21
CONFIG XINST = OFF

22 ; CODE ******************************************************

23 cblock

24 SecuenC ;Indice de la Secuencia

25 endc

26

27 ORG 0x00 ;Iniciar el programa en el registro 0x00

28

29 movlw 0x62 ;Palabra de congiguracin del OSC Interno


30 movwf OSCCON ;Configurar OSCC2ON <- W

31

32 clrf PORTD ;Borra posibles valores en PORTD

clrf PORTB ;Borra posibles valores en PORTB


33

34

movlw 0x03 ;Configurar RD0 y RD1 como entradas


35

movwf TRISD ;TRISD <- W


36
clrf TRISB ;Configurar PORTD como salida
37
clrf SecuenC ;Estado de Posicin a 0x00
38

39
INICIO
40
movf SecuenC, W
41
call MotorPosition

42
movwf PORTB

43
call Retardo200ms

44

45
ButtonRight ;Verificar Botn Derecho

46 btfss PORTD, 0 ;Verificar RB0 == 1, R == ON

47 bra ButtonLeft ;RB0 == 0, R == OFF

48 btfsc PORTD, 1 ;Verificar RB1 == 0, L == OFF


49 bra INICIO ;Ambos estn Presionados

50 bra MoveRight ;Entradas RB0 == 1, RB1 == 0

ButtonLeft ;Verificar Botn Izquierdo


51

btfss PORTD, 1 ;R == OFF ahora Verificar RB1 == 0, L == ON


52

bra INICIO ;Ambos estn Sueltos


53
bra MoveLeft
54

55
MoveRight ;Aumentar indice para la tabla
56
movf SecuenC, W
57
xorlw 0x06 ;Verificar el indice Max
58
btfss STATUS, Z ;Salta si Z == 1, SecuenC = Indice Max
59
bra Continue1
60
clrf SecuenC

61
bra INICIO

62
Continue1

63 incf SecuenC, F

64 incf SecuenC, F

65 bra INICIO

66

67 MoveLeft
68 movf SecuenC, W ;SecuenC -> W

69 xorlw 0x00 ;Comprobar si W == 0

70 btfss STATUS, Z ;Salta si Z == 1, SecuenC = Indice Min

71 bra Continue2 ;Secuence =/= 0

72 movlw 0x06 ;Rotar hasta Indice Max

movwf SecuenC ;Asignar Indice Max -> SecuenC


73

bra INICIO
74
Continue2
75
decf SecuenC, F
76
decf SecuenC, F
77
bra INICIO
78

79
MotorPosition
80
addwf PCL, F

81
retlw 0x0A ;0000 1010

82
retlw 0x09 ;0000 1001

83
retlw 0x05 ;0000 0101

84
retlw 0x06 ;0000 0110

85

86
include "Retardo.inc" ;Agregar librera Retardo.inc
87

88 END ;Fin de Programa

89

90

91

92

93

Simulacin en ISIS Proteus

Se construy en ISIS Proteus el diagrama elctrico de la siguiente manera y se verific


que el motor responda como se esperaba al presionar los pulsadores que controlan el
sentido de giro del mismo. El motor siempre se mueve slo un paso si se presiona slo
una vez, el sentido depende del botn presionado.

Si el botn se mantiene presionado el motor seguir girando en el sentido


correspondiente hasta que se suelte, y si ambos se ambos se encuentran en el mismo
estado el motor no har nada.
Figura 11. Circuito para el control de un Motor a Pasos Bipolar

Desarrollo Experimental
Material y Equipo requerido

1 PIC18F4550
1 CI L293D (Puente H con diodos)
3 Resistencias de 10k
8 Diodos 1N4007
1 Motor a pasos Bipolar
1 Tablilla de experimentacin (Protoboard)
1 Fuente de 5V
1 Multmetro
1 Programador de Microcontroladores
1 Computadora
Software MPLAB y software de programador
Software ISIS Proteus
4. Control de un LCD, PIC18F4550 ASM
Posted on August 18, 2012by need4bits

Introduccin
En algunas ocasiones es necesario desplegar informacin textual y al mismo tiempo
valores numricos que no es suficiente utilizar LEDs como indicadores o display de 7
segmentos, por ello existen mdulos LCD (Display de Cristal Lquido) que permiten
conectar al microcontrolador una pantalla donde se pueda enviar y mostrar informacin
de inters.

Objetivo
Mostrar texto desde un PIC18F4550 a travs de un LCD

Objetivos especficos

Identificar las caractersticas del PIC18F4550.


Manejar el software MPLAB para crear un proyecto y simular su funcionamiento.
Conocer el funcionamiento, control y aplicacin de un LCD
Crear el cdigo en MikroC para el control del LCD
Realizar la simulacin del cdigo en MPLAB.
Armar el circuito en ISIS Proteus y simularlo.
Programar el microcontrolador mediante el software Pickit2.
Armar el circuito fsico y realizar pruebas.
Marco Terico
En el siguiente grfico (Figura 1) se muestran los puertos disponibles en el PIC18F4550,
sus ubicaciones y las posibles funciones de cada pin.
Figura1. Diagrama de los Pines del PIC18F4550

A continuacin se muestra el diagrama de Bloques de dicho microcontrolador (Figura 2)


figura 2. Diagrama de Bloques del PIC18F4550

Y por ltimo una tabla con funciones para su programacin (Figura 3)


Figura 3. Conjunto de instrucciones del PIC18F4550

Hemos mencionado que un microcontrolador puede ser considerado como una


computadora, pues posee una ALU (Unidad de Aritmtica y Lgica), registros, buses
y unidad de control, es decir tiene una CPU (Unidad Central de Procesamiento).

La mayora de los dispositivos de lgica secuencial, entre ellos los CPU, son de
naturaleza sncrona. Es decir, estn diseados y operan en funcin de una seal de
sincronizacin. Esta seal, conocida como seal de reloj, usualmente toma la forma de
una onda cuadrada peridica. Calculando el tiempo mximo en que las seales elctricas
pueden moverse en las varias bifurcaciones de los muchos circuitos de un CPU, los
diseadores pueden seleccionar un perodo apropiado para la seal de reloj.
Para el correcto funcionamiento del microcontrolador debemos definir la frecuencia del
oscilador pues determinar los ciclos de instruccin; podemos utilizar un oscilador
interno o externo, sin embargo es recomendable utilizar un oscilador de cristal externo
para evitar un mal funcionamiento frente a las variaciones de temparatura dentro del
microcontrolador.

A continuacin mostramos la tabla del registro de configuracin del oscilador (Figura 4)


Figura 4. Registro OSCCON para la Configuracin del Oscilador

Podemos ver que por default tiene cargado el valor: 0100 X000 que de acuerdo con los
valores de la tabla anterior corresponderan a la siguiente configuracin:

0 | El dispositivo entra en reposo/bajo consumo cuando se ejecuta la instruccin Sleep.


100 | Frecuencia del oscilador interno: 1MHz
X | Depende del estado del bit IESO
0 | INTOSC La frecuencia del Oscilador Interno no es estable
00 | Oscilador primario, externo
Aunque el microcontrolador est configurado por defecto con 1MHz es necesario
especificarlo en la palabra de configuracin.
Para estas prcticas se utilizar una frecuencia de 4MHz y, como no es necesario
precisin en el tiempo, no pondremos ningn oscilador externo, de esta manera el valor
a cargar ser el siguiente:

0 110 0 0 00 => 0110 0000 => 0x60


LCD 216 (Displays de Cristal Lquido)
Clculos
Dado que se configur el oscilador interno del microcontrolador a 4MHz, se tiene:

Ciclo de reloj:

Ciclo de instruccin:

Para limitar la corriente del pin de Reset y el botn


pulsador a 0.5mA, utilizar una resistencia de 10k.

Se emplea un retardo de 200 ms para verificar la secuencia de pulsos de los botones,


tomando en cuenta que es un tiempo considerable para pulsar y soltar un botn. Por lo tanto
se crean 2 variables quedando definidas de la siguiente manera:
Conta 1: 256
Conta 2: 256

El contador 1 se encuentra dentro del ciclo de conteo del contador 2. Tomando en


cuenta que se necesitan 3 ciclos de instruccin 3 us para la ejecucin de cada sustraccin
al contador 1. La frmula queda como sigue:

Simulacin
Antes de comenzar la simulacin es necesario leer lo siguiente: Cmo simular en
MPLAB? y Cmo simular en ISIS Proteus? en caso de saber cmo hacerlo se pueden
omitir los enlaces anteriores.
Simulacin en MPLAB

Librera de Retardos

1 CBLOCK
2 Conta1

3 Conta2

Conta3
4

ENDC
5
;Retardo_20ms *********************
6
Retardo_20ms
7
movlw .247
8
movwf Conta1
9
movlw .26

10
movwf Conta2

11
Re_20ms

12
decfsz Conta1, F ;Salta cuando Conta1 llega a 0

13 bra Re_20ms ;Salta a Repeat para Decrementar Conta1

14 decfsz Conta2, F ;Salta cuando Conta2 llega a 0

15 bra Re_20ms ;Salta a Repeat

16 Return

17

;Retardo_5ms *********************
18

Retardo_5ms
19

movlw .146
20
movwf Conta1
21 movlw .7

22 movwf Conta2

Re_5ms
23

decfsz Conta1, F ;Salta cuando Conta1 llega a 0


24
bra Re_5ms ;Salta a Repeat para Decrementar Conta1
25
decfsz Conta2, F ;Salta cuando Conta2 llega a 0
26
bra Re_5ms ;Salta a Repeat
27
Return
28

29
;Retardo_200us *********************

30
Retardo_200us

31
movlw .65

32
movwf Conta1

33 Re_200us

34 decfsz Conta1, F ;Salta cuando Conta1 llega a 0

35 bra Re_200us ;Salta a Repeat para Decrementar Conta1

36 Return

37

;Retardo_2ms *********************
38

Retardo_2ms
39
40 movlw .151

41 movwf Conta1

movlw .3
42

movwf Conta2
43
Re_2ms
44
decfsz Conta1, F ;Salta cuando Conta1 llega a 0
45
bra Re_2ms ;Salta a Repeat para Decrementar Conta1
46
decfsz Conta2, F ;Salta cuando Conta2 llega a 0
47
bra Re_2ms ;Salta a Repeat

48
Return

49

50
;Retardo_50us *********************

51
Retardo_50us

52 movlw .15

53 movwf Conta1

54 Re_50us

55 decfsz Conta1, F ;Salta cuando Conta1 llega a 0

bra Re_50us ;Salta a Repeat para Decrementar Conta1


56

Return
57

58
59 Delay

60 clrf Conta1

clrf Conta2
61

movlw .3
62
movwf Conta3
63
Re_Delay
64
decfsz Conta1, F ;Salta cuando Conta1 llega a 0
65
bra Re_Delay ;Salta a Repeat para Decrementar Conta1
66

67
decfsz Conta2, F ;Salta cuando Conta2 llega a 0

68
bra Re_Delay ;Salta a Repeat

69

70
decfsz Conta3, F

71
bra Re_Delay

72

73 Return

74

75

76

77
78

Cdigo del programa

1 ; ********************************************************

2 ; Desarrollo de Microcontroladores y DSPS

3 ; Manejo de un LCD

4 ; Prctica 4

;
5

; Fecha: 18/06/2012
6
; Notas: Controlar un LCD LM016
7
;
8
; ek
9
; ************************************************************
10
LIST P = 18F4550

11
INCLUDE <P18F4550.INC>

12
;************************************************************

13 CONFIG FOSC = HS

14 CONFIG PWRT = ON

15 CONFIG BOR = OFF

16 CONFIG WDT = OFF

17 CONFIG MCLRE = ON
18 CONFIG PBADEN = OFF

19 CONFIG LVP = OFF

CONFIG DEBUG = OFF


20

CONFIG XINST = OFF


21
; CODE ******************************************************
22
CBLOCK 0x0C
23
ENDC
24

25
#define LCD_RS PORTD,0
26
#define LCD_RW PORTD,1

27
#define LCD_E PORTD,2

28

29
ORG 0x00

30

31
clrf PORTB

32 clrf PORTD

33

34 clrf TRISB

35 clrf TRISD

36
37 call LCD_Inicializa

38 bcf LCD_E

39

Inicio
40

call Delay ;Esperar un tiempo antes de comenzar a escribir


41
movlw 'H'
42
call LCD_Caracter
43
movlw 'o'
44
call LCD_Caracter
45
movlw 'l'

46
call LCD_Caracter

47
movlw 'a'

48
call LCD_Caracter

49 movlw ' '

50 call LCD_Caracter

51 movlw 'M'

52 call LCD_Caracter

movlw 'u'
53

call LCD_Caracter
54

movlw 'n'
55
call LCD_Caracter
56 movlw 'd'

57 call LCD_Caracter

movlw 'o'
58

call LCD_Caracter
59
movlw '!'
60
call LCD_Caracter
61
call Delay
62
call Delay
63

64
call LCD_Borrar

65
goto Inicio

66

67
LCD_Inicializa

68
call Retardo_20ms ;Esperar 20 ms

69 movlw b'00110000' ;Mandar 0x30 -> W

70 movwf PORTB ;Enviar W -> PORTB

71

72 call Retardo_5ms ;Esperar 5ms

73 movlw b'00110000' ;Enviar 0x30 -> W

movwf PORTB
74
75

76 call Retardo_50us ;Acumular 100us

77 call Retardo_50us ;Acumular 100us

movlw b'00110000'
78

movwf PORTB
79

80
movlw 0x0F
81
movwf PORTB
82

83
bsf LCD_E
84
bcf LCD_E
85
return

86

87
LCD_Caracter

88
bsf LCD_RS ;Modo Caracter RS = 1

89
movwf PORTB ;Lo que se carg previamente en W -> PORTB

90 bsf LCD_E ;Activar Enable

91 call Retardo_50us ;Esperar 50us para enviar informacin

92 bcf LCD_E ;Transicin del Enable a 0

93 call Delay ;Esperar a poner la siguiente llamada


94 return

95

96 LCD_Borrar

movlw b'00000001' ;Comando para Borrar


97

call LCD_Comando ;Enviar un comando


98

99
LCD_Comando
100
bcf LCD_RS ;Modo Comando RS = 0
101
movwf PORTB ;Envia W -> PORTB
102
bsf LCD_E ;Activa Enable
103
call Retardo_50us ;Espera que se envie la informacin
104
bcf LCD_E ;Transicin del Enable

105
return

106

107
INCLUDE <LCD_Retardo.inc>

108

109 END ;Fin de Programa

110

111

112
113

114

115

116

Simulacin en ISIS Proteus

Figura 5. Circuito LCD

Desarrollo Experimental
Material y Equipo requerido

1 PIC18F4550
1 Pulsador (Push Button)
3 Resistencias de 10k
1 LCD JHD162A
1 Tablilla de experimentacin (Protoboard)
1 Fuente de 5V
1 Multmetro
1 Programador de Microcontroladores
1 Computadora
Software MPLAB y software de programador
Software ISIS Proteus
Advertisements
1. ;**********************************************************************
********
2. ;
*
3. ; Nombre: parpadea.asm
4. ; Fecha: 30-07-2008
5. ; Version: V1.00
6. ;
*
7. ; Autor: Sander
8. ; Empresa:
9. ;
*
10. ;*****************************************************************
*************
11. ;
*
12. ; Archivos Requeridos: P18F4550.INC
13. ;
*
14. ;*****************************************************************
*************
15. ; Notas:Este programa implementa rutinas de retardos de 1
ms, 1 seg
16. ; para asi poder realizar un parpadeo de 1 seg de todos los
pines del
17. ; PIC18F4550, estas rutinas estan hechas para un oscilador
de 4 MHz
18. ;*****************************************************************
*************
19.
20. LIST P=18F4550 ;Directiva para definir el
procesador
21. #include <P18F4550.INC> ;Definicion de SFRs para el
procesador
22.
23. ;*****************************************************************
*************
24. ;Bits de Configuracion
25. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
26. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
27. ;Abajo hay algunos ejemplos
28.
29. ;******** Configuracion del Oscilador **********
30. CONFIG FOSC = INTOSCIO_EC ;Osc interno, RA6 como
pin, USB usa Osc EC
31. ;******** Otros bits de configuracion **********
32. CONFIG PWRT =
ON ;PWRT habilitado
33. CONFIG BOR =
OFF ;Brown out reset deshabilitado
34. CONFIG WDT =
OFF ;Watchdog deshabilitado
35. CONFIG MCLRE =
OFF ;MCLR como entrada
36. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
37. CONFIG LVP =
OFF ;Programacion en bajo voltaje
apagado
38. ;********* Bits de proteccion ******************
39. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
40. CONFIG CP1 =
OFF ;no estan protegidos
41. CONFIG CP2 = OFF
42. CONFIG CP3 = OFF
43. CONFIG CPB =
OFF ;Sector Boot no esta protegido
44. CONFIG CPD =
OFF ;La EEPROM no esta protegida
45.
46.
47. ;*****************************************************************
*************
48. ; Definicion de variables
49. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
50. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
51. ; interrupcion.
52.
53. CBLOCK 0x080
54. WREG_TEMP ;variable usada para
salvar contexto
55. STATUS_TEMP ;variable usada para
salvar contexto
56. BSR_TEMP ;variable usada para
salvar contexto
57. ENDC
58.
59. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco
0) max 96 bytes
60. Cantms:2 ;variable para generar
hasta 65535 ms
61. CantSeg ;Variable para producir
retardos de hasta 255 seg
62. ENDC
63.
64. ;*****************************************************************
*************
65. ;Datos de la EEPROM
66. ;Los Datos a ser programados en la EEPROM son definidos aqui
67.
68. ORG 0xf00000
69.
70. DE "Test Data",0,1,2,3,4,5
71.
72. ;*****************************************************************
*************
73. ; Vector de Reset.
74. ; Este codigo comenzara a ejecutarse cuando suceda un reset
75.
76. ORG 0x0000
77.
78. goto Main ;Se va al inicio del
codigo principal
79.
80. ;*****************************************************************
*************
81. ; Vector de interrupcion de alta prioridad
82. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
83. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
84. ; no estan habilitadas
85.
86. ORG 0x0008
87.
88. bra HighInt
;Va a la rutina de interrupcion de alta prioridad
89.
90. ;*****************************************************************
*************
91. ; Vector de interrupcion de baja prioridad y rutina
92. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
93. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
94.
95. ORG 0x0018
96.
97. movff STATUS,STATUS_TEMP ;Salva el
registro STATUS
98. movff WREG,WREG_TEMP ;Salva el
registro de trabajo
99. movff BSR,BSR_TEMP ;Salva el
registro BSR
100.
101. ; *** El codigo de la interrupcion de baja prioridad va aqui
***
102.
103.
104. movff BSR_TEMP,BSR ;recupera
el registro BSR
105. movff WREG_TEMP,WREG ;recupera
el registro de trabajo
106. movff STATUS_TEMP,STATUS ;recupera
el registro STATUS
107. retfie
108.
109. ;*****************************************************************
*************
110. ; Rutina de interrupcion de alta prioridad
111. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
112. ; evitar conflictos con el vector de interrupciones de baja
prioridad
113.
114. HighInt:
115.
116. ; *** El codigo para las interrupciones de alta prioridad va
aqui ***
117.
118.
119. retfie FAST
120.
121. ;*****************************************************************
*************
122. ; Comienzo del programa principal
123. ; El codigo del programa principal es colocado aqui
124.
125. Main:
126.
127. ; *** EL codigo principal va aqui ***
128.
129. ;******************* Inicializamos
perifericos ***************************
130.
131. movlw B'01100000' ;Ajustamos
el oscilador interno a 4 MHz
132. movwf OSCCON,.0
133. movlw B'00001111'
134. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
135. clrf TRISA,.0
136. clrf TRISB,.0
137. clrf TRISC,.0
138. clrf TRISD,.0
139. clrf TRISE,.0 ;Todos los
pines como salida
140.
141. MainP0
142. setf LATA,.0
143. setf LATB,.0
144. setf LATC,.0
145. setf LATD,.0
146. setf LATE,.0 ;Ponemos
los puertos en 1
147. movlw .1
148. movwf CantSeg,.0
149. rcall RetardoSeg ;esperamos
1 seg
150. clrf LATA,.0
151. clrf LATB,.0
152. clrf LATC,.0
153. clrf LATD,.0
154. clrf LATE,.0 ;ponemos
los puertos en 0
155. movlw .1
156. movwf CantSeg,.0
157. rcall RetardoSeg ;esperamos
1 seg
158. bra MainP0 ;S
altamos para continuar con el ciclo
159.
160. ;**************************** RetardoSeg ******************
****************
161. ; RetardoSeg Realiza una espera de la cantidad de
segundos indicados
162. ; mediante la variable CantSeg.
CantSeg es de 8 bits
163. ;*****************************************************************
************
164. RetardoSeg
165. movf CantSeg,W,.0
166. btfsc STATUS,Z ;CantSeg
== 0?
167. return ;S
i => retornamos
168. movlw 0x03 ;No =>
hacemos Cantms = 1000
169. movwf Cantms+1,.0
170. movlw 0xE8
171. movwf Cantms,.0
172. rcall Retardo_ms ;realizamo
s un retardo de 1000 ms
173. decf CantSeg,F,.0 ;CantSeg --,
174. bra RetardoSeg ;C
ontinuamos con el ciclo
175. ;*****************************************************************
************
176.
177. ;**************************** Retardo_ms ******************
****************
178. ; Retardo_ms Realiza un retardo de la cantidad de
milisegundos indicados
179. ; mediante Cantms y Cantms+1, Cantms
y Cantms+1 son tratados como
180. ; variables de 16 bits.
181. ;*****************************************************************
************
182. Retardo_ms
183. rcall Retardo1ms ;realizamo
s un retardo de 1 ms
184. decfsz Cantms,F,.0 ;Cantms --
, Cantms == 0
185. bra Retardo_ms ;n
o => vamos a Retardo_ms
186. movf Cantms+1,W,.0 ;
187. btfsc STATUS,Z ;Cantms+1
== 0?
188. return ;S
i => retornamos
189. decf Cantms+1,F,.0 ;No =>
decrementamos
190. bra Retardo_ms ;C
ontinuamos con el ciclo
191. ;*****************************************************************
************
192.
193. ;**************************** Retardo1ms ******************
****************
194. ; Retardo1ms realiza una espera de 1 ms decrementado W
249 veces en un ciclo
195. ; que ocupa 4 us
196. ;*****************************************************************
************
197. Retardo1ms
198. movlw .249
199. Retardo1msP0
200. addlw 0xFF ;W--
201. btfss STATUS,Z,.0 ;W == 0?
202. bra Retardo1msP0 ;No =>
seguimos esperando
203. return ;S
i => ya paso 1 ms
204. ;*****************************************************************
************
205.
206.
207. ;*****************************************************************
*************
208.
209.
210. END ;Directiva fin del
programa
Tema: Ejemplos PIC18F4550 (Ledo 58186 veces)
0 Usuarios y 1 Visitante estn viendo este tema.
sander
Colaborador
PIC24F

Mensajes: 606

Ejemplos PIC18F4550
en: 07 de Agosto de 2008, 23:27:57

He comenzado a usar este microcontrolador y para aprender un poco mas de las nuevas cosas
que trae la arquitectura he decidido realizar algunos programas en ensamblador. por el momento
solo llevo dos probados en el Proteus y en un protoboard, y los coloco a continuacion a
disposicion del foro

Parpadea.asm

Este programa simplemente realiza un parpadeo de 1 segundo de todos los pines del
microcontrolador, para este programa uso el oscilador interno configurado a 4 MHz , y
deshabilito el MCLR, (pero este puede usarse solo como entrada ).

Cdigo: ASM

1. ;**********************************************************************
********
2. ;
*
3. ; Nombre: parpadea.asm
4. ; Fecha: 30-07-2008
5. ; Version: V1.00
6. ;
*
7. ; Autor: Sander
8. ; Empresa:
9. ;
*
10. ;*****************************************************************
*************
11. ;
*
12. ; Archivos Requeridos: P18F4550.INC
13. ;
*
14. ;*****************************************************************
*************
15. ; Notas:Este programa implementa rutinas de retardos de 1
ms, 1 seg
16. ; para asi poder realizar un parpadeo de 1 seg de todos los
pines del
17. ; PIC18F4550, estas rutinas estan hechas para un oscilador
de 4 MHz
18. ;*****************************************************************
*************
19.
20. LIST P=18F4550 ;Directiva para definir el
procesador
21. #include <P18F4550.INC> ;Definicion de SFRs para el
procesador
22.
23. ;*****************************************************************
*************
24. ;Bits de Configuracion
25. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
26. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
27. ;Abajo hay algunos ejemplos
28.
29. ;******** Configuracion del Oscilador **********
30. CONFIG FOSC = INTOSCIO_EC ;Osc interno, RA6 como
pin, USB usa Osc EC
31. ;******** Otros bits de configuracion **********
32. CONFIG PWRT =
ON ;PWRT habilitado
33. CONFIG BOR =
OFF ;Brown out reset deshabilitado
34. CONFIG WDT =
OFF ;Watchdog deshabilitado
35. CONFIG MCLRE =
OFF ;MCLR como entrada
36. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
37. CONFIG LVP =
OFF ;Programacion en bajo voltaje
apagado
38. ;********* Bits de proteccion ******************
39. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
40. CONFIG CP1 =
OFF ;no estan protegidos
41. CONFIG CP2 = OFF
42. CONFIG CP3 = OFF
43. CONFIG CPB =
OFF ;Sector Boot no esta protegido
44. CONFIG CPD =
OFF ;La EEPROM no esta protegida
45.
46.
47. ;*****************************************************************
*************
48. ; Definicion de variables
49. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
50. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
51. ; interrupcion.
52.
53. CBLOCK 0x080
54. WREG_TEMP ;variable usada para
salvar contexto
55. STATUS_TEMP ;variable usada para
salvar contexto
56. BSR_TEMP ;variable usada para
salvar contexto
57. ENDC
58.
59. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco
0) max 96 bytes
60. Cantms:2 ;variable para generar
hasta 65535 ms
61. CantSeg ;Variable para producir
retardos de hasta 255 seg
62. ENDC
63.
64. ;*****************************************************************
*************
65. ;Datos de la EEPROM
66. ;Los Datos a ser programados en la EEPROM son definidos aqui
67.
68. ORG 0xf00000
69.
70. DE "Test Data",0,1,2,3,4,5
71.
72. ;*****************************************************************
*************
73. ; Vector de Reset.
74. ; Este codigo comenzara a ejecutarse cuando suceda un reset
75.
76. ORG 0x0000
77.
78. goto Main ;Se va al inicio del
codigo principal
79.
80. ;*****************************************************************
*************
81. ; Vector de interrupcion de alta prioridad
82. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
83. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
84. ; no estan habilitadas
85.
86. ORG 0x0008
87.
88. bra HighInt
;Va a la rutina de interrupcion de alta prioridad
89.
90. ;*****************************************************************
*************
91. ; Vector de interrupcion de baja prioridad y rutina
92. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
93. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
94.
95. ORG 0x0018
96.
97. movff STATUS,STATUS_TEMP ;Salva el
registro STATUS
98. movff WREG,WREG_TEMP ;Salva el
registro de trabajo
99. movff BSR,BSR_TEMP ;Salva el
registro BSR
100.
101. ; *** El codigo de la interrupcion de baja prioridad va aqui
***
102.
103.
104. movff BSR_TEMP,BSR ;recupera
el registro BSR
105. movff WREG_TEMP,WREG ;recupera
el registro de trabajo
106. movff STATUS_TEMP,STATUS ;recupera
el registro STATUS
107. retfie
108.
109. ;*****************************************************************
*************
110. ; Rutina de interrupcion de alta prioridad
111. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
112. ; evitar conflictos con el vector de interrupciones de baja
prioridad
113.
114. HighInt:
115.
116. ; *** El codigo para las interrupciones de alta prioridad va
aqui ***
117.
118.
119. retfie FAST
120.
121. ;*****************************************************************
*************
122. ; Comienzo del programa principal
123. ; El codigo del programa principal es colocado aqui
124.
125. Main:
126.
127. ; *** EL codigo principal va aqui ***
128.
129. ;******************* Inicializamos
perifericos ***************************
130.
131. movlw B'01100000' ;Ajustamos
el oscilador interno a 4 MHz
132. movwf OSCCON,.0
133. movlw B'00001111'
134. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
135. clrf TRISA,.0
136. clrf TRISB,.0
137. clrf TRISC,.0
138. clrf TRISD,.0
139. clrf TRISE,.0 ;Todos los
pines como salida
140.
141. MainP0
142. setf LATA,.0
143. setf LATB,.0
144. setf LATC,.0
145. setf LATD,.0
146. setf LATE,.0 ;Ponemos
los puertos en 1
147. movlw .1
148. movwf CantSeg,.0
149. rcall RetardoSeg ;esperamos
1 seg
150. clrf LATA,.0
151. clrf LATB,.0
152. clrf LATC,.0
153. clrf LATD,.0
154. clrf LATE,.0 ;ponemos
los puertos en 0
155. movlw .1
156. movwf CantSeg,.0
157. rcall RetardoSeg ;esperamos
1 seg
158. bra MainP0 ;S
altamos para continuar con el ciclo
159.
160. ;**************************** RetardoSeg ******************
****************
161. ; RetardoSeg Realiza una espera de la cantidad de
segundos indicados
162. ; mediante la variable CantSeg.
CantSeg es de 8 bits
163. ;*****************************************************************
************
164. RetardoSeg
165. movf CantSeg,W,.0
166. btfsc STATUS,Z ;CantSeg
== 0?
167. return ;S
i => retornamos
168. movlw 0x03 ;No =>
hacemos Cantms = 1000
169. movwf Cantms+1,.0
170. movlw 0xE8
171. movwf Cantms,.0
172. rcall Retardo_ms ;realizamo
s un retardo de 1000 ms
173. decf CantSeg,F,.0 ;CantSeg --,
174. bra RetardoSeg ;C
ontinuamos con el ciclo
175. ;*****************************************************************
************
176.
177. ;**************************** Retardo_ms ******************
****************
178. ; Retardo_ms Realiza un retardo de la cantidad de
milisegundos indicados
179. ; mediante Cantms y Cantms+1, Cantms
y Cantms+1 son tratados como
180. ; variables de 16 bits.
181. ;*****************************************************************
************
182. Retardo_ms
183. rcall Retardo1ms ;realizamo
s un retardo de 1 ms
184. decfsz Cantms,F,.0 ;Cantms --
, Cantms == 0
185. bra Retardo_ms ;n
o => vamos a Retardo_ms
186. movf Cantms+1,W,.0 ;
187. btfsc STATUS,Z ;Cantms+1
== 0?
188. return ;S
i => retornamos
189. decf Cantms+1,F,.0 ;No =>
decrementamos
190. bra Retardo_ms ;C
ontinuamos con el ciclo
191. ;*****************************************************************
************
192.
193. ;**************************** Retardo1ms ******************
****************
194. ; Retardo1ms realiza una espera de 1 ms decrementado W
249 veces en un ciclo
195. ; que ocupa 4 us
196. ;*****************************************************************
************
197. Retardo1ms
198. movlw .249
199. Retardo1msP0
200. addlw 0xFF ;W--
201. btfss STATUS,Z,.0 ;W == 0?
202. bra Retardo1msP0 ;No =>
seguimos esperando
203. return ;S
i => ya paso 1 ms
204. ;*****************************************************************
************
205.
206.
207. ;*****************************************************************
*************
208.
209.
210. END ;Directiva fin del
programa

Notas

En la version de proteus que tengo (7.2 SP0) por algun motivo toma al pin RA4 como si
tuviera salida de colector abierto por lo que se necesita colocarle una resistencia de PULL-
UP para que se simule ese pin correctamente, en la hoja de datos no dice que este pin
sea de colector abierto, y como es de esperarse la prueba en protoboard le da la razon a
la hoja de datos
En la primer programa que hice no me preocupe del bit de configuracion LVP (que por
defecto esta activado), y el circuito no funcionaba bien en el protoboard, luego de varios
dolores de cabeza y revisando con mas detenimiento la hoja de datos lei que si no se
piensa usar el modo de programacion en bajo voltaje (LVP) se debe colocar el pin RB5 a
tierra mediante una resistencia, una vez hecho esto el circuito funciono como se
esperaba, y como puede verse ahora en el codigo fuente LVP = OFF
Saludos
En lnea

La electronica es el arte de manipular seales electricas que transportan informacin

Jan Davidse

Visita mi blog

sander
Colaborador
PIC24F

Mensajes: 606

Re: Ejemplos PIC18F4550


Respuesta #1 en: 07 de Agosto de 2008, 23:44:25

Disp7Seg.asm

En este ejemplo se visualiza en un display de 7 segmentos un conteo de 0 a 9, en un ciclo


infinito. El display debe ser de anodo comun y debe estar conectado al PORT D, hice este
ejemplo para probar el manejo de tablas en los PIC18.

Cdigo: ASM

1. ;**********************************************************************
********
2. ;
*
3. ; Nombre: Disp7seg.asm
4. ; Fecha: 31/07/2008
5. ; Version: v1.00
6. ;
*
7. ; Autor: Sander
8. ; Empresa:
9. ;
*
10. ;*****************************************************************
*************
11. ;
*
12. ; Archivos Requeridos: P18F4550.INC
13. ;
*
14. ;*****************************************************************
*************
15. ; Notas: El programa realiza un conteo de 0 - 9 dentro de
un ciclo infinito,
16. ; visualiza los valores en un display de 7
segmentos conectado al
17. ; puerto D, el incremento del display se lo realiza cada
segundo.
18. ;
19. ; Para realizar los retardos se usaran las rutinas de
retardo del proyecto
20. ; parpadea, para convertir el valor BCD que cuenta se
implementara una tabla
21. ; en la memoria de programa usando la directiva DB
22. ;
23. ; El display que se usara sera de anodo comun , y tendra la
siguiente conexion
24. ; con el Puerto D
25. ;
26. ; _Vdd_
27. ; |
28. ; ____________|_
29. ; | |
30. ; A(RD0) -->| AAAAAAA |
31. ; B(RD1) -->| F B |
32. ; C(RD2) -->| F B |
33. ; D(RD3) -->| F B |
34. ; | GGGGGG |
35. ; E(RD4) -->| E C |
36. ; F(RD5) -->| E C |
37. ; G(RD6) -->| E C |
38. ; DP(RD7) -->| DDDDDDD DP|
39. ; |______________|
40. ;
41. ;*****************************************************************
*************
42.
43. LIST P=18F4550 ;Directiva para
definir el procesador
44. #include <P18F4550.INC> ;Definicion de SFRs para
el procesador
45.
46. ;*****************************************************************
*************
47. ;Bits de Configuracion
48. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
49. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
50. ;Abajo hay algunos ejemplos
51.
52. ;******** Configuracion del Oscilador **********
53. CONFIG FOSC = INTOSCIO_EC ;Osc interno, RA6 como
pin, USB usa Osc EC
54. ;******** Otros bits de configuracion **********
55. CONFIG PWRT =
ON ;PWRT habilitado
56. CONFIG BOR =
OFF ;Brown out resete
deshabilitado
57. CONFIG WDT =
OFF ;Watch dog deshabilitado
58. CONFIG MCLRE =
OFF ;MCLR como entrada
59. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
60. CONFIG LVP =
OFF ;Programacion en bajo voltaje
apagado
61. ;********* Bits de proteccion ******************
62. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
63. CONFIG CP1 =
OFF ;no estan protegidos
64. CONFIG CP2 = OFF
65. CONFIG CP3 = OFF
66. CONFIG CPB =
OFF ;Sector Boot no esta protegido
67. CONFIG CPD =
OFF ;La EEPROM no esta protegida
68. ;*****************************************************************
*************
69. ; Definicion de variables
70. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
71. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
72. ; interrupcion.
73.
74. CBLOCK 0x080
75. WREG_TEMP ;variable usada para
salvar contexto
76. STATUS_TEMP ;variable usada para
salvar contexto
77. BSR_TEMP ;variable usada para
salvar contexto
78. ENDC
79.
80. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco
0) max 96 bytes
81. Cantms:2 ;variable para generar
hasta 65535 ms
82. CantSeg ;Variable para producir
retardos de hasta 255 seg
83. Cont ;Variable para realizar el
conteo
84. TablaOffs ;Para movernos por la
tabla
85. ENDC
86.
87. ;*****************************************************************
*************
88. ;Datos de la EEPROM
89. ;Los Datos a ser programados en la EEPROM son definidos aqui
90.
91. ORG 0xf00000
92.
93. DE "Test Data",0,1,2,3,4,5
94.
95. ;*****************************************************************
*************
96. ; Vector de Reset.
97. ; Este codigo comenzara a ejecutarse cuando suceda un reset
98.
99. ORG 0x0000
100.
101. goto Main ;Se va al inicio del
codigo principal
102.
103. ;*****************************************************************
*************
104. ; Vector de interrupcion de alta prioridad
105. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
106. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
107. ; no estan habilitadas
108.
109. ORG 0x0008
110.
111. bra HighInt
;Va a la rutina de interrupcion de alta prioridad
112.
113. ;*****************************************************************
*************
114. ; Vector de interrupcion de baja prioridad y rutina
115. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
116. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
117.
118. ORG 0x0018
119.
120. movff STATUS,STATUS_TEMP ;Salva el
registro STATUS
121. movff WREG,WREG_TEMP ;Salva el
registro de trabajo
122. movff BSR,BSR_TEMP ;Salva el
registro BSR
123.
124. ; *** El codigo de la interrupcion de baja prioridad va aqui
***
125.
126.
127. movff BSR_TEMP,BSR ;recupera
el registro BSR
128. movff WREG_TEMP,WREG ;recupera
el registro de trabajo
129. movff STATUS_TEMP,STATUS ;recupera
el registro STATUS
130. retfie
131.
132. ;*****************************************************************
*************
133. ; Rutina de interrupcion de alta prioridad
134. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
135. ; evitar conflictos con el vector de interrupciones de baja
prioridad
136.
137. HighInt:
138.
139. ; *** El codigo para las interrupciones de alta prioridad va
aqui ***
140.
141. retfie FAST
142.
143. ;*****************************************************************
*************
144. ; Comienzo del programa principal
145. ; El codigo del programa principal es colocado aqui
146.
147. Main:
148. ; *** EL codigo principal va aqui ***
149.
150. ;******************** Inicializacion de
perifericos *********************
151. movlw B'01100000'
152. movwf OSCCON ;Ajustamos
el oscilador interno a 4 MHz
153. movlw B'00001111'
154. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
155.
156. clrf TRISD,.0 ;Puerto D
como salida
157.
;Los demas se quedan como entradas
158. ;******************** Inicializacion de
Variables ************************
159. clrf Cont,.0 ;Cont = 0
160.
161. MainP0
162.
163. movf Cont,W,.0 ;W = Cont,
para realizar el despliegue
164. rcall Conv7Seg ;realizamo
s la conversion de BCD a 7 segmentos
165. movwf LATD,.0 ;movemos
el valor convertido al PORT D
166. movlw .1
167. movwf CantSeg ;CantSeg =
1 , para el retardo de 1 seg
168. rcall RetardoSeg ;Esperamos
1 seg
169. incf Cont,F,.0 ;Cont ++
170. movlw 0x0A
171. cpfseq Cont,.0 ;Cont ==
0x0A (Cont==WREG)?
172. bra MainP0 ;N
o => continuamos en el ciclo
173. clrf Cont,.0 ;Si
=> reiniciamos la cuenta (Cont = 0)
174. bra MainP0 ;C
ontinuamos con el ciclo
175.
176. ;********************** Conv7Seg ******************
*************************
177. ; Conv7Seg Esta subrutina maneja realiza el acceso a
la tabla BCD7Seg, recibe
178. ; en W un offset para que sea sumado
a TBLPTRL para asi acceder al
179. ; valor de 7 segmentos correspondiente al valor BCD recibido
en WREG
180. ;
181. ; Devuelve el valor de 7 seg en el registro W.
182. ;*****************************************************************
*****************
183. Conv7Seg
184. movwf TablaOffs,.0 ;Guardamos el
valor BCD recibido
185. movlw UPPER BCD7Seg ;tomamos la parte
mas alta de la dir de la tabla
186. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
187. movlw HIGH BCD7Seg ;tomamos la
parte alta de la dir de la tabla
188. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
189. movlw LOW BCD7Seg ;tomamos
la parte baja de la dir de la tabla
190. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
191.
;apuntado al inicio de la tabla BCD7seg
192. movf TablaOffs,W,.0 ;Nos preparamos
para recorrer la tabla
193. addwf TBLPTRL,F,.0 ;TBLPTR apunta al
valor de 7 seg que necesitamos
194. tblrd * ;L
eemos el valor de la tabla
195. movf TABLAT,W,.0 ;guardamos
el valor leido en WREG
196. return ;r
etornamos
197. ;*****************************************************************
*****************
198.
199. ;**************************** RetardoSeg ******************
****************
200. ; RetardoSeg Realiza una espera de la cantidad de
segundos indicados
201. ; mediante la variable CantSeg.
CantSeg es de 8 bits
202. ;*****************************************************************
************
203. RetardoSeg
204. movf CantSeg,W,.0
205. btfsc STATUS,Z ;CantSeg
== 0?
206. return ;S
i => retornamos
207. movlw 0x03 ;No =>
hacemos Cantms = 1000
208. movwf Cantms+1,.0
209. movlw 0xE8
210. movwf Cantms,.0
211. rcall Retardo_ms ;realizamo
s un retardo de 1000 ms
212. decf CantSeg,F,.0 ;CantSeg --,
213. bra RetardoSeg ;C
ontinuamos con el ciclo
214. ;*****************************************************************
************
215.
216. ;**************************** Retardo_ms ******************
****************
217. ; Retardo_ms Realiza un retardo de la cantidad de
milisegundos indicados
218. ; mediante Cantms y Cantms+1, Cantms
y Cantms+1 son tratados como
219. ; variables de 16 bits.
220. ;*****************************************************************
************
221. Retardo_ms
222. rcall Retardo1ms ;realizamo
s un retardo de 1 ms
223. decfsz Cantms,F,.0 ;Cantms --
, Cantms == 0
224. bra Retardo_ms ;n
o => vamos a Retardo_ms
225. movf Cantms+1,W,.0 ;
226. btfsc STATUS,Z ;Cantms+1
== 0?
227. return ;S
i => retornamos
228. decf Cantms+1,F,.0 ;No =>
decrementamos
229. bra Retardo_ms ;C
ontinuamos con el ciclo
230. ;*****************************************************************
************
231.
232. ;**************************** Retardo1ms ******************
****************
233. ; Retardo1ms realiza una espera de 1 ms decrementado W
249 veces en un ciclo
234. ; que ocupa 4 us
235. ;*****************************************************************
************
236. Retardo1ms
237. movlw .249
238. Retardo1msP0
239. addlw 0xFF ;W--
240. btfss STATUS,Z,.0 ;W == 0?
241. bra Retardo1msP0 ;No =>
seguimos esperando
242. return ;S
i => ya paso 1 ms
243. ;*****************************************************************
************
244.
245.
246. ORG 0x800
247.
248.
249. ;******************************* BCD7Seg **********
*************************
250. ; BCD7Seg Es una tabla que se utiliza para convertir
valores BCD a 7 Segmentos
251. ;
252. ; |RB7|RB6|RB5|RB4 | |RB3|RB2|RB1|RB0| |
253. ; |DP |G |F |E | |D |C
|B |A |Hex|
254. ; |---|---|---|-------|---|---|---|---|---|
255. ; 0 |1 |1 |0 |0 | 0 |0
|0 |0 |C0 |
256. ; 1 |1 |1 |1 |1 | 1 |0 |0
|1 |F9 |
257. ; 2 |1 |0 |1 |0 | 0 |1 |0
|0 |A4 |
258. ; 3 |1 |0 |1 |1 | 0 |0 |0
|0 |B0 |
259. ; 4 |1 |0 |0 |1 | 1 |0 |0
|1 |99 |
260. ; 5 |1 |0 |0 |1 | 0 |0 |1
|0 |92 |
261. ; 6 |1 |0 |0 |0 | 0 |0
|1 |0 |82 |
262. ; 7 |1 |1 |1 |1 | 1 |0
|0 |0 |F8 |
263. ; 8 |1 |0 |0 |0 | 0 |0
|0 |0 |80 |
264. ; 9 |1 |0 |0 |1 | 0 |0
|0 |0 |90 |
265. ;*****************************************************************
*****************
266. BCD7Seg
267. ; 0 1 2 3 4
5 6 7 8 9
268. DB 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x
80,0x90
269. ;*****************************************************************
*****************
270.
271.
272. END ;Directiva fin del
programa

Como no me gusta como se ve en el GeShi aqui les dejo el programa y la simulacion

Saludos
Disp7Seg.rar (10.89 kB - descargado 449 veces.)

En lnea

La electronica es el arte de manipular seales electricas que transportan informacin

Jan Davidse

Visita mi blog

Cryn
Colaborador
DsPIC33

Mensajes: 4169

Re: Ejemplos PIC18F4550


Respuesta #2 en: 08 de Agosto de 2008, 18:56:23

muy bien hecho sander, muy buenas aplicaciones, buena iniciativa, te ha quedado muy bien

felicidades por eso compatriota!


a colocar ms!

un saludo

En lnea

Slalen
Colaborador
PIC24H

Mensajes: 1079

Re: Ejemplos PIC18F4550


Respuesta #3 en: 09 de Agosto de 2008, 05:17:42

Felicidades!!

Te han quedado unos programas muy bien explicados!!!

Sigue as y a ver si consigues controlar el USB con ensamblador

En lnea

http://www.guillehg.com

Cryn
Colaborador
DsPIC33

Mensajes: 4169

Re: Ejemplos PIC18F4550


Respuesta #4 en: 09 de Agosto de 2008, 11:07:24

Citar

controlar el USB con ensamblador

lo mismo iba a decir

esperare eso

En lnea

sander
Colaborador
PIC24F

Mensajes: 606

Re: Ejemplos PIC18F4550


Respuesta #5 en: 17 de Agosto de 2008, 00:34:47

USB en ensamblador? suena interesante , si bien la idea paso por mi mente no habia decidido si
lo hacia o no, asi que decidi comenzar con cosas mas faciles pero ya veremos que pasa, por lo
pronto sigo avanzando y ya he hecho algo con interrupciones y aqui se los dejo.

IntExt1y2.asm

Este programa lo hice para comprobar que una interrupcion definida con alta prioridad puede ser
ejecutada cuando ya se esta ejecutando una interrupcion pero de baja prioridad. Para esto uso la
INT1(RB1) , la INT2(RB2), y un display de 7 segmentos. La INT1 incrementa el display y la INT2
lo decrementa. mas explicaciones estan en el programa.

Cdigo: ASM
1. ;**********************************************************************
********
2. ;
*
3. ; Nombre: IntExt1y2.asm
4. ; Fecha: 09/08/2008
5. ; Version: v0.90
6. ;
*
7. ; Autor: Sander
8. ; Empresa:
9. ;
*
10. ;*****************************************************************
*************
11. ;
*
12. ; Archivos Requeridos: P18F4550.INC
13. ;
*
14. ;*****************************************************************
*************
15. ; Notas: Este programa mostrara el uso de las
interrupciones INT1, INT2
16. ; asignandoles prioridades diferentes a cada una.
17. ;
18. ; El programa controlara un display de 7 segmentos de
acuerdo al estado de dos
19. ; pulsadores que se conectaran a RB1(INT1) y RB2(INT2)
20. ;
21. ; RB1(INT1) hara que el display incremente y su interrupcion
tendra prioridad
22. ; alta
23. ; RB2(INT2) hara que el display decremente y su interrupcion
tendra prioridad
24. ; baja
25. ;
26. ; Para que pueda verse el efecto de la asigancion de
prioridades, es decir, que
27. ; la interrupcion de alta prioridad se ejecute aun cuando
se esta ejecutando
28. ; la interrupcion de baja prioridad, el incremento o
decremento se lo hara en la
29. ; misma rutina de interrupcion.
30. ;
31. ; Para realizar retardos se usaran las rutinas de retardo
del proyecto
32. ; parpadea, el display de 7 segmentos se incrementara de 0 a
F, se habilitaran las
33. ; resistencias de PULL-UP y para convertir el valor BCD que
cuenta se implementara
34. ; una tabla en la memoria de programa usando la directiva DB
35. ;
36. ; La conexion del display de anodo comun , y de los
pulsadores sera como se muestra
37. ; a continuacion
38. ;
39. ; _Vdd_
40. ; |
41. ; ____________|_
42. ; | |
43. ; A(RD0) --
>| AAAAAAA |
44. ; B(RD1) --
>| F B | _|_
45. ; C(RD2) --
>| F B | X-0 0--->
RB1(INT1)
46. ; D(RD3) --
>| F B | |
47. ; | GGGGGG |
| _|_
48. ; E(RD4) --
>| E C | X-0 0---> RB2(INT2)
49. ; F(RD5) --
>| E C | |
50. ; G(RD6) --
>| E C | |
51. ; DP(RD7) --
>| DDDDDDD DP| -GND-
52. ; |______________|
53. ;
54. ;*****************************************************************
*************
55.
56. LIST P=18F4550 ;Directiva para
definir el procesador
57. #include <P18F4550.INC> ;Definicion de SFRs para
el procesador
58.
59. ;*****************************************************************
*************
60. ;Bits de Configuracion
61. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
62. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
63. ;Abajo hay algunos ejemplos
64.
65. ;******** Configuracion del Oscilador **********
66. CONFIG FOSC = INTOSCIO_EC ;Osc interno, RA6 como
pin, USB usa Osc EC
67. ;******** Otros bits de configuracion **********
68. CONFIG PWRT =
ON ;PWRT habilitado
69. CONFIG BOR =
OFF ;Brown out resete
deshabilitado
70. CONFIG WDT =
OFF ;Watch dog deshabilitado
71. CONFIG MCLRE =
OFF ;MCLR como entrada
72. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
73. CONFIG LVP =
OFF ;Programacion en bajo voltaje
apagado
74. ;********* Bits de proteccion ******************
75. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
76. CONFIG CP1 =
OFF ;no estan protegidos
77. CONFIG CP2 = OFF
78. CONFIG CP3 = OFF
79. CONFIG CPB =
OFF ;Sector Boot no esta protegido
80. CONFIG CPD =
OFF ;La EEPROM no esta protegida
81. ;*****************************************************************
*************
82. ; Definicion de variables
83. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
84. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
85. ; interrupcion.
86.
87. CBLOCK 0x080
88. WREG_TEMP ;variable usada para
salvar contexto
89. STATUS_TEMP ;variable usada para
salvar contexto
90. BSR_TEMP ;variable usada para
salvar contexto
91. ENDC
92.
93. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco
0) max 96 bytes
94. Cantms:2 ;variable para generar
hasta 65535 ms
95. CantSeg ;Variable para producir
retardos de hasta 255 seg
96. Cont ;Variable para realizar el
conteo
97. TablaOffs ;Para movernos por la
tabla
98. ENDC
99.
100. #DEFINE BotU PORTB,.1
101. #DEFINE BotD PORTB,.2
102.
103. ;*****************************************************************
*************
104. ;Datos de la EEPROM
105. ;Los Datos a ser programados en la EEPROM son definidos aqui
106.
107. ORG 0xf00000
108.
109. DE "Test Data",0,1,2,3,4,5
110.
111. ;*****************************************************************
*************
112. ; Vector de Reset.
113. ; Este codigo comenzara a ejecutarse cuando suceda un reset
114.
115. ORG 0x0000
116.
117. goto Main ;Se va al inicio del
codigo principal
118.
119. ;*****************************************************************
*************
120. ; Vector de interrupcion de alta prioridad
121. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
122. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
123. ; no estan habilitadas
124.
125. ORG 0x0008
126.
127. bra HighInt
;Va a la rutina de interrupcion de alta prioridad
128.
129. ;*****************************************************************
*************
130. ; Vector de interrupcion de baja prioridad y rutina
131. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
132. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
133.
134. ORG 0x0018
135.
136. movff STATUS,STATUS_TEMP ;Salva el
registro STATUS
137. movff WREG,WREG_TEMP ;Salva el
registro de trabajo
138. movff BSR,BSR_TEMP ;Salva el
registro BSR
139. ;********* El codigo de la interrupcion de baja prioridad va aqui
**************
140.
141. btfsc INTCON3,INT2IF,.0 ;INT2IF ==
1?(ocurrio la INT2?)
142. bra IntINT2
;Si => vamos a su rutina
143. movlw B'10110110' ;N
o => un error extrao sucedio,encedemos los
144. movwf LATD,.0 ;s
egmentos A,D y G para indicarlo y detenemos
145. bcf INTCON,GIEH
;la ejecucion el programa
146. bcf INTCON,GIEL

147. sleep
148. IntINT2
149. clrf Cantms+1,.0
150. movlw .50
;Hacemos un retardo de 50 ms para antirrebote
151. movwf Cantms,.0
152. rcall Retardo_ms
153. IntINT2_0
154. btfsc BotD ;S
igue presionado el boton de decremento?
155. bra IntINT2_X
;No => vamos a salir de esta interrupcion
156. decf Cont,F,.0 ;S
i => Cont --
157. movlw 0xFF
158. cpfseq Cont,.0 ;C
ont == 0xFF (Cont==WREG)?
159. bra IntINT2_00
;No => vamos a actualizar el display
160. movlw 0x0F ;S
i => reiniciamos el decremento
161. movwf Cont,.0 ;
y continuamos actualizando el display
162. IntINT2_00
163. movf Cont,W,.0 ;W
= Cont, para realizar el despliegue
164. rcall Conv7Seg ;r
ealizamos la conversion de BCD a 7 segmentos
165. movwf LATD,.0 ;m
ovemos el valor convertido al PORT D
166. movlw .1
167. movwf CantSeg,.0 ;r
ealizamos una espera de 1 seg, para
168. rcall RetardoSeg ;v
er el cambio en el display
169. bra IntINT2_0
;volvemos a revisar el boton
170. IntINT2_X
171. bcf INTCON3,INT2IF ;P
ara dar por terminada la interrupcion y
172.
;salir de las interrupciones de baja prioridad
173. X_IntLow
174. movff BSR_TEMP,BSR ;recupera
el registro BSR
175. movff WREG_TEMP,WREG ;recupera
el registro de trabajo
176. movff STATUS_TEMP,STATUS ;recupera
el registro STATUS
177. retfie
178. ;*****************************************************************
*************
179. ; Rutina de interrupcion de alta prioridad
180. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
181. ; evitar conflictos con el vector de interrupciones de baja
prioridad
182.
183. HighInt:
184.
185. ; *** El codigo para las interrupciones de alta prioridad va
aqui ***
186. btfsc INTCON3,INT1IF,.0 ;INT1IF ==
1?(ocurrio la INT1?)
187. bra IntINT1
;Si => vamos a su rutina
188. movlw B'10110110' ;N
o => un error extrao sucedio,encedemos los
189. movwf LATD,.0 ;s
egmentos A,D y G para indicarlo y detenemos
190. bcf INTCON,GIEH
;la ejecucion el programa
191. bcf INTCON,GIEL

192. sleep
193. IntINT1
194. clrf Cantms+1,.0
195. movlw .50
;Hacemos un retardo de 50 ms para antirrebote
196. movwf Cantms,.0
197. rcall Retardo_ms
198. IntINT1_0
199. btfsc BotU ;S
igue presionado el boton de incremento?
200. bra IntINT1_X
;No => vamos a salir de esta interrupcion
201. incf Cont,F,.0 ;S
i => Cont ++
202. movlw 0x10
203. cpfseq Cont,.0 ;C
ont == 0x10 (Cont==WREG)?
204. bra IntINT1_00
;No => vamos a actualizar el display
205. clrf Cont,.0 ;S
i => reiniciamos el incremento
206.
; y continuamos actualizando el display
207. IntINT1_00
208. movf Cont,W,.0 ;W
= Cont, para realizar el despliegue
209. rcall Conv7Seg ;r
ealizamos la conversion de BCD a 7 segmentos
210. movwf LATD,.0 ;m
ovemos el valor convertido al PORT D
211. movlw .1
212. movwf CantSeg,.0 ;r
ealizamos una espera de 1 seg, para
213. rcall RetardoSeg ;v
er el cambio en el display
214. bra IntINT1_0
;volvemos a revisar el boton
215. IntINT1_X
216. bcf INTCON3,INT1IF ;P
ara dar por terminada la interrupcion y
217.
;salir de las interrupciones de alta prioridad
218. X_IntHigh
219. retfie FAST
220.
221. ;*****************************************************************
*************
222. ; Comienzo del programa principal
223. ; El codigo del programa principal es colocado aqui
224.
225. Main:
226. ; *** EL codigo principal va aqui ***
227.
228. ;******************** Inicializacion de
perifericos *********************
229. movlw B'01100000'
230. movwf OSCCON ;Ajustamos
el oscilador interno a 4 MHz
231. movlw B'00001111'
232. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
233.
234. clrf TRISD,.0 ;Puerto D
como salida
235.
;Los demas se quedan como entradas
236. movlw B'01000101' ;habilitam
os PULL-UPs(bit 7), y hacemos que
237. movwf INTCON2,.0 ;INT1 e
INT2 se activen en flanco de bajada
238.
;(Bits 4 y 5), lo demas se queda como estaba
239. movlw B'01011000' ;Asignamos
prioridades(Bits 7 y 6), y habilitamos
240. movwf INTCON3,.0 ;las
interrupciones para INT1 e INT2 (bits 3 y 4)
241.
242. bsf RCON,IPEN,.0 ;Habilitam
os las prioridades para las interrupciones
243.
244. ;******************** Inicializacion de
Variables ************************
245. clrf Cont,.0 ;Cont = 0
246. ;*****************************************************************
**********
247. bsf INTCON,GIEH,.0 ;Habilitam
os las interrupciones de prioridad alta
248. bsf INTCON,GIEL,.0 ;y las de
prioridad baja
249.
250. movf Cont,W,.0 ;W = Cont,
para realizar el despliegue
251. rcall Conv7Seg ;realizamo
s la conversion de BCD a 7 segmentos
252. movwf LATD,.0 ;movemos
el valor convertido al PORT D
253.
254. MainP0
255.
256. bra MainP0 ;C
ontinuamos con el ciclo
257.
258. ;********************** Conv7Seg ******************
*************************
259. ; Conv7Seg Esta subrutina maneja realiza el acceso a
la tabla BCD7Seg, recibe
260. ; en W un offset para que sea sumado
a TBLPTRL para asi acceder al
261. ; valor de 7 segmentos correspondiente al valor BCD recibido
en WREG
262. ;
263. ; Devuelve el valor de 7 seg en el registro W.
264. ;*****************************************************************
*****************
265. Conv7Seg
266. movwf TablaOffs,.0 ;Guardamos el
valor BCD recibido
267. movlw UPPER BCD7Seg ;tomamos la parte
mas alta de la dir de la tabla
268. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
269. movlw HIGH BCD7Seg ;tomamos la
parte alta de la dir de la tabla
270. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
271. movlw LOW BCD7Seg ;tomamos
la parte baja de la dir de la tabla
272. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
273.
;apuntado al inicio de la tabla BCD7seg
274. movf TablaOffs,W,.0 ;Nos preparamos
para recorrer la tabla
275. addwf TBLPTRL,F,.0 ;TBLPTR apunta al
valor de 7 seg que necesitamos
276. tblrd * ;L
eemos el valor de la tabla
277. movf TABLAT,W,.0 ;guardamos
el valor leido en WREG
278. return ;r
etornamos
279. ;*****************************************************************
*****************
280.
281. ;**************************** RetardoSeg ******************
****************
282. ; RetardoSeg Realiza una espera de la cantidad de
segundos indicados
283. ; mediante la variable CantSeg.
CantSeg es de 8 bits
284. ;*****************************************************************
************
285. RetardoSeg
286. movf CantSeg,W,.0
287. btfsc STATUS,Z ;CantSeg
== 0?
288. return ;S
i => retornamos
289. movlw 0x03 ;No =>
hacemos Cantms = 1000
290. movwf Cantms+1,.0
291. movlw 0xE8
292. movwf Cantms,.0
293. rcall Retardo_ms ;realizamo
s un retardo de 1000 ms
294. decf CantSeg,F,.0 ;CantSeg --,
295. bra RetardoSeg ;C
ontinuamos con el ciclo
296. ;*****************************************************************
************
297.
298. ;**************************** Retardo_ms ******************
****************
299. ; Retardo_ms Realiza un retardo de la cantidad de
milisegundos indicados
300. ; mediante Cantms y Cantms+1, Cantms
y Cantms+1 son tratados como
301. ; variables de 16 bits.
302. ;*****************************************************************
************
303. Retardo_ms
304. rcall Retardo1ms ;realizamo
s un retardo de 1 ms
305. decfsz Cantms,F,.0 ;Cantms --
, Cantms == 0
306. bra Retardo_ms ;n
o => vamos a Retardo_ms
307. movf Cantms+1,W,.0 ;
308. btfsc STATUS,Z ;Cantms+1
== 0?
309. return ;S
i => retornamos
310. decf Cantms+1,F,.0 ;No =>
decrementamos
311. bra Retardo_ms ;C
ontinuamos con el ciclo
312. ;*****************************************************************
************
313.
314. ;**************************** Retardo1ms ******************
****************
315. ; Retardo1ms realiza una espera de 1 ms decrementado W
249 veces en un ciclo
316. ; que ocupa 4 us
317. ;*****************************************************************
************
318. Retardo1ms
319. movlw .249
320. Retardo1msP0
321. addlw 0xFF ;W--
322. btfss STATUS,Z,.0 ;W == 0?
323. bra Retardo1msP0 ;No =>
seguimos esperando
324. return ;S
i => ya paso 1 ms
325. ;*****************************************************************
************
326.
327.
328. ORG 0x800
329.
330.
331. ;******************************* BCD7Seg **********
*************************
332. ; BCD7Seg Es una tabla que se utiliza para convertir
valores BCD a 7 Segmentos
333. ;
334. ; |RB7|RB6|RB5|RB4 | |RB3|RB2|RB1|RB0| |
335. ; |DP |G |F |E | |D |C
|B |A |Hex|
336. ; |---|---|---|-------|---|---|---|---|---|
337. ; 0 |1 |1 |0 |0 | 0 |0
|0 |0 |C0 |
338. ; 1 |1 |1 |1 |1 | 1 |0 |0
|1 |F9 |
339. ; 2 |1 |0 |1 |0 | 0 |1 |0
|0 |A4 |
340. ; 3 |1 |0 |1 |1 | 0 |0 |0
|0 |B0 |
341. ; 4 |1 |0 |0 |1 | 1 |0 |0
|1 |99 |
342. ; 5 |1 |0 |0 |1 | 0 |0 |1
|0 |92 |
343. ; 6 |1 |0 |0 |0 | 0 |0
|1 |0 |82 |
344. ; 7 |1 |1 |1 |1 | 1 |0
|0 |0 |F8 |
345. ; 8 |1 |0 |0 |0 | 0 |0
|0 |0 |80 |
346. ; 9 |1 |0 |0 |1 | 0 |0
|0 |0 |90 |
347. ; A |1 |0 |0 |0 | 1 |0
|0 |0 |88 |
348. ; B |1 |0 |0 |0 | 0 |0
|1 |1 |83 |
349. ; C |1 |1 |0 |0 | 0 |1
|1 |0 |C6 |
350. ; D |1 |0 |1 |0 | 0 |0
|0 |1 |A1 |
351. ; E |1 |0 |0 |0 | 0 |1
|1 |0 |86 |
352. ; F |1 |0 |0 |0 | 1 |1
|1 |0 |8E |
353. ;*****************************************************************
*****************
354. BCD7Seg
355. ; 0 1 2 3 4
5 6 7 8 9 A B C
D E F
356. DB 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x
80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
357. ;*****************************************************************
*****************
358.
359.
360. END ;Directiva fin del
programa
Notas

Simulando en el MPLAB pude notar que cuando se pasaba de la INT2 a la INT1 y luego se
retornaba a la INT2 ,el programa como que se colgaba, pero en realidad solo se tenia que
esperar unos 255 seg, esto porque las rutinas de interrupcion comparten rutinas de
retardo y al volver de la INT1 las variables usadas en las rutinas de retardo toman otros
valores.
La version del PROTEUS que uso (7.2 SP0) no simula correctamente las resistencias
internas de PULLUP del este PIC en los pines RB0 y RB1.

Bueno finalmente aqui les dejo el circuito para la simulacion y el programa

IntExt1y2.rar (17.92 kB - descargado 206 veces.)


En lnea

La electronica es el arte de manipular seales electricas que transportan informacin

Jan Davidse

Visita mi blog

sander
Colaborador
PIC24F

Mensajes: 606

Re: Ejemplos PIC18F4550


Respuesta #6 en: 17 de Agosto de 2008, 00:47:56

IntExt1y2_1

Bueno , este programa lo hice para corregir el fallo que apunte en la nota 1 para el anterior
programa, para corregir este fallo se debe guardar las variables de retardo o talvez usar rutinas
de retardo independientes para cada rutina de interrupcion , yo me incline por la primera opcion,
y utilizo la pila para guardar estas variables, ya que los PIC18 permiten acceder a la Pila hay que
usar esta caracteristica.

Cdigo: ASM

1. ;**********************************************************************
********
2. ;
*
3. ; Nombre: IntExt1y2_1.asm
4. ; Fecha: 12/08/2008
5. ; Version: v1.00
6. ;
*
7. ; Autor: Sander
8. ; Empresa:
9. ;
*
10. ;*****************************************************************
*************
11. ;
*
12. ; Archivos Requeridos: P18F4550.INC
13. ;
*
14. ;*****************************************************************
*************
15. ; Notas: Este programa mostrara el uso de las
interrupciones INT1, INT2
16. ; asignandoles prioridades diferentes a cada una.
17. ;
18. ; El programa controlara un display de 7 segmentos de
acuerdo al estado de dos
19. ; pulsadores que se conectaran a RB1(INT1) y RB2(INT2)
20. ;
21. ; RB1(INT1) hara que el display incremente y su interrupcion
tendra prioridad
22. ; alta
23. ; RB2(INT2) hara que el display decremente y su interrupcion
tendra prioridad
24. ; baja
25. ;
26. ; Para que pueda verse el efecto de la asigancion de
prioridades, es decir, que
27. ; la interrupcion de alta prioridad se ejecute aun cuando
se esta ejecutando
28. ; la interrupcion de baja prioridad, el incremento o
decremento se lo hara en la
29. ; misma rutina de interrupcion.
30. ;
31. ; Para realizar retardos se usaran las rutinas de retardo
del proyecto
32. ; parpadea, el display de 7 segmentos se incrementara de 0 a
F, se habilitaran las
33. ; resistencias de PULL-UP y para convertir el valor BCD que
cuenta se implementara
34. ; una tabla en la memoria de programa usando la directiva DB
35. ;
36. ; La conexion del display de anodo comun , y de los
pulsadores sera como se muestra
37. ; a continuacion
38. ;
39. ; _Vdd_
40. ; |
41. ; ____________|_
42. ; | |
43. ; A(RD0) --
>| AAAAAAA |
44. ; B(RD1) --
>| F B | _|_
45. ; C(RD2) --
>| F B | X-0 0--->
RB1(INT1)
46. ; D(RD3) --
>| F B | |
47. ; | GGGGGG |
| _|_
48. ; E(RD4) --
>| E C | X-0 0---> RB2(INT2)
49. ; F(RD5) --
>| E C | |
50. ; G(RD6) --
>| E C | |
51. ; DP(RD7) --
>| DDDDDDD DP| -GND-
52. ; |______________|
53. ;
54.
55. ; Esta version corrige los errores vistos en la simulacion
al momento
56. ; de pasar de la interrupcion de baja prioridad a la de alta
prioridad, para esto
57. ; usaremos la bandera IntHigh_F que le indicara a la
interrupcion de baja
58. ; prioridad que se produjo una interrupcion de alta
prioridad, ademas guardaremos
59. ; las variables que son compartidas por ambas interrupciones
en la PILA
60. ;*****************************************************************
*************
61.
62. LIST P=18F4550 ;Directiva para
definir el procesador
63. #include <P18F4550.INC> ;Definicion de SFRs para
el procesador
64.
65. ;*****************************************************************
*************
66. ;Bits de Configuracion
67. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
68. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
69. ;Abajo hay algunos ejemplos
70.
71. ;******** Configuracion del Oscilador **********
72. CONFIG FOSC = INTOSCIO_EC ;Osc interno, RA6 como
pin, USB usa Osc EC
73. ;******** Otros bits de configuracion **********
74. CONFIG PWRT =
ON ;PWRT habilitado
75. CONFIG BOR =
OFF ;Brown out resete
deshabilitado
76. CONFIG WDT =
OFF ;Watch dog deshabilitado
77. CONFIG MCLRE =
OFF ;MCLR como entrada
78. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
79. CONFIG LVP =
OFF ;Programacion en bajo voltaje
apagado
80. ;********* Bits de proteccion ******************
81. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
82. CONFIG CP1 =
OFF ;no estan protegidos
83. CONFIG CP2 = OFF
84. CONFIG CP3 = OFF
85. CONFIG CPB =
OFF ;Sector Boot no esta protegido
86. CONFIG CPD =
OFF ;La EEPROM no esta protegida
87. ;*****************************************************************
*************
88. ; Definicion de variables
89. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
90. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
91. ; interrupcion.
92.
93. CBLOCK 0x080
94. WREG_TEMP ;variable usada para salvar
contexto
95. STATUS_TEMP ;variable usada para salvar
contexto
96. BSR_TEMP ;variable usada para salvar
contexto
97. ENDC
98.
99. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco 0) max
96 bytes
100. Cantms:2 ;variable para generar hasta 65535
ms
101. CantSeg ;Variable para producir retardos
de hasta 255 seg
102. Cont ;Variable para realizar el conteo
103. Banderas ;Variable para el manejo de
banderas, que controlan la ejecucion
104. TablaOffs ;Para movernos por la tabla
105. ENDC
106.
107. #DEFINE BotU PORTB,.1
108. #DEFINE BotD PORTB,.2
109.
110. #DEFINE IntHigh_F Banderas,.0,.0
111. ;*****************************************************************
*************
112. ;Datos de la EEPROM
113. ;Los Datos a ser programados en la EEPROM son definidos aqui
114.
115. ORG 0xf00000
116.
117. DE "Test Data",0,1,2,3,4,5
118.
119. ;*****************************************************************
*************
120. ; Vector de Reset.
121. ; Este codigo comenzara a ejecutarse cuando suceda un reset
122.
123. ORG 0x0000
124.
125. goto Main ;Se va al inicio del codigo
principal
126.
127. ;*****************************************************************
*************
128. ; Vector de interrupcion de alta prioridad
129. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
130. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
131. ; no estan habilitadas
132.
133. ORG 0x0008
134.
135. bra HighInt ;V
a a la rutina de interrupcion de alta prioridad
136.
137. ;*****************************************************************
*************
138. ; Vector de interrupcion de baja prioridad y rutina
139. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
140. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
141.
142. ORG 0x0018
143.
144. movff STATUS,STATUS_TEMP ;Salva el registro
STATUS
145. movff WREG,WREG_TEMP ;Salva el registro
de trabajo
146. movff BSR,BSR_TEMP ;Salva el registro
BSR
147. ;********* El codigo de la interrupcion de baja prioridad va aqui
**************
148.
149. btfsc INTCON3,INT2IF,.0 ;INT2IF ==
1?(ocurrio la INT2?)
150. bra IntINT2 ;S
i => vamos a su rutina
151. movlw B'10110110' ;No => un
error extrao sucedio,encedemos los
152. movwf LATD,.0 ;segmentos
A,D y G para indicarlo y detenemos
153. bcf INTCON,GIEH ;l
a ejecucion el programa
154. bcf INTCON,GIEL
155. sleep
156. IntINT2
157. clrf Cantms+1,.0
158. movlw .50 ;H
acemos un retardo de 50 ms para antirrebote
159. movwf Cantms,.0
160. rcall Retardo_ms
161. IntINT2_0
162. bcf IntHigh_F ;p
onemos en cero esta bandera, por si venimos
163.
;de la interrupcion alta
164. btfsc BotD ;Sigue
presionado el boton de decremento?
165. bra IntINT2_X ;N
o => vamos a salir de esta interrupcion
166. btfsc IntHigh_F ;Se
produjo una interrupcion de mayor prioridad?
167. bra IntINT2_0 ;S
i => usamos el valor de Cont que dejo la int alta
168. decf Cont,F,.0 ;Si =>
Cont --
169. movlw 0xFF
170. cpfseq Cont,.0 ;Cont ==
0xFF (Cont==WREG)?
171. bra IntINT2_00 ;N
o => vamos a actualizar el display
172. movlw 0x0F ;Si =>
reiniciamos el decremento
173. movwf Cont,.0 ; y
continuamos actualizando el display
174. IntINT2_00
175. movf Cont,W,.0 ;W = Cont,
para realizar el despliegue
176. rcall Conv7Seg ;realizamo
s la conversion de BCD a 7 segmentos
177. btfsc IntHigh_F ;Se
produjo una interrupcion de mayor prioridad?
178. bra IntINT2_0 ;S
i => usamos el valor de Cont que dejo la int alta
179. movwf LATD,.0 ;No =>
movemos el valor convertido al PORT D
180. movlw .1
181. movwf CantSeg,.0 ;realizamo
s una espera de 1 seg, para
182. rcall RetardoSeg ;ver el
cambio en el display
183. bra IntINT2_0 ;v
olvemos a revisar el boton
184. IntINT2_X
185. bcf INTCON3,INT2IF ;Para dar
por terminada la interrupcion y
186.
;salir de las interrupciones de baja prioridad
187. X_IntLow
188. movff BSR_TEMP,BSR ;recupera el
registro BSR
189. movff WREG_TEMP,WREG ;recupera el
registro de trabajo
190. movff STATUS_TEMP,STATUS ;recupera el
registro STATUS
191. retfie
192. ;*****************************************************************
*************
193. ; Rutina de interrupcion de alta prioridad
194. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
195. ; evitar conflictos con el vector de interrupciones de baja
prioridad
196.
197. HighInt:
198. ;****** El codigo para las interrupciones de alta prioridad va
aqui ******
199.
200. push ;P
ara comenzar a guarda las variables que se
201.
;comparten en la pila, primero apilamos la direccion
202.
;actual
203.
204. movf Cantms,W,.0 ;Guardamos
Cantms en la parte baja del
205. movwf TOSL ;Top Of
Stack
206. movf Cantms+1,W,.0 ;Guardamos
Cantms+1 en la parte alta del
207. movwf TOSH ;Top Of
Stack
208.
209. push ;a
pilamos la direccion actual
210. movf CantSeg,W,.0 ;Guardamos Cantms
en la parte baja del
211. movwf TOSL ;Top Of
Stack
212.
213. btfsc INTCON3,INT1IF,.0 ;INT1IF ==
1?(ocurrio la INT1?)
214. bra IntINT1 ;S
i => vamos a su rutina
215. movlw B'10110110' ;No => un
error extrao sucedio,encedemos los
216. movwf LATD,.0 ;segmentos
A,D y G para indicarlo y detenemos
217. bcf INTCON,GIEH ;l
a ejecucion el programa
218. bcf INTCON,GIEL
219. sleep
220. IntINT1
221. clrf Cantms+1,.0
222. movlw .50 ;H
acemos un retardo de 50 ms para antirrebote
223. movwf Cantms,.0
224. rcall Retardo_ms
225. IntINT1_0
226. btfsc BotU ;Sigue
presionado el boton de incremento?
227. bra IntINT1_X ;N
o => vamos a salir de esta interrupcion
228. incf Cont,F,.0 ;Si =>
Cont ++
229. movlw 0x10
230. cpfseq Cont,.0 ;Cont ==
0x10 (Cont==WREG)?
231. bra IntINT1_00 ;N
o => vamos a actualizar el display
232. clrf Cont,.0 ;Si =>
reiniciamos el incremento
233.
; y continuamos actualizando el display
234. IntINT1_00
235. movf Cont,W,.0 ;W = Cont,
para realizar el despliegue
236. rcall Conv7Seg ;realizamo
s la conversion de BCD a 7 segmentos
237. movwf LATD,.0 ;movemos
el valor convertido al PORT D
238. movlw .1
239. movwf CantSeg,.0 ;realizamo
s una espera de 1 seg, para
240. rcall RetardoSeg ;ver el
cambio en el display
241. bra IntINT1_0 ;v
olvemos a revisar el boton
242. IntINT1_X
243. ;************ Recuperamos los valores de la
pila ****************
244. movff TOSL,CantSeg ;Recuperamos el
valor guardado, primero CantSeg
245. pop
;El pop efectivamente decrementa el STKPTR y
246.
;descarta e valor de TOS
247.
248. movff TOSL,Cantms ;Recuperam
os Cantms
249. movff TOSH,Cantms+1 ;y Cantms+1
250. pop
;STKPTR --, y descartamos TOS
251.
252. bcf INTCON3,INT1IF ;Para dar
por terminada la interrupcion y
253.
;salir de las interrupciones de alta prioridad
254. bsf IntHigh_F ;p
onemos en 1 esta bandera par indicar que se produjo
255.
;esta interrupcion
256. X_IntHigh
257. retfie FAST
258.
259. ;*****************************************************************
*************
260. ; Comienzo del programa principal
261. ; El codigo del programa principal es colocado aqui
262.
263. Main:
264. ; *** EL codigo principal va aqui ***
265.
266. ;******************** Inicializacion de
perifericos *********************
267. movlw B'01100000'
268. movwf OSCCON ;Ajustamos
el oscilador interno a 4 MHz
269. movlw B'00001111'
270. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
271.
272. clrf TRISD,.0 ;Puerto D
como salida
273.
;Los demas se quedan como entradas
274. movlw B'01000101' ;habilitam
os PULL-UPs(bit 7), y hacemos que
275. movwf INTCON2,.0 ;INT1 e
INT2 se activen en flanco de bajada
276.
;(Bits 4 y 5), lo demas se queda como estaba
277. movlw B'01011000' ;Asignamos
prioridades(Bits 7 y 6), y habilitamos
278. movwf INTCON3,.0 ;las
interrupciones para INT1 e INT2 (bits 3 y 4)
279.
280. bsf RCON,IPEN,.0 ;Habilitam
os las prioridades para las interrupciones
281.
282. ;******************** Inicializacion de
Variables ************************
283. clrf Cont,.0 ;Cont = 0
284. clrf Banderas,.0 ;Banderas
= 0
285. ;*****************************************************************
**********
286. bsf INTCON,GIEH,.0 ;Habilitam
os las interrupciones de prioridad alta
287. bsf INTCON,GIEL,.0 ;y las de
prioridad baja
288.
289. movf Cont,W,.0 ;W = Cont,
para realizar el primer despliegue
290. rcall Conv7Seg ;realizamo
s la conversion de BCD a 7 segmentos
291. movwf LATD,.0 ;movemos
el valor convertido al PORT D
292.
293. MainP0
294.
295. bra MainP0 ;C
ontinuamos con el ciclo, esperando que las
296.
;interrupciones cambien el valor del display
297.
298.
299. ;********************** Conv7Seg ******************
*************************
300. ; Conv7Seg Esta subrutina maneja realiza el acceso a
la tabla BCD7Seg, recibe
301. ; en W un offset para que sea sumado
a TBLPTRL para asi acceder al
302. ; valor de 7 segmentos correspondiente al valor BCD recibido
en WREG
303. ;
304. ; Devuelve el valor de 7 seg en el registro W.
305. ;*****************************************************************
*****************
306. Conv7Seg
307. movwf TablaOffs,.0 ;Guardamos el
valor BCD recibido
308. movlw UPPER BCD7Seg ;tomamos la parte
mas alta de la dir de la tabla
309. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
310. movlw HIGH BCD7Seg ;tomamos la
parte alta de la dir de la tabla
311. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
312. movlw LOW BCD7Seg ;tomamos
la parte baja de la dir de la tabla
313. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
314.
;apuntado al inicio de la tabla BCD7seg
315. movf TablaOffs,W,.0 ;Nos preparamos
para recorrer la tabla
316. addwf TBLPTRL,F,.0 ;TBLPTR apunta al
valor de 7 seg que necesitamos
317. tblrd * ;L
eemos el valor de la tabla
318. movf TABLAT,W,.0 ;guardamos
el valor leido en WREG
319. return ;r
etornamos
320. ;*****************************************************************
*****************
321.
322. ;**************************** RetardoSeg ******************
****************
323. ; RetardoSeg Realiza una espera de la cantidad de
segundos indicados
324. ; mediante la variable CantSeg.
CantSeg es de 8 bits
325. ;*****************************************************************
************
326. RetardoSeg
327. movf CantSeg,W,.0
328. btfsc STATUS,Z ;CantSeg
== 0?
329. return ;S
i => retornamos
330. movlw 0x03 ;No =>
hacemos Cantms = 1000
331. movwf Cantms+1,.0
332. movlw 0xE8
333. movwf Cantms,.0
334. rcall Retardo_ms ;realizamo
s un retardo de 1000 ms
335. decf CantSeg,F,.0 ;CantSeg --,
336. bra RetardoSeg ;C
ontinuamos con el ciclo
337. ;*****************************************************************
************
338.
339. ;**************************** Retardo_ms ******************
****************
340. ; Retardo_ms Realiza un retardo de la cantidad de
milisegundos indicados
341. ; mediante Cantms y Cantms+1, Cantms
y Cantms+1 son tratados como
342. ; variables de 16 bits.
343. ;*****************************************************************
************
344. Retardo_ms
345. rcall Retardo1ms ;realizamo
s un retardo de 1 ms
346. decfsz Cantms,F,.0 ;Cantms --
, Cantms == 0
347. bra Retardo_ms ;n
o => vamos a Retardo_ms
348. movf Cantms+1,W,.0 ;
349. btfsc STATUS,Z ;Cantms+1
== 0?
350. return ;S
i => retornamos
351. decf Cantms+1,F,.0 ;No =>
decrementamos
352. bra Retardo_ms ;C
ontinuamos con el ciclo
353. ;*****************************************************************
************
354.
355. ;**************************** Retardo1ms ******************
****************
356. ; Retardo1ms realiza una espera de 1 ms decrementado W
249 veces en un ciclo
357. ; que ocupa 4 us
358. ;*****************************************************************
************
359. Retardo1ms
360. movlw .249
361. Retardo1msP0
362. addlw 0xFF ;W--
363. btfss STATUS,Z,.0 ;W == 0?
364. bra Retardo1msP0 ;No =>
seguimos esperando
365. return ;S
i => ya paso 1 ms
366. ;*****************************************************************
************
367.
368.
369. ORG 0x800
370.
371.
372. ;******************************* BCD7Seg **********
*************************
373. ; BCD7Seg Es una tabla que se utiliza para convertir
valores BCD a 7 Segmentos
374. ;
375. ; |RB7|RB6|RB5|RB4 | |RB3|RB2|RB1|RB0| |
376. ; |DP |G |F |E | |D |C
|B |A |Hex|
377. ; |---|---|---|-------|---|---|---|---|---|
378. ; 0 |1 |1 |0 |0 | 0 |0
|0 |0 |C0 |
379. ; 1 |1 |1 |1 |1 | 1 |0 |0
|1 |F9 |
380. ; 2 |1 |0 |1 |0 | 0 |1 |0
|0 |A4 |
381. ; 3 |1 |0 |1 |1 | 0 |0 |0
|0 |B0 |
382. ; 4 |1 |0 |0 |1 | 1 |0 |0
|1 |99 |
383. ; 5 |1 |0 |0 |1 | 0 |0 |1
|0 |92 |
384. ; 6 |1 |0 |0 |0 | 0 |0
|1 |0 |82 |
385. ; 7 |1 |1 |1 |1 | 1 |0
|0 |0 |F8 |
386. ; 8 |1 |0 |0 |0 | 0 |0
|0 |0 |80 |
387. ; 9 |1 |0 |0 |1 | 0 |0
|0 |0 |90 |
388. ; A |1 |0 |0 |0 | 1 |0
|0 |0 |88 |
389. ; B |1 |0 |0 |0 | 0 |0
|1 |1 |83 |
390. ; C |1 |1 |0 |0 | 0 |1
|1 |0 |C6 |
391. ; D |1 |0 |1 |0 | 0 |0
|0 |1 |A1 |
392. ; E |1 |0 |0 |0 | 0 |1
|1 |0 |86 |
393. ; F |1 |0 |0 |0 | 1 |1
|1 |0 |8E |
394. ;*****************************************************************
*****************
395. BCD7Seg
396. ; 0 1 2 3 4 5
6 7 8 9 A B C
D E F
397. DB 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
0x88,0x83,0xC6,0xA1,0x86,0x8E
398. ;*****************************************************************
*****************
399.
400.
401. END ;Directiva fin del
programa

Como el circuito para la simulacion es el mismo que el anterior les dejo solo el programa

Saludos
IntExt1y2_1.rar (5.11 kB - descargado 152 veces.)

En lnea

La electronica es el arte de manipular seales electricas que transportan informacin

Jan Davidse
Visita mi blog

Lock
PIC10

Mensajes: 3

Re: Ejemplos PIC18F4550


Respuesta #7 en: 18 de Agosto de 2008, 09:28:28

Cita de: sander en 07 de Agosto de 2008, 23:27:57

He comenzado a usar este microcontrolador y para aprender un poco mas de las nuevas
cosas que trae la arquitectura he decidido realizar algunos programas en ensamblador. por
el momento solo llevo dos probados en el Proteus y en un protoboard, y los coloco a
continuacion a disposicion del foro

Parpadea.asm

Este programa simplemente realiza un parpadeo de 1 segundo de todos los pines del
microcontrolador, para este programa uso el oscilador interno configurado a 4 MHz , y
deshabilito el MCLR, (pero este puede usarse solo como entrada ).

Cdigo: ASM

1. ;**********************************************************************
********
2. ;
*
3. ; Nombre: parpadea.asm
4. ; Fecha: 30-07-2008
5. ; Version: V1.00
6. ;
*
7. ; Autor: Sander
8. ; Empresa:
9. ;
*
10. ;*****************************************************************
*************
11. ;
*
12. ; Archivos Requeridos: P18F4550.INC
13. ;
*
14. ;*****************************************************************
*************
15. ; Notas:Este programa implementa rutinas de retardos de 1
ms, 1 seg
16. ; para asi poder realizar un parpadeo de 1 seg de todos los
pines del
17. ; PIC18F4550, estas rutinas estan hechas para un oscilador
de 4 MHz
18. ;*****************************************************************
*************
19.
20. LIST P=18F4550 ;Directiva para definir el
procesador
21. #include <P18F4550.INC> ;Definicion de SFRs para el
procesador
22.
23. ;*****************************************************************
*************
24. ;Bits de Configuracion
25. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
26. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
27. ;Abajo hay algunos ejemplos
28.
29. ;******** Configuracion del Oscilador **********
30. CONFIG FOSC = INTOSCIO_EC ;Osc interno, RA6 como
pin, USB usa Osc EC
31. ;******** Otros bits de configuracion **********
32. CONFIG PWRT =
ON ;PWRT habilitado
33. CONFIG BOR =
OFF ;Brown out reset deshabilitado
34. CONFIG WDT =
OFF ;Watchdog deshabilitado
35. CONFIG MCLRE =
OFF ;MCLR como entrada
36. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
37. CONFIG LVP =
OFF ;Programacion en bajo voltaje
apagado
38. ;********* Bits de proteccion ******************
39. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
40. CONFIG CP1 =
OFF ;no estan protegidos
41. CONFIG CP2 = OFF
42. CONFIG CP3 = OFF
43. CONFIG CPB =
OFF ;Sector Boot no esta protegido
44. CONFIG CPD =
OFF ;La EEPROM no esta protegida
45.
46.
47. ;*****************************************************************
*************
48. ; Definicion de variables
49. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
50. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
51. ; interrupcion.
52.
53. CBLOCK 0x080
54. WREG_TEMP ;variable usada para
salvar contexto
55. STATUS_TEMP ;variable usada para
salvar contexto
56. BSR_TEMP ;variable usada para
salvar contexto
57. ENDC
58.
59. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco
0) max 96 bytes
60. Cantms:2 ;variable para generar
hasta 65535 ms
61. CantSeg ;Variable para producir
retardos de hasta 255 seg
62. ENDC
63.
64. ;*****************************************************************
*************
65. ;Datos de la EEPROM
66. ;Los Datos a ser programados en la EEPROM son definidos aqui
67.
68. ORG 0xf00000
69.
70. DE "Test Data",0,1,2,3,4,5
71.
72. ;*****************************************************************
*************
73. ; Vector de Reset.
74. ; Este codigo comenzara a ejecutarse cuando suceda un reset
75.
76. ORG 0x0000
77.
78. goto Main ;Se va al inicio del
codigo principal
79.
80. ;*****************************************************************
*************
81. ; Vector de interrupcion de alta prioridad
82. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
83. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
84. ; no estan habilitadas
85.
86. ORG 0x0008
87.
88. bra HighInt
;Va a la rutina de interrupcion de alta prioridad
89.
90. ;*****************************************************************
*************
91. ; Vector de interrupcion de baja prioridad y rutina
92. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
93. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
94.
95. ORG 0x0018
96.
97. movff STATUS,STATUS_TEMP ;Salva el
registro STATUS
98. movff WREG,WREG_TEMP ;Salva el
registro de trabajo
99. movff BSR,BSR_TEMP ;Salva el
registro BSR
100.
101. ; *** El codigo de la interrupcion de baja prioridad va aqui
***
102.
103.
104. movff BSR_TEMP,BSR ;recupera
el registro BSR
105. movff WREG_TEMP,WREG ;recupera
el registro de trabajo
106. movff STATUS_TEMP,STATUS ;recupera
el registro STATUS
107. retfie
108.
109. ;*****************************************************************
*************
110. ; Rutina de interrupcion de alta prioridad
111. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
112. ; evitar conflictos con el vector de interrupciones de baja
prioridad
113.
114. HighInt:
115.
116. ; *** El codigo para las interrupciones de alta prioridad va
aqui ***
117.
118.
119. retfie FAST
120.
121. ;*****************************************************************
*************
122. ; Comienzo del programa principal
123. ; El codigo del programa principal es colocado aqui
124.
125. Main:
126.
127. ; *** EL codigo principal va aqui ***
128.
129. ;******************* Inicializamos
perifericos ***************************
130.
131. movlw B'01100000' ;Ajustamos
el oscilador interno a 4 MHz
132. movwf OSCCON,.0
133. movlw B'00001111'
134. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
135. clrf TRISA,.0
136. clrf TRISB,.0
137. clrf TRISC,.0
138. clrf TRISD,.0
139. clrf TRISE,.0 ;Todos los
pines como salida
140.
141. MainP0
142. setf LATA,.0
143. setf LATB,.0
144. setf LATC,.0
145. setf LATD,.0
146. setf LATE,.0 ;Ponemos
los puertos en 1
147. movlw .1
148. movwf CantSeg,.0
149. rcall RetardoSeg ;esperamos
1 seg
150. clrf LATA,.0
151. clrf LATB,.0
152. clrf LATC,.0
153. clrf LATD,.0
154. clrf LATE,.0 ;ponemos
los puertos en 0
155. movlw .1
156. movwf CantSeg,.0
157. rcall RetardoSeg ;esperamos
1 seg
158. bra MainP0 ;S
altamos para continuar con el ciclo
159.
160. ;**************************** RetardoSeg ******************
****************
161. ; RetardoSeg Realiza una espera de la cantidad de
segundos indicados
162. ; mediante la variable CantSeg.
CantSeg es de 8 bits
163. ;*****************************************************************
************
164. RetardoSeg
165. movf CantSeg,W,.0
166. btfsc STATUS,Z ;CantSeg
== 0?
167. return ;S
i => retornamos
168. movlw 0x03 ;No =>
hacemos Cantms = 1000
169. movwf Cantms+1,.0
170. movlw 0xE8
171. movwf Cantms,.0
172. rcall Retardo_ms ;realizamo
s un retardo de 1000 ms
173. decf CantSeg,F,.0 ;CantSeg --,
174. bra RetardoSeg ;C
ontinuamos con el ciclo
175. ;*****************************************************************
************
176.
177. ;**************************** Retardo_ms ******************
****************
178. ; Retardo_ms Realiza un retardo de la cantidad de
milisegundos indicados
179. ; mediante Cantms y Cantms+1, Cantms
y Cantms+1 son tratados como
180. ; variables de 16 bits.
181. ;*****************************************************************
************
182. Retardo_ms
183. rcall Retardo1ms ;realizamo
s un retardo de 1 ms
184. decfsz Cantms,F,.0 ;Cantms --
, Cantms == 0
185. bra Retardo_ms ;n
o => vamos a Retardo_ms
186. movf Cantms+1,W,.0 ;
187. btfsc STATUS,Z ;Cantms+1
== 0?
188. return ;S
i => retornamos
189. decf Cantms+1,F,.0 ;No =>
decrementamos
190. bra Retardo_ms ;C
ontinuamos con el ciclo
191. ;*****************************************************************
************
192.
193. ;**************************** Retardo1ms ******************
****************
194. ; Retardo1ms realiza una espera de 1 ms decrementado W
249 veces en un ciclo
195. ; que ocupa 4 us
196. ;*****************************************************************
************
197. Retardo1ms
198. movlw .249
199. Retardo1msP0
200. addlw 0xFF ;W--
201. btfss STATUS,Z,.0 ;W == 0?
202. bra Retardo1msP0 ;No =>
seguimos esperando
203. return ;S
i => ya paso 1 ms
204. ;*****************************************************************
************
205.
206.
207. ;*****************************************************************
*************
208.
209.
210. END ;Directiva fin del
programa

Notas

En la version de proteus que tengo (7.2 SP0) por algun motivo toma al pin RA4 como
si tuviera salida de colector abierto por lo que se necesita colocarle una resistencia
de PULL-UP para que se simule ese pin correctamente, en la hoja de datos no dice
que este pin sea de colector abierto, y como es de esperarse la prueba en
protoboard le da la razon a la hoja de datos
En la primer programa que hice no me preocupe del bit de configuracion LVP (que
por defecto esta activado), y el circuito no funcionaba bien en el protoboard, luego
de varios dolores de cabeza y revisando con mas detenimiento la hoja de datos lei
que si no se piensa usar el modo de programacion en bajo voltaje (LVP) se debe
colocar el pin RB5 a tierra mediante una resistencia, una vez hecho esto el circuito
funciono como se esperaba, y como puede verse ahora en el codigo fuente LVP =
OFF
Saludos

A pesar de que muchos sitios en internet me dicen que la gama 18Fxxxx slo usan C, por fin
veo a alguienque usa el ASM para los 18F.
En lnea

RALF2
Moderadores
PIC24H

Mensajes: 1996

Re: Ejemplos PIC18F4550


Respuesta #8 en: 19 de Agosto de 2008, 12:42:39

Que tal amigos!


Sander Excelente iniciativa, yo estoy haciendo lo mismo que tu pero con el proton y asm

Estaba leyendo los ejemplos que colocaste y hubo una partecita que no entendi es esta:

CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco 0) max 96 bytes


Cantms:2 ;variable para generar hasta 65535 ms
CantSeg ;Variable para producir retardos de hasta 255 seg
ENDC

Como se interpreta esto Cantms:2, no me quedo claro eso, me la podrias explicar, que significa
esos dos puntos?

Saludos

En lnea
sander
Colaborador
PIC24F

Mensajes: 606

Re: Ejemplos PIC18F4550


Respuesta #9 en: 19 de Agosto de 2008, 14:48:26

Hola RALF2, lo de los dos puntos sirve para que el ensamblador reserve dos bytes en memoria
para esa variable , si te fijas Cantms la utilizo como variable de 16 bits, por eso puse en el
comentario lo de los 65535 ms . Usando los dos puntos tambien puedes reservar espacio en
memoria para variables mas grandes.

Saludos

En lnea

La electronica es el arte de manipular seales electricas que transportan informacin

Jan Davidse

Visita mi blog

RALF2
Moderadores
PIC24H

Mensajes: 1996

Re: Ejemplos PIC18F4550


Respuesta #10 en: 19 de Agosto de 2008, 17:40:44
Cita de: sander en 19 de Agosto de 2008, 14:48:26

Hola RALF2, lo de los dos puntos sirve para que el ensamblador reserve dos bytes en
memoria para esa variable , si te fijas Cantms la utilizo como variable de 16 bits, por eso
puse en el comentario lo de los 65535 ms . Usando los dos puntos tambien puedes reservar
espacio en memoria para variables mas grandes.

Saludos

Muy intersante sander no habia visto eso antes en asembler, voy a hacer unos ejemplos
aplicando esa tecnica

Gracias!

En lnea

picNIC
PIC16

Mensajes: 140

Re: Ejemplos PIC18F4550


Respuesta #11 en: 19 de Agosto de 2008, 22:16:43

Hola gente... muy buena la idea de poner ejemplos....


y hablando de ejemplos de usb en asm encontre esta pagina...
Aunque todavia no estudie el programa parece que puede servir de guia..

Sal u 2

En lnea

sander
Colaborador
PIC24F


Mensajes: 606

Re: Ejemplos PIC18F4550


Respuesta #12 en: 12 de Octubre de 2008, 01:52:13

Bueno continuando con lo de los ejemplos aqui pongo un par mas

BlinkT0.asm

Cdigo: ASM

1. ;**********************************************************************
********
2.
3. ;
*
4.
5. ; Nombre: BlinkT0.asm
6.
7. ; Fecha: 27/08/2008
8.
9. ; Version: v0.90
10.
11. ;
*
12.
13. ; Autor: Sander
14.
15. ; Empresa:
16.
17. ;
*
18.
19. ;*****************************************************************
*************
20.
21. ;
*
22.
23. ; Archivos Requeridos: P18F4550.INC
24.
25. ;
*
26.
27. ;*****************************************************************
*************
28.
29. ; Notas: El programa hace parpadear los pines del PIC a
razon de 1 seg usando
30.
31. ; el TMR0 para generar los retardos.
32.
33. ; El TMR0 sera usado en su modo de 16 bits y se configurara
para que genere
34.
35. ; con presicion un retardo de 100 ms.
36.
37. ;
38.
39. ; Tiempo = (NumCuentasTMR0)(4/Fosc)(preescaler)
40.
41. ;
42.
43. ; Para Fosc = 4 MHz; y el Tiempo de 100 ms , tenemos :
44.
45. ;
46.
47. ; (4 MHz/4)(100 ms) = (NumCuentasTMR0)(preescaler)
48.
49. ; (NumCuentasTMR0)(preescaler) = 100000
50.
51. ; Los valores posibles para el preescaler son:
2,4,16,32,64,128 y 256, entonces
52.
53. ; son posibles diferentes combinaciones para el
(NumCuentasTMR0) y el preescaler,
54.
55. ; Sin embargo debe notarse que al ser el TMR0 un contador
ascendente el valor
56.
57. ; hallado anteriormente no es el que debe cargarse al TMR0
si no :
58.
59. ;
60.
61. ; TMR0 = 65536 - (NumCuentasTMR0)
62.
63. ;
64.
65. ; ---------------------------------------------------------
--
66.
67. ; |Preescaler | NumCuentasTMR0|Valor a cargar |Valor a
cargar |
68.
69. ; | | |
TMR0 | TMR0(Hex) |
70.
71. ; ---------------------------------------------------------
--
72.
73. ; | 2 | 50000 | 15
536 | 0x3CB0 |
74.
75. ; | 4 | 25000 | 40
536 | 0x9E58 |
76.
77. ; | 8 | 12500 | 53
036 | 0xCF2C |
78.
79. ; | 16 | 6250 | 59
286 | 0xE796 |
80.
81. ; | 32 | 3125 | 62
411 | 0xF3CB |
82.
83. ; | 64 | 1562,5 | --
--- | ------ |
84.
85. ; | 128 | 781,25 | --
--- | ------ |
86.
87. ; | 256 | 390,625 | --
--- | ------ |
88.
89. ; ---------------------------------------------------------
--
90.
91. ; Ta
bla 1
92.
93. ;*****************************************************************
*************
94.
95.
96.
97. LIST P=18F4550 ;Directiva para definir el
procesador
98.
99. #include <P18F4550.INC> ;Definicion de SFRs para el
procesador
100.
101.
102.
103. ;*****************************************************************
*************
104.
105. ;Bits de Configuracion
106.
107. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
108.
109. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
110.
111. ;Abajo hay algunos ejemplos
112.
113.
114.
115. ;******** Configuracion del Oscilador **********
116.
117. CONFIG FOSC = XT_XT ;Osc XT, XT usado
para el USB
118.
119.
120.
121. ;******** Otros bits de configuracion **********
122.
123. CONFIG PWRT =
ON ;PWRT habilitado
124.
125. CONFIG BOR =
OFF ;Brown out resete
deshabilitado
126.
127. CONFIG WDT =
OFF ;Watch dog deshabilitado
128.
129. CONFIG MCLRE =
OFF ;MCLR como entrada
130.
131. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
132.
133. CONFIG LVP =
OFF ;programacion en bajo voltaje
deshabilitado
134.
135. ;********* Bits de proteccion ******************
136.
137. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
138.
139. CONFIG CP1 =
OFF ;no estan protegidos
140.
141. CONFIG CP2 = OFF
142.
143. CONFIG CP3 = OFF
144.
145. CONFIG CPB =
OFF ;Sector Boot no esta protegido
146.
147. CONFIG CPD =
OFF ;La EEPROM no esta protegida
148.
149. ;*****************************************************************
*************
150.
151. ; Definicion de variables
152.
153. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
154.
155. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
156.
157. ; interrupcion.
158.
159.
160.
161. CBLOCK 0x080
162.
163. WREG_TEMP ;variable usada para
salvar contexto
164.
165. STATUS_TEMP ;variable usada para
salvar contexto
166.
167. BSR_TEMP ;variable usada para
salvar contexto
168.
169. ENDC
170.
171.
172.
173. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco
0) max 96 bytes
174.
175. ContT0 ;para contar las veces que
TMR0 desborda
176.
177. ENDC
178.
179.
180.
181. ;*****************************************************************
*************
182.
183. ;Datos de la EEPROM
184.
185. ;Los Datos a ser programados en la EEPROM son definidos aqui
186.
187.
188.
189. ORG 0xf00000
190.
191.
192.
193. DE "Test Data",0,1,2,3,4,5
194.
195.
196.
197. ;*****************************************************************
*************
198.
199. ; Vector de Reset.
200.
201. ; Este codigo comenzara a ejecutarse cuando suceda un reset
202.
203.
204.
205. ORG 0x0000
206.
207.
208.
209. goto Main ;Se va al inicio del
codigo principal
210.
211.
212.
213. ;*****************************************************************
*************
214.
215. ; Vector de interrupcion de alta prioridad
216.
217. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
218.
219. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
220.
221. ; no estan habilitadas
222.
223.
224.
225. ORG 0x0008
226.
227.
228.
229. bra HighInt ;V
a a la rutina de interrupcion de alta prioridad
230.
231.
232.
233. ;*****************************************************************
*************
234.
235. ; Vector de interrupcion de baja prioridad y rutina
236.
237. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
238.
239. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
240.
241.
242.
243. ORG 0x0018
244.
245.
246.
247. movff STATUS,STATUS_TEMP ;Salva el registro
STATUS
248.
249. movff WREG,WREG_TEMP ;Salva el registro
de trabajo
250.
251. movff BSR,BSR_TEMP ;Salva el registro
BSR
252.
253.
254.
255. ; *** El codigo de la interrupcion de baja prioridad va aqui
***
256.
257.
258.
259.
260.
261. movff BSR_TEMP,BSR ;recupera el
registro BSR
262.
263. movff WREG_TEMP,WREG ;recupera el
registro de trabajo
264.
265. movff STATUS_TEMP,STATUS ;recupera el
registro STATUS
266.
267. retfie
268.
269.
270.
271. ;*****************************************************************
*************
272.
273. ; Rutina de interrupcion de alta prioridad
274.
275. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
276.
277. ; evitar conflictos con el vector de interrupciones de baja
prioridad
278.
279.
280.
281. HighInt:
282.
283.
284.
285. ; *** El codigo para las interrupciones de alta prioridad va
aqui ***
286.
287.
288.
289.
290.
291. retfie FAST
292.
293.
294.
295. ;*****************************************************************
*************
296.
297. ; Comienzo del programa principal
298.
299. ; El codigo del programa principal es colocado aqui
300.
301.
302.
303. Main:
304.
305. ; *** EL codigo principal va aqui ***
306.
307.
308.
309. ;******************* Inicializacion de
puertos ***************************
310.
311. movlw B'00001111'
312.
313. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
314.
315. clrf TRISA,.0
316.
317. clrf TRISB,.0
318.
319. clrf TRISC,.0
320.
321. clrf TRISD,.0
322.
323. clrf TRISE,.0 ;Todos los
pines como salida
324.
325.
326.
327. clrf LATA,.0
328.
329. clrf LATB,.0
330.
331. clrf LATC,.0
332.
333. clrf LATD,.0
334.
335. clrf LATE,.0 ;Ponemos
las salidas en cero
336.
337. ;*****************************************************************
*************
338.
339.
340.
341. ;******************* Inicializacion del
TMR0 ***************************
342.
343. movlw B'10010000' ;TMR0 on,
modo 16 bits, cambia con las
344.
345. movwf T0CON,.0 ;instrucci
ones, asignamos preescaler de 2
346.
347.
348.
349. movlw 0x3C ;De
acuerdo a la Tabla 1 cargamos los valores
350.
351. movwf TMR0H,.0 ;a TMR0H y
TMR0L, pero a TMR0L se le aumenta
352.
353. movlw 0xB1 ;un 1 para
compensar los 2 ciclos de
354.
355. movwf TMR0L,.0 ;instrucci
on que el TMR0 permanece detenido
356.
357. ;*****************************************************************
*************
358.
359. Ciclo
360.
361. movlw .10 ;
362.
363. movwf ContT0,.0 ;ContT0 =
10 para controlar 1 segundo
364.
365. CicloP0
366.
367. btfss INTCON,TMR0IF ;TMR0IF == 1?
(TMR0 desbordo?)
368.
369. bra CicloP0 ;N
o => continuamos esperando
370.
371. movlw 0xB1 ;Si =>
recargamos el TMR0L, no es necesario
372.
373. movwf TMR0L,.0 ;recargar
el TMR0H
374.
375. bcf INTCON,TMR0IF ;limpiamos
TMR0IF para reiniciar la cuenta
376.
377. decfsz ContT0,F,.0 ;ContT0 --
, y ContT0 == 0?
378.
379. bra CicloP0 ;N
o => Volvemos al ciclo de espera
380.
381. movlw 0xFF ;Si =>
Cambiamos el estado de los puertos (toggle)
382.
383. xorwf LATA,F,.0 ;para eso
realizamos un XOR de cada puerto con 0xFF
384.
385. xorwf LATB,F,.0
386.
387. xorwf LATC,F,.0
388.
389. xorwf LATD,F,.0
390.
391. xorwf LATE,F,.0
392.
393. bra Ciclo ;V
olvemos a recargar el valor de ContT0,
394.
395.
396.
397. ;*****************************************************************
*************
398.
399.
400.
401. END ;Directiva fin del
programa
402.

Bueno , este programa muestra el uso del TMR0 en su modo temporizador de 16 bits , lo he
usado para generar retardos de 1 seg, de la manera mas precisa posible , a la primera obtuve un
tiempo de 1,000004 seg si no me equivoco, , dentro del programa se explica con cierto detalle
como es que configure el TMR0 .

Lo que el programa hace simplemente es prender y apagar los Leds cada segundo , no es gran
cosa pero el objetivo en si era usar el TMR0 como temporizador de 16 bits , ademas de usar un
oscilador con cristal de 4MHz. Aunque me sirvio para ver algo de lo que no me habia dado cuenta
y que ademas lo pase por alto en la hoja de datos y en el anterior programa de parpadeo y es
que los pines RC4 y RC5 (que son usados para el USB) no pueden ser usados como salidas
digitales de proposito general, esto ultimo mi version del proteus tampoco los simula , asi que
tiene otro punto menos .

Saludos
BlinkT0.rar (31.33 kB - descargado 152 veces.)

ltima modificacin: 12 de Octubre de 2008, 03:25:07 por sander

En lnea

La electronica es el arte de manipular seales electricas que transportan informacin

Jan Davidse

Visita mi blog

sander
Colaborador
PIC24F

Mensajes: 606

Re: Ejemplos PIC18F4550


Respuesta #13 en: 12 de Octubre de 2008, 02:52:06

TxRx_0.asm

Cdigo: ASM

1.
2. ;**********************************************************************
********
3.
4. ;

5.
6. ; Nombre: TxRx_0.asm
7.
8. ; Fecha: 02/09/2008
9.
10. ; Version: v0.90
11.
12. ;

13.
14. ; Autor: Sander
15.
16. ; Empresa:
17.
18. ;

19.
20. ;*****************************************************************
***************
21.
22. ;

23.
24. ; Archivos Requeridos: P18F4550.INC
25.
26. ;

27.
28. ;*****************************************************************
***************
29.
30. ; Notas: El programa muestra el uso del EUSART para
realizar una comunicacion
31.
32. ; asincrona con la PC, para este ejemplo
configuraremos el oscilador
33.
34. ; para que funcione a 48 MHz usando un cristal externo de 4
MHz.
35.
36. ;
37.
38. ; Para configurar la velocidad de transmision se usara el
modo de 16 bits y
39.
40. ; el modo de alta de velocidad para el generador de baudios
(BRG16=1; BRGH=1),
41.
42. ; para este caso tenemos que la velocidad esta dada por:
43.
44. ;
45.
46. ; Vel = Fosc/[4(n+1)] Donde n es el valor que se
carga a SPBRGH:SPBRG
47.
48. ; n = [(Fosc/Vel)-1]/4
49.
50. ;
51.
52. ; ---------------------------------------------------------
------------------
53.
54. ; |Velocidad |Valor n |Valor
para |Valor Hex para |Velocidad | % |
55.
56. ; |(Baudios) | |SPBRGH:SPBRG |S
PBRGH:SPBRG |real | Error |
57.
58. ; ---------------------------------------------------------
------------------
59.
60. ; | 110 | 109090,66 | -------
- | -------- | ------- | ----- |
61.
62. ; | 300 | 39999,75 | 39999 |
0x9C3F | 300 | 0 |
63.
64. ; | 1200 | 9999,75 | 9999 |
0x270F | 1200 | 0 |
65.
66. ; | 2400 | 4999,75 | 4999 |
0xC34F | 2400 | 0 |
67.
68. ; | 4800 | 2499,75 | 2499 |
0x09C3 | 4800 | 0 |
69.
70. ; | 9600 | 1249,75 | 1249 |
0x04E1 | 9600 | 0 |
71.
72. ; | 19600 | 611,99 | 611 |
0x0263 | 19607,84 | 0,04 |
73.
74. ; | 38400 | 312,25 | 312 |
0x0137 | 38338,65 | 0,16 |
75.
76. ; | 57600 | 208,08 | 207 |
0x00CF | 57692,30 | 0,16 |
77.
78. ; | 115200 | 103,91 | 103 |
0x0067 | 115384,61 | 0,16 |
79.
80. ; | 230400 | 51,83 | 51 |
0x0033 | 230769,23 | 0,16 |
81.
82. ; | 460800 | 25,79 | 25 |
0x0019 | 461538,46 | 0,16 |
83.
84. ; | 921600 | 12,77 | 12 |
0x000C | 923076,92 | 0,16 |
85.
86. ; ---------------------------------------------------------
------------------
87.
88. ;
Tabla 1
89.
90. ; Lo que el programa hara es recibir caracteres e ir
almacenandolos en BufferRx,
91.
92. ; dejara de recibir caracteres si recibe el caracter
enter(0x0D ), si ya han
93.
94. ; llegado 256 caracteres, o si se ha dejado de recibir
caracteres durante 2
95.
96. ; segundos aproximadamente.
97.
98. ;
99.
100. ; Cuando se deja de recibir los caracteres , el
microcontrolador recorrera el
101.
102. ; arreglo BufferRx y convertira todas las letras minusculas
en mayusculas , la
103.
104. ; cadena modificada se ira guardando en BufferTx , durante
este proceso cualquier
105.
106. ; caracter recibido sera descartado, una vez que BufferTx
haya sido cargado con
107.
108. ; todos los caracteres estos seran enviados de regreso a la
PC.
109.
110. ;
111.
112. ; Tanto para la recepcion como para la transmision se usran
interrupciones,
113.
114. ; cualquier retardo que se necesite sera realizado usando el
TMR0
115.
116. ;*****************************************************************
*****************
117.
118.
119.
120. LIST P=18F4550 ;Directiva para definir el
procesador
121.
122. #include <P18F4550.INC> ;Definicion de SFRs para el
procesador
123.
124.
125.
126. ;*****************************************************************
*************
127.
128. ;Bits de Configuracion
129.
130. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
131.
132. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
133.
134. ;Abajo hay algunos ejemplos
135.
136.
137.
138. ;******** Configuracion del Oscilador **********
139.
140. CONFIG FOSC = XTPLL_XT ;Osc XT que pasa a
travez del PLL,USB usa
141.
142.
;el Osc XT
143.
144. CONFIG PLLDIV =
1 ;La entrada del Osc de 4 MHz va
directo al PLL
145.
146. CONFIG CPUDIV = OSC1_PLL2 ;La salida
del PLL (96 MHz) , la dividimos entre dos
147.
148.
;para que sea la seal del oscilador del sistema,
149.
150.
;Entoces tenemos 48 MHz
151.
152. ;******** Otros bits de configuracion **********
153.
154. CONFIG PWRT =
ON ;PWRT habilitado
155.
156. CONFIG BOR =
OFF ;Brown out resete
deshabilitado
157.
158. CONFIG WDT =
OFF ;Watch dog deshabilitado
159.
160. CONFIG MCLRE =
OFF ;MCLR como entrada
161.
162. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
163.
164. CONFIG LVP =
OFF ;programacion en bajo voltaje
deshabilitado
165.
166. ;********* Bits de proteccion ******************
167.
168. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
169.
170. CONFIG CP1 =
OFF ;no estan protegidos
171.
172. CONFIG CP2 = OFF
173.
174. CONFIG CP3 = OFF
175.
176. CONFIG CPB =
OFF ;Sector Boot no esta protegido
177.
178. CONFIG CPD =
OFF ;La EEPROM no esta protegida
179.
180. ;*****************************************************************
*************
181.
182. ; Definicion de variables
183.
184. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
185.
186. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
187.
188. ; interrupcion.
189.
190.
191.
192. VelHI EQU 0x04 ;Estas
constantes sirven para definir la velocidad
193.
194. VelLO EQU 0xE1 ;de la
comunicacion, 9600 baudios
195.
196.
197.
198. CBLOCK 0x080
199.
200. WREG_TEMP ;variable usada para
salvar contexto
201.
202. STATUS_TEMP ;variable usada para
salvar contexto
203.
204. BSR_TEMP ;variable usada para
salvar contexto
205.
206. ENDC
207.
208.
209.
210. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco
0) max 96 bytes
211.
212. ContT0 ;para contar las veces que
TMR0 desborda
213.
214. ContRx ;para contar los bytes
recibidos
215.
216. ContTx ;para contar los bytes
transmitidos
217.
218. DatoRx ;variable temporal para la
recepcion
219.
220. DatoTemp ;usado como variable
auxiliar
221.
222. Banderas
223.
224. TablaOffs ;Para movernos en las
tablas
225.
226. ENDC
227.
228.
229.
230. CBLOCK 0x100 ;Variables en el Banco 1
231.
232. BufferRx:.256 ;Buffer para la recepcion
233.
234. ENDC
235.
236.
237.
238. CBLOCK 0x200 ;Variables en el banco 2
239.
240. BufferTx:.256 ;Buffer para la transmision
241.
242. ENDC
243.
244.
245.
246. #DEFINE TimeOut Banderas,.0
;=1 si el pasan 2 seg
247.
248. #DEFINE RxOK Banderas,.1
;=1 si se termino de recibir
249.
250. #DEFINE TxOK Banderas,.2
251.
252. ;*****************************************************************
*************
253.
254. ;Datos de la EEPROM
255.
256. ;Los Datos a ser programados en la EEPROM son definidos aqui
257.
258.
259.
260. ORG 0xf00000
261.
262.
263.
264. DE "Test Data",0,1,2,3,4,5
265.
266.
267.
268. ;*****************************************************************
*************
269.
270. ; Vector de Reset.
271.
272. ; Este codigo comenzara a ejecutarse cuando suceda un reset
273.
274.
275.
276. ORG 0x0000
277.
278.
279.
280. goto Main ;Se va al inicio del
codigo principal
281.
282.
283.
284. ;*****************************************************************
*************
285.
286. ; Vector de interrupcion de alta prioridad
287.
288. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
289.
290. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
291.
292. ; no estan habilitadas
293.
294.
295.
296. ORG 0x0008
297.
298.
299.
300. bra LowInt ;c
uando las prioridades estan deshabilitadas
301.
302.
;se salta a 0x0008 en caso de interrupcion
303.
304. ;*****************************************************************
*************
305.
306. ; Vector de interrupcion de baja prioridad y rutina
307.
308. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
309.
310. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
311.
312.
313.
314. ORG 0x0018
315.
316. LowInt
317.
318. movff STATUS,STATUS_TEMP ;Salva el registro
STATUS
319.
320. movff WREG,WREG_TEMP ;Salva el registro
de trabajo
321.
322. movff BSR,BSR_TEMP ;Salva el registro
BSR
323.
324.
325.
326. ; *** El codigo de la interrupcion de baja prioridad va aqui
***
327.
328. btfsc INTCON,TMR0IF ;Interrupcion del
TMR0
329.
330. bra IntT0 ;S
i => vamos a IntT0
331.
332. btfsc PIR1,RCIF ;No =>
interupcion de recepcion?
333.
334. bra IntRx ;S
i => vamos a IntRx
335.
336. btfsc PIR1,TXIF ;No =>
interrupcion de transmision?
337.
338. bra IntTx ;S
i => vamos a IntTx
339.
340. movlw .6 ;N
o => enviamos mensaje de error
341.
342. call EnvMsg ;
343.
344. sleep ;y
dormimos
345.
346.
347.
348. ;**************************** IntT0 **************************
********
349.
350. ; IntT0 atiende la interrupcion de desborde del TMR0 y
controla
351.
352. ; cuando transcuren dos segundos sin recibir
nada para producir
353.
354. ; el time out
355.
356. ;*****************************************************************
********
357.
358. IntT0
359.
360. movlw 0x61
361.
362. movwf TMR0L ;recargamo
s TMR0L, para desbordes de 100 ms
363.
364. bcf INTCON,TMR0IF ;limpiamos
la bandera de interrupcion
365.
366. decfsz ContT0 ;ContT0 --
, ya paso 2 seg?
367.
368. bra IntT0_X ;N
o => salimos
369.
370. bsf TimeOut ;S
i => indicamos que hubo un time out
371.
372. bra IntT0_X
373.
374. IntT0_X
375.
376. bra SalirInt ;V
amos a salir de las interrupciones
377.
378. ;*****************************************************************
***********
379.
380.
381.
382. ;**************************** IntRx **************************
********
383.
384. ; IntRx se encarga de guardar los bytes recibidos en el
BufferRx,
385.
386. ; descarta los bytes recibidos cuando se
esta procesando la trama
387.
388. ; ademas controla cuando el buffer de recepcion desborda
389.
390. ;*****************************************************************
********
391.
392. IntRx
393.
394. btfsc RCSTA,OERR ;Desbordo
el buffer de recepcion?
395.
396. bra IntRx_Er1 ;v
amos a atender el error
397.
398. btfsc RxOK ;termino
la recepcion?
399.
400. bra IntRx_P1 ;S
i => vamos a descartar el caracter recibido
401.
402.
403.
404. movf RCREG,W,.0 ;No =>
guardamos el caracter
405.
406. movwf DatoRx
407.
408. movlw 0x0D ;Revisamos
si se recibio enter
409.
410. xorwf DatoRx,W,.0
411.
412. btfsc STATUS,Z ;RCREG ==
0x0D?, se recibio 0x0D(enter)?
413.
414. bra IntRx_P0_1 ;S
i => vamos a terminar la recepcion
415.
416. movf DatoRx,W,.0 ;No =>
guardamos el caracter
417.
418. movwf POSTINC0 ;Guardamos
e incrementamos FSR
419.
420. movlw .20
421.
422. movwf ContT0 ;Reiniciam
os el contador para el TimeOut
423.
424. incfsz ContRx,F,.0 ;ContRx
llego a 256, (desbordo?)
425.
426. bra IntRx_X ;N
o => terminamos
427.
428.
;Si => tenemos 256 caracteres recibidos
429.
430. IntRx_P0_1
431.
432. bsf RxOK ;p
onemos en 1 RxOK
433.
434. bra IntRx_X
435.
436. IntRx_P1
437.
438. movf RCREG,W,.0 ;Descartam
os el byte recibido
439.
440. bra IntRx_X
441.
442. IntRx_Er1
443.
444. bcf RCSTA,CREN
445.
446. bsf RCSTA,CREN ;R
einiciamos el EUSART
447.
448. movf RCREG,W,.0 ;Descartam
os el byte recibido
449.
450. IntRx_X
451.
452. bra SalirInt ;V
amos a salir de las interrupciones
453.
454. ;*****************************************************************
*****************
455.
456.
457.
458. ;******************************* IntTx ******************
*********************
459.
460. ; IntTx Atiende la interrupcion que se produce cuando el
TXREG envia su
461.
462. ; dato a al registro TSR, por lo aqui se
copia el nuevo valor a
463.
464. ; transmitir a TXREG, esto mientras ContTx > 0.
465.
466. ;*****************************************************************
*****************
467.
468. IntTx
469.
470. decfsz ContTx,F,.0 ;ContTx --
, ContTx == 0?
471.
472. bra IntTxP0 ;N
o => vamos a cargar otro caracter
473.
474. bra IntTxP1 ;S
i => vamos a terminar la transmision
475.
476. IntTxP0
477.
478. movf POSTINC1,W ;Cargamos
el caracter a W e incrementamos FSR1
479.
480. movwf TXREG ;Cargamos
TXREG
481.
482. bra $+2
;Esperamos a que TXIF se ponga en cero
483.
484. bra IntTx_X ;v
amos a salir de la IntTx
485.
486. IntTxP1
487.
488. bsf TxOK ;I
ndicamos que la transmision termino
489.
490. bcf PIE1,TXIE ;D
eshabilitamos esta interrupcion
491.
492. bra IntTx_X ;v
amos a salir de la IntTx
493.
494. IntTx_X
495.
496. bra SalirInt ;V
amos a salir de las interrupciones
497.
498. ;*****************************************************************
*****************
499.
500.
501.
502.
503.
504. SalirInt
505.
506. movff BSR_TEMP,BSR ;recupera el
registro BSR
507.
508. movff WREG_TEMP,WREG ;recupera el
registro de trabajo
509.
510. movff STATUS_TEMP,STATUS ;recupera el
registro STATUS
511.
512. retfie
513.
514.
515.
516. ;*****************************************************************
*************
517.
518. ; Rutina de interrupcion de alta prioridad
519.
520. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
521.
522. ; evitar conflictos con el vector de interrupciones de baja
prioridad
523.
524.
525.
526. HighInt:
527.
528.
529.
530. ; *** El codigo para las interrupciones de alta prioridad va
aqui ***
531.
532.
533.
534.
535.
536. retfie FAST
537.
538.
539.
540. ;*****************************************************************
*************
541.
542. ; Comienzo del programa principal
543.
544. ; El codigo del programa principal es colocado aqui
545.
546.
547.
548. Main:
549.
550.
551.
552. ; *** EL codigo principal va aqui ***
553.
554.
555.
556. ;************************ Inicializacion de
Puertos ***********************
557.
558.
559.
560. movlw B'00001111'
561.
562. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
563.
564.
;NO ES NECESARIO MODIFICAR LOS REGISTROS
565.
566.
;TRIS (estan todos en 1)
567.
568. ;************************ Configuracion del
EUSART ***********************
569.
570.
571.
572. movlw B'00000100' ;Configura
mos para una transmision de 8 bit(bit 6)
573.
574. movwf TXSTA,.0 ;modo
asincrono (bit 4),para ajustar los baudios
575.
576.
;BRGH = 1 (bit 2)
577.
578.
579.
580. movlw B'01001000' ;Habilitam
os los 16 bits del generador de baudios
581.
582. movwf BAUDCON,.0 ;BRG16 = 1
(bit 3)
583.
584.
585.
586. movlw VelHI ;Cargamos
los registros SPBRGH:SPBRG con los
587.
588. movwf SPBRGH,.0 ;valores
de la tabla 1 para la velocidad deseada
589.
590. movlw VelLO
591.
592. movwf SPBRG,.0
593.
594.
595.
596. movlw B'10010000' ;Habilitam
os el puerto seria (Bit 7), modo 8 bits
597.
598. movwf RCSTA ;(bit 6),
y habilitamos el receptor (Bit 4).
599.
600.
601.
602. ;*********************** Configuracion del
TMR0 *************************
603.
604. movlw B'10010110' ;TMR0 on,
modo 16 bits, cambia con las
605.
606. movwf T0CON,.0 ;instrucci
ones, asignamos preescaler de 128
607.
608.
609.
610. movlw 0xDB ;De
acuerdo a BlinkT0.asm calculamos los valores a
611.
612. movwf TMR0H,.0 ;cargar
para TMR0H y TMR0L, para el oscilador
613.
614. movlw 0x61 ;de 48
MHz. y un tiempo de 100 ms
615.
616. movwf TMR0L,.0 ;
617.
618.
619.
620. movlw .20 ;
621.
622. movwf ContT0,.0 ;ContT0 =
20 para controlar 2 segundos
623.
624. ;********************** Configuracion de interrupciones
**********************
625.
626.
627.
628. bsf PIE1,RCIE,.0 ;Habilitam
os la interrupcion de recepcion
629.
630. bsf INTCON,TMR0IE,.0 ;Habilitam
os la interruocion de desborde del TMR0
631.
632. bsf INTCON,PEIE,.0 ;Habilitam
os las interrupciones para los perifericos
633.
634.
635.
636. ;************************ Inicializacion de
variables ***************************
637.
638.
639.
640. clrf Banderas,.0
641.
642. clrf ContRx,.0
643.
644.
645.
646. ;*****************************************************************
*************
647.
648. clrf WREG
649.
650. rcall EnvMsg ;Enviamos
el primer mensaje
651.
652. bsf INTCON,GIE ;H
abilitamos las interrupciones
653.
654. MainP0
655.
656. movlw HIGH BufferRx
657.
658. movwf FSR0H,.0
659.
660. movlw LOW BufferRx
661.
662. movwf FSR0L,.0 ;FSR0
apunta al inicio de BufferRx
663.
664. clrf ContRx,.0 ;para
reiniciar el conteo de bytes recibidos
665.
666. clrf Banderas ;reiniciam
os las banderas
667.
668. movlw .20 ;r
einiciamos el contador del time out
669.
670. movwf ContT0,.0 ;ContT0 =
20 para controlar 2 segundos
671.
672. movlw .1
673.
674. rcall EnvMsg
675.
676. MainP1
677.
678. btfsc TimeOut ;Se
produjo un time out?
679.
680. bra MainP2 ;S
i => vamos a atender el timeout
681.
682. btfsc RxOK ;No, Se
termino la recepcion?
683.
684. bra MainP3 ;S
i => vamos a atender la recepcion
685.
686. bra MainP1 ;N
o => continuamos esperando
687.
688.
689.
690. MainP2
691.
692. bsf RxOK ;P
ara detener la recepcion
693.
694. movlw .4
695.
696. rcall EnvMsg ;Enviamos
el mensaje de timeout
697.
698. tstfsz ContRx,.0 ;ContRx ==
0?;
699.
700. bra MainP2_P0 ;N
o => se recibieron caracteres y vamos a procesarlos
701.
702. bcf RxOK ;S
i => no se recibieron caracteres,
703.
704. bra MainP0 ;a
si que volvemos a empezar
705.
706. MainP2_P0
707.
708. movlw .2
709.
710. rcall EnvMsg ;Indicamos
que procesamos la trama
711.
712. rcall ProcTrama ;vamos a
procesar la trama
713.
714. bcf TimeOut ;r
einiciamos las banderas
715.
716. bra MainTx ;V
amos a ennviar la nueva trama
717.
718. bra MainP0 ;V
olvemos a empezar
719.
720.
721.
722. MainP3
723.
724. tstfsz ContRx,.0 ;ContRx ==
0?;
725.
726. bra MainP3_P0 ;N
o => se recibio un 0x0D (enter)
727.
728. movlw .5 ;S
i => se lleno el buffer, y enviamos
729.
730. rcall EnvMsg ;el
mensaje respectivo
731.
732. MainP3_P0
733.
734. movlw .2
735.
736. rcall EnvMsg ;Indicamos
que procesamos la trama
737.
738. rcall ProcTrama ;vamos a
procesar la trama
739.
740. bra MainTx ;V
amos a Enviar la nueva trama
741.
742. bra MainP0 ;V
olvemos a empezar
743.
744.
745.
746. MainTx
747.
748. movlw .3
749.
750. rcall EnvMsg ;Enviamos
el mensaje para transmitir
751.
752. bsf TXSTA,TXEN ;H
abilitamos es transmisor
753.
754. movf POSTINC1,W ;leemos el
dato e incrementamos FSR1
755.
756. movwf TXREG ;copiamos
el dato a TXREG
757.
758. bsf PIE1,TXIE,.0 ;Habilitam
os la interrupcion de transmision
759.
760. btfss TxOK ;La
transmision termino?
761.
762. bra $-
2 ;No => esperamos
763.
764. btfss TXSTA,TRMT ;Si =>
esperamos a que el ultimo caracter sea enviado
765.
766. bra $-
2 ;
767.
768. bcf TXSTA,TXEN ;c
uando se envia el ultimo caracter
769.
770.
;deshabilitamos es transmisor
771.
772. bcf RxOK ;r
eniciamos las banderas
773.
774. bcf TxOK ;
775.
776. bra MainP0 ;;
Volvemos a empezar
777.
778. ;******************************* ProcTrama **********
********************
779.
780. ; ProcTrama Copia los datos del buffer de recepcion al
buffer de transmision
781.
782. ; convirtiendo las minusculas en
mayusculas.
783.
784. ;*****************************************************************
*************
785.
786. ProcTrama
787.
788. movlw HIGH BufferRx
789.
790. movwf FSR0H,.0
791.
792. movlw LOW BufferRx
793.
794. movwf FSR0L,.0 ;FSR0 apu
nta al inicio del BufferRx
795.
796.
797.
798. movlw HIGH BufferTx
799.
800. movwf FSR1H,.0
801.
802. movlw LOW BufferTx
803.
804. movwf FSR1L,.0 ;FSR1 apu
nta al inicio del BufferTx
805.
806. clrf ContTx,.0 ;ContTx =
0
807.
808. ProcTramaP0
809.
810. movf POSTINC0,W ;Cargamos
el caracter a W e incrementamos FSR0
811.
812. movwf DatoTemp ;guardamos
el dato para procesar
813.
814. movlw 'a'
815.
816. cpfslt DatoTemp ;DatoTemp
<'a'
817.
818. bra ProcTramaP0_0 ;No => es
>= 'a' vamos a ver si es menor a z
819.
820. bra ProcTramaP0_2 ;Si => no
es minuscula y vamos a guardar DatoTemp
821.
822. ProcTramaP0_0
823.
824. movlw 'z'
825.
826. cpfsgt DatoTemp ;DatoTemp
> 'z'
827.
828. bra ProcTramaP0_1 ;No => es
<= 'z' vamos a convertirlo en mayuscula
829.
830. bra ProcTramaP0_2 ;Si => no
es minuscula y vamos a guardar DatoTemp
831.
832. ProcTramaP0_1
833.
834. movlw 0x20 ;le
restamos 0x20 al dato para que sea mayuscula
835.
836. subwf DatoTemp,F ;
837.
838. ProcTramaP0_2
839.
840. movf DatoTemp,W ;
841.
842. movwf POSTINC1 ;Guardamos
el dato e incrementamos FSR1
843.
844. incf ContTx,F,.0 ;ContTx
++
845.
846. movf ContRx,W,.0
847.
848. cpfseq ContTx ;ContTx ==
ContRx ?
849.
850. bra ProcTramaP0 ;N
o => seguimos copiando
851.
852.
853.
854. movlw HIGH BufferTx ;Si => volvemos a
apuntar FSR1 a BufferTx, para
855.
856. movwf FSR1H,.0 ;salir
857.
858. movlw LOW BufferTx
859.
860. movwf FSR1L,.0
861.
862. return
863.
864. ;*****************************************************************
*************
865.
866.
867.
868. ;*********************************** EnvMsg ******************
**************
869.
870. ; EnvMsg Recibe en WREG el numero de mensaje que se quiere
enviar, luego
871.
872. ; realiza un "computed goto", para ir a la
rutina que atiende el
873.
874. ; numero de mensaje recibido en WREG.
875.
876. ;*****************************************************************
*************
877.
878.
879.
880. EnvMsg
881.
882. rlcf WREG,.0,.0 ;WREG =
WREG*2, solo se usan posiciones pares
883.
884. movwf TablaOffs,.0 ;guardamos el
valor de W en TablaOffs
885.
886. movlw UPPER EnvMsgP0 ;Tomamos la Parte
mas alta de EnvMsgP0
887.
888. movwf PCLATU,.0 ;y
actualizamos PCLATU
889.
890. movlw HIGH EnvMsgP0 ;Tomamos la Parte
alta de EnvMsgP0
891.
892. movwf PCLATH,.0 ;y
actualizamos PCLATh
893.
894. movlw LOW EnvMsgP0 ;Tomamos la Parte
baja de EnvMsgP0
895.
896. addwf TablaOffs,W,.0 ;y realizamos el
calculo para el salto
897.
898. btfsc STATUS,C ;el salto
es mayor de 256?
899.
900. incf PCLATH,F,.0 ;Si =>
incrementamos PCLATH
901.
902. movf TablaOffs,W,.0 ;leemos el valor a
saltar
903.
904. addwf PCL,F ;cuando se
suma TablaOffs a PCL se realiza el salto
905.
906. EnvMsgP0
907.
908. bra EnvMsg_0 ;V
amos a atender el mensaje respectivo
909.
910. bra EnvMsg_1
911.
912. bra EnvMsg_2
913.
914. bra EnvMsg_3
915.
916. bra EnvMsg_4
917.
918. bra EnvMsg_5
919.
920. bra EnvMsg_6
921.
922. EnvMsg_0
923.
924. movlw UPPER Msg_0 ;tomamos
la parte mas alta del mensage que enviaremos
925.
926. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
927.
928. movlw HIGH Msg_0 ;tomamos
la parte alta del mensage que enviaremos
929.
930. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
931.
932. movlw LOW Msg_0 ;tomamos
la parte baja del mensage que enviaremos
933.
934. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
935.
936.
;apuntado al inicio del mensaje
937.
938. rcall EnviarMsg ;llamamos
a enviar el mensaje
939.
940. return
941.
942.
943.
944. EnvMsg_1
945.
946. movlw UPPER Msg_1 ;tomamos
la parte mas alta del mensage que enviaremos
947.
948. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
949.
950. movlw HIGH Msg_1 ;tomamos
la parte alta del mensage que enviaremos
951.
952. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
953.
954. movlw LOW Msg_1 ;tomamos
la parte baja del mensage que enviaremos
955.
956. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
957.
958.
;apuntado al inicio del mensaje
959.
960. rcall EnviarMsg ;llamamos
a enviar el mensaje
961.
962. return
963.
964. EnvMsg_2
965.
966. movlw UPPER Msg_2 ;tomamos
la parte mas alta del mensage que enviaremos
967.
968. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
969.
970. movlw HIGH Msg_2 ;tomamos
la parte alta del mensage que enviaremos
971.
972. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
973.
974. movlw LOW Msg_2 ;tomamos
la parte baja del mensage que enviaremos
975.
976. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
977.
978.
;apuntado al inicio del mensaje
979.
980. rcall EnviarMsg ;llamamos
a enviar el mensaje
981.
982. return
983.
984. EnvMsg_3
985.
986. movlw UPPER Msg_3 ;tomamos
la parte mas alta del mensage que enviaremos
987.
988. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
989.
990. movlw HIGH Msg_3 ;tomamos
la parte alta del mensage que enviaremos
991.
992. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
993.
994. movlw LOW Msg_3 ;tomamos
la parte baja del mensage que enviaremos
995.
996. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
997.
998.
;apuntado al inicio del mensaje
999.
1000. rcall EnviarMsg ;llamamos
a enviar el mensaje
1001.
1002. return
1003.
1004. EnvMsg_4
1005.
1006. movlw UPPER Msg_4 ;tomamos
la parte mas alta del mensage que enviaremos
1007.
1008. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
1009.
1010. movlw HIGH Msg_4 ;tomamos
la parte alta del mensage que enviaremos
1011.
1012. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
1013.
1014. movlw LOW Msg_4 ;tomamos
la parte baja del mensage que enviaremos
1015.
1016. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
1017.
1018.
;apuntado al inicio del mensaje
1019.
1020. rcall EnviarMsg ;llamamos
a enviar el mensaje
1021.
1022. return
1023.
1024. EnvMsg_5
1025.
1026. movlw UPPER Msg_5 ;tomamos
la parte mas alta del mensage que enviaremos
1027.
1028. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
1029.
1030. movlw HIGH Msg_5 ;tomamos
la parte alta del mensage que enviaremos
1031.
1032. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
1033.
1034. movlw LOW Msg_5 ;tomamos
la parte baja del mensage que enviaremos
1035.
1036. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
1037.
1038.
;apuntado al inicio del mensaje
1039.
1040. rcall EnviarMsg ;llamamos
a enviar el mensaje
1041.
1042. return
1043.
1044. EnvMsg_6
1045.
1046. movlw UPPER Msg_6 ;tomamos
la parte mas alta del mensage que enviaremos
1047.
1048. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
1049.
1050. movlw HIGH Msg_6 ;tomamos
la parte alta del mensage que enviaremos
1051.
1052. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
1053.
1054. movlw LOW Msg_6 ;tomamos
la parte baja del mensage que enviaremos
1055.
1056. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
1057.
1058.
;apuntado al inicio del mensaje
1059.
1060. rcall EnviarMsg ;llamamos
a enviar el mensaje
1061.
1062. return
1063.
1064. ;*****************************************************************
*************
1065.
1066.
1067.
1068. ;********************************* EnviarMsg **********
********************
1069.
1070. ; EnviarMsg recibe como dato el registro TBLPTR
apuntando al mensaje que
1071.
1072. ; quiere ser enviado y va
recorriendo el mensaje enviando
1073.
1074. ; caracter por caracter hasta que se encuentre con el
caracter 0x00
1075.
1076. ;*****************************************************************
*************
1077.
1078. EnviarMsg
1079.
1080. tblrd *+ ;L
eemos el valor de la tabla e incrementamos
1081.
1082.
;el puntero
1083.
1084. tstfsz TABLAT,.0 ;El valor
leido es 0x000?
1085.
1086. bra EnviarMsgP0 ;N
o => vamos a enviar el caracter
1087.
1088. return ;S
i => retornamos
1089.
1090. EnviarMsgP0
1091.
1092. bsf TXSTA,TXEN ;H
abilitamos el transmisor
1093.
1094. movff TABLAT,TXREG ;Movemos el
caracter a TXREG
1095.
1096. bra $+2
;espera a que el dato vaya al registro TSR
1097.
1098. btfss TXSTA,TRMT ;EL
caracter fue enviado?
1099.
1100. bra $-
2 ;No => esperamos
1101.
1102. bcf TXSTA,TXEN ;S
i => apagamos el transmisor
1103.
1104. bra EnviarMsg ;V
olvemos a leer el otro caracter
1105.
1106. ;*****************************************************************
*************
1107.
1108.
1109.
1110. ;*****************************************************************
*************
1111.
1112.
1113.
1114. ORG 0x800
1115.
1116.
1117.
1118. Msg_0
1119.
1120. DB '\n','\r'
1121.
1122. DB 'P','r','o','g','r','a','m','a','
','e','j','e','m','p','l','o'
1123.
1124. DB ' ','p','a','r','a',' ','e','l',' ','u','s','o','
','d','e','l'
1125.
1126. DB ' ','E','U','S','A','R','T','\n','\r',0x00
1127.
1128. Msg_1
1129.
1130. DB '\n','\r'
1131.
1132. DB 'I','n','t','r','o','d','u','z','c','a','
','l','a',' ','c','a'
1133.
1134. DB 'd','e','n','a','.','.','.','.','\n','\r',0x00
1135.
1136. Msg_2
1137.
1138. DB '\n','\r'
1139.
1140. DB 'P','r','o','c','e','s','a','n','d','o','.','.','.
','\n','\r',0x00
1141.
1142. Msg_3
1143.
1144. DB 'L','a',' ','n','u','e','v','a','
','c','a','d','e','n','a',' '
1145.
1146. DB 'e','s',':','\n','\r',0x00
1147.
1148. Msg_4
1149.
1150. DB '\n','\r'
1151.
1152. DB 'T','i','m','e',' ','o','u','t','\n','\r',0x00
1153.
1154. Msg_5
1155.
1156. DB '\n','\r'
1157.
1158. DB 'B','u','f','f','e','r',' ','d','e','
','r','e','c','e','p','c'
1159.
1160. DB 'i','o','n',' ','l','l','e','n','o','\n','\r',0x00
1161.
1162.
1163.
1164. Msg_6
1165.
1166. DB '\n','\r'
1167.
1168. DB 'E','r','r','o','r','\n','\r',0x00
1169.
1170.
1171.
1172. END ;Directiva fin del
programa
1173.

Este programa al principio tenia como objetivo mostrar una simple comunicacion serial usando el
EUSART, pero mientras estaba realizando algo del codigo se me ocurrieron algunas ideas que
talvez hicieron el ejemplo mas complicado de lo que tenia pensado para estos ejemplos, bueno lo
que se podria aprender de este ejemplo es:

1. Configurar el EUSART para una comunicacion de 8 bits de datos sin paridad y


velocidad de 9600 baudios usando un reloj de 48 MHz, es decir usando un cristal externo
de 4 MHz junto con el PLL interno
2. Muestra la recepcion de caracteres con interrupciones, y la transmision de caracteres
con y sin interrupciones
3. Muestra el uso del direccionamiento indirecto (usando FSRx e INDFx), para manejar
arreglos
4. Muestra como almacenar mensajes de caracteres en la memoria de programa y como
manejarlos para enviarlos usando el EUSART
5. Muestra como realizar saltos calculados (Computed gotos)

Bueno creo que esos son las cosas mas relevantes en cuanto a lo que se maneja en el
programa, en cuanto al hardware pues no utilizo mas que un MAX232 para adaptar las seales
TTL a RS232.

Para las pruebas en protoboard que he realizado he usado el programa para monitorear el puerto
serial de CCS (Siow), donde ha funcionado bien, aunque para ver los caracteres que se envian
debe de habilitarse el eco local, las pruebas las he realizado con la velocidad de 9600 baudios, y
pienso probar con otras velocidades tambien.

En los proximos ejemplos pienso probar otras caracteristicas del EUSART, como su deteccion
automatica de baudios, su capacidad de salir del Sleep y otras mas que queden

Saludos

TxRx.rar (58.32 kB - descargado 164 veces.)


ltima modificacin: 12 de Octubre de 2008, 03:26:48 por sander

En lnea

La electronica es el arte de manipular seales electricas que transportan informacin

Jan Davidse

Visita mi blog

Leon Pic
Colaborador
DsPIC30

Mensajes: 3471

Re: Ejemplos PIC18F4550


Respuesta #14 en: 12 de Octubre de 2008, 10:31:01

Que buena gua Sander. Voy a seguir el hilo de serquita.

Por el comentario del usb en asm, me ha dado una idea, que nos puede servir a todos los que
trabajamos en asm.

El lenguaje C, es ms fcil, por que una de las cosas que tiene, es que ya tiene creadas las
rutinas para todo. Desde un teclado hasta el USB. DE esta menera, el programador (usuario)
solo se concentra en armar el programa y no hacer toda la comunicacin.

Lo que voy hacer, es organizar mis rutinas, y las subir en un hilo nuevo. Explicar como usarlo
y listo. Adems, podremos ir mejorando las rutinas para hacerlas ms eficientes y que cada uno
las modifique a su gusto. Igual como en C.

En lnea

l dijo: "destruyan a la Iglesia y yo la levantar en tres das". Con esto defini que la Iglesia, somos nosotros; el

cuerpo y alma, y no el edificio o templo.

-"mense los unos a los otros como yo los he amado" Nuestro Seor Dios hecho hombre: Jess.
-l, fue a la cruz, pag nuestro pecado con un dolor increible siendo inocente de lo que lo acusaban, para

salvarnos.

-Mi propio Foro de Meteorologa

www.meteorologiafacil.com.ar/foros/index.php

-Web

www.meteorologiafacil.com.ar

1. ;**********************************************************************
********
2. ;
*
3. ; Nombre: Disp7seg.asm
4. ; Fecha: 31/07/2008
5. ; Version: v1.00
6. ;
*
7. ; Autor: Sander
8. ; Empresa:
9. ;
*
10. ;*****************************************************************
*************
11. ;
*
12. ; Archivos Requeridos: P18F4550.INC
13. ;
*
14. ;*****************************************************************
*************
15. ; Notas: El programa realiza un conteo de 0 - 9 dentro de
un ciclo infinito,
16. ; visualiza los valores en un display de 7
segmentos conectado al
17. ; puerto D, el incremento del display se lo realiza cada
segundo.
18. ;
19. ; Para realizar los retardos se usaran las rutinas de
retardo del proyecto
20. ; parpadea, para convertir el valor BCD que cuenta se
implementara una tabla
21. ; en la memoria de programa usando la directiva DB
22. ;
23. ; El display que se usara sera de anodo comun , y tendra la
siguiente conexion
24. ; con el Puerto D
25. ;
26. ; _Vdd_
27. ; |
28. ; ____________|_
29. ; | |
30. ; A(RD0) -->| AAAAAAA |
31. ; B(RD1) -->| F B |
32. ; C(RD2) -->| F B |
33. ; D(RD3) -->| F B |
34. ; | GGGGGG |
35. ; E(RD4) -->| E C |
36. ; F(RD5) -->| E C |
37. ; G(RD6) -->| E C |
38. ; DP(RD7) -->| DDDDDDD DP|
39. ; |______________|
40. ;
41. ;*****************************************************************
*************
42.
43. LIST P=18F4550 ;Directiva para
definir el procesador
44. #include <P18F4550.INC> ;Definicion de SFRs para
el procesador
45.
46. ;*****************************************************************
*************
47. ;Bits de Configuracion
48. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
49. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
50. ;Abajo hay algunos ejemplos
51.
52. ;******** Configuracion del Oscilador **********
53. CONFIG FOSC = INTOSCIO_EC ;Osc interno, RA6 como
pin, USB usa Osc EC
54. ;******** Otros bits de configuracion **********
55. CONFIG PWRT =
ON ;PWRT habilitado
56. CONFIG BOR =
OFF ;Brown out resete
deshabilitado
57. CONFIG WDT =
OFF ;Watch dog deshabilitado
58. CONFIG MCLRE =
OFF ;MCLR como entrada
59. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
60. CONFIG LVP =
OFF ;Programacion en bajo voltaje
apagado
61. ;********* Bits de proteccion ******************
62. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
63. CONFIG CP1 =
OFF ;no estan protegidos
64. CONFIG CP2 = OFF
65. CONFIG CP3 = OFF
66. CONFIG CPB =
OFF ;Sector Boot no esta protegido
67. CONFIG CPD =
OFF ;La EEPROM no esta protegida
68. ;*****************************************************************
*************
69. ; Definicion de variables
70. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
71. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
72. ; interrupcion.
73.
74. CBLOCK 0x080
75. WREG_TEMP ;variable usada para
salvar contexto
76. STATUS_TEMP ;variable usada para
salvar contexto
77. BSR_TEMP ;variable usada para
salvar contexto
78. ENDC
79.
80. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco
0) max 96 bytes
81. Cantms:2 ;variable para generar
hasta 65535 ms
82. CantSeg ;Variable para producir
retardos de hasta 255 seg
83. Cont ;Variable para realizar el
conteo
84. TablaOffs ;Para movernos por la
tabla
85. ENDC
86.
87. ;*****************************************************************
*************
88. ;Datos de la EEPROM
89. ;Los Datos a ser programados en la EEPROM son definidos aqui
90.
91. ORG 0xf00000
92.
93. DE "Test Data",0,1,2,3,4,5
94.
95. ;*****************************************************************
*************
96. ; Vector de Reset.
97. ; Este codigo comenzara a ejecutarse cuando suceda un reset
98.
99. ORG 0x0000
100.
101. goto Main ;Se va al inicio del
codigo principal
102.
103. ;*****************************************************************
*************
104. ; Vector de interrupcion de alta prioridad
105. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
106. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
107. ; no estan habilitadas
108.
109. ORG 0x0008
110.
111. bra HighInt
;Va a la rutina de interrupcion de alta prioridad
112.
113. ;*****************************************************************
*************
114. ; Vector de interrupcion de baja prioridad y rutina
115. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
116. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
117.
118. ORG 0x0018
119.
120. movff STATUS,STATUS_TEMP ;Salva el
registro STATUS
121. movff WREG,WREG_TEMP ;Salva el
registro de trabajo
122. movff BSR,BSR_TEMP ;Salva el
registro BSR
123.
124. ; *** El codigo de la interrupcion de baja prioridad va aqui
***
125.
126.
127. movff BSR_TEMP,BSR ;recupera
el registro BSR
128. movff WREG_TEMP,WREG ;recupera
el registro de trabajo
129. movff STATUS_TEMP,STATUS ;recupera
el registro STATUS
130. retfie
131.
132. ;*****************************************************************
*************
133. ; Rutina de interrupcion de alta prioridad
134. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
135. ; evitar conflictos con el vector de interrupciones de baja
prioridad
136.
137. HighInt:
138.
139. ; *** El codigo para las interrupciones de alta prioridad va
aqui ***
140.
141. retfie FAST
142.
143. ;*****************************************************************
*************
144. ; Comienzo del programa principal
145. ; El codigo del programa principal es colocado aqui
146.
147. Main:
148. ; *** EL codigo principal va aqui ***
149.
150. ;******************** Inicializacion de
perifericos *********************
151. movlw B'01100000'
152. movwf OSCCON ;Ajustamos
el oscilador interno a 4 MHz
153. movlw B'00001111'
154. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
155.
156. clrf TRISD,.0 ;Puerto D
como salida
157.
;Los demas se quedan como entradas
158. ;******************** Inicializacion de
Variables ************************
159. clrf Cont,.0 ;Cont = 0
160.
161. MainP0
162.
163. movf Cont,W,.0 ;W = Cont,
para realizar el despliegue
164. rcall Conv7Seg ;realizamo
s la conversion de BCD a 7 segmentos
165. movwf LATD,.0 ;movemos
el valor convertido al PORT D
166. movlw .1
167. movwf CantSeg ;CantSeg =
1 , para el retardo de 1 seg
168. rcall RetardoSeg ;Esperamos
1 seg
169. incf Cont,F,.0 ;Cont ++
170. movlw 0x0A
171. cpfseq Cont,.0 ;Cont ==
0x0A (Cont==WREG)?
172. bra MainP0 ;N
o => continuamos en el ciclo
173. clrf Cont,.0 ;Si
=> reiniciamos la cuenta (Cont = 0)
174. bra MainP0 ;C
ontinuamos con el ciclo
175.
176. ;********************** Conv7Seg ******************
*************************
177. ; Conv7Seg Esta subrutina maneja realiza el acceso a
la tabla BCD7Seg, recibe
178. ; en W un offset para que sea sumado
a TBLPTRL para asi acceder al
179. ; valor de 7 segmentos correspondiente al valor BCD recibido
en WREG
180. ;
181. ; Devuelve el valor de 7 seg en el registro W.
182. ;*****************************************************************
*****************
183. Conv7Seg
184. movwf TablaOffs,.0 ;Guardamos el
valor BCD recibido
185. movlw UPPER BCD7Seg ;tomamos la parte
mas alta de la dir de la tabla
186. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
187. movlw HIGH BCD7Seg ;tomamos la
parte alta de la dir de la tabla
188. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
189. movlw LOW BCD7Seg ;tomamos
la parte baja de la dir de la tabla
190. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
191.
;apuntado al inicio de la tabla BCD7seg
192. movf TablaOffs,W,.0 ;Nos preparamos
para recorrer la tabla
193. addwf TBLPTRL,F,.0 ;TBLPTR apunta al
valor de 7 seg que necesitamos
194. tblrd * ;L
eemos el valor de la tabla
195. movf TABLAT,W,.0 ;guardamos
el valor leido en WREG
196. return ;r
etornamos
197. ;*****************************************************************
*****************
198.
199. ;**************************** RetardoSeg ******************
****************
200. ; RetardoSeg Realiza una espera de la cantidad de
segundos indicados
201. ; mediante la variable CantSeg.
CantSeg es de 8 bits
202. ;*****************************************************************
************
203. RetardoSeg
204. movf CantSeg,W,.0
205. btfsc STATUS,Z ;CantSeg
== 0?
206. return ;S
i => retornamos
207. movlw 0x03 ;No =>
hacemos Cantms = 1000
208. movwf Cantms+1,.0
209. movlw 0xE8
210. movwf Cantms,.0
211. rcall Retardo_ms ;realizamo
s un retardo de 1000 ms
212. decf CantSeg,F,.0 ;CantSeg --,
213. bra RetardoSeg ;C
ontinuamos con el ciclo
214. ;*****************************************************************
************
215.
216. ;**************************** Retardo_ms ******************
****************
217. ; Retardo_ms Realiza un retardo de la cantidad de
milisegundos indicados
218. ; mediante Cantms y Cantms+1, Cantms
y Cantms+1 son tratados como
219. ; variables de 16 bits.
220. ;*****************************************************************
************
221. Retardo_ms
222. rcall Retardo1ms ;realizamo
s un retardo de 1 ms
223. decfsz Cantms,F,.0 ;Cantms --
, Cantms == 0
224. bra Retardo_ms ;n
o => vamos a Retardo_ms
225. movf Cantms+1,W,.0 ;
226. btfsc STATUS,Z ;Cantms+1
== 0?
227. return ;S
i => retornamos
228. decf Cantms+1,F,.0 ;No =>
decrementamos
229. bra Retardo_ms ;C
ontinuamos con el ciclo
230. ;*****************************************************************
************
231.
232. ;**************************** Retardo1ms ******************
****************
233. ; Retardo1ms realiza una espera de 1 ms decrementado W
249 veces en un ciclo
234. ; que ocupa 4 us
235. ;*****************************************************************
************
236. Retardo1ms
237. movlw .249
238. Retardo1msP0
239. addlw 0xFF ;W--
240. btfss STATUS,Z,.0 ;W == 0?
241. bra Retardo1msP0 ;No =>
seguimos esperando
242. return ;S
i => ya paso 1 ms
243. ;*****************************************************************
************
244.
245.
246. ORG 0x800
247.
248.
249. ;******************************* BCD7Seg **********
*************************
250. ; BCD7Seg Es una tabla que se utiliza para convertir
valores BCD a 7 Segmentos
251. ;
252. ; |RB7|RB6|RB5|RB4 | |RB3|RB2|RB1|RB0| |
253. ; |DP |G |F |E | |D |C
|B |A |Hex|
254. ; |---|---|---|-------|---|---|---|---|---|
255. ; 0 |1 |1 |0 |0 | 0 |0
|0 |0 |C0 |
256. ; 1 |1 |1 |1 |1 | 1 |0 |0
|1 |F9 |
257. ; 2 |1 |0 |1 |0 | 0 |1 |0
|0 |A4 |
258. ; 3 |1 |0 |1 |1 | 0 |0 |0
|0 |B0 |
259. ; 4 |1 |0 |0 |1 | 1 |0 |0
|1 |99 |
260. ; 5 |1 |0 |0 |1 | 0 |0 |1
|0 |92 |
261. ; 6 |1 |0 |0 |0 | 0 |0
|1 |0 |82 |
262. ; 7 |1 |1 |1 |1 | 1 |0
|0 |0 |F8 |
263. ; 8 |1 |0 |0 |0 | 0 |0
|0 |0 |80 |
264. ; 9 |1 |0 |0 |1 | 0 |0
|0 |0 |90 |
265. ;*****************************************************************
*****************
266. BCD7Seg
267. ; 0 1 2 3 4
5 6 7 8 9

268. DB 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x
80,0x90
269. ;*****************************************************************
*****************
270.
271.
272. END ;Directiva fin del
programa

;***************************************************************
***************

;
*
; Nombre: IntExt1y2.asm
; Fecha: 09/08/2008
; Version: v0.90

;
*
; Autor: Sander
; Empresa:

;
*

;***************************************************************
***************

;
*
; Archivos Requeridos: P18F4550.INC

;
*

;***************************************************************
***************
; Notas: Este programa mostrara el uso de las
interrupciones INT1, INT2
; asignandoles prioridades diferentes a cada una.
;
; El programa controlara un display de 7 segmentos de
acuerdo al estado de dos
; pulsadores que se conectaran a RB1(INT1) y RB2(INT2)
;
; RB1(INT1) hara que el display incremente y su
interrupcion tendra prioridad
; alta
; RB2(INT2) hara que el display decremente y su
interrupcion tendra prioridad
; baja
;
; Para que pueda verse el efecto de la asigancion de
prioridades, es decir, que
; la interrupcion de alta prioridad se ejecute aun
cuando se esta ejecutando
; la interrupcion de baja prioridad, el incremento o
decremento se lo hara en la
; misma rutina de interrupcion.
;
; Para realizar retardos se usaran las rutinas de retardo
del proyecto
; parpadea, el display de 7 segmentos se incrementara de
0 a F, se habilitaran las
; resistencias de PULL-UP y para convertir el valor BCD
que cuenta se implementara
; una tabla en la memoria de programa usando la directiva
DB
;
; La conexion del display de anodo comun , y de los
pulsadores sera como se muestra
; a continuacion
;
; _Vdd_

;
|
; ____________|_
; | |
; A(RD0) --
>| AAAAAAA |
; B(RD1) --
>| F B | _|_
; C(RD2) --
>| F B | X-0 0---
> RB1(INT1)
; D(RD3) --
>| F B | |

; | GGGGGG |
| _|_
; E(RD4) --
>| E C | X-0 0--->
RB2(INT2)
; F(RD5) --
>| E C | |
; G(RD6) --
>| E C | |
; DP(RD7) --
>| DDDDDDD DP| -GND-
; |______________|
;

;***************************************************************
***************

LIST P=18F4550 ;Directiva para


definir el procesador
#include <P18F4550.INC> ;Definicion de SFRs
para el procesador

;***************************************************************
***************
;Bits de Configuracion
;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
;revisar el archivo P18F4550.INC para informacion adicional de
la notacion
;Abajo hay algunos ejemplos

;******** Configuracion del Oscilador **********


CONFIG FOSC = INTOSCIO_EC ;Osc interno, RA6
como pin, USB usa Osc EC
;******** Otros bits de configuracion **********
CONFIG PWRT =
ON ;PWRT habilitado
CONFIG BOR =
OFF ;Brown out resete
deshabilitado
CONFIG WDT =
OFF ;Watch dog
deshabilitado
CONFIG MCLRE =
OFF ;MCLR como entrada
CONFIG PBADEN =
ON ;Todos los pines como
entradas analogicas
CONFIG LVP =
OFF ;Programacion en bajo
voltaje apagado
;********* Bits de proteccion ******************
CONFIG CP0 =
OFF ;los bloques del codigo de
programa
CONFIG CP1 =
OFF ;no estan protegidos
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB =
OFF ;Sector Boot no esta
protegido
CONFIG CPD =
OFF ;La EEPROM no esta
protegida

;***************************************************************
***************
; Definicion de variables
; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
; interrupcion.

CBLOCK 0x080
WREG_TEMP ;variable usada para
salvar contexto
STATUS_TEMP ;variable usada para
salvar contexto
BSR_TEMP ;variable usada para
salvar contexto
ENDC

CBLOCK 0x000 ;Variables en la ACCESS RAM


(Banco 0) max 96 bytes
Cantms:2 ;variable para generar
hasta 65535 ms
CantSeg ;Variable para producir
retardos de hasta 255 seg
Cont ;Variable para realizar
el conteo
TablaOffs ;Para movernos por la
tabla
ENDC

#DEFINE BotU PORTB,.1


#DEFINE BotD PORTB,.2


;***************************************************************
***************
;Datos de la EEPROM
;Los Datos a ser programados en la EEPROM son definidos aqui

ORG 0xf00000

DE "Test Data",0,1,2,3,4,5

;***************************************************************
***************
; Vector de Reset.
; Este codigo comenzara a ejecutarse cuando suceda un reset

ORG 0x0000

goto Main ;Se va al inicio del


codigo principal

;***************************************************************
***************
; Vector de interrupcion de alta prioridad
; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
; o cuando cualquier interrupcion ocurra si es que las
prioridades de las interrupciones
; no estan habilitadas

ORG 0x0008

bra HighInt
;Va a la rutina de interrupcion de alta prioridad

;***************************************************************
***************
; Vector de interrupcion de baja prioridad y rutina
; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas

ORG 0x0018

movff STATUS,STATUS_TEMP ;Salva


el registro STATUS
movff WREG,WREG_TEMP ;Salva
el registro de trabajo
movff BSR,BSR_TEMP ;Salva
el registro BSR
;********* El codigo de la interrupcion de baja prioridad va
aqui **************

btfsc INTCON3,INT2IF,.0 ;INT2IF


== 1?(ocurrio la INT2?)
bra IntINT2
;Si => vamos a su rutina
movlw B'10110110'
;No => un error extrao sucedio,encedemos los
movwf LATD,.0
;segmentos A,D y G para indicarlo y detenemos
bcf INTCON,GIEH
;la ejecucion el programa
bcf INTCON,GIEL

sleep
IntINT2
clrf Cantms+1,.0
movlw .50
;Hacemos un retardo de 50 ms para antirrebote
movwf Cantms,.0
rcall Retardo_ms
IntINT2_0
btfsc BotD
;Sigue presionado el boton de decremento?
bra IntINT2_X
;No => vamos a salir de esta interrupcion
decf Cont,F,.0
;Si => Cont --
movlw 0xFF
cpfseq Cont,.0
;Cont == 0xFF (Cont==WREG)?
bra IntINT2_00
;No => vamos a actualizar el display
movlw 0x0F
;Si => reiniciamos el decremento
movwf Cont,.0
; y continuamos actualizando el display
IntINT2_00
movf Cont,W,.0
;W = Cont, para realizar el despliegue
rcall Conv7Seg
;realizamos la conversion de BCD a 7 segmentos
movwf LATD,.0
;movemos el valor convertido al PORT D
movlw .1
movwf CantSeg,.0
;realizamos una espera de 1 seg, para
rcall RetardoSeg
;ver el cambio en el display
bra IntINT2_0
;volvemos a revisar el boton
IntINT2_X
bcf INTCON3,INT2IF
;Para dar por terminada la interrupcion y

;salir de las interrupciones de baja prioridad


X_IntLow
movff BSR_TEMP,BSR ;recupe
ra el registro BSR
movff WREG_TEMP,WREG ;recupe
ra el registro de trabajo
movff STATUS_TEMP,STATUS ;recupe
ra el registro STATUS
retfie

;***************************************************************
***************
; Rutina de interrupcion de alta prioridad
; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
; evitar conflictos con el vector de interrupciones de baja
prioridad

HighInt:

; *** El codigo para las interrupciones de alta prioridad


va aqui ***
btfsc INTCON3,INT1IF,.0 ;INT1IF
== 1?(ocurrio la INT1?)
bra IntINT1
;Si => vamos a su rutina
movlw B'10110110'
;No => un error extrao sucedio,encedemos los
movwf LATD,.0
;segmentos A,D y G para indicarlo y detenemos
bcf INTCON,GIEH
;la ejecucion el programa
bcf INTCON,GIEL

sleep
IntINT1
clrf Cantms+1,.0
movlw .50
;Hacemos un retardo de 50 ms para antirrebote
movwf Cantms,.0
rcall Retardo_ms
IntINT1_0
btfsc BotU
;Sigue presionado el boton de incremento?
bra IntINT1_X
;No => vamos a salir de esta interrupcion
incf Cont,F,.0
;Si => Cont ++
movlw 0x10
cpfseq Cont,.0
;Cont == 0x10 (Cont==WREG)?
bra IntINT1_00
;No => vamos a actualizar el display
clrf Cont,.0
;Si => reiniciamos el incremento

; y continuamos actualizando el display


IntINT1_00
movf Cont,W,.0
;W = Cont, para realizar el despliegue
rcall Conv7Seg
;realizamos la conversion de BCD a 7 segmentos
movwf LATD,.0
;movemos el valor convertido al PORT D
movlw .1
movwf CantSeg,.0
;realizamos una espera de 1 seg, para
rcall RetardoSeg
;ver el cambio en el display
bra IntINT1_0
;volvemos a revisar el boton
IntINT1_X
bcf INTCON3,INT1IF
;Para dar por terminada la interrupcion y

;salir de las interrupciones de alta prioridad


X_IntHigh
retfie FAST

;***************************************************************
***************
; Comienzo del programa principal
; El codigo del programa principal es colocado aqui

Main:
; *** EL codigo principal va aqui ***

;******************** Inicializacion de
perifericos *********************
movlw B'01100000'
movwf OSCCON ;Ajusta
mos el oscilador interno a 4 MHz
movlw B'00001111'
movwf ADCON1,.0 ;Todos
los pines como I/O digitales

clrf TRISD,.0 ;Puerto


D como salida

;Los demas se quedan como entradas


movlw B'01000101' ;habili
tamos PULL-UPs(bit 7), y hacemos que
movwf INTCON2,.0 ;INT1 e
INT2 se activen en flanco de bajada

;(Bits 4 y 5), lo demas se queda como estaba


movlw B'01011000' ;Asigna
mos prioridades(Bits 7 y 6), y habilitamos
movwf INTCON3,.0 ;las
interrupciones para INT1 e INT2 (bits 3 y 4)

bsf RCON,IPEN,.0 ;Habili


tamos las prioridades para las interrupciones

;******************** Inicializacion de
Variables ************************
clrf Cont,.0 ;Cont =
0

;***************************************************************
************
bsf INTCON,GIEH,.0 ;Habili
tamos las interrupciones de prioridad alta
bsf INTCON,GIEL,.0 ;y las
de prioridad baja

movf Cont,W,.0 ;W =
Cont, para realizar el despliegue
rcall Conv7Seg ;realiz
amos la conversion de BCD a 7 segmentos
movwf LATD,.0 ;movemo
s el valor convertido al PORT D

MainP0

bra MainP0
;Continuamos con el ciclo

;********************** Conv7Seg ****************


***************************
; Conv7Seg Esta subrutina maneja realiza el acceso
a la tabla BCD7Seg, recibe
; en W un offset para que sea
sumado a TBLPTRL para asi acceder al
; valor de 7 segmentos correspondiente al valor BCD
recibido en WREG
;
; Devuelve el valor de 7 seg en el registro W.

;***************************************************************
*******************
Conv7Seg
movwf TablaOffs,.0 ;Guardamos el
valor BCD recibido
movlw UPPER BCD7Seg ;tomamos la
parte mas alta de la dir de la tabla
movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
movlw HIGH BCD7Seg ;tomamos la
parte alta de la dir de la tabla
movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
movlw LOW
BCD7Seg ;tomamos la parte baja de la
dir de la tabla
movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR

;apuntado al inicio de la tabla BCD7seg


movf TablaOffs,W,.0 ;Nos preparamos
para recorrer la tabla
addwf TBLPTRL,F,.0 ;TBLPTR apunta
al valor de 7 seg que necesitamos
tblrd *
;Leemos el valor de la tabla
movf TABLAT,W,.0 ;guarda
mos el valor leido en WREG
return
;retornamos

;***************************************************************
*******************

;**************************** RetardoSeg ****************


******************
; RetardoSeg Realiza una espera de la cantidad de
segundos indicados
; mediante la variable CantSeg.
CantSeg es de 8 bits

;***************************************************************
**************
RetardoSeg
movf CantSeg,W,.0
btfsc STATUS,Z ;CantSe
g == 0?
return
;Si => retornamos
movlw 0x03 ;No =>
hacemos Cantms = 1000
movwf Cantms+1,.0
movlw 0xE8
movwf Cantms,.0
rcall Retardo_ms ;realiz
amos un retardo de 1000 ms
decf CantSeg,F,.0 ;CantSeg --,
bra RetardoSeg
;Continuamos con el ciclo

;***************************************************************
**************

;**************************** Retardo_ms ****************


******************
; Retardo_ms Realiza un retardo de la cantidad de
milisegundos indicados
; mediante Cantms y Cantms+1,
Cantms y Cantms+1 son tratados como
; variables de 16 bits.

;***************************************************************
**************
Retardo_ms
rcall Retardo1ms ;realiz
amos un retardo de 1 ms
decfsz Cantms,F,.0 ;Cantms
--, Cantms == 0
bra Retardo_ms
;no => vamos a Retardo_ms
movf Cantms+1,W,.0 ;
btfsc STATUS,Z ;Cantms
+1 == 0?
return
;Si => retornamos
decf Cantms+1,F,.0 ;No =>
decrementamos
bra Retardo_ms
;Continuamos con el ciclo

;***************************************************************
**************

;**************************** Retardo1ms ****************


******************
; Retardo1ms realiza una espera de 1 ms decrementado
W 249 veces en un ciclo
; que ocupa 4 us

;***************************************************************
**************
Retardo1ms
movlw .249
Retardo1msP0
addlw 0xFF ;W--
btfss STATUS,Z,.0 ;W ==
0?
bra Retardo1msP0 ;No =>
seguimos esperando
return
;Si => ya paso 1 ms

;***************************************************************
**************

ORG 0x800

;******************************* BCD7Seg ********


***************************
; BCD7Seg Es una tabla que se utiliza para
convertir valores BCD a 7 Segmentos
;
; |RB7|RB6|RB5|RB4
| |RB3|RB2|RB1|RB0| |

; |DP |G |F |E | |D
|C |B |A |Hex|
; |---|---|---|-------|---|---|---|---|---|

; 0 |1 |1 |0 |0 | 0
|0 |0 |0 |C0 |

; 1 |1 |1 |1 |1 | 1 |0
|0 |1 |F9 |

; 2 |1 |0 |1 |0 | 0 |1
|0 |0 |A4 |

; 3 |1 |0 |1 |1 | 0 |0
|0 |0 |B0 |

; 4 |1 |0 |0 |1 | 1 |0
|0 |1 |99 |

; 5 |1 |0 |0 |1 | 0 |0
|1 |0 |92 |

; 6 |1 |0 |0 |0 | 0
|0 |1 |0 |82 |

; 7 |1 |1 |1 |1 | 1
|0 |0 |0 |F8 |

; 8 |1 |0 |0 |0 | 0
|0 |0 |0 |80 |

; 9 |1 |0 |0 |1 | 0
|0 |0 |0 |90 |

; A |1 |0 |0 |0 | 1
|0 |0 |0 |88 |

; B |1 |0 |0 |0 | 0
|0 |1 |1 |83 |

; C |1 |1 |0 |0 | 0
|1 |1 |0 |C6 |

; D |1 |0 |1 |0 | 0
|0 |0 |1 |A1 |

; E |1 |0 |0 |0 | 0
|1 |1 |0 |86 |

; F |1 |0 |0 |0 | 1
|1 |1 |0 |8E |

;***************************************************************
*******************
BCD7Seg
; 0 1 2 3
4 5 6 7 8 9 A
B C D E F
DB 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8
,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E

;***************************************************************
*******************

END ;Directiva fin del


programa

1. ;**********************************************************************
********
2. ;
*
3. ; Nombre: IntExt1y2_1.asm
4. ; Fecha: 12/08/2008
5. ; Version: v1.00
6. ;
*
7. ; Autor: Sander
8. ; Empresa:
9. ;
*
10. ;*****************************************************************
*************
11. ;
*
12. ; Archivos Requeridos: P18F4550.INC
13. ;
*
14. ;*****************************************************************
*************
15. ; Notas: Este programa mostrara el uso de las
interrupciones INT1, INT2
16. ; asignandoles prioridades diferentes a cada una.
17. ;
18. ; El programa controlara un display de 7 segmentos de
acuerdo al estado de dos
19. ; pulsadores que se conectaran a RB1(INT1) y RB2(INT2)
20. ;
21. ; RB1(INT1) hara que el display incremente y su interrupcion
tendra prioridad
22. ; alta
23. ; RB2(INT2) hara que el display decremente y su interrupcion
tendra prioridad
24. ; baja
25. ;
26. ; Para que pueda verse el efecto de la asigancion de
prioridades, es decir, que
27. ; la interrupcion de alta prioridad se ejecute aun cuando
se esta ejecutando
28. ; la interrupcion de baja prioridad, el incremento o
decremento se lo hara en la
29. ; misma rutina de interrupcion.
30. ;
31. ; Para realizar retardos se usaran las rutinas de retardo
del proyecto
32. ; parpadea, el display de 7 segmentos se incrementara de 0 a
F, se habilitaran las
33. ; resistencias de PULL-UP y para convertir el valor BCD que
cuenta se implementara
34. ; una tabla en la memoria de programa usando la directiva DB
35. ;
36. ; La conexion del display de anodo comun , y de los
pulsadores sera como se muestra
37. ; a continuacion
38. ;
39. ; _Vdd_
40. ; |
41. ; ____________|_
42. ; | |
43. ; A(RD0) --
>| AAAAAAA |
44. ; B(RD1) --
>| F B | _|_
45. ; C(RD2) --
>| F B | X-0 0--->
RB1(INT1)
46. ; D(RD3) --
>| F B | |
47. ; | GGGGGG |
| _|_
48. ; E(RD4) --
>| E C | X-0 0---> RB2(INT2)
49. ; F(RD5) --
>| E C | |
50. ; G(RD6) --
>| E C | |
51. ; DP(RD7) --
>| DDDDDDD DP| -GND-
52. ; |______________|
53. ;
54.
55. ; Esta version corrige los errores vistos en la simulacion
al momento
56. ; de pasar de la interrupcion de baja prioridad a la de alta
prioridad, para esto
57. ; usaremos la bandera IntHigh_F que le indicara a la
interrupcion de baja
58. ; prioridad que se produjo una interrupcion de alta
prioridad, ademas guardaremos
59. ; las variables que son compartidas por ambas interrupciones
en la PILA
60. ;*****************************************************************
*************
61.
62. LIST P=18F4550 ;Directiva para
definir el procesador
63. #include <P18F4550.INC> ;Definicion de SFRs para
el procesador
64.
65. ;*****************************************************************
*************
66. ;Bits de Configuracion
67. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
68. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
69. ;Abajo hay algunos ejemplos
70.
71. ;******** Configuracion del Oscilador **********
72. CONFIG FOSC = INTOSCIO_EC ;Osc interno, RA6 como
pin, USB usa Osc EC
73. ;******** Otros bits de configuracion **********
74. CONFIG PWRT =
ON ;PWRT habilitado
75. CONFIG BOR =
OFF ;Brown out resete
deshabilitado
76. CONFIG WDT =
OFF ;Watch dog deshabilitado
77. CONFIG MCLRE =
OFF ;MCLR como entrada
78. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
79. CONFIG LVP =
OFF ;Programacion en bajo voltaje
apagado
80. ;********* Bits de proteccion ******************
81. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
82. CONFIG CP1 =
OFF ;no estan protegidos
83. CONFIG CP2 = OFF
84. CONFIG CP3 = OFF
85. CONFIG CPB =
OFF ;Sector Boot no esta protegido
86. CONFIG CPD =
OFF ;La EEPROM no esta protegida
87. ;*****************************************************************
*************
88. ; Definicion de variables
89. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
90. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
91. ; interrupcion.
92.
93. CBLOCK 0x080
94. WREG_TEMP ;variable usada para salvar
contexto
95. STATUS_TEMP ;variable usada para salvar
contexto
96. BSR_TEMP ;variable usada para salvar
contexto
97. ENDC
98.
99. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco 0) max
96 bytes
100. Cantms:2 ;variable para generar hasta 65535
ms
101. CantSeg ;Variable para producir retardos
de hasta 255 seg
102. Cont ;Variable para realizar el conteo
103. Banderas ;Variable para el manejo de
banderas, que controlan la ejecucion
104. TablaOffs ;Para movernos por la tabla
105. ENDC
106.
107. #DEFINE BotU PORTB,.1
108. #DEFINE BotD PORTB,.2
109.
110. #DEFINE IntHigh_F Banderas,.0,.0
111. ;*****************************************************************
*************
112. ;Datos de la EEPROM
113. ;Los Datos a ser programados en la EEPROM son definidos aqui
114.
115. ORG 0xf00000
116.
117. DE "Test Data",0,1,2,3,4,5
118.
119. ;*****************************************************************
*************
120. ; Vector de Reset.
121. ; Este codigo comenzara a ejecutarse cuando suceda un reset
122.
123. ORG 0x0000
124.
125. goto Main ;Se va al inicio del codigo
principal
126.
127. ;*****************************************************************
*************
128. ; Vector de interrupcion de alta prioridad
129. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
130. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
131. ; no estan habilitadas
132.
133. ORG 0x0008
134.
135. bra HighInt ;V
a a la rutina de interrupcion de alta prioridad
136.
137. ;*****************************************************************
*************
138. ; Vector de interrupcion de baja prioridad y rutina
139. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
140. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
141.
142. ORG 0x0018
143.
144. movff STATUS,STATUS_TEMP ;Salva el registro
STATUS
145. movff WREG,WREG_TEMP ;Salva el registro
de trabajo
146. movff BSR,BSR_TEMP ;Salva el registro
BSR
147. ;********* El codigo de la interrupcion de baja prioridad va aqui
**************
148.
149. btfsc INTCON3,INT2IF,.0 ;INT2IF ==
1?(ocurrio la INT2?)
150. bra IntINT2 ;S
i => vamos a su rutina
151. movlw B'10110110' ;No => un
error extrao sucedio,encedemos los
152. movwf LATD,.0 ;segmentos
A,D y G para indicarlo y detenemos
153. bcf INTCON,GIEH ;l
a ejecucion el programa
154. bcf INTCON,GIEL
155. sleep
156. IntINT2
157. clrf Cantms+1,.0
158. movlw .50 ;H
acemos un retardo de 50 ms para antirrebote
159. movwf Cantms,.0
160. rcall Retardo_ms
161. IntINT2_0
162. bcf IntHigh_F ;p
onemos en cero esta bandera, por si venimos
163.
;de la interrupcion alta
164. btfsc BotD ;Sigue
presionado el boton de decremento?
165. bra IntINT2_X ;N
o => vamos a salir de esta interrupcion
166. btfsc IntHigh_F ;Se
produjo una interrupcion de mayor prioridad?
167. bra IntINT2_0 ;S
i => usamos el valor de Cont que dejo la int alta
168. decf Cont,F,.0 ;Si =>
Cont --
169. movlw 0xFF
170. cpfseq Cont,.0 ;Cont ==
0xFF (Cont==WREG)?
171. bra IntINT2_00 ;N
o => vamos a actualizar el display
172. movlw 0x0F ;Si =>
reiniciamos el decremento
173. movwf Cont,.0 ; y
continuamos actualizando el display
174. IntINT2_00
175. movf Cont,W,.0 ;W = Cont,
para realizar el despliegue
176. rcall Conv7Seg ;realizamo
s la conversion de BCD a 7 segmentos
177. btfsc IntHigh_F ;Se
produjo una interrupcion de mayor prioridad?
178. bra IntINT2_0 ;S
i => usamos el valor de Cont que dejo la int alta
179. movwf LATD,.0 ;No =>
movemos el valor convertido al PORT D
180. movlw .1
181. movwf CantSeg,.0 ;realizamo
s una espera de 1 seg, para
182. rcall RetardoSeg ;ver el
cambio en el display
183. bra IntINT2_0 ;v
olvemos a revisar el boton
184. IntINT2_X
185. bcf INTCON3,INT2IF ;Para dar
por terminada la interrupcion y
186.
;salir de las interrupciones de baja prioridad
187. X_IntLow
188. movff BSR_TEMP,BSR ;recupera el
registro BSR
189. movff WREG_TEMP,WREG ;recupera el
registro de trabajo
190. movff STATUS_TEMP,STATUS ;recupera el
registro STATUS
191. retfie
192. ;*****************************************************************
*************
193. ; Rutina de interrupcion de alta prioridad
194. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
195. ; evitar conflictos con el vector de interrupciones de baja
prioridad
196.
197. HighInt:
198. ;****** El codigo para las interrupciones de alta prioridad va
aqui ******
199.
200. push ;P
ara comenzar a guarda las variables que se
201.
;comparten en la pila, primero apilamos la direccion
202.
;actual
203.
204. movf Cantms,W,.0 ;Guardamos
Cantms en la parte baja del
205. movwf TOSL ;Top Of
Stack
206. movf Cantms+1,W,.0 ;Guardamos
Cantms+1 en la parte alta del
207. movwf TOSH ;Top Of
Stack
208.
209. push ;a
pilamos la direccion actual
210. movf CantSeg,W,.0 ;Guardamos Cantms
en la parte baja del
211. movwf TOSL ;Top Of
Stack
212.
213. btfsc INTCON3,INT1IF,.0 ;INT1IF ==
1?(ocurrio la INT1?)
214. bra IntINT1 ;S
i => vamos a su rutina
215. movlw B'10110110' ;No => un
error extrao sucedio,encedemos los
216. movwf LATD,.0 ;segmentos
A,D y G para indicarlo y detenemos
217. bcf INTCON,GIEH ;l
a ejecucion el programa
218. bcf INTCON,GIEL
219. sleep
220. IntINT1
221. clrf Cantms+1,.0
222. movlw .50 ;H
acemos un retardo de 50 ms para antirrebote
223. movwf Cantms,.0
224. rcall Retardo_ms
225. IntINT1_0
226. btfsc BotU ;Sigue
presionado el boton de incremento?
227. bra IntINT1_X ;N
o => vamos a salir de esta interrupcion
228. incf Cont,F,.0 ;Si =>
Cont ++
229. movlw 0x10
230. cpfseq Cont,.0 ;Cont ==
0x10 (Cont==WREG)?
231. bra IntINT1_00 ;N
o => vamos a actualizar el display
232. clrf Cont,.0 ;Si =>
reiniciamos el incremento
233.
; y continuamos actualizando el display
234. IntINT1_00
235. movf Cont,W,.0 ;W = Cont,
para realizar el despliegue
236. rcall Conv7Seg ;realizamo
s la conversion de BCD a 7 segmentos
237. movwf LATD,.0 ;movemos
el valor convertido al PORT D
238. movlw .1
239. movwf CantSeg,.0 ;realizamo
s una espera de 1 seg, para
240. rcall RetardoSeg ;ver el
cambio en el display
241. bra IntINT1_0 ;v
olvemos a revisar el boton
242. IntINT1_X
243. ;************ Recuperamos los valores de la
pila ****************
244. movff TOSL,CantSeg ;Recuperamos el
valor guardado, primero CantSeg
245. pop
;El pop efectivamente decrementa el STKPTR y
246.
;descarta e valor de TOS
247.
248. movff TOSL,Cantms ;Recuperam
os Cantms
249. movff TOSH,Cantms+1 ;y Cantms+1
250. pop
;STKPTR --, y descartamos TOS
251.
252. bcf INTCON3,INT1IF ;Para dar
por terminada la interrupcion y
253.
;salir de las interrupciones de alta prioridad
254. bsf IntHigh_F ;p
onemos en 1 esta bandera par indicar que se produjo
255.
;esta interrupcion
256. X_IntHigh
257. retfie FAST
258.
259. ;*****************************************************************
*************
260. ; Comienzo del programa principal
261. ; El codigo del programa principal es colocado aqui
262.
263. Main:
264. ; *** EL codigo principal va aqui ***
265.
266. ;******************** Inicializacion de
perifericos *********************
267. movlw B'01100000'
268. movwf OSCCON ;Ajustamos
el oscilador interno a 4 MHz
269. movlw B'00001111'
270. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
271.
272. clrf TRISD,.0 ;Puerto D
como salida
273.
;Los demas se quedan como entradas
274. movlw B'01000101' ;habilitam
os PULL-UPs(bit 7), y hacemos que
275. movwf INTCON2,.0 ;INT1 e
INT2 se activen en flanco de bajada
276.
;(Bits 4 y 5), lo demas se queda como estaba
277. movlw B'01011000' ;Asignamos
prioridades(Bits 7 y 6), y habilitamos
278. movwf INTCON3,.0 ;las
interrupciones para INT1 e INT2 (bits 3 y 4)
279.
280. bsf RCON,IPEN,.0 ;Habilitam
os las prioridades para las interrupciones
281.
282. ;******************** Inicializacion de
Variables ************************
283. clrf Cont,.0 ;Cont = 0
284. clrf Banderas,.0 ;Banderas
= 0
285. ;*****************************************************************
**********
286. bsf INTCON,GIEH,.0 ;Habilitam
os las interrupciones de prioridad alta
287. bsf INTCON,GIEL,.0 ;y las de
prioridad baja
288.
289. movf Cont,W,.0 ;W = Cont,
para realizar el primer despliegue
290. rcall Conv7Seg ;realizamo
s la conversion de BCD a 7 segmentos
291. movwf LATD,.0 ;movemos
el valor convertido al PORT D
292.
293. MainP0
294.
295. bra MainP0 ;C
ontinuamos con el ciclo, esperando que las
296.
;interrupciones cambien el valor del display
297.
298.
299. ;********************** Conv7Seg ******************
*************************
300. ; Conv7Seg Esta subrutina maneja realiza el acceso a
la tabla BCD7Seg, recibe
301. ; en W un offset para que sea sumado
a TBLPTRL para asi acceder al
302. ; valor de 7 segmentos correspondiente al valor BCD recibido
en WREG
303. ;
304. ; Devuelve el valor de 7 seg en el registro W.
305. ;*****************************************************************
*****************
306. Conv7Seg
307. movwf TablaOffs,.0 ;Guardamos el
valor BCD recibido
308. movlw UPPER BCD7Seg ;tomamos la parte
mas alta de la dir de la tabla
309. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
310. movlw HIGH BCD7Seg ;tomamos la
parte alta de la dir de la tabla
311. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
312. movlw LOW BCD7Seg ;tomamos
la parte baja de la dir de la tabla
313. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
314.
;apuntado al inicio de la tabla BCD7seg
315. movf TablaOffs,W,.0 ;Nos preparamos
para recorrer la tabla
316. addwf TBLPTRL,F,.0 ;TBLPTR apunta al
valor de 7 seg que necesitamos
317. tblrd * ;L
eemos el valor de la tabla
318. movf TABLAT,W,.0 ;guardamos
el valor leido en WREG
319. return ;r
etornamos
320. ;*****************************************************************
*****************
321.
322. ;**************************** RetardoSeg ******************
****************
323. ; RetardoSeg Realiza una espera de la cantidad de
segundos indicados
324. ; mediante la variable CantSeg.
CantSeg es de 8 bits
325. ;*****************************************************************
************
326. RetardoSeg
327. movf CantSeg,W,.0
328. btfsc STATUS,Z ;CantSeg
== 0?
329. return ;S
i => retornamos
330. movlw 0x03 ;No =>
hacemos Cantms = 1000
331. movwf Cantms+1,.0
332. movlw 0xE8
333. movwf Cantms,.0
334. rcall Retardo_ms ;realizamo
s un retardo de 1000 ms
335. decf CantSeg,F,.0 ;CantSeg --,
336. bra RetardoSeg ;C
ontinuamos con el ciclo
337. ;*****************************************************************
************
338.
339. ;**************************** Retardo_ms ******************
****************
340. ; Retardo_ms Realiza un retardo de la cantidad de
milisegundos indicados
341. ; mediante Cantms y Cantms+1, Cantms
y Cantms+1 son tratados como
342. ; variables de 16 bits.
343. ;*****************************************************************
************
344. Retardo_ms
345. rcall Retardo1ms ;realizamo
s un retardo de 1 ms
346. decfsz Cantms,F,.0 ;Cantms --
, Cantms == 0
347. bra Retardo_ms ;n
o => vamos a Retardo_ms
348. movf Cantms+1,W,.0 ;
349. btfsc STATUS,Z ;Cantms+1
== 0?
350. return ;S
i => retornamos
351. decf Cantms+1,F,.0 ;No =>
decrementamos
352. bra Retardo_ms ;C
ontinuamos con el ciclo
353. ;*****************************************************************
************
354.
355. ;**************************** Retardo1ms ******************
****************
356. ; Retardo1ms realiza una espera de 1 ms decrementado W
249 veces en un ciclo
357. ; que ocupa 4 us
358. ;*****************************************************************
************
359. Retardo1ms
360. movlw .249
361. Retardo1msP0
362. addlw 0xFF ;W--
363. btfss STATUS,Z,.0 ;W == 0?
364. bra Retardo1msP0 ;No =>
seguimos esperando
365. return ;S
i => ya paso 1 ms
366. ;*****************************************************************
************
367.
368.
369. ORG 0x800
370.
371.
372. ;******************************* BCD7Seg **********
*************************
373. ; BCD7Seg Es una tabla que se utiliza para convertir
valores BCD a 7 Segmentos
374. ;
375. ; |RB7|RB6|RB5|RB4 | |RB3|RB2|RB1|RB0| |
376. ; |DP |G |F |E | |D |C
|B |A |Hex|
377. ; |---|---|---|-------|---|---|---|---|---|
378. ; 0 |1 |1 |0 |0 | 0 |0
|0 |0 |C0 |
379. ; 1 |1 |1 |1 |1 | 1 |0 |0
|1 |F9 |
380. ; 2 |1 |0 |1 |0 | 0 |1 |0
|0 |A4 |
381. ; 3 |1 |0 |1 |1 | 0 |0 |0
|0 |B0 |
382. ; 4 |1 |0 |0 |1 | 1 |0 |0
|1 |99 |
383. ; 5 |1 |0 |0 |1 | 0 |0 |1
|0 |92 |
384. ; 6 |1 |0 |0 |0 | 0 |0
|1 |0 |82 |
385. ; 7 |1 |1 |1 |1 | 1 |0
|0 |0 |F8 |
386. ; 8 |1 |0 |0 |0 | 0 |0
|0 |0 |80 |
387. ; 9 |1 |0 |0 |1 | 0 |0
|0 |0 |90 |
388. ; A |1 |0 |0 |0 | 1 |0
|0 |0 |88 |
389. ; B |1 |0 |0 |0 | 0 |0
|1 |1 |83 |
390. ; C |1 |1 |0 |0 | 0 |1
|1 |0 |C6 |
391. ; D |1 |0 |1 |0 | 0 |0
|0 |1 |A1 |
392. ; E |1 |0 |0 |0 | 0 |1
|1 |0 |86 |
393. ; F |1 |0 |0 |0 | 1 |1
|1 |0 |8E |
394. ;*****************************************************************
*****************
395. BCD7Seg
396. ; 0 1 2 3 4 5
6 7 8 9 A B C
D E F
397. DB 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
0x88,0x83,0xC6,0xA1,0x86,0x8E
398. ;*****************************************************************
*****************
399.
400.
401. END ;Directiva fin del
programa

1. ;**********************************************************************
********
2. ;
*
3. ; Nombre: parpadea.asm
4. ; Fecha: 30-07-2008
5. ; Version: V1.00
6. ;
*
7. ; Autor: Sander
8. ; Empresa:
9. ;
*
10. ;*****************************************************************
*************
11. ;
*
12. ; Archivos Requeridos: P18F4550.INC
13. ;
*
14. ;*****************************************************************
*************
15. ; Notas:Este programa implementa rutinas de retardos de 1
ms, 1 seg
16. ; para asi poder realizar un parpadeo de 1 seg de todos los
pines del
17. ; PIC18F4550, estas rutinas estan hechas para un oscilador
de 4 MHz
18. ;*****************************************************************
*************
19.
20. LIST P=18F4550 ;Directiva para definir el
procesador
21. #include <P18F4550.INC> ;Definicion de SFRs para el
procesador
22.
23. ;*****************************************************************
*************
24. ;Bits de Configuracion
25. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
26. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
27. ;Abajo hay algunos ejemplos
28.
29. ;******** Configuracion del Oscilador **********
30. CONFIG FOSC = INTOSCIO_EC ;Osc interno, RA6 como
pin, USB usa Osc EC
31. ;******** Otros bits de configuracion **********
32. CONFIG PWRT =
ON ;PWRT habilitado
33. CONFIG BOR =
OFF ;Brown out reset deshabilitado
34. CONFIG WDT =
OFF ;Watchdog deshabilitado
35. CONFIG MCLRE =
OFF ;MCLR como entrada
36. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
37. CONFIG LVP =
OFF ;Programacion en bajo voltaje
apagado
38. ;********* Bits de proteccion ******************
39. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
40. CONFIG CP1 =
OFF ;no estan protegidos
41. CONFIG CP2 = OFF
42. CONFIG CP3 = OFF
43. CONFIG CPB =
OFF ;Sector Boot no esta protegido
44. CONFIG CPD =
OFF ;La EEPROM no esta protegida
45.
46.
47. ;*****************************************************************
*************
48. ; Definicion de variables
49. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
50. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
51. ; interrupcion.
52.
53. CBLOCK 0x080
54. WREG_TEMP ;variable usada para
salvar contexto
55. STATUS_TEMP ;variable usada para
salvar contexto
56. BSR_TEMP ;variable usada para
salvar contexto
57. ENDC
58.
59. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco
0) max 96 bytes
60. Cantms:2 ;variable para generar
hasta 65535 ms
61. CantSeg ;Variable para producir
retardos de hasta 255 seg
62. ENDC
63.
64. ;*****************************************************************
*************
65. ;Datos de la EEPROM
66. ;Los Datos a ser programados en la EEPROM son definidos aqui
67.
68. ORG 0xf00000
69.
70. DE "Test Data",0,1,2,3,4,5
71.
72. ;*****************************************************************
*************
73. ; Vector de Reset.
74. ; Este codigo comenzara a ejecutarse cuando suceda un reset
75.
76. ORG 0x0000
77.
78. goto Main ;Se va al inicio del
codigo principal
79.
80. ;*****************************************************************
*************
81. ; Vector de interrupcion de alta prioridad
82. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
83. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
84. ; no estan habilitadas
85.
86. ORG 0x0008
87.
88. bra HighInt
;Va a la rutina de interrupcion de alta prioridad
89.
90. ;*****************************************************************
*************
91. ; Vector de interrupcion de baja prioridad y rutina
92. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
93. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
94.
95. ORG 0x0018
96.
97. movff STATUS,STATUS_TEMP ;Salva el
registro STATUS
98. movff WREG,WREG_TEMP ;Salva el
registro de trabajo
99. movff BSR,BSR_TEMP ;Salva el
registro BSR
100.
101. ; *** El codigo de la interrupcion de baja prioridad va aqui
***
102.
103.
104. movff BSR_TEMP,BSR ;recupera
el registro BSR
105. movff WREG_TEMP,WREG ;recupera
el registro de trabajo
106. movff STATUS_TEMP,STATUS ;recupera
el registro STATUS
107. retfie
108.
109. ;*****************************************************************
*************
110. ; Rutina de interrupcion de alta prioridad
111. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
112. ; evitar conflictos con el vector de interrupciones de baja
prioridad
113.
114. HighInt:
115.
116. ; *** El codigo para las interrupciones de alta prioridad va
aqui ***
117.
118.
119. retfie FAST
120.
121. ;*****************************************************************
*************
122. ; Comienzo del programa principal
123. ; El codigo del programa principal es colocado aqui
124.
125. Main:
126.
127. ; *** EL codigo principal va aqui ***
128.
129. ;******************* Inicializamos
perifericos ***************************
130.
131. movlw B'01100000' ;Ajustamos
el oscilador interno a 4 MHz
132. movwf OSCCON,.0
133. movlw B'00001111'
134. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
135. clrf TRISA,.0
136. clrf TRISB,.0
137. clrf TRISC,.0
138. clrf TRISD,.0
139. clrf TRISE,.0 ;Todos los
pines como salida
140.
141. MainP0
142. setf LATA,.0
143. setf LATB,.0
144. setf LATC,.0
145. setf LATD,.0
146. setf LATE,.0 ;Ponemos
los puertos en 1
147. movlw .1
148. movwf CantSeg,.0
149. rcall RetardoSeg ;esperamos
1 seg
150. clrf LATA,.0
151. clrf LATB,.0
152. clrf LATC,.0
153. clrf LATD,.0
154. clrf LATE,.0 ;ponemos
los puertos en 0
155. movlw .1
156. movwf CantSeg,.0
157. rcall RetardoSeg ;esperamos
1 seg
158. bra MainP0 ;S
altamos para continuar con el ciclo
159.
160. ;**************************** RetardoSeg ******************
****************
161. ; RetardoSeg Realiza una espera de la cantidad de
segundos indicados
162. ; mediante la variable CantSeg.
CantSeg es de 8 bits
163. ;*****************************************************************
************
164. RetardoSeg
165. movf CantSeg,W,.0
166. btfsc STATUS,Z ;CantSeg
== 0?
167. return ;S
i => retornamos
168. movlw 0x03 ;No =>
hacemos Cantms = 1000
169. movwf Cantms+1,.0
170. movlw 0xE8
171. movwf Cantms,.0
172. rcall Retardo_ms ;realizamo
s un retardo de 1000 ms
173. decf CantSeg,F,.0 ;CantSeg --,
174. bra RetardoSeg ;C
ontinuamos con el ciclo
175. ;*****************************************************************
************
176.
177. ;**************************** Retardo_ms ******************
****************
178. ; Retardo_ms Realiza un retardo de la cantidad de
milisegundos indicados
179. ; mediante Cantms y Cantms+1, Cantms
y Cantms+1 son tratados como
180. ; variables de 16 bits.
181. ;*****************************************************************
************
182. Retardo_ms
183. rcall Retardo1ms ;realizamo
s un retardo de 1 ms
184. decfsz Cantms,F,.0 ;Cantms --
, Cantms == 0
185. bra Retardo_ms ;n
o => vamos a Retardo_ms
186. movf Cantms+1,W,.0 ;
187. btfsc STATUS,Z ;Cantms+1
== 0?
188. return ;S
i => retornamos
189. decf Cantms+1,F,.0 ;No =>
decrementamos
190. bra Retardo_ms ;C
ontinuamos con el ciclo
191. ;*****************************************************************
************
192.
193. ;**************************** Retardo1ms ******************
****************
194. ; Retardo1ms realiza una espera de 1 ms decrementado W
249 veces en un ciclo
195. ; que ocupa 4 us
196. ;*****************************************************************
************
197. Retardo1ms
198. movlw .249
199. Retardo1msP0
200. addlw 0xFF ;W--
201. btfss STATUS,Z,.0 ;W == 0?
202. bra Retardo1msP0 ;No =>
seguimos esperando
203. return ;S
i => ya paso 1 ms
204. ;*****************************************************************
************
205.
206.
207. ;*****************************************************************
*************
208.
209.
210. END ;Directiva fin del
programa
1. ;**********************************************************************
********
2.
3. ;
*
4.
5. ; Nombre: BlinkT0.asm
6.
7. ; Fecha: 27/08/2008
8.
9. ; Version: v0.90
10.
11. ;
*
12.
13. ; Autor: Sander
14.
15. ; Empresa:
16.
17. ;
*
18.
19. ;*****************************************************************
*************
20.
21. ;
*
22.
23. ; Archivos Requeridos: P18F4550.INC
24.
25. ;
*
26.
27. ;*****************************************************************
*************
28.
29. ; Notas: El programa hace parpadear los pines del PIC a
razon de 1 seg usando
30.
31. ; el TMR0 para generar los retardos.
32.
33. ; El TMR0 sera usado en su modo de 16 bits y se configurara
para que genere
34.
35. ; con presicion un retardo de 100 ms.
36.
37. ;
38.
39. ; Tiempo = (NumCuentasTMR0)(4/Fosc)(preescaler)
40.
41. ;
42.
43. ; Para Fosc = 4 MHz; y el Tiempo de 100 ms , tenemos :
44.
45. ;
46.
47. ; (4 MHz/4)(100 ms) = (NumCuentasTMR0)(preescaler)
48.
49. ; (NumCuentasTMR0)(preescaler) = 100000
50.
51. ; Los valores posibles para el preescaler son:
2,4,16,32,64,128 y 256, entonces
52.
53. ; son posibles diferentes combinaciones para el
(NumCuentasTMR0) y el preescaler,
54.
55. ; Sin embargo debe notarse que al ser el TMR0 un contador
ascendente el valor
56.
57. ; hallado anteriormente no es el que debe cargarse al TMR0
si no :
58.
59. ;
60.
61. ; TMR0 = 65536 - (NumCuentasTMR0)
62.
63. ;
64.
65. ; ---------------------------------------------------------
--
66.
67. ; |Preescaler | NumCuentasTMR0|Valor a cargar |Valor a
cargar |
68.
69. ; | | |
TMR0 | TMR0(Hex) |
70.
71. ; ---------------------------------------------------------
--
72.
73. ; | 2 | 50000 | 15
536 | 0x3CB0 |
74.
75. ; | 4 | 25000 | 40
536 | 0x9E58 |
76.
77. ; | 8 | 12500 | 53
036 | 0xCF2C |
78.
79. ; | 16 | 6250 | 59
286 | 0xE796 |
80.
81. ; | 32 | 3125 | 62
411 | 0xF3CB |
82.
83. ; | 64 | 1562,5 | --
--- | ------ |
84.
85. ; | 128 | 781,25 | --
--- | ------ |
86.
87. ; | 256 | 390,625 | --
--- | ------ |
88.
89. ; ---------------------------------------------------------
--
90.
91. ; Ta
bla 1
92.
93. ;*****************************************************************
*************
94.
95.
96.
97. LIST P=18F4550 ;Directiva para definir el
procesador
98.
99. #include <P18F4550.INC> ;Definicion de SFRs para el
procesador
100.
101.
102.
103. ;*****************************************************************
*************
104.
105. ;Bits de Configuracion
106.
107. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
108.
109. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
110.
111. ;Abajo hay algunos ejemplos
112.
113.
114.
115. ;******** Configuracion del Oscilador **********
116.
117. CONFIG FOSC = XT_XT ;Osc XT, XT usado
para el USB
118.
119.
120.
121. ;******** Otros bits de configuracion **********
122.
123. CONFIG PWRT =
ON ;PWRT habilitado
124.
125. CONFIG BOR =
OFF ;Brown out resete
deshabilitado
126.
127. CONFIG WDT =
OFF ;Watch dog deshabilitado
128.
129. CONFIG MCLRE =
OFF ;MCLR como entrada
130.
131. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
132.
133. CONFIG LVP =
OFF ;programacion en bajo voltaje
deshabilitado
134.
135. ;********* Bits de proteccion ******************
136.
137. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
138.
139. CONFIG CP1 =
OFF ;no estan protegidos
140.
141. CONFIG CP2 = OFF
142.
143. CONFIG CP3 = OFF
144.
145. CONFIG CPB =
OFF ;Sector Boot no esta protegido
146.
147. CONFIG CPD =
OFF ;La EEPROM no esta protegida
148.
149. ;*****************************************************************
*************
150.
151. ; Definicion de variables
152.
153. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
154.
155. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
156.
157. ; interrupcion.
158.
159.
160.
161. CBLOCK 0x080
162.
163. WREG_TEMP ;variable usada para
salvar contexto
164.
165. STATUS_TEMP ;variable usada para
salvar contexto
166.
167. BSR_TEMP ;variable usada para
salvar contexto
168.
169. ENDC
170.
171.
172.
173. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco
0) max 96 bytes
174.
175. ContT0 ;para contar las veces que
TMR0 desborda
176.
177. ENDC
178.
179.
180.
181. ;*****************************************************************
*************
182.
183. ;Datos de la EEPROM
184.
185. ;Los Datos a ser programados en la EEPROM son definidos aqui
186.
187.
188.
189. ORG 0xf00000
190.
191.
192.
193. DE "Test Data",0,1,2,3,4,5
194.
195.
196.
197. ;*****************************************************************
*************
198.
199. ; Vector de Reset.
200.
201. ; Este codigo comenzara a ejecutarse cuando suceda un reset
202.
203.
204.
205. ORG 0x0000
206.
207.
208.
209. goto Main ;Se va al inicio del
codigo principal
210.
211.
212.
213. ;*****************************************************************
*************
214.
215. ; Vector de interrupcion de alta prioridad
216.
217. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
218.
219. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
220.
221. ; no estan habilitadas
222.
223.
224.
225. ORG 0x0008
226.
227.
228.
229. bra HighInt ;V
a a la rutina de interrupcion de alta prioridad
230.
231.
232.
233. ;*****************************************************************
*************
234.
235. ; Vector de interrupcion de baja prioridad y rutina
236.
237. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
238.
239. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
240.
241.
242.
243. ORG 0x0018
244.
245.
246.
247. movff STATUS,STATUS_TEMP ;Salva el registro
STATUS
248.
249. movff WREG,WREG_TEMP ;Salva el registro
de trabajo
250.
251. movff BSR,BSR_TEMP ;Salva el registro
BSR
252.
253.
254.
255. ; *** El codigo de la interrupcion de baja prioridad va aqui
***
256.
257.
258.
259.
260.
261. movff BSR_TEMP,BSR ;recupera el
registro BSR
262.
263. movff WREG_TEMP,WREG ;recupera el
registro de trabajo
264.
265. movff STATUS_TEMP,STATUS ;recupera el
registro STATUS
266.
267. retfie
268.
269.
270.
271. ;*****************************************************************
*************
272.
273. ; Rutina de interrupcion de alta prioridad
274.
275. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
276.
277. ; evitar conflictos con el vector de interrupciones de baja
prioridad
278.
279.
280.
281. HighInt:
282.
283.
284.
285. ; *** El codigo para las interrupciones de alta prioridad va
aqui ***
286.
287.
288.
289.
290.
291. retfie FAST
292.
293.
294.
295. ;*****************************************************************
*************
296.
297. ; Comienzo del programa principal
298.
299. ; El codigo del programa principal es colocado aqui
300.
301.
302.
303. Main:
304.
305. ; *** EL codigo principal va aqui ***
306.
307.
308.
309. ;******************* Inicializacion de
puertos ***************************
310.
311. movlw B'00001111'
312.
313. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
314.
315. clrf TRISA,.0
316.
317. clrf TRISB,.0
318.
319. clrf TRISC,.0
320.
321. clrf TRISD,.0
322.
323. clrf TRISE,.0 ;Todos los
pines como salida
324.
325.
326.
327. clrf LATA,.0
328.
329. clrf LATB,.0
330.
331. clrf LATC,.0
332.
333. clrf LATD,.0
334.
335. clrf LATE,.0 ;Ponemos
las salidas en cero
336.
337. ;*****************************************************************
*************
338.
339.
340.
341. ;******************* Inicializacion del
TMR0 ***************************
342.
343. movlw B'10010000' ;TMR0 on,
modo 16 bits, cambia con las
344.
345. movwf T0CON,.0 ;instrucci
ones, asignamos preescaler de 2
346.
347.
348.
349. movlw 0x3C ;De
acuerdo a la Tabla 1 cargamos los valores
350.
351. movwf TMR0H,.0 ;a TMR0H y
TMR0L, pero a TMR0L se le aumenta
352.
353. movlw 0xB1 ;un 1 para
compensar los 2 ciclos de
354.
355. movwf TMR0L,.0 ;instrucci
on que el TMR0 permanece detenido
356.
357. ;*****************************************************************
*************
358.
359. Ciclo
360.
361. movlw .10 ;
362.
363. movwf ContT0,.0 ;ContT0 =
10 para controlar 1 segundo
364.
365. CicloP0
366.
367. btfss INTCON,TMR0IF ;TMR0IF == 1?
(TMR0 desbordo?)
368.
369. bra CicloP0 ;N
o => continuamos esperando
370.
371. movlw 0xB1 ;Si =>
recargamos el TMR0L, no es necesario
372.
373. movwf TMR0L,.0 ;recargar
el TMR0H
374.
375. bcf INTCON,TMR0IF ;limpiamos
TMR0IF para reiniciar la cuenta
376.
377. decfsz ContT0,F,.0 ;ContT0 --
, y ContT0 == 0?
378.
379. bra CicloP0 ;N
o => Volvemos al ciclo de espera
380.
381. movlw 0xFF ;Si =>
Cambiamos el estado de los puertos (toggle)
382.
383. xorwf LATA,F,.0 ;para eso
realizamos un XOR de cada puerto con 0xFF
384.
385. xorwf LATB,F,.0
386.
387. xorwf LATC,F,.0
388.
389. xorwf LATD,F,.0
390.
391. xorwf LATE,F,.0
392.
393. bra Ciclo ;V
olvemos a recargar el valor de ContT0,
394.
395.
396.
397. ;*****************************************************************
*************
398.
399.
400.
401. END ;Directiva fin del
programa
402.
1.
2. ;**********************************************************************
********
3.
4. ;

5.
6. ; Nombre: TxRx_0.asm
7.
8. ; Fecha: 02/09/2008
9.
10. ; Version: v0.90
11.
12. ;

13.
14. ; Autor: Sander
15.
16. ; Empresa:
17.
18. ;

19.
20. ;*****************************************************************
***************
21.
22. ;

23.
24. ; Archivos Requeridos: P18F4550.INC
25.
26. ;

27.
28. ;*****************************************************************
***************
29.
30. ; Notas: El programa muestra el uso del EUSART para
realizar una comunicacion
31.
32. ; asincrona con la PC, para este ejemplo
configuraremos el oscilador
33.
34. ; para que funcione a 48 MHz usando un cristal externo de 4
MHz.
35.
36. ;
37.
38. ; Para configurar la velocidad de transmision se usara el
modo de 16 bits y
39.
40. ; el modo de alta de velocidad para el generador de baudios
(BRG16=1; BRGH=1),
41.
42. ; para este caso tenemos que la velocidad esta dada por:
43.
44. ;
45.
46. ; Vel = Fosc/[4(n+1)] Donde n es el valor que se
carga a SPBRGH:SPBRG
47.
48. ; n = [(Fosc/Vel)-1]/4
49.
50. ;
51.
52. ; ---------------------------------------------------------
------------------
53.
54. ; |Velocidad |Valor n |Valor
para |Valor Hex para |Velocidad | % |
55.
56. ; |(Baudios) | |SPBRGH:SPBRG |S
PBRGH:SPBRG |real | Error |
57.
58. ; ---------------------------------------------------------
------------------
59.
60. ; | 110 | 109090,66 | -------
- | -------- | ------- | ----- |
61.
62. ; | 300 | 39999,75 | 39999 |
0x9C3F | 300 | 0 |
63.
64. ; | 1200 | 9999,75 | 9999 |
0x270F | 1200 | 0 |
65.
66. ; | 2400 | 4999,75 | 4999 |
0xC34F | 2400 | 0 |
67.
68. ; | 4800 | 2499,75 | 2499 |
0x09C3 | 4800 | 0 |
69.
70. ; | 9600 | 1249,75 | 1249 |
0x04E1 | 9600 | 0 |
71.
72. ; | 19600 | 611,99 | 611 |
0x0263 | 19607,84 | 0,04 |
73.
74. ; | 38400 | 312,25 | 312 |
0x0137 | 38338,65 | 0,16 |
75.
76. ; | 57600 | 208,08 | 207 |
0x00CF | 57692,30 | 0,16 |
77.
78. ; | 115200 | 103,91 | 103 |
0x0067 | 115384,61 | 0,16 |
79.
80. ; | 230400 | 51,83 | 51 |
0x0033 | 230769,23 | 0,16 |
81.
82. ; | 460800 | 25,79 | 25 |
0x0019 | 461538,46 | 0,16 |
83.
84. ; | 921600 | 12,77 | 12 |
0x000C | 923076,92 | 0,16 |
85.
86. ; ---------------------------------------------------------
------------------
87.
88. ;
Tabla 1
89.
90. ; Lo que el programa hara es recibir caracteres e ir
almacenandolos en BufferRx,
91.
92. ; dejara de recibir caracteres si recibe el caracter
enter(0x0D ), si ya han
93.
94. ; llegado 256 caracteres, o si se ha dejado de recibir
caracteres durante 2
95.
96. ; segundos aproximadamente.
97.
98. ;
99.
100. ; Cuando se deja de recibir los caracteres , el
microcontrolador recorrera el
101.
102. ; arreglo BufferRx y convertira todas las letras minusculas
en mayusculas , la
103.
104. ; cadena modificada se ira guardando en BufferTx , durante
este proceso cualquier
105.
106. ; caracter recibido sera descartado, una vez que BufferTx
haya sido cargado con
107.
108. ; todos los caracteres estos seran enviados de regreso a la
PC.
109.
110. ;
111.
112. ; Tanto para la recepcion como para la transmision se usran
interrupciones,
113.
114. ; cualquier retardo que se necesite sera realizado usando el
TMR0
115.
116. ;*****************************************************************
*****************
117.
118.
119.
120. LIST P=18F4550 ;Directiva para definir el
procesador
121.
122. #include <P18F4550.INC> ;Definicion de SFRs para el
procesador
123.
124.
125.
126. ;*****************************************************************
*************
127.
128. ;Bits de Configuracion
129.
130. ;Microchip ha cambiado el formato para definir los bits de
configuracion, por favor
131.
132. ;revisar el archivo P18F4550.INC para informacion adicional de la
notacion
133.
134. ;Abajo hay algunos ejemplos
135.
136.
137.
138. ;******** Configuracion del Oscilador **********
139.
140. CONFIG FOSC = XTPLL_XT ;Osc XT que pasa a
travez del PLL,USB usa
141.
142.
;el Osc XT
143.
144. CONFIG PLLDIV =
1 ;La entrada del Osc de 4 MHz va
directo al PLL
145.
146. CONFIG CPUDIV = OSC1_PLL2 ;La salida
del PLL (96 MHz) , la dividimos entre dos
147.
148.
;para que sea la seal del oscilador del sistema,
149.
150.
;Entoces tenemos 48 MHz
151.
152. ;******** Otros bits de configuracion **********
153.
154. CONFIG PWRT =
ON ;PWRT habilitado
155.
156. CONFIG BOR =
OFF ;Brown out resete
deshabilitado
157.
158. CONFIG WDT =
OFF ;Watch dog deshabilitado
159.
160. CONFIG MCLRE =
OFF ;MCLR como entrada
161.
162. CONFIG PBADEN =
ON ;Todos los pines como entradas
analogicas
163.
164. CONFIG LVP =
OFF ;programacion en bajo voltaje
deshabilitado
165.
166. ;********* Bits de proteccion ******************
167.
168. CONFIG CP0 =
OFF ;los bloques del codigo de
programa
169.
170. CONFIG CP1 =
OFF ;no estan protegidos
171.
172. CONFIG CP2 = OFF
173.
174. CONFIG CP3 = OFF
175.
176. CONFIG CPB =
OFF ;Sector Boot no esta protegido
177.
178. CONFIG CPD =
OFF ;La EEPROM no esta protegida
179.
180. ;*****************************************************************
*************
181.
182. ; Definicion de variables
183.
184. ; Estas variables son necesarias solo si las interrupciones de
baja prioridad son usadas.
185.
186. ; Mas variables podrian se necesarias para almacenar otros SFRs
usados en las rutinas de
187.
188. ; interrupcion.
189.
190.
191.
192. VelHI EQU 0x04 ;Estas
constantes sirven para definir la velocidad
193.
194. VelLO EQU 0xE1 ;de la
comunicacion, 9600 baudios
195.
196.
197.
198. CBLOCK 0x080
199.
200. WREG_TEMP ;variable usada para
salvar contexto
201.
202. STATUS_TEMP ;variable usada para
salvar contexto
203.
204. BSR_TEMP ;variable usada para
salvar contexto
205.
206. ENDC
207.
208.
209.
210. CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco
0) max 96 bytes
211.
212. ContT0 ;para contar las veces que
TMR0 desborda
213.
214. ContRx ;para contar los bytes
recibidos
215.
216. ContTx ;para contar los bytes
transmitidos
217.
218. DatoRx ;variable temporal para la
recepcion
219.
220. DatoTemp ;usado como variable
auxiliar
221.
222. Banderas
223.
224. TablaOffs ;Para movernos en las
tablas
225.
226. ENDC
227.
228.
229.
230. CBLOCK 0x100 ;Variables en el Banco 1
231.
232. BufferRx:.256 ;Buffer para la recepcion
233.
234. ENDC
235.
236.
237.
238. CBLOCK 0x200 ;Variables en el banco 2
239.
240. BufferTx:.256 ;Buffer para la transmision
241.
242. ENDC
243.
244.
245.
246. #DEFINE TimeOut Banderas,.0
;=1 si el pasan 2 seg
247.
248. #DEFINE RxOK Banderas,.1
;=1 si se termino de recibir
249.
250. #DEFINE TxOK Banderas,.2
251.
252. ;*****************************************************************
*************
253.
254. ;Datos de la EEPROM
255.
256. ;Los Datos a ser programados en la EEPROM son definidos aqui
257.
258.
259.
260. ORG 0xf00000
261.
262.
263.
264. DE "Test Data",0,1,2,3,4,5
265.
266.
267.
268. ;*****************************************************************
*************
269.
270. ; Vector de Reset.
271.
272. ; Este codigo comenzara a ejecutarse cuando suceda un reset
273.
274.
275.
276. ORG 0x0000
277.
278.
279.
280. goto Main ;Se va al inicio del
codigo principal
281.
282.
283.
284. ;*****************************************************************
*************
285.
286. ; Vector de interrupcion de alta prioridad
287.
288. ; Este codigo comenzara a ejecutarse cuando una interrupcion de
alta prioridad ocurra
289.
290. ; o cuando cualquier interrupcion ocurra si es que las prioridades
de las interrupciones
291.
292. ; no estan habilitadas
293.
294.
295.
296. ORG 0x0008
297.
298.
299.
300. bra LowInt ;c
uando las prioridades estan deshabilitadas
301.
302.
;se salta a 0x0008 en caso de interrupcion
303.
304. ;*****************************************************************
*************
305.
306. ; Vector de interrupcion de baja prioridad y rutina
307.
308. ; Este codigo comenzara a ejecutrase cuando una interrupcion de
baja prioridad ocurra
309.
310. ; Este codigo puede ser eliminado si las interrupciones de baja
prioridad no son usadas
311.
312.
313.
314. ORG 0x0018
315.
316. LowInt
317.
318. movff STATUS,STATUS_TEMP ;Salva el registro
STATUS
319.
320. movff WREG,WREG_TEMP ;Salva el registro
de trabajo
321.
322. movff BSR,BSR_TEMP ;Salva el registro
BSR
323.
324.
325.
326. ; *** El codigo de la interrupcion de baja prioridad va aqui
***
327.
328. btfsc INTCON,TMR0IF ;Interrupcion del
TMR0
329.
330. bra IntT0 ;S
i => vamos a IntT0
331.
332. btfsc PIR1,RCIF ;No =>
interupcion de recepcion?
333.
334. bra IntRx ;S
i => vamos a IntRx
335.
336. btfsc PIR1,TXIF ;No =>
interrupcion de transmision?
337.
338. bra IntTx ;S
i => vamos a IntTx
339.
340. movlw .6 ;N
o => enviamos mensaje de error
341.
342. call EnvMsg ;
343.
344. sleep ;y
dormimos
345.
346.
347.
348. ;**************************** IntT0 **************************
********
349.
350. ; IntT0 atiende la interrupcion de desborde del TMR0 y
controla
351.
352. ; cuando transcuren dos segundos sin recibir
nada para producir
353.
354. ; el time out
355.
356. ;*****************************************************************
********
357.
358. IntT0
359.
360. movlw 0x61
361.
362. movwf TMR0L ;recargamo
s TMR0L, para desbordes de 100 ms
363.
364. bcf INTCON,TMR0IF ;limpiamos
la bandera de interrupcion
365.
366. decfsz ContT0 ;ContT0 --
, ya paso 2 seg?
367.
368. bra IntT0_X ;N
o => salimos
369.
370. bsf TimeOut ;S
i => indicamos que hubo un time out
371.
372. bra IntT0_X
373.
374. IntT0_X
375.
376. bra SalirInt ;V
amos a salir de las interrupciones
377.
378. ;*****************************************************************
***********
379.
380.
381.
382. ;**************************** IntRx **************************
********
383.
384. ; IntRx se encarga de guardar los bytes recibidos en el
BufferRx,
385.
386. ; descarta los bytes recibidos cuando se
esta procesando la trama
387.
388. ; ademas controla cuando el buffer de recepcion desborda
389.
390. ;*****************************************************************
********
391.
392. IntRx
393.
394. btfsc RCSTA,OERR ;Desbordo
el buffer de recepcion?
395.
396. bra IntRx_Er1 ;v
amos a atender el error
397.
398. btfsc RxOK ;termino
la recepcion?
399.
400. bra IntRx_P1 ;S
i => vamos a descartar el caracter recibido
401.
402.
403.
404. movf RCREG,W,.0 ;No =>
guardamos el caracter
405.
406. movwf DatoRx
407.
408. movlw 0x0D ;Revisamos
si se recibio enter
409.
410. xorwf DatoRx,W,.0
411.
412. btfsc STATUS,Z ;RCREG ==
0x0D?, se recibio 0x0D(enter)?
413.
414. bra IntRx_P0_1 ;S
i => vamos a terminar la recepcion
415.
416. movf DatoRx,W,.0 ;No =>
guardamos el caracter
417.
418. movwf POSTINC0 ;Guardamos
e incrementamos FSR
419.
420. movlw .20
421.
422. movwf ContT0 ;Reiniciam
os el contador para el TimeOut
423.
424. incfsz ContRx,F,.0 ;ContRx
llego a 256, (desbordo?)
425.
426. bra IntRx_X ;N
o => terminamos
427.
428.
;Si => tenemos 256 caracteres recibidos
429.
430. IntRx_P0_1
431.
432. bsf RxOK ;p
onemos en 1 RxOK
433.
434. bra IntRx_X
435.
436. IntRx_P1
437.
438. movf RCREG,W,.0 ;Descartam
os el byte recibido
439.
440. bra IntRx_X
441.
442. IntRx_Er1
443.
444. bcf RCSTA,CREN
445.
446. bsf RCSTA,CREN ;R
einiciamos el EUSART
447.
448. movf RCREG,W,.0 ;Descartam
os el byte recibido
449.
450. IntRx_X
451.
452. bra SalirInt ;V
amos a salir de las interrupciones
453.
454. ;*****************************************************************
*****************
455.
456.
457.
458. ;******************************* IntTx ******************
*********************
459.
460. ; IntTx Atiende la interrupcion que se produce cuando el
TXREG envia su
461.
462. ; dato a al registro TSR, por lo aqui se
copia el nuevo valor a
463.
464. ; transmitir a TXREG, esto mientras ContTx > 0.
465.
466. ;*****************************************************************
*****************
467.
468. IntTx
469.
470. decfsz ContTx,F,.0 ;ContTx --
, ContTx == 0?
471.
472. bra IntTxP0 ;N
o => vamos a cargar otro caracter
473.
474. bra IntTxP1 ;S
i => vamos a terminar la transmision
475.
476. IntTxP0
477.
478. movf POSTINC1,W ;Cargamos
el caracter a W e incrementamos FSR1
479.
480. movwf TXREG ;Cargamos
TXREG
481.
482. bra $+2
;Esperamos a que TXIF se ponga en cero
483.
484. bra IntTx_X ;v
amos a salir de la IntTx
485.
486. IntTxP1
487.
488. bsf TxOK ;I
ndicamos que la transmision termino
489.
490. bcf PIE1,TXIE ;D
eshabilitamos esta interrupcion
491.
492. bra IntTx_X ;v
amos a salir de la IntTx
493.
494. IntTx_X
495.
496. bra SalirInt ;V
amos a salir de las interrupciones
497.
498. ;*****************************************************************
*****************
499.
500.
501.
502.
503.
504. SalirInt
505.
506. movff BSR_TEMP,BSR ;recupera el
registro BSR
507.
508. movff WREG_TEMP,WREG ;recupera el
registro de trabajo
509.
510. movff STATUS_TEMP,STATUS ;recupera el
registro STATUS
511.
512. retfie
513.
514.
515.
516. ;*****************************************************************
*************
517.
518. ; Rutina de interrupcion de alta prioridad
519.
520. ; El codigo para la rutina de interrupcion de alta prioridad es
colocado aqui para
521.
522. ; evitar conflictos con el vector de interrupciones de baja
prioridad
523.
524.
525.
526. HighInt:
527.
528.
529.
530. ; *** El codigo para las interrupciones de alta prioridad va
aqui ***
531.
532.
533.
534.
535.
536. retfie FAST
537.
538.
539.
540. ;*****************************************************************
*************
541.
542. ; Comienzo del programa principal
543.
544. ; El codigo del programa principal es colocado aqui
545.
546.
547.
548. Main:
549.
550.
551.
552. ; *** EL codigo principal va aqui ***
553.
554.
555.
556. ;************************ Inicializacion de
Puertos ***********************
557.
558.
559.
560. movlw B'00001111'
561.
562. movwf ADCON1,.0 ;Todos los
pines como I/O digitales
563.
564.
;NO ES NECESARIO MODIFICAR LOS REGISTROS
565.
566.
;TRIS (estan todos en 1)
567.
568. ;************************ Configuracion del
EUSART ***********************
569.
570.
571.
572. movlw B'00000100' ;Configura
mos para una transmision de 8 bit(bit 6)
573.
574. movwf TXSTA,.0 ;modo
asincrono (bit 4),para ajustar los baudios
575.
576.
;BRGH = 1 (bit 2)
577.
578.
579.
580. movlw B'01001000' ;Habilitam
os los 16 bits del generador de baudios
581.
582. movwf BAUDCON,.0 ;BRG16 = 1
(bit 3)
583.
584.
585.
586. movlw VelHI ;Cargamos
los registros SPBRGH:SPBRG con los
587.
588. movwf SPBRGH,.0 ;valores
de la tabla 1 para la velocidad deseada
589.
590. movlw VelLO
591.
592. movwf SPBRG,.0
593.
594.
595.
596. movlw B'10010000' ;Habilitam
os el puerto seria (Bit 7), modo 8 bits
597.
598. movwf RCSTA ;(bit 6),
y habilitamos el receptor (Bit 4).
599.
600.
601.
602. ;*********************** Configuracion del
TMR0 *************************
603.
604. movlw B'10010110' ;TMR0 on,
modo 16 bits, cambia con las
605.
606. movwf T0CON,.0 ;instrucci
ones, asignamos preescaler de 128
607.
608.
609.
610. movlw 0xDB ;De
acuerdo a BlinkT0.asm calculamos los valores a
611.
612. movwf TMR0H,.0 ;cargar
para TMR0H y TMR0L, para el oscilador
613.
614. movlw 0x61 ;de 48
MHz. y un tiempo de 100 ms
615.
616. movwf TMR0L,.0 ;
617.
618.
619.
620. movlw .20 ;
621.
622. movwf ContT0,.0 ;ContT0 =
20 para controlar 2 segundos
623.
624. ;********************** Configuracion de interrupciones
**********************
625.
626.
627.
628. bsf PIE1,RCIE,.0 ;Habilitam
os la interrupcion de recepcion
629.
630. bsf INTCON,TMR0IE,.0 ;Habilitam
os la interruocion de desborde del TMR0
631.
632. bsf INTCON,PEIE,.0 ;Habilitam
os las interrupciones para los perifericos
633.
634.
635.
636. ;************************ Inicializacion de
variables ***************************
637.
638.
639.
640. clrf Banderas,.0
641.
642. clrf ContRx,.0
643.
644.
645.
646. ;*****************************************************************
*************
647.
648. clrf WREG
649.
650. rcall EnvMsg ;Enviamos
el primer mensaje
651.
652. bsf INTCON,GIE ;H
abilitamos las interrupciones
653.
654. MainP0
655.
656. movlw HIGH BufferRx
657.
658. movwf FSR0H,.0
659.
660. movlw LOW BufferRx
661.
662. movwf FSR0L,.0 ;FSR0
apunta al inicio de BufferRx
663.
664. clrf ContRx,.0 ;para
reiniciar el conteo de bytes recibidos
665.
666. clrf Banderas ;reiniciam
os las banderas
667.
668. movlw .20 ;r
einiciamos el contador del time out
669.
670. movwf ContT0,.0 ;ContT0 =
20 para controlar 2 segundos
671.
672. movlw .1
673.
674. rcall EnvMsg
675.
676. MainP1
677.
678. btfsc TimeOut ;Se
produjo un time out?
679.
680. bra MainP2 ;S
i => vamos a atender el timeout
681.
682. btfsc RxOK ;No, Se
termino la recepcion?
683.
684. bra MainP3 ;S
i => vamos a atender la recepcion
685.
686. bra MainP1 ;N
o => continuamos esperando
687.
688.
689.
690. MainP2
691.
692. bsf RxOK ;P
ara detener la recepcion
693.
694. movlw .4
695.
696. rcall EnvMsg ;Enviamos
el mensaje de timeout
697.
698. tstfsz ContRx,.0 ;ContRx ==
0?;
699.
700. bra MainP2_P0 ;N
o => se recibieron caracteres y vamos a procesarlos
701.
702. bcf RxOK ;S
i => no se recibieron caracteres,
703.
704. bra MainP0 ;a
si que volvemos a empezar
705.
706. MainP2_P0
707.
708. movlw .2
709.
710. rcall EnvMsg ;Indicamos
que procesamos la trama
711.
712. rcall ProcTrama ;vamos a
procesar la trama
713.
714. bcf TimeOut ;r
einiciamos las banderas
715.
716. bra MainTx ;V
amos a ennviar la nueva trama
717.
718. bra MainP0 ;V
olvemos a empezar
719.
720.
721.
722. MainP3
723.
724. tstfsz ContRx,.0 ;ContRx ==
0?;
725.
726. bra MainP3_P0 ;N
o => se recibio un 0x0D (enter)
727.
728. movlw .5 ;S
i => se lleno el buffer, y enviamos
729.
730. rcall EnvMsg ;el
mensaje respectivo
731.
732. MainP3_P0
733.
734. movlw .2
735.
736. rcall EnvMsg ;Indicamos
que procesamos la trama
737.
738. rcall ProcTrama ;vamos a
procesar la trama
739.
740. bra MainTx ;V
amos a Enviar la nueva trama
741.
742. bra MainP0 ;V
olvemos a empezar
743.
744.
745.
746. MainTx
747.
748. movlw .3
749.
750. rcall EnvMsg ;Enviamos
el mensaje para transmitir
751.
752. bsf TXSTA,TXEN ;H
abilitamos es transmisor
753.
754. movf POSTINC1,W ;leemos el
dato e incrementamos FSR1
755.
756. movwf TXREG ;copiamos
el dato a TXREG
757.
758. bsf PIE1,TXIE,.0 ;Habilitam
os la interrupcion de transmision
759.
760. btfss TxOK ;La
transmision termino?
761.
762. bra $-
2 ;No => esperamos
763.
764. btfss TXSTA,TRMT ;Si =>
esperamos a que el ultimo caracter sea enviado
765.
766. bra $-
2 ;
767.
768. bcf TXSTA,TXEN ;c
uando se envia el ultimo caracter
769.
770.
;deshabilitamos es transmisor
771.
772. bcf RxOK ;r
eniciamos las banderas
773.
774. bcf TxOK ;
775.
776. bra MainP0 ;;
Volvemos a empezar
777.
778. ;******************************* ProcTrama **********
********************
779.
780. ; ProcTrama Copia los datos del buffer de recepcion al
buffer de transmision
781.
782. ; convirtiendo las minusculas en
mayusculas.
783.
784. ;*****************************************************************
*************
785.
786. ProcTrama
787.
788. movlw HIGH BufferRx
789.
790. movwf FSR0H,.0
791.
792. movlw LOW BufferRx
793.
794. movwf FSR0L,.0 ;FSR0 apu
nta al inicio del BufferRx
795.
796.
797.
798. movlw HIGH BufferTx
799.
800. movwf FSR1H,.0
801.
802. movlw LOW BufferTx
803.
804. movwf FSR1L,.0 ;FSR1 apu
nta al inicio del BufferTx
805.
806. clrf ContTx,.0 ;ContTx =
0
807.
808. ProcTramaP0
809.
810. movf POSTINC0,W ;Cargamos
el caracter a W e incrementamos FSR0
811.
812. movwf DatoTemp ;guardamos
el dato para procesar
813.
814. movlw 'a'
815.
816. cpfslt DatoTemp ;DatoTemp
<'a'
817.
818. bra ProcTramaP0_0 ;No => es
>= 'a' vamos a ver si es menor a z
819.
820. bra ProcTramaP0_2 ;Si => no
es minuscula y vamos a guardar DatoTemp
821.
822. ProcTramaP0_0
823.
824. movlw 'z'
825.
826. cpfsgt DatoTemp ;DatoTemp
> 'z'
827.
828. bra ProcTramaP0_1 ;No => es
<= 'z' vamos a convertirlo en mayuscula
829.
830. bra ProcTramaP0_2 ;Si => no
es minuscula y vamos a guardar DatoTemp
831.
832. ProcTramaP0_1
833.
834. movlw 0x20 ;le
restamos 0x20 al dato para que sea mayuscula
835.
836. subwf DatoTemp,F ;
837.
838. ProcTramaP0_2
839.
840. movf DatoTemp,W ;
841.
842. movwf POSTINC1 ;Guardamos
el dato e incrementamos FSR1
843.
844. incf ContTx,F,.0 ;ContTx
++
845.
846. movf ContRx,W,.0
847.
848. cpfseq ContTx ;ContTx ==
ContRx ?
849.
850. bra ProcTramaP0 ;N
o => seguimos copiando
851.
852.
853.
854. movlw HIGH BufferTx ;Si => volvemos a
apuntar FSR1 a BufferTx, para
855.
856. movwf FSR1H,.0 ;salir
857.
858. movlw LOW BufferTx
859.
860. movwf FSR1L,.0
861.
862. return
863.
864. ;*****************************************************************
*************
865.
866.
867.
868. ;*********************************** EnvMsg ******************
**************
869.
870. ; EnvMsg Recibe en WREG el numero de mensaje que se quiere
enviar, luego
871.
872. ; realiza un "computed goto", para ir a la
rutina que atiende el
873.
874. ; numero de mensaje recibido en WREG.
875.
876. ;*****************************************************************
*************
877.
878.
879.
880. EnvMsg
881.
882. rlcf WREG,.0,.0 ;WREG =
WREG*2, solo se usan posiciones pares
883.
884. movwf TablaOffs,.0 ;guardamos el
valor de W en TablaOffs
885.
886. movlw UPPER EnvMsgP0 ;Tomamos la Parte
mas alta de EnvMsgP0
887.
888. movwf PCLATU,.0 ;y
actualizamos PCLATU
889.
890. movlw HIGH EnvMsgP0 ;Tomamos la Parte
alta de EnvMsgP0
891.
892. movwf PCLATH,.0 ;y
actualizamos PCLATh
893.
894. movlw LOW EnvMsgP0 ;Tomamos la Parte
baja de EnvMsgP0
895.
896. addwf TablaOffs,W,.0 ;y realizamos el
calculo para el salto
897.
898. btfsc STATUS,C ;el salto
es mayor de 256?
899.
900. incf PCLATH,F,.0 ;Si =>
incrementamos PCLATH
901.
902. movf TablaOffs,W,.0 ;leemos el valor a
saltar
903.
904. addwf PCL,F ;cuando se
suma TablaOffs a PCL se realiza el salto
905.
906. EnvMsgP0
907.
908. bra EnvMsg_0 ;V
amos a atender el mensaje respectivo
909.
910. bra EnvMsg_1
911.
912. bra EnvMsg_2
913.
914. bra EnvMsg_3
915.
916. bra EnvMsg_4
917.
918. bra EnvMsg_5
919.
920. bra EnvMsg_6
921.
922. EnvMsg_0
923.
924. movlw UPPER Msg_0 ;tomamos
la parte mas alta del mensage que enviaremos
925.
926. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
927.
928. movlw HIGH Msg_0 ;tomamos
la parte alta del mensage que enviaremos
929.
930. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
931.
932. movlw LOW Msg_0 ;tomamos
la parte baja del mensage que enviaremos
933.
934. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
935.
936.
;apuntado al inicio del mensaje
937.
938. rcall EnviarMsg ;llamamos
a enviar el mensaje
939.
940. return
941.
942.
943.
944. EnvMsg_1
945.
946. movlw UPPER Msg_1 ;tomamos
la parte mas alta del mensage que enviaremos
947.
948. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
949.
950. movlw HIGH Msg_1 ;tomamos
la parte alta del mensage que enviaremos
951.
952. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
953.
954. movlw LOW Msg_1 ;tomamos
la parte baja del mensage que enviaremos
955.
956. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
957.
958.
;apuntado al inicio del mensaje
959.
960. rcall EnviarMsg ;llamamos
a enviar el mensaje
961.
962. return
963.
964. EnvMsg_2
965.
966. movlw UPPER Msg_2 ;tomamos
la parte mas alta del mensage que enviaremos
967.
968. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
969.
970. movlw HIGH Msg_2 ;tomamos
la parte alta del mensage que enviaremos
971.
972. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
973.
974. movlw LOW Msg_2 ;tomamos
la parte baja del mensage que enviaremos
975.
976. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
977.
978.
;apuntado al inicio del mensaje
979.
980. rcall EnviarMsg ;llamamos
a enviar el mensaje
981.
982. return
983.
984. EnvMsg_3
985.
986. movlw UPPER Msg_3 ;tomamos
la parte mas alta del mensage que enviaremos
987.
988. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
989.
990. movlw HIGH Msg_3 ;tomamos
la parte alta del mensage que enviaremos
991.
992. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
993.
994. movlw LOW Msg_3 ;tomamos
la parte baja del mensage que enviaremos
995.
996. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
997.
998.
;apuntado al inicio del mensaje
999.
1000. rcall EnviarMsg ;llamamos
a enviar el mensaje
1001.
1002. return
1003.
1004. EnvMsg_4
1005.
1006. movlw UPPER Msg_4 ;tomamos
la parte mas alta del mensage que enviaremos
1007.
1008. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
1009.
1010. movlw HIGH Msg_4 ;tomamos
la parte alta del mensage que enviaremos
1011.
1012. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
1013.
1014. movlw LOW Msg_4 ;tomamos
la parte baja del mensage que enviaremos
1015.
1016. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
1017.
1018.
;apuntado al inicio del mensaje
1019.
1020. rcall EnviarMsg ;llamamos
a enviar el mensaje
1021.
1022. return
1023.
1024. EnvMsg_5
1025.
1026. movlw UPPER Msg_5 ;tomamos
la parte mas alta del mensage que enviaremos
1027.
1028. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
1029.
1030. movlw HIGH Msg_5 ;tomamos
la parte alta del mensage que enviaremos
1031.
1032. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
1033.
1034. movlw LOW Msg_5 ;tomamos
la parte baja del mensage que enviaremos
1035.
1036. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
1037.
1038.
;apuntado al inicio del mensaje
1039.
1040. rcall EnviarMsg ;llamamos
a enviar el mensaje
1041.
1042. return
1043.
1044. EnvMsg_6
1045.
1046. movlw UPPER Msg_6 ;tomamos
la parte mas alta del mensage que enviaremos
1047.
1048. movwf TBLPTRU,.0 ;y la
actualizamos TBLPTRU
1049.
1050. movlw HIGH Msg_6 ;tomamos
la parte alta del mensage que enviaremos
1051.
1052. movwf TBLPTRH,.0 ;y la
actualizamos TBLPTRH
1053.
1054. movlw LOW Msg_6 ;tomamos
la parte baja del mensage que enviaremos
1055.
1056. movwf TBLPTRL,.0 ;y la
actualizamos TBLPTRL, Aqui tenemos a TBLPTR
1057.
1058.
;apuntado al inicio del mensaje
1059.
1060. rcall EnviarMsg ;llamamos
a enviar el mensaje
1061.
1062. return
1063.
1064. ;*****************************************************************
*************
1065.
1066.
1067.
1068. ;********************************* EnviarMsg **********
********************
1069.
1070. ; EnviarMsg recibe como dato el registro TBLPTR
apuntando al mensaje que
1071.
1072. ; quiere ser enviado y va
recorriendo el mensaje enviando
1073.
1074. ; caracter por caracter hasta que se encuentre con el
caracter 0x00
1075.
1076. ;*****************************************************************
*************
1077.
1078. EnviarMsg
1079.
1080. tblrd *+ ;L
eemos el valor de la tabla e incrementamos
1081.
1082.
;el puntero
1083.
1084. tstfsz TABLAT,.0 ;El valor
leido es 0x000?
1085.
1086. bra EnviarMsgP0 ;N
o => vamos a enviar el caracter
1087.
1088. return ;S
i => retornamos
1089.
1090. EnviarMsgP0
1091.
1092. bsf TXSTA,TXEN ;H
abilitamos el transmisor
1093.
1094. movff TABLAT,TXREG ;Movemos el
caracter a TXREG
1095.
1096. bra $+2
;espera a que el dato vaya al registro TSR
1097.
1098. btfss TXSTA,TRMT ;EL
caracter fue enviado?
1099.
1100. bra $-
2 ;No => esperamos
1101.
1102. bcf TXSTA,TXEN ;S
i => apagamos el transmisor
1103.
1104. bra EnviarMsg ;V
olvemos a leer el otro caracter
1105.
1106. ;*****************************************************************
*************
1107.
1108.
1109.
1110. ;*****************************************************************
*************
1111.
1112.
1113.
1114. ORG 0x800
1115.
1116.
1117.
1118. Msg_0
1119.
1120. DB '\n','\r'
1121.
1122. DB 'P','r','o','g','r','a','m','a','
','e','j','e','m','p','l','o'
1123.
1124. DB ' ','p','a','r','a',' ','e','l',' ','u','s','o','
','d','e','l'
1125.
1126. DB ' ','E','U','S','A','R','T','\n','\r',0x00
1127.
1128. Msg_1
1129.
1130. DB '\n','\r'
1131.
1132. DB 'I','n','t','r','o','d','u','z','c','a','
','l','a',' ','c','a'
1133.
1134. DB 'd','e','n','a','.','.','.','.','\n','\r',0x00
1135.
1136. Msg_2
1137.
1138. DB '\n','\r'
1139.
1140. DB 'P','r','o','c','e','s','a','n','d','o','.','.','.
','\n','\r',0x00
1141.
1142. Msg_3
1143.
1144. DB 'L','a',' ','n','u','e','v','a','
','c','a','d','e','n','a',' '
1145.
1146. DB 'e','s',':','\n','\r',0x00
1147.
1148. Msg_4
1149.
1150. DB '\n','\r'
1151.
1152. DB 'T','i','m','e',' ','o','u','t','\n','\r',0x00
1153.
1154. Msg_5
1155.
1156. DB '\n','\r'
1157.
1158. DB 'B','u','f','f','e','r',' ','d','e','
','r','e','c','e','p','c'
1159.
1160. DB 'i','o','n',' ','l','l','e','n','o','\n','\r',0x00
1161.
1162.
1163.
1164. Msg_6
1165.
1166. DB '\n','\r'
1167.
1168. DB 'E','r','r','o','r','\n','\r',0x00
1169.
1170.
1171.
1172. END ;Directiva fin del
programa

You might also like