PIC18F4550 Asembler.docx

PIC18F4550 Asembler Programación del PIC18F4550 con nuestro Programador USB 4 November 2016 Ahora en este artículo se m

Views 99 Downloads 2 File size 4MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

PIC18F4550 Asembler

Programación del PIC18F4550 con nuestro Programador USB 4 November 2016 Ahora en este artículo 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 programación en lenguaje C, además 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 artículo, para demostrar como nuestro programador USB es capaz de programar algún PIC de la familia PIC18F. PIC18F4550 Es un microcontrolador con arquitectura de 8 bits, pero con 32K de memoria de programa, entre sus periféricos más llamativos esta el puerto USB 2.0 también incluye un módulo 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 características resumidas de este microcontrolador.

La siguiente imagen muestra una foto del PIC18F4550

Y enseguida se muestra un diagrama de terminales

Más 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. Programación del PIC16F1824 Igual que en los ejemplos de los artículos pasados, para mostrar cómo 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 código fuente, es bien simple, aún así se puede descargar desde nuestro repositorio: https://github.com/TecdigitaldelBajio/Programador-USB-de-PICsPaso #1 Diagrama esquemático La figura siguiente muestra el diagrama esquemático 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 esquemático anterior en la protoboard, la imagen muestra la conexión necesaria para el programa de muestra.

Después 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 conexión:

Con esa conexión 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á automáticamente el PIC18F4550 como lo muestra en la pantalla. Ahora solo basta con importar el archivo HEX, y programar dando clic en el botón "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 práctica en ASM para el PIC18F4550, algo tan práctico como el típico”Hello World!” para las computadoras pero en este caso encenderemos un LED. Si entraste a este blog posiblemente tengas relación con el mundo de la tecnología y debes tener una idea de la programación de computadoras, en el caso de que alguna vez hayas programado posiblemente lo hayas hecho en un lenguaje de programación de alto nivel; es decir te resultó demasiado fácil 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 código y pasandolo a un lenguaje de bajo nivel para que la computadora lo pueda ensamblar y posteriormente interpretar. Al hablar de un microcontrolador también 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 mayoría de ellos son muy comunes debido a la extensa bibliografía de que disponen, además de que el fabricante proporciona el software para su programación. Material:  PIC18F4550  Resistencia 1kΩ, 330 Ω  Un Botón  2 Capacitores de .22pF  1 Cristal de 4MHz, es opcional y servirá para futuras prácticas, pero ahorita se puede omitir.  1 LED  1 Fuente de +5V  1 Programador  MPLAB IDE de Microchip  Pickit 2 Introducción El PIC18F4550 tiene puertos que podemos configurar como entradas o salidas, el manejo de estos puertos es a través 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 están orientados a entradas analógicas. Además 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 b’00001100’) o en hexadecimal 0x0C, existen otras formas de introducir valores en ensamblador pero estas son las más 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 tecnología nos permite simular circuitos eléctricos en computadora y ahora es posible simular el código de un PIC virtualmente sin necesidad de grabar el microcontrolador y probarlo físicamente. 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 cómo bajar MPLAB IDE y usarlo, conforme subimos más prácticas irémos explicando otras funcionalidades de este software.

Simulación en MPLAB IDE Posted on June 30, 2012by need4bits

La simulación del código de programa nos ayuda a ver el desarrollo de las instrucciones así como los tiempos de ejecución en determinados bloques o líneas 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 ejecución del programa. Microchip te proporciona este software para programar sus dispositivos y también para grabarlos, de manera que accediendo al área de descargas de su página podremos obtener dicho software. http://www.microchip.com/ Después 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, también tenemos la opción 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 configuración (Figura 6)

Figura 6. Información de configuración 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 título ni formato que debemos guardar con la extensión *.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 atención en asignar la extensión .asm al final; por último activar la casilla de verificación 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 extensión *.asm podemos introducir las líneas de código y estas se resaltaran de acuerdo a la sintaxis (Directivas, Instrucciones, Direcciones, Variables, Comentarios), debemos comenzar declarando la palabra de configuración y posteriormente el programa. Como buena práctica de programación, podemos comenzar comentando el programa con información básica del mismo, para ello usamos “punto y coma” y lo que esté después de éste símbolo serán comentarios, ejemplo: ;Esto es un comentario ;Información del Proyecto para su documentación ;*********************************************** Posteriormente escribimos: List P = 18F4550 ; Pic utilizado Inclue

; Archivo con las directivas del Pic Los archivos *.inc se encuentran en la carpeta de instalación de MPLAB y contienen la mayoría de familias de microcontroladores de esta empresa.

La palabra de configuración contiene las instrucciones de cómo debe configurarse el PIC, para esta práctica utilizamos la palabra CONFIG con las siguientes opciones: CONFIG CONFIG CONFIG CONFIG CONFIG CONFIG CONFIG CONFIG

FOSC = HS ; Tipo de Oscilador PWRT = ON ; Esperar a que el PIC se estabilice BOR = OFF ; Genera un reset cuando el voltaje disminuye WDT = OFF ; Perro Guardian MCLRF = ON ; Master Clear habilitado PBADEN = OFF ; Puerto B Analógico LVP = OFF ; Voltaje Bajo de Programación DEBUG = OFF ; Depuración Incircuit

CONFIG XINST = OFF ; Conjunto de instrucciones extendidas Una vez escrita la palabra de configuración se escribe el programa.

Como buena práctica de programación es importante la indentación (tabular) al escribir el código, pues permite una mejor lectura y comprensión de cada bloque, para ello dejaremos a las etiquetas/banderas sin indentar, las instrucciones, direcciones, variables y comentarios llevarán indentación 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 código introducido y se verifican posibles errores; ejecutamos los siguientes comandos: Configure » Select Device Aquí elegimos el PIC con el que deseamos realizar la simulación, el ensamblador puede construir el código sin problemas, pero esta opción crea un archivo que permite una simulación 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 más 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 código, en este caso elegir MPLAB SIM; para ello hacer clic en: Debugger » Select Tool » MPLAB SIM (Figura 10)

Figura 10. MPLAB SIM

Después de seleccionar MPLAB SIM, se activa un cuadro de herramientas llamado Debug. En caso de no haber construido todo el proyecto también 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. Botón para ejecutar el programa 2. Botón para detener la ejecución 3. Botón para animar el programa, es decir, ejecutarlo automáticamente línea por línea. 4. Ejecutar instrucción dentro (subrutinas) 5. Ejecutar instrucción sobre (subrutinas) 6. Ejecutar instrucción fuera (subrutinas) 7. Reset 8. Breakpoints para detener la ejecución animada o resaltar una línea de código A continuación se mencionan las ventanas de programa donde se visualizan los eventos de la simulación. 

Ventana Source Es la ventana donde se edita el código en ensamblador y al depurar aparece una flecha verde que apunta a la siguiente instrucción a ejecutar:

Indicador de la siguiente instrucción 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 algún 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 también 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 construcción: Ejecución…] En otra publicación explicaremos cómo grabar un el código .hex en un microcontrolador utilizando Pickit 2.

Simulación en ISIS Proteus Posted on August 2, 2012by need4bits

ISIS Proteus en un software de simulación de circuitos eléctricos que permite simular el código hexadecimal de un programa creado en Ensamblador o C. Para realizar una simulación seguir las siguientes indicaciones: 1. Una vez instalada la aplicación, 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. Después 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 búsqueda; aunque también es posible buscar componentes por categorías pero resulta más tardado. (Figura 4):

Figura 4. Búsqueda por palabras clave

5. Una vez encontrado el componente, se agrega seleccionando su nombre en la ventana de resultados y posteriormente presionando el botón «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, también se puede arrastrar y soltar los componentes y mientras se hace esta operación el puntero del mouse cambiará a un lápiz verde y se podrá visualizar la figura (Figura 6):

Figura 6. Inserción de componentes

7. Dependiendo de la práctica se pueden agregar instrumentos de medición como: Osciloscopio, Multimetro, Generador de Señales, entre otros. En este caso al trabajar con un PIC es necesario saber cómo 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 botón anterior abre una ventana para buscar el archivo, seleccionarlo y poder importarlo; para ello podemos importar archivos con extensión *.hex o *.cof. Una vez se ha encontrado el archivo se da “Abrir” 10. Por último se comienza la simulación dando clic en el botón “Play” que se encuentra en la parte inferior del lado izquierdo (Figura 10).

Figura 10. Iniciar simulación

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 botón, PIC18F4550 ASM Posted on June 30, 2012by need4bits

Objetivo       

Identificar y conocer las características 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 botón pulsador conectado a RB4. Realizar la simulación del circuito en ISIS Proteus, cargando el *.hex al PIC18F4550. Programar el microcontrolador mediante Pickit2

Marco Teórico

En el siguiente gráfico (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 continuación 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 programación (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 Aritmética y Lógica), registros, buses y unidad de control, es decir tiene una CPU (Unidad Central de Procesamiento). La mayoría de los dispositivos de lógica secuencial, entre ellos los CPU, son de naturaleza síncrona. Es decir, están diseñados y operan en función de una señal de sincronización. Esta señal, conocida como señal de reloj, usualmente toma la forma de una onda cuadrada periódica. Calculando el tiempo máximo en que las señales eléctricas pueden moverse en las varias bifurcaciones de los muchos circuitos de un CPU, los diseñadores pueden seleccionar un período apropiado para la señal de reloj. Para el correcto funcionamiento del microcontrolador debemos definir la frecuencia del oscilador pues determinará los ciclos de instrucción; 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 continuación mostramos la tabla del registro de configuración del oscilador (Figura 4)

Figura 4. Registro OSCCON para la Configuración del Oscilador

Podemos ver que por default tiene cargado el valor: 0100 X000 que de acuerdo con los valores de la tabla anterior corresponderían a la siguiente configuración: 0 | El dispositivo entra en reposo/bajo consumo cuando se ejecuta la instrucción 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 configuración. 

Para estas prácticas se utilizará una frecuencia de 4MHz y, como no es necesario precisión en el tiempo, no pondremos ningún oscilador externo, de esta manera el valor a cargar será el siguiente: 

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

Cálculos

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

Ciclo de reloj:



Ciclo de instrucción:

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 botón pulsador a 0.5mA, utilizar una resistencia de 10kΩ.

Simulación Para simular el siguiente código por favor revisar la publicación de ¿Cómo utilizar y simular en MPLAB? y ¿Cómo utilizar y simular en ISIS Proteus?, si sabes hacerlo puedes seguir leyendo. Creamos un proyecto nuevo y lo llamamos LedOn, como buena práctica de programación y para una mejor organización conviene que el archivo fuente del código lleve el mismo nombre del proyecto, es decir LedOn.asm este archivo con extensión *.asm es de ensamblador. 1

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

2

; Desarrollo de Microcontroladores y DSPS

3

; Encender un LED

4

; Práctica 1

5

;

6 7

; Fecha: 03/06/2012 ; Notas: Encender un LED en RB4 al presionar un botón en RB0 ;

8 ; Autor: ek

9 ; ************************************************************

10 LIST

11 12

P = 18F4550

INCLUDE ;************************************************************

13

CONFIG

FOSC = HS

14

CONFIG

PWRT = ON

15

CONFIG

BOR = OFF

16

CONFIG

WDT = OFF

CONFIG

MCLRE = ON

CONFIG

PBADEN = OFF

CONFIG

LVP = OFF

CONFIG

DEBUG = OFF

CONFIG

XINST = OFF

17 18

;INTOSC_XT no disponible para simulación, usar HS

19 20 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 0110 0000 => 0x60

Cálculos

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

Ciclo de reloj:



Ciclo de instrucción:

Para limitar la corriente que circulará por los LED’s conectados al Puerto B, se proponen resistencias de 330Ω:

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

Para generar el retardo se utilizarán tres registros de la memoria y se cargarán 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 están dentro del ciclo del contador 3 (Conta3). Tomando en cuenta que se necesitan 3 ciclos de instrucción para ir decrementando los ciclos, la fórmula queda como sigue:

Simulación

Antes de comenzar la simulación es necesario leer lo siguiente: ¿Cómo simular en MPLAB? y ¿Cómo simular en ISIS Proteus? en caso de saber cómo hacerlo se pueden omitir los enlaces anteriores. Desarrollar una simulación en MPLAB con la finalidad de medir los tiempos de ejecución para los retardos y observar la ejecución de cada instrucción. 1

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

2

; Desarrollo de Microcontroladores y DSPS

3

; Barrido de LEDs bidireccional

4

; Práctica 2

5 6

; ; Fecha: 08/06/2012 ; Notas: Hacer el barrido de un LED

7 ;

8 ; Autor: ek

9 ; ************************************************************

10 LIST

11 12

P = 18F4550

INCLUDE ;************************************************************

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

CONFIG

XINST = OFF

20 21

; CODE ******************************************************

22 23 #define Conta

0x12

24 cblock

25 Conta1

26

Conta2

27

Conta3

28 29

Sweep endc

30 31

#define Time1 0x00

;Configuración para 300ms 0x00

32

#define Time2 0x85

;Configuración para 300ms 0x85

33

#define Time3 0x02

;Configuración para 300ms 0x02

34 35

ORG

0x00

clrf

PORTB

;Iniciar el programa en el registro 0x00

36 37

;Limpia los posibles valores actuales de PORTB

38

clrf

PORTD

;Limpia los posibles valores actuales de PORTD

39

clrf

TRISB

;Configura TRISB

40

movwf

TRISD

;Configura TRISD =>=>

call

Retardo

;Esperar un tiempo

rrncf

Sweep, F

;Rotar hacia la Derecha y Guardar en Sweep

movff

Sweep, PORTB

btfss

PORTD, 0

41 42

movlw

0x01

;Entrada RD0 de habilitaci

;Mover el valor de Sweep a PORTB

43 ;Salta si RD0 = 1, Cambio

;btfsc

PORTD, 0

;Salta si RD0 = 0, Cambio ==>

bra

MoveLeft

bra

INICIO

47 48 49

;Mover el valor de Sweep a PORTB PRESIONAR Y SOLTAR

50 51

;Repetir Ciclo Conta1, reconfigurar el valor

decfsz

Conta2, F

;Salta cuando Conta2 llega a 0

bra

Repeat

;Salta a Repeat

71

decfsz

Conta3

72

bra

Repeat

73

Return

64 65 66 67 68 69 70

74 75 76 77

END

;Fin de Programa

78 79 Armar el siguientes circuito en ISIS Proteus y simularlo, de la misma manera será el circuito físico (Figura 5).

Figura 5. Circuito

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

Introducción En varios sistemas electrónicos nos encontramos con una parte mecánica que transmite algún movimiento por palancas, levas, poleas, ejes de rotación, entre otras, todas ellas obtienen, en primera instancia, el movimiento de algún motor. Existen diferentes tipos de motores, sin embargo para sistemas como: DVD’s, 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 más convenientes. De igual manera disponemos de motores a pasos unipolares o bipolares, cada uno de ellos tiene una combinación a sus entradas que determina su posición. 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 específicos   

   

Identificar las características 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 sólo 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 simulación del código en MPLAB. Armar el circuito en ISIS Proteus y simularlo. Programar el microcontrolador mediante el software Pickit2. Armar el circuito físico y realizar pruebas.

Marco Teórico

En el siguiente gráfico (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 continuación 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 programación (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 Aritmética y Lógica), registros, buses y unidad de control, es decir tiene una CPU (Unidad Central de Procesamiento). La mayoría de los dispositivos de lógica secuencial, entre ellos los CPU, son de naturaleza síncrona. Es decir, están diseñados y operan en función de una señal de sincronización. Esta señal, conocida como señal de reloj, usualmente toma la forma de una onda cuadrada periódica. Calculando el tiempo máximo en que las señales eléctricas pueden moverse en las varias bifurcaciones de los muchos circuitos de un CPU, los diseñadores pueden seleccionar un período apropiado para la señal de reloj. Para el correcto funcionamiento del microcontrolador debemos definir la frecuencia del oscilador pues determinará los ciclos de instrucción; 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 continuación mostramos la tabla del registro de configuración del oscilador (Figura 4)

Figura 4. Registro OSCCON para la Configuración del Oscilador

Podemos ver que por default tiene cargado el valor: 0100 X000 que de acuerdo con los valores de la tabla anterior corresponderían a la siguiente configuración:     

0 | El dispositivo entra en reposo/bajo consumo cuando se ejecuta la instrucción 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 configuración.

Para estas prácticas se utilizará una frecuencia de 4MHz y, como no es necesario precisión en el tiempo, no pondremos ningún 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 sóla posición o bien totalmente libres; si una o más de sus bobinas esta energizada el motor permanecerá en la posición correspondiente, o bien, si no hay flujo de corriente en las bobinas el eje del motor estará libre. Estos motores están constituidos normalmente por un rotor sobre el que van aplicados distintos imanes permanentes y por un cierto número de bobinas excitadoras en su estator. Para controlar un motor a pasos es necesario conocer su funcionamiento, diseñar 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 activación específica, pero se diferencian en el modo en que están conectadas sus bobinas. Debido a que se usará un motor a pasos bipolar se caracterizará a continuación. 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

función de cuatro interruptores electrónicos dobles, que nos permiten variar la polaridad de alimentacón de las bobinas. Con la activación y desactivación 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 posición, estos motores necesitan la inversión de la corriente que circula en sus bobinas en una secuencia determinada; Cada inversión 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 más 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 activación (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: Sólo activa una bobina a la vez. 3. Secuencia del tipo medio paso: Activa una bobina y después 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.

Cálculos Dado que se configuró el oscilador interno del microcontrolador a 4MHz, se tiene: 



Ciclo de reloj:

Ciclo de instrucción:



Para limitar la corriente del pin de Reset y el botón 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 botón. 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 instrucción 3 us para la ejecución de cada sustracción al contador 1. La fórmula queda como sigue:

Simulación Antes de comenzar la simulación es necesario leer lo siguiente: ¿Cómo simular en MPLAB? y ¿Cómo simular en ISIS Proteus? en caso de saber cómo hacerlo se pueden omitir los enlaces anteriores. Simulación en MPLAB Para el desarrollo de esta práctica haremos uso de una librería que contendrá las funciones para los retardos, de manera que necesitaremos un archivo con extensión *.inc y un *.asm, éste último será el archivo principal. En primer lugar se realizará el código 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 código, sin embargo la sintaxis no se resaltará hasta que tenga una extensión, para ello ejecutamos el comando Guardar como… mediante el menú File\Save As En la ventana que

aparece asignar el nombre de la librería, en este caso le llamaremos “Retardo” y le colocamos la extensión “.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 Librería de la función Retardo

Después de verificar la configuración 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 código que se interpretará como una función incluida en una librería.

Figura 10. Archivo Fuente y para Librería

Ahora en el archivo Retardo.inc escribiremos el siguiente código:

1 2

#define Conta cblock Conta1

3 Conta2

4 Conta3

5 endc

6 7 Retardo200ms

8 9 10

clrf Conta1 clrf Conta2 Repeat

11

decfsz Conta1, F

;Salta cuando Conta1 llega a 0

12

bra Repeat

;Salta a Repeat para Decrementar Conta1

decfsz Conta2, F

;Salta cuando Conta2 llega a 0

bra Repeat

;Salta a Repeat

13 14 15 16 Return

17 18

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

; ******************************************************** ; Desarrollo de Microcontroladores y DSPS ; Control de un Motor a pasos Bipolar ; Práctica 3

4 ;

5 ; Fecha: 15/06/2012

6 ; Notas: Control de un motor a pasos bipolar mediante

7 8 9 10

;

dos botones que controlan su dirección

; ; Autor: ek ; ************************************************************

11

LIST P = 18F4550

12

INCLUDE

13 14

;************************************************************ CONFIG FOSC = HS ;INTOSC_XT no disponible para simulación, usar HS CONFIG PWRT = ON

15 CONFIG BOR = OFF

16 CONFIG WDT = OFF

17 CONFIG MCLRE = ON

18 CONFIG PBADEN = OFF

19 20

CONFIG LVP = OFF CONFIG DEBUG = OFF

21

CONFIG XINST = OFF

22

; CODE ******************************************************

23

cblock SecuenC ;Indice de la Secuencia

24 25

endc

26 27

ORG 0x00

;Iniciar el programa en el registro 0x00

28 29

movlw 0x62

;Palabra de congiguración del OSC Interno

30

movwf OSCCON

;Configurar OSCC2ON SecuenC

bra INICIO Continue2

75 decf SecuenC, F

76 decf SecuenC, F

77 bra INICIO

78 79 MotorPosition

80 81 82 83 84

addwf PCL, F retlw 0x0A

;0000 1010

retlw 0x09

;0000 1001

retlw 0x05

;0000 0101

retlw 0x06

;0000 0110

85 86

include "Retardo.inc" ;Agregar librería Retardo.inc

87 88

END ;Fin de Programa

89 90 91 92 93

Simulación en ISIS Proteus Se construyó en ISIS Proteus el diagrama eléctrico de la siguiente manera y se verificó que el motor respondía como se esperaba al presionar los pulsadores que controlan el sentido de giro del mismo. El motor siempre se mueve sólo un paso si se presiona sólo una vez, el sentido depende del botón presionado. Si el botón 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 experimentación (Protoboard) 1 Fuente de 5V 1 Multímetro 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

Introducción En algunas ocasiones es necesario desplegar información textual y al mismo tiempo valores numéricos que no es suficiente utilizar LEDs como indicadores o display de 7 segmentos, por ello existen módulos LCD (Display de Cristal Líquido) que permiten conectar al microcontrolador una pantalla donde se pueda enviar y mostrar información de interés.

Objetivo Mostrar texto desde un PIC18F4550 a través de un LCD Objetivos específicos        

Identificar las características del PIC18F4550. Manejar el software MPLAB para crear un proyecto y simular su funcionamiento. Conocer el funcionamiento, control y aplicación de un LCD Crear el código en MikroC para el control del LCD Realizar la simulación del código en MPLAB. Armar el circuito en ISIS Proteus y simularlo. Programar el microcontrolador mediante el software Pickit2. Armar el circuito físico y realizar pruebas.

Marco Teórico

En el siguiente gráfico (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 continuación 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 programación (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 Aritmética y Lógica), registros, buses y unidad de control, es decir tiene una CPU (Unidad Central de Procesamiento). La mayoría de los dispositivos de lógica secuencial, entre ellos los CPU, son de naturaleza síncrona. Es decir, están diseñados y operan en función de una señal de sincronización. Esta señal, conocida como señal de reloj, usualmente toma la forma de una onda cuadrada periódica. Calculando el tiempo máximo en que las señales eléctricas pueden moverse en las varias bifurcaciones de los muchos circuitos de un CPU, los diseñadores pueden seleccionar un período apropiado para la señal de reloj. Para el correcto funcionamiento del microcontrolador debemos definir la frecuencia del oscilador pues determinará los ciclos de instrucción; 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 continuación mostramos la tabla del registro de configuración del oscilador (Figura 4)

Figura 4. Registro OSCCON para la Configuración del Oscilador

Podemos ver que por default tiene cargado el valor: 0100 X000 que de acuerdo con los valores de la tabla anterior corresponderían a la siguiente configuración:     

0 | El dispositivo entra en reposo/bajo consumo cuando se ejecuta la instrucción 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 configuración.

Para estas prácticas se utilizará una frecuencia de 4MHz y, como no es necesario precisión en el tiempo, no pondremos ningún oscilador externo, de esta manera el valor a cargar será el siguiente: 

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

LCD 2×16 (Displays de Cristal Líquido)

Cálculos

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

Ciclo de reloj:



Ciclo de instrucción:



Para limitar la corriente del pin de Reset y el botón 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 botón. 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 instrucción 3 us para la ejecución de cada sustracción al contador 1. La fórmula queda como sigue:

Simulación Antes de comenzar la simulación es necesario leer lo siguiente: ¿Cómo simular en MPLAB? y ¿Cómo simular en ISIS Proteus? en caso de saber cómo hacerlo se pueden omitir los enlaces anteriores. Simulación en MPLAB Librería de Retardos 1

CBLOCK

2

Conta1

3

Conta2 Conta3

4 5

ENDC ;Retardo_20ms *********************

6 Retardo_20ms

7 movlw

.247

movwf

Conta1

movlw

.26

movwf

Conta2

8 9 10 11

Re_20ms

12

decfsz Conta1, F

;Salta cuando Conta1 llega a 0

13

bra

;Salta a Repeat para Decrementar Conta1

14

decfsz Conta2, F

;Salta cuando Conta2 llega a 0

15

bra

;Salta a Repeat

16

Return

Re_20ms

Re_20ms

17 18 19 20

;Retardo_5ms ********************* Retardo_5ms movlw

.146

movwf

Conta1

21

movlw

.7

22

movwf

Conta2

23 24

Re_5ms decfsz Conta1, F ;Salta cuando Conta1 llega a 0 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 31 32 33

Retardo_200us movlw

.65

movwf

Conta1

Re_200us

34

decfsz

Conta1, F ;Salta cuando Conta1 llega a 0

35

bra

Re_200us

36

Return

;Salta a Repeat para Decrementar Conta1

37 38 39

;Retardo_2ms ********************* Retardo_2ms

40

movlw

.151

41

movwf

Conta1

movlw

.3

movwf

Conta2

42 43

Re_2ms

44 decfsz

Conta1, F ;Salta cuando Conta1 llega a 0

bra

Re_2ms

decfsz

Conta2, F ;Salta cuando Conta2 llega a 0

bra

Re_2ms

45 ;Salta a Repeat para Decrementar Conta1

46 47 48

;Salta a Repeat

Return

49 50 51

;Retardo_50us ********************* Retardo_50us

52

movlw

.15

53

movwf

Conta1

54 55 56 57 58

Re_50us decfsz Conta1, F ;Salta cuando Conta1 llega a 0 bra Return

Re_50us

;Salta a Repeat para Decrementar Conta1

59 60 61 62

Delay clrf

Conta1

clrf

Conta2

movlw

.3

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

69 70 71

decfsz Conta3, F bra

72 73 74 75 76 77

Return

Re_Delay

;Salta a Repeat

78

Código del programa 1

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

2

; Desarrollo de Microcontroladores y DSPS

3

; Manejo de un LCD

4

; Práctica 4

5 6

; ; Fecha: 18/06/2012 ; Notas: Controlar un LCD LM016

7 ;

8 ; ek

9 ; ************************************************************

10 LIST P = 18F4550

11 12

INCLUDE ;************************************************************

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

20 21

CONFIG DEBUG = OFF CONFIG XINST = OFF ; 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 40 41

Inicio call Delay ;Esperar un tiempo antes de comenzar a escribir movlw

'H'

call

LCD_Caracter

movlw

'o'

call

LCD_Caracter

movlw

'l'

call

LCD_Caracter

movlw

'a'

48

call

LCD_Caracter

49

movlw

' '

50

call

LCD_Caracter

51

movlw

'M'

52

call

LCD_Caracter

movlw

'u'

call

LCD_Caracter

movlw

'n'

call

LCD_Caracter

42 43 44 45 46 47

53 54 55

56

movlw

'd'

57

call

LCD_Caracter

movlw

'o'

call

LCD_Caracter

movlw

'!'

call

LCD_Caracter

call

Delay

call

Delay

call

LCD_Borrar

goto

Inicio

58 59 60 61 62 63 64 65 66 67

LCD_Inicializa

68

call

Retardo_20ms ;Esperar 20 ms

69

movlw

b'00110000' ;Mandar 0x30 -> W

70

movwf

PORTB ;Enviar W -> PORTB

72

call

Retardo_5ms ;Esperar 5ms

73

movlw

b'00110000' ;Enviar 0x30 -> W

movwf

PORTB

71

74

75 76

call

Retardo_50us ;Acumular 100us

77

call

Retardo_50us ;Acumular 100us

movlw

b'00110000'

movwf

PORTB

movlw

0x0F

movwf

PORTB

bsf

LCD_E

bcf

LCD_E

78 79 80 81 82 83 84 85

return

86 87 88

LCD_Caracter 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 información

92

bcf

LCD_E ;Transición del Enable a 0

93

call

Delay ;Esperar a poner la siguiente llamada

94

return

95 96 97 98

LCD_Borrar movlw

b'00000001' ;Comando para Borrar

call

LCD_Comando ;Enviar un comando

99 LCD_Comando

100 bcf

LCD_RS ;Modo Comando RS = 0

movwf

PORTB ;Envia W -> PORTB

bsf

LCD_E ;Activa Enable

call

Retardo_50us ;Espera que se envie la información

bcf

LCD_E ;Transición del Enable

101 102 103 104 105

return

106 107

INCLUDE

108 109 110 111 112

END ;Fin de Programa

113 114 115 116

Simulación 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 experimentación (Protoboard)  1 Fuente de 5V  1 Multímetro  1 Programador de Microcontroladores  1 Computadora  Software MPLAB y software de programador Advertisements Software ISIS Proteus

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 ;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. 30.

;******** Configuracion del Oscilador ********** 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

BSR_TEMP

;variable usada para

salvar contexto 56. salvar contexto 57. 58. 59.

ENDC 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. 89. 90.

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

;***************************************************************** ************* 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 (Leído 58186 veces) 0 Usuarios y 1 Visitante están 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 ).

Código: 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. 13.

; ; ;

* Archivos Requeridos:

P18F4550.INC

* ;***************************************************************** ************* 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 ;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 14.

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. 66. 67. 68. 69. 70. 71. 72.

;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

;***************************************************************** ************* 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. registro BSR 100. 101. ; *** 102. 103. 104.

movff

BSR,BSR_TEMP

;Salva el

*** El codigo de la interrupcion de baja prioridad va aqui

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 PULLUP 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 línea La electronica es el arte de manipular señales electricas que transportan información 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.

Código: ASM 1. ;********************************************************************** ******** 2. ; * 3. ; Nombre: Disp7seg.asm 4. ; Fecha: 31/07/2008 5. ; Version: v1.00 6. ; * 7. ; Autor: Sander 8. ; Empresa:

9. ; * ;***************************************************************** ************* 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. ;***************************************************************** ************* 10.

42. 43.

LIST P=18F4550 definir el procesador 44. #include

;Directiva para ;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 OFF

CPD

=

;La EEPROM no esta protegida ;***************************************************************** ************* 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 68.

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. 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x DB 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 línea La electronica es el arte de manipular señales electricas que transportan información 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 más! un saludo En línea .

Slalen  

Colaborador PIC24H



  

Mensajes: 1079

 o 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 línea 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 línea .

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.

Código: 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| -GND52. ; |______________| 53. ; 54. ;***************************************************************** ************* 55. 56. LIST P=18F4550 ;Directiva para definir el procesador 57. #include ;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 extraño sucedio,encedemos los 144. movwf LATD,.0 ;s egmentos A,D y G para indicarlo y detenemos

145. 146. 147. 148. 149. 150.

bcf ;la ejecucion el programa bcf

INTCON,GIEH INTCON,GIEL

sleep IntINT2

clrf Cantms+1,.0 movlw .50 ;Hacemos un retardo de 50 ms para antirrebote 151. movwf Cantms,.0 152. rcall Retardo_ms 153. IntINT2_0 154. btfsc BotD igue presionado el boton de decremento? 155. bra IntINT2_X ;No => vamos a salir de esta interrupcion 156. decf Cont,F,.0 i => Cont -157. movlw 0xFF 158. cpfseq Cont,.0 ont == 0xFF (Cont==WREG)? 159. bra IntINT2_00 ;No => vamos a actualizar el display 160. movlw 0x0F i => reiniciamos el decremento 161. movwf Cont,.0 y continuamos actualizando el display 162. IntINT2_00 163. movf Cont,W,.0 = Cont, para realizar el despliegue 164. rcall Conv7Seg ealizamos la conversion de BCD a 7 segmentos 165. movwf LATD,.0 ovemos el valor convertido al PORT D 166. movlw .1 167. movwf CantSeg,.0 ealizamos una espera de 1 seg, para 168. rcall RetardoSeg er el cambio en el display 169. bra IntINT2_0 ;volvemos a revisar el boton 170. IntINT2_X 171. bcf INTCON3,INT2IF ara dar por terminada la interrupcion y

;S

;S

;C

;S ;

;W ;r ;m

;r ;v

;P

172. ;salir de las interrupciones de baja prioridad 173. 174.

X_IntLow 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 extraño 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. 193. 194. 195. 196. 197. 198. 199.

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

igue presionado el boton de incremento?

;S

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. RCON,IPEN,.0 bsf ;Habilitam os las prioridades para las interrupciones 243. 244. ;******************** Inicializacion de Variables ************************ 245. clrf Cont,.0 ;Cont = 0 246. ;***************************************************************** ********** 247. INTCON,GIEH,.0 bsf ;Habilitam os las interrupciones de prioridad alta 248. INTCON,GIEL,.0 bsf ;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. 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x DB 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 línea La electronica es el arte de manipular señales electricas que transportan información 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.

Código: 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| -GND52. ; |______________| 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 ;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. 143. 144. STATUS 145. de trabajo 146.

ORG

0x0018

movff

STATUS,STATUS_TEMP

;Salva el registro

movff

WREG,WREG_TEMP

;Salva el registro

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 extraño 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 0xFF (Cont==WREG)? 171. bra IntINT2_00 o => vamos a actualizar el display 172. movlw 0x0F reiniciamos el decremento 173. movwf Cont,.0 continuamos actualizando el display 174. IntINT2_00 175. movf Cont,W,.0 para realizar el despliegue 176. rcall Conv7Seg s la conversion de BCD a 7 segmentos 177. btfsc IntHigh_F produjo una interrupcion de mayor prioridad? 178. bra IntINT2_0 i => usamos el valor de Cont que dejo la int alta 179. movwf LATD,.0 movemos el valor convertido al PORT D 180. movlw .1 181. movwf CantSeg,.0 s una espera de 1 seg, para 182. rcall RetardoSeg cambio en el display 183. bra IntINT2_0 olvemos a revisar el boton 184. IntINT2_X 185. bcf INTCON3,INT2IF por terminada la interrupcion y 186. ;salir de las interrupciones de baja prioridad 187. X_IntLow 188. movff BSR_TEMP,BSR

;Cont == ;N ;Si => ; y

;W = Cont, ;realizamo ;Se ;S ;No =>

;realizamo ;ver el ;v

;Para dar

;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 extraño 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. os Cantms 249. 250.

movff

TOSL,Cantms

movff TOSH,Cantms+1 pop ;STKPTR --, y descartamos TOS

;Recuperam ;y Cantms+1

251. 252. bcf INTCON3,INT1IF ;Para dar por terminada la interrupcion y 253. ;salir de las interrupciones de alta prioridad 254. IntHigh_F bsf ;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' prioridades(Bits 7 y 6), y habilitamos 278. movwf INTCON3,.0 interrupciones para INT1 e INT2 (bits 3 y 4) 279. 280. RCON,IPEN,.0 bsf

;Asignamos ;las

;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. INTCON,GIEH,.0 bsf ;Habilitam os las interrupciones de prioridad alta 287. INTCON,GIEL,.0 bsf ;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. 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90, DB 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 línea La electronica es el arte de manipular señales electricas que transportan información 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 ). Código: 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. 13.

; ; ;

* Archivos Requeridos:

P18F4550.INC

* ;***************************************************************** ************* 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 ;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 14.

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. 66. 67. 68. 69. 70. 71. 72.

;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

;***************************************************************** ************* 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. registro BSR 100. 101. ; *** 102. 103. 104.

movff

BSR,BSR_TEMP

;Salva el

*** El codigo de la interrupcion de baja prioridad va aqui

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 sólo usan C, por fin veo a alguienque usa el ASM para los 18F. En línea

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

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

es esta:

ENDC

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

Saludos En línea

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 línea La electronica es el arte de manipular señales electricas que transportan información 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 línea

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 línea

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 Código: 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. 24. 25.

;

Archivos Requeridos:

P18F4550.INC

; *

26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59.

;***************************************************************** ************* ; Notas: El programa hace parpadear los pines del PIC a razon de 1 seg usando ;

el TMR0 para generar los retardos.

; El TMR0 sera usado en su modo de 16 bits y se configurara para que genere ;

con presicion un retardo de 100 ms.

; ;

Tiempo = (NumCuentasTMR0)(4/Fosc)(preescaler)

; ;

Para Fosc = 4 MHz; y el Tiempo de 100 ms , tenemos :

; ;

(4 MHz/4)(100 ms) = (NumCuentasTMR0)(preescaler)

;

(NumCuentasTMR0)(preescaler) = 100000

; Los valores posibles para el preescaler son: 2,4,16,32,64,128 y 256, entonces ; son posibles diferentes combinaciones para el (NumCuentasTMR0) y el preescaler, ; Sin embargo debe notarse que al ser el TMR0 un contador ascendente el valor ; si no : ;

hallado anteriormente no es el que debe cargarse al TMR0

60. 61. 62. 63. 64. 65.

;

TMR0 = 65536 - (NumCuentasTMR0)

; ;

---------------------------------------------------------

-66. 67.

; cargar |

68. 69.

; TMR0

70. 71.

;

|Preescaler

| NumCuentasTMR0|Valor a cargar |Valor a

|

| TMR0(Hex)

|

| |

---------------------------------------------------------

-72. 73.

;

| |

2 0x3CB0

| |

50000

|

15

;

| |

4 0x9E58

| |

25000

|

40

;

| |

8 0xCF2C

| |

12500

|

53

;

| |

16 0xE796

| |

6250

|

59

;

| |

32 0xF3CB

| |

3125

|

62

;

| |

64 ------

| |

1562,5

|

--

;

| |

128 ------

| |

781,25

|

--

;

| |

256 ------

| |

390,625

|

--

536 74. 75. 536 76. 77. 036 78. 79. 286 80. 81. 411 82. 83. --84. 85. --86. 87. --88. 89.

; --

90.

---------------------------------------------------------

91.

;

Ta

bla 1 92. 93.

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

94. 95. 96. 97.

LIST P=18F4550

;Directiva para definir el

procesador 98. 99.

#include ;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 modificación: 12 de Octubre de 2008, 03:25:07 por sander » En línea La electronica es el arte de manipular señales electricas que transportan información 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 Código: ASM 1. 2. ;********************************************************************** ******** 3. 4. ; 5.

6. ; 7. 8. ; 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.

31. 32.

Fecha:

02/09/2008

;

Version:

v0.90

;

;

Autor:

;

Empresa:

Sander

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

23. 24. 25. 26.

29. 30.

TxRx_0.asm

;

21. 22.

27. 28.

Nombre:

;

Archivos Requeridos:

P18F4550.INC

;

;***************************************************************** *************** ; Notas: El programa muestra el uso del EUSART para realizar una comunicacion ; configuraremos el oscilador

33. 34.

;

asincrona con la PC, para este ejemplo

para que funcione a 48 MHz usando un cristal externo de 4

MHz. 35. 36. 37. 38. 39.

; ; Para configurar la modo de 16 bits y

velocidad de transmision

se usara el

40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52.

; el modo de alta de velocidad para el generador de baudios (BRG16=1; BRGH=1), ; ; ; Vel = Fosc/[4(n+1)] carga a SPBRGH:SPBRG ;

57. 58.

para

;

|Velocidad |Valor n |Valor Hex para |Velocidad

; PBRGH:SPBRG

|(Baudios) |real

65. 66. 67. 68. 69. 70. 71.

|Valor | %

| | Error |

| |SPBRGH:SPBRG

|S

; -------------------------------------------------------------------------; -

63. 64.

n = [(Fosc/Vel)-1]/4

; --------------------------------------------------------------------------

59. 60. 61. 62.

Donde n es el valor que se

;

53. 54. 55. 56.

para este caso tenemos que la velocidad esta dada por:

| |

; 0x9C3F

|

; 0x270F

|

; 0xC34F

|

; 0x09C3

|

; 0x04E1

|

110 -------300

39999,75 300 | 0

| |

39999

|

1200

| 9999,75 1200 | 0

| |

9999

|

2400

| 4999,75 2400 | 0

| |

4999

|

4800

| 2499,75 4800 | 0

| |

2499

|

9600

| 1249,75 9600 | 0

| |

1249

|

|

|

|

|

|

| 109090,66 | ------| ------- | ----- | |

72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88.

; 0x0263

|

19600 | | 19607,84

611,99 | | 0,04 |

611

|

; 0x0137

|

38400 | | 38338,65

312,25 | | 0,16 |

312

|

; 0x00CF

|

57600 | | 57692,30

208,08 | | 0,16 |

207

|

; 0x0067

|

115200 | | 115384,61

103,91 | | 0,16 |

103

|

; 0x0033

|

230400 | | 230769,23

51,83 | | 0,16 |

51

|

; 0x0019

|

460800 | | 461538,46

25,79 | | 0,16 |

25

|

; 0x000C

|

921600 | | 923076,92

12,77 | | 0,16 |

12

|

; -------------------------------------------------------------------------; Tabla 1

89. 90. 91. 92. 93. 94.

; Lo que el programa hara es recibir caracteres e ir almacenandolos en BufferRx, ; dejara de recibir caracteres si recibe el caracter enter(0x0D ), si ya han ; 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 ;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 señal 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 0x04 EQU ;Estas constantes sirven para definir la velocidad 193. 194. VelLO 0xE1 EQU ;de la comunicacion, 9600 baudios 195. 196. 197. 198. CBLOCK 0x080 199.

200. salvar contexto 201. 202. salvar contexto 203. 204. salvar contexto 205. 206. 207. 208. 209. 210. 0) max 96 bytes 211. 212. TMR0 desborda 213. 214. recibidos 215. 216. transmitidos 217. 218. recepcion 219. 220. auxiliar 221. 222. 223. 224. tablas 225. 226. 227. 228. 229. 230. 231. 232. 233. 234.

WREG_TEMP

;variable usada para

STATUS_TEMP

;variable usada para

BSR_TEMP

;variable usada para

ENDC

CBLOCK

0x000

;Variables en la ACCESS RAM (Banco

ContT0

;para contar las veces que

ContRx

;para contar los bytes

ContTx

;para contar los bytes

DatoRx

;variable temporal para la

DatoTemp

;usado como variable

Banderas TablaOffs

;Para movernos en las

ENDC

CBLOCK

0x100

BufferRx:.256 ENDC

;Variables en el Banco 1 ;Buffer para la recepcion

235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248.

CBLOCK

0x200

BufferTx:.256

;Variables en el banco 2 ;Buffer para la transmision

ENDC

#DEFINE TimeOut ;=1 si el pasan 2 seg

Banderas,.0

#DEFINE RxOK ;=1 si se termino de recibir

Banderas,.1

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. 315. 316. LowInt 317. 318. STATUS 319. 320. de trabajo 321. 322.

ORG

0x0018

movff

STATUS,STATUS_TEMP

;Salva el registro

movff

WREG,WREG_TEMP

;Salva el registro

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. EnvMsg call ; 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. TimeOut bsf ;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 i => vamos a terminar la recepcion 415. 416. movf DatoRx,W,.0 guardamos el caracter 417. 418. movwf POSTINC0 e incrementamos FSR 419. 420. movlw .20 421. 422. movwf ContT0 os el contador para el TimeOut 423. 424. incfsz ContRx,F,.0 llego a 256, (desbordo?) 425. 426. bra IntRx_X o => terminamos 427. 428. ;Si => tenemos 256 caracteres recibidos 429. 430. IntRx_P0_1 431. 432. RxOK bsf onemos en 1 RxOK 433. 434. bra 435. 436. IntRx_P1 437. 438. movf os el byte recibido 439. 440. bra 441. 442. IntRx_Er1 443. 444. bcf 445. 446. bsf einiciamos el EUSART 447.

;S

;No =>

;Guardamos

;Reiniciam

;ContRx

;N

;p

IntRx_X

RCREG,W,.0

;Descartam

IntRx_X

RCSTA,CREN RCSTA,CREN

;R

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 amos a salir de la IntTx 485. 486. IntTxP1 487. 488. bsf

IntTx_X

;v

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 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' mos para una transmision de 8 bit(bit 6) 573. 574. movwf TXSTA,.0 asincrono (bit 4),para ajustar los baudios 575. 576. ;BRGH = 1 (bit 2) 577. 578. 579. 580. movlw B'01001000' os los 16 bits del generador de baudios 581. 582. movwf BAUDCON,.0 (bit 3) 583. 584. 585. 586. movlw VelHI los registros SPBRGH:SPBRG con los 587. 588. movwf SPBRGH,.0 de la tabla 1 para la velocidad deseada

;Todos los

;Configura

;modo

;Habilitam

;BRG16 = 1

;Cargamos

;valores

589. 590. movlw VelLO 591. 592. movwf SPBRG,.0 593. 594. 595. 596. movlw B'10010000' os el puerto seria (Bit 7), modo 8 bits 597. 598. movwf RCSTA y habilitamos el receptor (Bit 4). 599. 600. 601. 602. ;*********************** Configuracion del TMR0 ************************* 603. 604. movlw B'10010110' modo 16 bits, cambia con las 605. 606. movwf T0CON,.0 ones, asignamos preescaler de 128 607. 608. 609. 610. movlw 0xDB acuerdo a BlinkT0.asm calculamos los valores a 611. 612. movwf TMR0H,.0 para TMR0H y TMR0L, para el oscilador 613. 614. movlw 0x61 MHz. y un tiempo de 100 ms 615. 616. movwf TMR0L,.0 617. 618. 619. 620. movlw .20 621. 622. movwf ContT0,.0 20 para controlar 2 segundos 623.

;Habilitam

;(bit 6),

;TMR0 on,

;instrucci

;De

;cargar

;de 48

;

; ;ContT0 =

624. ;********************** Configuracion de interrupciones ********************** 625. 626. 627. 628. PIE1,RCIE,.0 bsf ;Habilitam os la interrupcion de recepcion 629. 630. INTCON,TMR0IE,.0 bsf ;Habilitam os la interruocion de desborde del TMR0 631. 632. INTCON,PEIE,.0 bsf ;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. INTCON,GIE bsf ;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 apunta al inicio de BufferRx 663. 664. clrf ContRx,.0 reiniciar el conteo de bytes recibidos 665. 666. clrf Banderas os las banderas 667. 668. movlw .20 einiciamos el contador del time out 669. 670. movwf ContT0,.0 20 para controlar 2 segundos 671. 672. movlw .1 673. 674. rcall EnvMsg 675. 676. MainP1 677. 678. btfsc TimeOut produjo un time out? 679. 680. bra MainP2 i => vamos a atender el timeout 681. 682. btfsc RxOK termino la recepcion? 683. 684. bra MainP3 i => vamos a atender la recepcion 685. 686. bra MainP1 o => continuamos esperando 687. 688. 689. 690. MainP2 691. 692. RxOK bsf ara detener la recepcion 693. 694. movlw .4

;FSR0

;para

;reiniciam

;r

;ContT0 =

;Se

;S

;No, Se

;S

;N

;P

695. 696. rcall EnvMsg el mensaje de timeout 697. 698. tstfsz ContRx,.0 0?; 699. 700. bra MainP2_P0 o => se recibieron caracteres y vamos a procesarlos 701. 702. bcf RxOK i => no se recibieron caracteres, 703. 704. bra MainP0 si que volvemos a empezar 705. 706. MainP2_P0 707. 708. movlw .2 709. 710. rcall EnvMsg que procesamos la trama 711. 712. rcall ProcTrama procesar la trama 713. 714. bcf TimeOut einiciamos las banderas 715. 716. bra MainTx amos a ennviar la nueva trama 717. 718. bra MainP0 olvemos a empezar 719. 720. 721. 722. MainP3 723. 724. tstfsz ContRx,.0 0?; 725. 726. bra MainP3_P0 o => se recibio un 0x0D (enter) 727.

;Enviamos

;ContRx ==

;N

;S

;a

;Indicamos

;vamos a

;r

;V

;V

;ContRx ==

;N

728. movlw .5 i => se lleno el buffer, y enviamos 729. 730. rcall EnvMsg mensaje respectivo 731. 732. MainP3_P0 733. 734. movlw .2 735. 736. rcall EnvMsg que procesamos la trama 737. 738. rcall ProcTrama procesar la trama 739. 740. bra MainTx amos a Enviar la nueva trama 741. 742. bra MainP0 olvemos a empezar 743. 744. 745. 746. MainTx 747. 748. movlw .3 749. 750. rcall EnvMsg el mensaje para transmitir 751. 752. TXSTA,TXEN bsf abilitamos es transmisor 753. 754. movf POSTINC1,W dato e incrementamos FSR1 755. 756. movwf TXREG el dato a TXREG 757. 758. PIE1,TXIE,.0 bsf os la interrupcion de transmision 759. 760. btfss TxOK transmision termino?

;S

;el

;Indicamos

;vamos a

;V

;V

;Enviamos

;H

;leemos el

;copiamos

;Habilitam

;La

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 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 nta al inicio del BufferTx 805. 806. clrf ContTx,.0 0 807. 808. ProcTramaP0 809. 810. movf POSTINC0,W el caracter a W e incrementamos FSR0 811. 812. movwf DatoTemp el dato para procesar 813. 814. movlw 'a' 815. 816. cpfslt DatoTemp = 'a' vamos a ver si es menor a z 819. 820. bra ProcTramaP0_2 es minuscula y vamos a guardar DatoTemp 821. 822. ProcTramaP0_0 823. 824. movlw 'z' 825. 826. cpfsgt DatoTemp > 'z' 827. 828. bra ProcTramaP0_1 es

;Si => no

;DatoTemp

;No => es

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 es mayor de 256? 899. 900. incf PCLATH,F,.0 incrementamos PCLATH 901. 902. movf TablaOffs,W,.0 saltar 903. 904. addwf PCL,F suma TablaOffs a PCL se realiza el salto 905. 906. EnvMsgP0 907. 908. bra EnvMsg_0 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 la parte mas alta del mensage que enviaremos 925. 926. movwf TBLPTRU,.0 actualizamos TBLPTRU 927. 928. movlw HIGH Msg_0 la parte alta del mensage que enviaremos 929. 930. movwf TBLPTRH,.0 actualizamos TBLPTRH 931. 932. movlw LOW Msg_0 la parte baja del mensage que enviaremos

;el salto

;Si =>

;leemos el valor a

;cuando se

;V

;tomamos

;y la

;tomamos

;y la

;tomamos

933. 934. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR 935. 936. ;apuntado al inicio del mensaje 937. 938. rcall EnviarMsg a enviar el mensaje 939. 940. return 941. 942. 943. 944. EnvMsg_1 945. 946. movlw UPPER Msg_1 la parte mas alta del mensage que enviaremos 947. 948. movwf TBLPTRU,.0 actualizamos TBLPTRU 949. 950. movlw HIGH Msg_1 la parte alta del mensage que enviaremos 951. 952. movwf TBLPTRH,.0 actualizamos TBLPTRH 953. 954. movlw LOW Msg_1 la parte baja del mensage que enviaremos 955. 956. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR 957. 958. ;apuntado al inicio del mensaje 959. 960. rcall EnviarMsg a enviar el mensaje 961. 962. return 963. 964. EnvMsg_2 965.

;y la

;llamamos

;tomamos

;y la

;tomamos

;y la

;tomamos

;y la

;llamamos

966. movlw UPPER Msg_2 la parte mas alta del mensage que enviaremos 967. 968. movwf TBLPTRU,.0 actualizamos TBLPTRU 969. 970. movlw HIGH Msg_2 la parte alta del mensage que enviaremos 971. 972. movwf TBLPTRH,.0 actualizamos TBLPTRH 973. 974. movlw LOW Msg_2 la parte baja del mensage que enviaremos 975. 976. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR 977. 978. ;apuntado al inicio del mensaje 979. 980. rcall EnviarMsg a enviar el mensaje 981. 982. return 983. 984. EnvMsg_3 985. 986. movlw UPPER Msg_3 la parte mas alta del mensage que enviaremos 987. 988. movwf TBLPTRU,.0 actualizamos TBLPTRU 989. 990. movlw HIGH Msg_3 la parte alta del mensage que enviaremos 991. 992. movwf TBLPTRH,.0 actualizamos TBLPTRH 993. 994. movlw LOW Msg_3 la parte baja del mensage que enviaremos 995. 996. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR

;tomamos

;y la

;tomamos

;y la

;tomamos

;y la

;llamamos

;tomamos

;y la

;tomamos

;y la

;tomamos

;y la

997. 998. ;apuntado al inicio del mensaje 999. 1000. rcall EnviarMsg a enviar el mensaje 1001. 1002. return 1003. 1004. EnvMsg_4 1005. 1006. movlw UPPER Msg_4 la parte mas alta del mensage que enviaremos 1007. 1008. movwf TBLPTRU,.0 actualizamos TBLPTRU 1009. 1010. movlw HIGH Msg_4 la parte alta del mensage que enviaremos 1011. 1012. movwf TBLPTRH,.0 actualizamos TBLPTRH 1013. 1014. movlw LOW Msg_4 la parte baja del mensage que enviaremos 1015. 1016. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR 1017. 1018. ;apuntado al inicio del mensaje 1019. 1020. rcall EnviarMsg a enviar el mensaje 1021. 1022. return 1023. 1024. EnvMsg_5 1025. 1026. movlw UPPER Msg_5 la parte mas alta del mensage que enviaremos 1027. 1028. movwf TBLPTRU,.0 actualizamos TBLPTRU 1029.

;llamamos

;tomamos

;y la

;tomamos

;y la

;tomamos

;y la

;llamamos

;tomamos

;y la

1030. movlw HIGH Msg_5 la parte alta del mensage que enviaremos 1031. 1032. movwf TBLPTRH,.0 actualizamos TBLPTRH 1033. 1034. movlw LOW Msg_5 la parte baja del mensage que enviaremos 1035. 1036. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR 1037. 1038. ;apuntado al inicio del mensaje 1039. 1040. rcall EnviarMsg a enviar el mensaje 1041. 1042. return 1043. 1044. EnvMsg_6 1045. 1046. movlw UPPER Msg_6 la parte mas alta del mensage que enviaremos 1047. 1048. movwf TBLPTRU,.0 actualizamos TBLPTRU 1049. 1050. movlw HIGH Msg_6 la parte alta del mensage que enviaremos 1051. 1052. movwf TBLPTRH,.0 actualizamos TBLPTRH 1053. 1054. movlw LOW Msg_6 la parte baja del mensage que enviaremos 1055. 1056. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR 1057. 1058. ;apuntado al inicio del mensaje 1059. 1060. rcall EnviarMsg a enviar el mensaje

;tomamos

;y la

;tomamos

;y la

;llamamos

;tomamos

;y la

;tomamos

;y la

;tomamos

;y la

;llamamos

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. TXSTA,TXEN bsf ;H abilitamos el transmisor 1093.

1094. movff caracter a TXREG 1095. 1096. bra

TABLAT,TXREG

;Movemos el

$+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. '\n','\r' DB 1121. 1122. 'P','r','o','g','r','a','m','a',' DB ','e','j','e','m','p','l','o' 1123. 1124. ' ','p','a','r','a',' ','e','l',' ','u','s','o',' DB ','d','e','l' 1125. 1126. ' ','E','U','S','A','R','T','\n','\r',0x00 DB 1127. 1128. Msg_1

1129. 1130. '\n','\r' DB 1131. 1132. 'I','n','t','r','o','d','u','z','c','a',' DB ','l','a',' ','c','a' 1133. 1134. 'd','e','n','a','.','.','.','.','\n','\r',0x00 DB 1135. 1136. Msg_2 1137. 1138. '\n','\r' DB 1139. 1140. 'P','r','o','c','e','s','a','n','d','o','.','.','. DB ','\n','\r',0x00 1141. 1142. Msg_3 1143. 1144. 'L','a',' ','n','u','e','v','a',' DB ','c','a','d','e','n','a',' ' 1145. 1146. 'e','s',':','\n','\r',0x00 DB 1147. 1148. Msg_4 1149. 1150. '\n','\r' DB 1151. 1152. 'T','i','m','e',' ','o','u','t','\n','\r',0x00 DB 1153. 1154. Msg_5 1155. 1156. '\n','\r' DB 1157. 1158. 'B','u','f','f','e','r',' ','d','e',' DB ','r','e','c','e','p','c' 1159. 1160. 'i','o','n',' ','l','l','e','n','o','\n','\r',0x00 DB 1161. 1162. 1163. 1164. Msg_6 1165. 1166. '\n','\r' DB 1167. 1168. 'E','r','r','o','r','\n','\r',0x00 DB 1169.

1170. 1171. 1172. programa 1173.

END

;Directiva fin del

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 señales 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 modificación: 12 de Octubre de 2008, 03:26:48 por sander » En línea La electronica es el arte de manipular señales electricas que transportan información Jan Davidse

Visita mi blog

Leon Pic  

Colaborador DsPIC30



  

Mensajes: 3471

 o Re: Ejemplos PIC18F4550 « Respuesta #14 en: 12 de Octubre de 2008, 10:31:01 »

Que buena guía 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 más fácil, 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 comunicación. Lo que voy hacer, es organizar mis rutinas, y las subiré en un hilo nuevo. Explicaré como usarlo y listo. Además, podremos ir mejorando las rutinas para hacerlas más eficientes y que cada uno las modifique a su gusto. Igual como en C. En línea Él dijo: "destruyan a la Iglesia y yo la levantaré en tres días". 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 Señor Dios hecho hombre: Jesús.

-É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 Meteorología 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 ;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 56.

;PWRT habilitado CONFIG

BOR

=

OFF deshabilitado 57.

;Brown out resete CONFIG

WDT

OFF 58.

;Watch dog deshabilitado CONFIG

MCLRE =

OFF 59.

60.

;MCLR como entrada CONFIG

ON analogicas

=

PBADEN = ;Todos los pines como entradas

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. 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x DB 80,0x90 269. ;***************************************************************** ***************** 270. 271. 272. END ;Directiva fin del programa

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

 ; *  ;  ;  ;

Autor: Empresa:

Sander

*  ;*************************************************************** ***************  ; * 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 ;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 ;Salva BSR,BSR_TEMP  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 extraño 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  == 1?(ocurrio la INT1?) bra IntINT1  ;Si => vamos a su rutina movlw B'10110110'  ;No => un error extraño 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 

;INT1IF

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)  RCON,IPEN,.0 ;Habili bsf  tamos las prioridades para las interrupciones  Inicializacion de  ;******************** Variables ************************ clrf Cont,.0 ;Cont =  0  ;*************************************************************** ************ INTCON,GIEH,.0 ;Habili bsf  tamos las interrupciones de prioridad alta INTCON,GIEL,.0 ;y las bsf  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  ; |0  ; |0  ; |0  ; |0  ; |1  ; |0  ; |0  ; |0  ; |0  ; |0  ; |0  ; |1  ; |0

|---|---|---|-------|---|---|---|---|---| 0 |0

|1 |0

|1 |C0

|0 |

|0

|

0

1

|1 |1

|1 |F9

|1 |

|1

|

1

|0

2

|1 |0

|1

|0

|

0

|1

3

|1 |0

|0 |B0

|1 |

|1

|

0

|0

4

|1 |1

|0 |99

|0 |

|1

|

1

|0

5

|1 |0

|0 |92

|0 |

|1

|

0

|0

6 |1

|1 |0

|0 |82

|0 |

|0

|

0

7 |0

|1 |0

|1 |F8

|1 |

|1

|

1

8 |0

|1 |0

|0 |80

|0 |

|0

|

0

9 |0

|1 |0

|0 |90

|0 |

|1

|

0

A |0

|1 |0

|0 |88

|0 |

|0

|

1

B |1

|1 |1

|0 |83

|0 |

|0

|

0

C |1

|1 |0

|1 |C6

|0 |

|0

|

0

D |0

|1 |1

|0 |A1

|1 |

|0

|

0

|0 |A4 |

 ; 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 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8 DB  ,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. 13.

; ; ;

* Archivos Requeridos:

P18F4550.INC

* ;***************************************************************** ************* 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. ; ____________|_ 14.

42. 43.

; ; AAAAAAA ;

>| 44. >|

| ---

B

B(RD1) | C(RD2) |

--

B

D(RD3) |

|

F

45.

A(RD0)

B ;

>| F RB1(INT1) 46. ; >| F 47. ;

E

>|

E

49.

>|

X-0 F(RD5)

C

>|

E

|

0---> RB2(INT2)

--

|

| G(RD6)

C ; DDDDDDD ; ;

| GGGGGG

0--->

--

|

;

51. 52. 53. 54. 55.

E(RD4) C

;

50.

X-0

_|_

; >|

_|_ --

| |

48.

|

--

|

| DP(RD7) --

DP|

-GND|______________|

; 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 ;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. 94.

CBLOCK 0x080 WREG_TEMP

;variable usada para salvar

STATUS_TEMP

;variable usada para salvar

BSR_TEMP

;variable usada para salvar

contexto 95. contexto 96. contexto 97. 98. 99.

ENDC 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 extraño 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 acemos un retardo de 50 ms para antirrebote 159. movwf Cantms,.0 160. rcall Retardo_ms 161. IntINT2_0 162. bcf IntHigh_F onemos en cero esta bandera, por si venimos 163. ;de la interrupcion alta 164. btfsc BotD presionado el boton de decremento? 165. bra IntINT2_X o => vamos a salir de esta interrupcion 166. btfsc IntHigh_F produjo una interrupcion de mayor prioridad? 167. bra IntINT2_0 i => usamos el valor de Cont que dejo la int alta 168. decf Cont,F,.0 Cont -169. movlw 0xFF 170. cpfseq Cont,.0 0xFF (Cont==WREG)? 171. bra IntINT2_00 o => vamos a actualizar el display 172. movlw 0x0F reiniciamos el decremento 173. movwf Cont,.0 continuamos actualizando el display 174. IntINT2_00 175. movf Cont,W,.0 para realizar el despliegue 176. rcall Conv7Seg s la conversion de BCD a 7 segmentos 177. btfsc IntHigh_F produjo una interrupcion de mayor prioridad? 178. bra IntINT2_0 i => usamos el valor de Cont que dejo la int alta 179. movwf LATD,.0 movemos el valor convertido al PORT D 180. movlw .1 181. movwf CantSeg,.0 s una espera de 1 seg, para

;H

;p

;Sigue ;N ;Se ;S ;Si =>

;Cont == ;N ;Si => ; y

;W = Cont, ;realizamo ;Se ;S ;No =>

;realizamo

182. rcall RetardoSeg cambio en el display 183. bra IntINT2_0 olvemos a revisar el boton 184. IntINT2_X 185. bcf INTCON3,INT2IF por terminada la interrupcion y 186. ;salir de las interrupciones de baja prioridad 187. X_IntLow 188. movff BSR_TEMP,BSR

;ver el ;v

;Para dar

;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 extraño 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 s la conversion de BCD a 7 segmentos 237. movwf LATD,.0 el valor convertido al PORT D 238. movlw .1 239. movwf CantSeg,.0 s una espera de 1 seg, para 240. rcall RetardoSeg cambio en el display 241. bra IntINT1_0 olvemos a revisar el boton 242. IntINT1_X 243. ;************ Recuperamos los valores de la pila **************** 244. movff TOSL,CantSeg valor guardado, primero CantSeg 245. pop ;El pop efectivamente decrementa el STKPTR y 246. ;descarta e valor de TOS 247. 248. movff TOSL,Cantms os Cantms 249. movff TOSH,Cantms+1 250. pop ;STKPTR --, y descartamos TOS 251. 252. bcf INTCON3,INT1IF por terminada la interrupcion y 253. ;salir de las interrupciones de alta prioridad 254. IntHigh_F bsf

;realizamo ;movemos

;realizamo ;ver el ;v

;Recuperamos el

;Recuperam ;y Cantms+1

;Para dar

;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 el oscilador interno a 4 MHz 269. movlw B'00001111' 270. movwf ADCON1,.0 pines como I/O digitales 271. 272. clrf TRISD,.0 como salida 273. ;Los demas se quedan como entradas 274. movlw B'01000101' os PULL-UPs(bit 7), y hacemos que 275. movwf INTCON2,.0 INT2 se activen en flanco de bajada 276. ;(Bits 4 y 5), lo demas se queda como estaba 277. movlw B'01011000' prioridades(Bits 7 y 6), y habilitamos 278. movwf INTCON3,.0 interrupciones para INT1 e INT2 (bits 3 y 4) 279. 280. RCON,IPEN,.0 bsf

;Ajustamos

;Todos los

;Puerto D

;habilitam ;INT1 e

;Asignamos ;las

;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. INTCON,GIEH,.0 bsf ;Habilitam os las interrupciones de prioridad alta 287. INTCON,GIEL,.0 bsf ;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. 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90, DB 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. 13.

; ; ;

* Archivos Requeridos:

P18F4550.INC

* ;***************************************************************** ************* 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 ;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 14.

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. 66. 67. 68. 69. 70. 71. 72.

;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

;***************************************************************** ************* 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. registro BSR 100. 101. ; *** 102. 103. 104.

movff

BSR,BSR_TEMP

;Salva el

*** El codigo de la interrupcion de baja prioridad va aqui

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. 24. 25.

;

Archivos Requeridos:

P18F4550.INC

; *

26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56.

;***************************************************************** ************* ; Notas: El programa hace parpadear los pines del PIC a razon de 1 seg usando ;

el TMR0 para generar los retardos.

; El TMR0 sera usado en su modo de 16 bits y se configurara para que genere ;

con presicion un retardo de 100 ms.

; ;

Tiempo = (NumCuentasTMR0)(4/Fosc)(preescaler)

; ;

Para Fosc = 4 MHz; y el Tiempo de 100 ms , tenemos :

; ;

(4 MHz/4)(100 ms) = (NumCuentasTMR0)(preescaler)

;

(NumCuentasTMR0)(preescaler) = 100000

; Los valores posibles para el preescaler son: 2,4,16,32,64,128 y 256, entonces ; son posibles diferentes combinaciones para el (NumCuentasTMR0) y el preescaler, ; Sin embargo debe notarse que al ser el TMR0 un contador ascendente el valor

57.

; si no :

58. 59. 60. 61. 62. 63. 64. 65.

hallado anteriormente no es el que debe cargarse al TMR0

; ;

TMR0 = 65536 - (NumCuentasTMR0)

; ;

---------------------------------------------------------

-66. 67.

; cargar |

68. 69.

; TMR0

70. 71.

;

|Preescaler

| NumCuentasTMR0|Valor a cargar |Valor a

|

| TMR0(Hex)

|

| |

---------------------------------------------------------

-72. 73.

;

| |

2 0x3CB0

| |

50000

|

15

;

| |

4 0x9E58

| |

25000

|

40

;

| |

8 0xCF2C

| |

12500

|

53

;

| |

16 0xE796

| |

6250

|

59

;

| |

32 0xF3CB

| |

3125

|

62

;

| |

64 ------

| |

1562,5

|

--

;

| |

128 ------

| |

781,25

|

--

;

| |

256 ------

| |

390,625

|

--

536 74. 75. 536 76. 77. 036 78. 79. 286 80. 81. 411 82. 83. --84. 85. --86. 87. --88.

89.

;

---------------------------------------------------------

;

Ta

-90. 91. bla 1 92. 93.

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

94. 95. 96. 97.

LIST P=18F4550

;Directiva para definir el

procesador 98. 99.

#include ;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. ; 7. 8. ; 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.

Nombre:

TxRx_0.asm

Fecha:

02/09/2008

;

Version:

v0.90

;

;

Autor:

;

Empresa:

Sander

;

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

;

Archivos Requeridos:

P18F4550.INC

;

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

30. 31. 32.

; Notas: El programa muestra el uso del EUSART para realizar una comunicacion ; configuraremos el oscilador

33. 34.

;

asincrona con la PC, para este ejemplo

para que funcione a 48 MHz usando un cristal externo de 4

MHz. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52.

; ; Para configurar la modo de 16 bits y

57. 58.

;

para este caso tenemos que la velocidad esta dada por:

; ; Vel = Fosc/[4(n+1)] carga a SPBRGH:SPBRG ;

Donde n es el valor que se

n = [(Fosc/Vel)-1]/4

; ; -------------------------------------------------------------------------; para

|Velocidad |Valor n |Valor Hex para |Velocidad

; PBRGH:SPBRG

|(Baudios) |real

|Valor | %

| | Error |

| |SPBRGH:SPBRG

|S

; --------------------------------------------------------------------------

59. 60.

; -

61. 62.

se usara el

; el modo de alta de velocidad para el generador de baudios (BRG16=1; BRGH=1),

53. 54. 55. 56.

velocidad de transmision

|

110 --------

|

300

| ; 0x9C3F

|

| 109090,66 | ------| ------- | ----- | |

39999,75 300 | 0

| |

39999

|

63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88.

; 0x270F

|

1200

| 9999,75 1200 | 0

| |

9999

|

; 0xC34F

|

2400

| 4999,75 2400 | 0

| |

4999

|

; 0x09C3

|

4800

| 2499,75 4800 | 0

| |

2499

|

; 0x04E1

|

9600

| 1249,75 9600 | 0

| |

1249

|

; 0x0263

|

19600 | | 19607,84

611,99 | | 0,04 |

611

|

; 0x0137

|

38400 | | 38338,65

312,25 | | 0,16 |

312

|

; 0x00CF

|

57600 | | 57692,30

208,08 | | 0,16 |

207

|

; 0x0067

|

115200 | | 115384,61

103,91 | | 0,16 |

103

|

; 0x0033

|

230400 | | 230769,23

51,83 | | 0,16 |

51

|

; 0x0019

|

460800 | | 461538,46

25,79 | | 0,16 |

25

|

; 0x000C

|

921600 | | 923076,92

12,77 | | 0,16 |

12

|

|

|

|

|

; -------------------------------------------------------------------------; Tabla 1

89. 90. 91. 92.

; Lo que el programa hara es recibir caracteres e ir almacenandolos en BufferRx, ; 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 ;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 señal 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. constantes 193. 194.

VelHI

0x04 EQU sirven para definir la velocidad VelLO

EQU comunicacion, 9600 baudios 195. 196. 197. 198. CBLOCK 0x080 199. 200. WREG_TEMP salvar contexto 201. 202. STATUS_TEMP salvar contexto 203. 204. BSR_TEMP salvar contexto 205. 206. ENDC 207. 208. 209. 210. CBLOCK 0x000 0) max 96 bytes 211. 212. ContT0 TMR0 desborda 213. 214. ContRx recibidos 215. 216. ContTx transmitidos 217. 218. DatoRx recepcion 219. 220. DatoTemp auxiliar 221. 222. Banderas

0xE1

;Estas

;de la

;variable usada para

;variable usada para

;variable usada para

;Variables en la ACCESS RAM (Banco

;para contar las veces que

;para contar los bytes

;para contar los bytes

;variable temporal para la

;usado como variable

223. 224. tablas 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248.

TablaOffs

;Para movernos en las

ENDC

CBLOCK

0x100

BufferRx:.256

;Variables en el Banco 1 ;Buffer para la recepcion

ENDC

CBLOCK

0x200

BufferTx:.256

;Variables en el banco 2 ;Buffer para la transmision

ENDC

#DEFINE TimeOut ;=1 si el pasan 2 seg

Banderas,.0

#DEFINE RxOK ;=1 si se termino de recibir

Banderas,.1

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. EnvMsg call ; 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. o => salimos 369. 370.

bra

IntT0_X

;N

TimeOut bsf ;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 guardamos el caracter 405. 406. movwf DatoRx 407. 408. movlw 0x0D si se recibio enter 409. 410. xorwf DatoRx,W,.0 411. 412. btfsc STATUS,Z 0x0D?, se recibio 0x0D(enter)? 413. 414. bra IntRx_P0_1 i => vamos a terminar la recepcion 415. 416. movf DatoRx,W,.0 guardamos el caracter 417. 418. movwf POSTINC0 e incrementamos FSR 419. 420. movlw .20 421. 422. movwf ContT0 os el contador para el TimeOut 423. 424. incfsz ContRx,F,.0 llego a 256, (desbordo?) 425. 426. bra IntRx_X o => terminamos 427. 428. ;Si => tenemos 256 caracteres recibidos 429. 430. IntRx_P0_1 431. 432. RxOK bsf onemos en 1 RxOK 433. 434. bra

IntRx_X

;No =>

;Revisamos

;RCREG ==

;S

;No =>

;Guardamos

;Reiniciam

;ContRx

;N

;p

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. RCSTA,CREN bsf ;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 == 0? 471. 472. bra IntTxP0 o => vamos a cargar otro caracter 473. 474. bra IntTxP1 i => vamos a terminar la transmision 475. 476. IntTxP0 477. 478. movf POSTINC1,W el caracter a W e incrementamos FSR1 479. 480. movwf TXREG TXREG 481. 482. bra $+2 ;Esperamos a que TXIF se ponga en cero 483. 484. bra IntTx_X amos a salir de la IntTx 485. 486. IntTxP1 487. 488. TxOK bsf

;ContTx --

;N

;S

;Cargamos

;Cargamos

;v

;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. 505. 506.

SalirInt 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' os los 16 bits del generador de baudios 581. 582. movwf BAUDCON,.0 (bit 3) 583. 584. 585. 586. movlw VelHI los registros SPBRGH:SPBRG con los 587. 588. movwf SPBRGH,.0 de la tabla 1 para la velocidad deseada 589. 590. movlw VelLO 591. 592. movwf SPBRG,.0 593. 594. 595. 596. movlw B'10010000' os el puerto seria (Bit 7), modo 8 bits 597. 598. movwf RCSTA y habilitamos el receptor (Bit 4). 599. 600. 601. 602. ;*********************** Configuracion del TMR0 ************************* 603. 604. movlw B'10010110' modo 16 bits, cambia con las 605. 606. movwf T0CON,.0 ones, asignamos preescaler de 128 607. 608. 609.

;Habilitam

;BRG16 = 1

;Cargamos

;valores

;Habilitam

;(bit 6),

;TMR0 on,

;instrucci

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. PIE1,RCIE,.0 bsf ;Habilitam os la interrupcion de recepcion 629. 630. INTCON,TMR0IE,.0 bsf ;Habilitam os la interruocion de desborde del TMR0 631. 632. INTCON,PEIE,.0 bsf ;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. INTCON,GIE bsf ;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 termino la recepcion? 683. 684. bra MainP3 i => vamos a atender la recepcion 685. 686. bra MainP1 o => continuamos esperando 687. 688. 689. 690. MainP2 691. 692. RxOK bsf ara detener la recepcion 693. 694. movlw .4 695. 696. rcall EnvMsg el mensaje de timeout 697. 698. tstfsz ContRx,.0 0?; 699. 700. bra MainP2_P0 o => se recibieron caracteres y vamos a procesarlos 701. 702. bcf RxOK i => no se recibieron caracteres, 703. 704. bra MainP0 si que volvemos a empezar 705. 706. MainP2_P0 707. 708. movlw .2 709. 710. rcall EnvMsg que procesamos la trama 711. 712. rcall ProcTrama procesar la trama 713.

;No, Se

;S

;N

;P

;Enviamos

;ContRx ==

;N

;S

;a

;Indicamos

;vamos a

714. bcf TimeOut einiciamos las banderas 715. 716. bra MainTx amos a ennviar la nueva trama 717. 718. bra MainP0 olvemos a empezar 719. 720. 721. 722. MainP3 723. 724. tstfsz ContRx,.0 0?; 725. 726. bra MainP3_P0 o => se recibio un 0x0D (enter) 727. 728. movlw .5 i => se lleno el buffer, y enviamos 729. 730. rcall EnvMsg mensaje respectivo 731. 732. MainP3_P0 733. 734. movlw .2 735. 736. rcall EnvMsg que procesamos la trama 737. 738. rcall ProcTrama procesar la trama 739. 740. bra MainTx amos a Enviar la nueva trama 741. 742. bra MainP0 olvemos a empezar 743. 744. 745. 746. MainTx 747.

;r

;V

;V

;ContRx ==

;N

;S

;el

;Indicamos

;vamos a

;V

;V

748. movlw .3 749. 750. rcall EnvMsg el mensaje para transmitir 751. 752. TXSTA,TXEN bsf abilitamos es transmisor 753. 754. movf POSTINC1,W dato e incrementamos FSR1 755. 756. movwf TXREG el dato a TXREG 757. 758. PIE1,TXIE,.0 bsf

;Enviamos

;H

;leemos el

;copiamos

;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 = 'a' vamos a ver si es menor a z 819. 820. bra ProcTramaP0_2 es minuscula y vamos a guardar DatoTemp 821. 822. ProcTramaP0_0 823. 824. movlw 'z' 825. 826. cpfsgt DatoTemp > 'z' 827. 828. bra ProcTramaP0_1 es

;Si => no

;DatoTemp

;No => es

;Si => no

;le

;

; ;Guardamos

;ContTx

;ContTx ==

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 mas alta de EnvMsgP0 887. 888. movwf PCLATU,.0 actualizamos PCLATU 889. 890. movlw HIGH EnvMsgP0 alta de EnvMsgP0 891. 892. movwf PCLATH,.0 actualizamos PCLATh 893. 894. movlw LOW EnvMsgP0 baja de EnvMsgP0 895. 896. addwf TablaOffs,W,.0 calculo para el salto 897. 898. btfsc STATUS,C es mayor de 256? 899. 900. incf PCLATH,F,.0 incrementamos PCLATH 901. 902. movf TablaOffs,W,.0 saltar 903. 904. addwf PCL,F suma TablaOffs a PCL se realiza el salto 905. 906. EnvMsgP0 907. 908. bra EnvMsg_0 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.

;Tomamos la Parte

;y

;Tomamos la Parte

;y

;Tomamos la Parte

;y realizamos el

;el salto

;Si =>

;leemos el valor a

;cuando se

;V

920. bra EnvMsg_6 921. 922. EnvMsg_0 923. 924. movlw UPPER Msg_0 la parte mas alta del mensage que enviaremos 925. 926. movwf TBLPTRU,.0 actualizamos TBLPTRU 927. 928. movlw HIGH Msg_0 la parte alta del mensage que enviaremos 929. 930. movwf TBLPTRH,.0 actualizamos TBLPTRH 931. 932. movlw LOW Msg_0 la parte baja del mensage que enviaremos 933. 934. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR 935. 936. ;apuntado al inicio del mensaje 937. 938. rcall EnviarMsg a enviar el mensaje 939. 940. return 941. 942. 943. 944. EnvMsg_1 945. 946. movlw UPPER Msg_1 la parte mas alta del mensage que enviaremos 947. 948. movwf TBLPTRU,.0 actualizamos TBLPTRU 949. 950. movlw HIGH Msg_1 la parte alta del mensage que enviaremos 951. 952. movwf TBLPTRH,.0 actualizamos TBLPTRH

;tomamos

;y la

;tomamos

;y la

;tomamos

;y la

;llamamos

;tomamos

;y la

;tomamos

;y la

953. 954. movlw LOW Msg_1 la parte baja del mensage que enviaremos 955. 956. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR 957. 958. ;apuntado al inicio del mensaje 959. 960. rcall EnviarMsg a enviar el mensaje 961. 962. return 963. 964. EnvMsg_2 965. 966. movlw UPPER Msg_2 la parte mas alta del mensage que enviaremos 967. 968. movwf TBLPTRU,.0 actualizamos TBLPTRU 969. 970. movlw HIGH Msg_2 la parte alta del mensage que enviaremos 971. 972. movwf TBLPTRH,.0 actualizamos TBLPTRH 973. 974. movlw LOW Msg_2 la parte baja del mensage que enviaremos 975. 976. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR 977. 978. ;apuntado al inicio del mensaje 979. 980. rcall EnviarMsg a enviar el mensaje 981. 982. return 983. 984. EnvMsg_3 985.

;tomamos

;y la

;llamamos

;tomamos

;y la

;tomamos

;y la

;tomamos

;y la

;llamamos

986. movlw UPPER Msg_3 la parte mas alta del mensage que enviaremos 987. 988. movwf TBLPTRU,.0 actualizamos TBLPTRU 989. 990. movlw HIGH Msg_3 la parte alta del mensage que enviaremos 991. 992. movwf TBLPTRH,.0 actualizamos TBLPTRH 993. 994. movlw LOW Msg_3 la parte baja del mensage que enviaremos 995. 996. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR 997. 998. ;apuntado al inicio del mensaje 999. 1000. rcall EnviarMsg a enviar el mensaje 1001. 1002. return 1003. 1004. EnvMsg_4 1005. 1006. movlw UPPER Msg_4 la parte mas alta del mensage que enviaremos 1007. 1008. movwf TBLPTRU,.0 actualizamos TBLPTRU 1009. 1010. movlw HIGH Msg_4 la parte alta del mensage que enviaremos 1011. 1012. movwf TBLPTRH,.0 actualizamos TBLPTRH 1013. 1014. movlw LOW Msg_4 la parte baja del mensage que enviaremos 1015. 1016. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR

;tomamos

;y la

;tomamos

;y la

;tomamos

;y la

;llamamos

;tomamos

;y la

;tomamos

;y la

;tomamos

;y la

1017. 1018. ;apuntado al inicio del mensaje 1019. 1020. rcall EnviarMsg a enviar el mensaje 1021. 1022. return 1023. 1024. EnvMsg_5 1025. 1026. movlw UPPER Msg_5 la parte mas alta del mensage que enviaremos 1027. 1028. movwf TBLPTRU,.0 actualizamos TBLPTRU 1029. 1030. movlw HIGH Msg_5 la parte alta del mensage que enviaremos 1031. 1032. movwf TBLPTRH,.0 actualizamos TBLPTRH 1033. 1034. movlw LOW Msg_5 la parte baja del mensage que enviaremos 1035. 1036. movwf TBLPTRL,.0 actualizamos TBLPTRL, Aqui tenemos a TBLPTR 1037. 1038. ;apuntado al inicio del mensaje 1039. 1040. rcall EnviarMsg a enviar el mensaje 1041. 1042. return 1043. 1044. EnvMsg_6 1045. 1046. movlw UPPER Msg_6 la parte mas alta del mensage que enviaremos 1047. 1048. movwf TBLPTRU,.0 actualizamos TBLPTRU 1049.

;llamamos

;tomamos

;y la

;tomamos

;y la

;tomamos

;y la

;llamamos

;tomamos

;y la

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 leido es 0x000? 1085. 1086. bra EnviarMsgP0 o => vamos a enviar el caracter 1087. 1088. return i => retornamos 1089. 1090. EnviarMsgP0 1091. 1092. TXSTA,TXEN bsf abilitamos el transmisor 1093. 1094. movff TABLAT,TXREG caracter a TXREG 1095. 1096. bra $+2

;El valor

;N

;S

;H

;Movemos el

;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. '\n','\r' DB 1121. 1122. 'P','r','o','g','r','a','m','a',' DB ','e','j','e','m','p','l','o' 1123. 1124. ' ','p','a','r','a',' ','e','l',' ','u','s','o',' DB ','d','e','l' 1125. 1126. ' ','E','U','S','A','R','T','\n','\r',0x00 DB 1127. 1128. Msg_1 1129. 1130. '\n','\r' DB 1131. 1132. 'I','n','t','r','o','d','u','z','c','a',' DB ','l','a',' ','c','a' 1133. 1134. 'd','e','n','a','.','.','.','.','\n','\r',0x00 DB 1135. 1136. Msg_2 1137. 1138. '\n','\r' DB 1139. 1140. 'P','r','o','c','e','s','a','n','d','o','.','.','. DB ','\n','\r',0x00 1141. 1142. Msg_3 1143. 1144. 'L','a',' ','n','u','e','v','a',' DB ','c','a','d','e','n','a',' ' 1145. 1146. 'e','s',':','\n','\r',0x00 DB 1147. 1148. Msg_4 1149. 1150. '\n','\r' DB 1151. 1152. 'T','i','m','e',' ','o','u','t','\n','\r',0x00 DB 1153.

1154. Msg_5 1155. 1156. '\n','\r' DB 1157. 1158. 'B','u','f','f','e','r',' ','d','e',' DB ','r','e','c','e','p','c' 1159. 1160. 'i','o','n',' ','l','l','e','n','o','\n','\r',0x00 DB 1161. 1162. 1163. 1164. Msg_6 1165. 1166. '\n','\r' DB 1167. 1168. 'E','r','r','o','r','\n','\r',0x00 DB 1169. 1170. 1171. 1172. END ;Directiva fin del programa