Entren Adores

283
Entrenadores de Microcontroladores PIC Profesor: Pedro Alonso Sanz Instituto: I.E.S. Joan Miró Localidad: San Sebastián de los Reyes

Transcript of Entren Adores

Page 1: Entren Adores

Entrenadores de Microcontroladores PIC

Profesor: Pedro Alonso SanzInstituto: I.E.S. Joan MiróLocalidad: San Sebastián de los Reyes

Page 2: Entren Adores

Índice Página

1.- Entrenador Básico 0 ................................................................................................... 4

1.1.- Ejemplo1.asm Leer el Puerto C y transferirlo al Puerto B ....................... 5 1.2.- Ejemplo2.asm Leer el Puerto C complementarlo y

transferirlo al Puerto B ..................................................... 7

1.3.- Ejemplo3.asm Parpadeo de un Led ........................................................ 9 1.4.- Ejemplo3A.asm Parpadeo de un Led ,utilizando una librería

de Tiempo RETAR_1S.INC............................................... 12 1.5.- Ejemplo3B.asm Parpadeo de un Led utilizando una librería llamada RETARDOS.INC del libro de Desarrollo de Proyectos. .... 14

1.6.- Ejemplo4.asm Simular las luces del Coche Fantástico. ........................... 15

1.7.- Ejemplo5.asm Simular las luces del Coche Fantásticocontrolado por PCO. .......................................................... 18

1.8.- Nom_disp.asm Poner el Nombre en el Display. ......................................... 21

1.9.- Sum_Nibl.asm Sumar los nibles del Puerto C y llevarlos al Puerto B. ...... 24

1.10.- Dir_ind.asm Direccionamiento Indirecto. ............................................... 26

1.11.- Pagina1.asm Trabajar con la Pagina 1 de memoria de programa. ......... 28

1.12.- RETARDO_1S.INC Librería Casera de Retardo 1 Segundo. ....... .................... 30 1.13.- RETARDOS.INC Librería de Retardos del libro de Desarrollo

de Proyectos. ..................................................................... 31

2.- Entrenador Básico 1 .................................................................................................... 35

2.1.- Ejemplo6.asm Encender displays dependiendo de PC0. ........................ 36

2.2.- Ejemplo7.asm Contar pulsos procedentes de PC0 y llevarlos al Display de Unidades. ................................................... 38

2.3.- Ejemplo8.asm Contar pulsos procedentes de PC0 y llevarlos al Display de Unidades y Decenas. .................................. 41

3.- Entrenador Básico 2 ..................................................................................................... 46

3.1.- Ejemplo9.asm Contar pulsos procedentes de PC0 y llevarlos al Display de Unidades y Decenas. ................................. 47

4 .- Entrenador Básico 2A ................................................................................................ 52

4.1.- PWM_1.asm. Control de un Servomotor de Posicióncon PWM a través del Puerto B ....................................... 53

4.2.- PWM_CAD.asm Control de un Servomotor de Posición

con PWM a través de un Potenciómetro. ........................ 55

5.- Entrenador Básico 3. ............................................................................................... 58

5.1.- Ejempl10.asm Interrupción Externa. ..................................................... 59

2

Page 3: Entren Adores

Índice Página 5.2.- Ejemp_11.asm Conversión Analógico/Digital. ....................................... 64 5.3.- Ejemp_12.asm Contar pulsos del exterior utilizando un

Temporizador TIMER 0. ................................................ 66

5.4.- Ejemp_13.asm Transferir una Tabla de datos de memoria EPROM a RAM y Puerto B utilizando como subrutina de tiempo el TIMER 0 y direccionamiento indirecto. ............................................ 68

5.5.- Ejemp_14.asm Detectar el numero mayor de una Tabla. ....................... 71

6.- Entrenador Básico 4 .................................................................................................. 75

6.1.- T_S_A.asm Transmisor SERIE asíncrona. ....................................... 76

6.2.- R_S_A.asm Receptor SERIE asíncrona. ........................................... 79 6.3.- T1_S_RF.asm Transmisor SERIE asíncrona utilizando

Librería de Transmisión T_S_RF_INC. ......................... 82

6.4.- RE1_S_RF.asm Receptor SERIE asíncrona utilizando Librería de Recepción R_S_RF.INC. ............................. 84

6.5.- T_S_RF.INC Librería Transmisor SERIE vía Radiofrecuencia para una Tarjeta Emisora SAW para Datos 433,92 MHz( CEBEK C-0503 )Llave de entrada fija.Cargar en W el dato a transmitir..................................... 87

6.6.- R_S_RF.INC Librería Receptor SERIE vía Radiofrecuencia para una Tarjeta Emisora SAW para Datos 433,92 MHz( CEBEK C-0504 ) La Llave de entrada fija.Los datos se validan si llegan dos datosidénticos consecutivos.El dato recibido se carga en el registroDATO_SERIE_VALIDO. ............................................... 90

6.7.- T_M_S_RF.INC Librería de Transmisor SERIE vía Radiofrecuencia para una Tarjeta Emisora SAW para Datos 433,92 MHz. ( CEBEK C-0503 ) Cargar la llave de entrada en el registroLLAVE_ENTRADACargar en W el dato a transmitir. .................................... 94

6.8.- R_M_S_RF.INC Librería Receptor SERIE víaRadiofrecuencia para una Tarjeta Emisora ;SAW para Datos 433,92 MHz.( CEBEK C-0504 )La Llave de entrada aleatoria.Los datos se validan si llegan dos datosidénticos consecutivos.El dato recibido se carga en el registroDATO_SERIE_VALIDO. ................................................. 98

3

Page 4: Entren Adores

Índice Página

7.- Entrenador Básico 5 .................................................................................................. 102

7.1.- Tecla0.asm Manejo del Teclado utilizando la técnica de polling. ...... 103 7.2.- Tecl_01.asm Manejo del Teclado utilizando la técnica de

interrupción del programa principal. ............................... 105

7.2.- Tecl_02.asm Manejo del Teclado utilizando la técnica de interrupción del programa principal y llevando los datos al display de 7 segmentos. .............................. 108

7.4.- HEX_7SEG.INC Librería que transforma un código hexadecimal en 7 segmentos. .............................................................. 110

7.5.-TECLADO.INC Librería de control del teclado. ........................................ 111

8.- Entrenador Básico 6 .................................................................................................. 115

8.1.- LCD_01.asm Visualización de un mensaje en el LCDcarácter a carácter. ......................................................... 116

8.2.- LCD_02.asm Visualización de un mensaje en el LCD carácter a carácter con retardo de 500 mS, borrar pantalla y comenzar de nuevo. .............................. 117

8.3.- LCD_03.asm Programa ejemplo para comprender lautilización de las subrutinas LCD_ByteCompleto,LCD_Byte, LCD_Nibble y LCD_DosEspaciosBlancos. ... 118

8.4.- LCD_04.asm Visualización en el LCD un contador descendente. ........ 120

8.5.- LCD_05.asm Visualizar en la pantalla del LCD los pulsosgenerados del exterior. .................................................... 122

8.6.- LCD_06.asm Visualizar en la pantalla del LCD los pulsosgenerados del exterior hasta un número máximo,se resetea y comienza de nuevo la cuenta. ..................... 123

8.7.- LCD_07.asm Mientras se mantenga presionado el pulsador conectado al pin RA4, incrementa un contadorque se visualiza en la pantalla del LCD. .......................... 125

8.8.- LCD_08.asm Mientras se mantenga presionado el pulsadorconectado al pin RA4, incrementa un contadorque se visualiza en la pantalla del LCD en formatodecimal ,hexadecimal y binario. ....................................... 127

8.9.- Mens_01.asm Visualización de un mensaje fijo utilizandola librería LCD_4BIT.INC. ................................................ 129

8.10.- Mens_02.asm Visualización de un mensaje fijo utilizandola librería LCD_MENS.INC. ............................................. 131

8.11.- Mens_03.asm Visualización de varios mensajes fijo utilizandola librería LCD_MENS.INC. ............................................. 132

8.12.- Mens_03B.asm Visualización de varios mensajes fijo utilizandola librería LCD_MENS.INC cuando se visualiza elultimo mensaje el proceso se repite. ............................... 133

4

Page 5: Entren Adores

Índice Página

8.13.- Mens_04.asm Visualización de mensajes parpadeantes en dos líneas del LCD. .................................................... 135

8.14.- Mens_05.asm Visualización de un mensaje fijo y parpadeantes. .......... 137

8.15.- Mens_06.asm Visualización de mensajes en función de un pulsador. ... 138

8.16.- Mens_07.asm El modulo LCD visualiza un mensaje largo(mas de 16 caracteres) que se desplaza. ....................... 141

8.17.- Mens_08.asm Juego de la Quiniela. ...................................................... 142

8.18.- Mens_09.asm La pantalla del LCD visualiza un mensajeen función de un pulsador. .............................................. 144

8.19.- BIN_BCD.INC Librería que convierte un número Binario en BCD. El resultado se guarda en tres posiciones de memorias llamadas: BCD_Centenas, BCD_Decenasy BCD_Unidades. ............................................................ 145

8.20.- LCD_4BIT.INC Librería que permiten realizar las tareas básicasde control de un módulo LCD de 2 líneas por 16caracteres, compatible con el modelo LM016L. .............. 146

8.21.- LCD_MENS.INC Librería de subrutinas para el manejo de mensajesa visualizar en un visualizador LCD. ............................... 151

9.- Entrenador Básico 7 .................................................................................................. 154

9.1.- Tecla_01.asm La pantalla del LCD visualiza el orden de la teclapulsada utilizando la técnica de polling. ......................... 155

9.2.- Tecla_02.asm La pantalla del LCD visualiza el valor hexadecimalde la tecla pulsada utilizando la técnica de polling. ........ 156

9.3.- Tecl_03.asm La pantalla del LCD visualiza el valor hexadecimalde la tecla pulsada utilizando técnicas de interrupción. .. 157

9.4.- Tecla_04.asm La pantalla del LCD visualiza caracteres españolesen función de la tecla pulsada. ........................................ 159

9.5.- Tecla_05.asm La pantalla del LCD aparece un mensaje en movimiento y fijo en la primera línea y en lasegunda línea visualiza la tecla pulsada. ………………… 161

9.6.- Tecla_06.asm La pantalla del LCD aparece la tecla pulsada primero la línea 1 y después en la línea 2 repitiéndose el proceso. ................................................... 163

9.7.- Tecla_07.asm La pantalla del LCD aparece la tecla pulsada si estaes decimal y si se pulsa otra tecla borra pantalla. ........... 165

9.8.- Tecla_08.asm Suma el valor de tres teclas y aparece en el LCD en decimal y hexadecimal. .............................................. 166

9.8.- Tecla_09.asm Cerradura Electrónica. .................................................... 169

5

Page 6: Entren Adores

Índice Página

10.- Entrenador Básico 7-1 ............................................................................................ 173

10.1.- Tecla_10.asm Cerradura Electrónica activando un motor PAP. ........... 174

11.- Entrenador Básico 8. .............................................................................................. 179 11.1.- I2C1.asm Leer un dato del circuito integrado expansor de

bus PCF8476 y transmitirlo a través del bus I2C al microprocesador. Transferir el dato delmicroprocesador a otro C.I. PCF8476. ........................... 180

11.2.- I2C2.asm Leer un dato del circuito integrado expansor debus PCF8476 y transmitirlo a través del bus I2C al microprocesador. Transferir el dato delmicroprocesador a otro C.I. PCF8476 interrumpiendoun programa principal. ..................................................... 181

11.3.- I2C3.asm Realizar una conversión Analógica / Digital ytransmitirla a los expansores de bus PCF8476. .............. 183

12.- Entrenador Básico 8-1. .............................................................................................. 186

12.1.- I2C4.asm Leer datos cada vez que activamos un Pulsador,de circuitos integrados expansores de bus PCF8476 y transmitirlo a través del bus I2C al microprocesador.Transferir los dato del microprocesador a otros C.I. PCF8476. .......................................................... 187

12.2.- I2C5.asm Leer datos de circuitos integrados expansores debus PCF8476 y transmitirlo a través del bus I2Cal microprocesador. Transferir los datos del microprocesador a otrosC.I. PCF8476, interrumpiendo un programa principal. ..... 189

13.- Entrenador Básico 9. .................................................................................................. 192

13.1.- I2C6.asm Leer constantemente la entrada analógica ANI0 del Esclavo 1 (PCF8591) y visualiza la tensión en la pantalla del modulo LCD. ......................................... 193

13.2.- I2C7.asm En la salida analógica del Esclavo 2 (PCF8591) que trabaja como DAC se obtiene una tensiónseleccionada por un pulsador conectado a la líneaRB6 del PIC. La tensión varia entre 0,50 y 2,50 V en saltos de 0,25 V y se visualiza en el modulo LCD. ..... 196

13.3.- I2C8.asm Leer constantemente la entrada analógica ANI0del Esclavo 1(PCF8591), llevarla al Esclavo 2 (PCF8591) y visualiza la tensión en la pantalladel modulo LCD. ................................................................ 199

13.4.- I2C.INC Librería de Transmisión y recepción de datos con I2C. .... 203

13.5.- I2C1.INC Librería de Transmisión y recepción de datos con I2C1. En la subrutina (Transmitir_dato_I2C) el Esclavo noconfirma la transmisión. ............................................. 205

6

Page 7: Entren Adores

14.- Entrenador Básico 10. ................................................................................................ 208

14.1.- RTS232_1.asm En la pantalla del modulo LCD se visualizaran los caracteres que se reciban a través del puertoserie del ordenador. Lo que se escriba por el tecladodel ordenador aparecerá en la pantalla del sistemacon microcontrolador. ....................................................... 209

14.2.- RTS232_2.asm En el modulo LCD se visualizan los caracteres que seescriban en el teclado del ordenador y se transmitena través de su puerto serie. Estos datos volverán a ser enviados por el microcontrolador al ordenador, para que se visualicen en su monitor. ....................................... 210

14.3.- RTS232_3.asm Lo que se escriba por el teclado se visualiza en el LCD y en el monitor del ordenador, pero en este ultimo se visualiza un solo carácter por línea. ................... 211

14.4.- RTS232_4.asm En el modulo LCD se visualizan los caracteres que se escriben en el teclado del ordenador. Si pulsa la tecla Enter se comienza a escribir en la segunda línea de la pantalla del modulo LCD. .................................................. 213

14.5.- RTS232_5.asm Este programa envía un mensaje grabado en lamemoria de programa del microcontrolador al ordenador. Es decir, en el monitor del ordenadoraparecerá el mensaje grabado en el PIC. ......................... 214

14.6.- RTS232_6.asm Este programa envía varios mensajes grabados en lamemoria de programa del microcontrolador al ordenador.Cada mensaje permanecerá en pantalla durante unos segundos hasta que sea sustituido por el siguiente. ......... 216

14.7.- RTS232_7.asm En el monitor del ordenador se visualizan mensajesgrabados en la memoria de programa del microcontrolador. El cambio de mensaje se ejecutacada vez que se pulse la tecla Enter. ................................ 218

14.8.- RTS232_8.asm Programa que visualiza en el modulo LCD el códigoASCII en formato hexadecimal de la tecla pulsaday también en el monitor del ordenador en formatodecimal. ............................................................................... 220

14.9.- RTS232_9.asm SISTEMA DE MONITORIZACION: Se trata de leer el estado de las entradas conectadas a las líneas <RB7:RB4> del Puerto B y se envia por el puerto RS232 a un terminal para monitorizar el estado de los mismos.El estado de las entradas se mostrara cada 1 segundos. ... 221

14.10.- RTS23_10.asm SISTEMA DE MONITORIZACION: Se trata de leer el estado de las entradas conectadas a las líneas <RB7:RB4> del Puerto B y se envia por el puerto RS232a un terminal para monitorizar el estado de los mismos.Se utilizara las interrupciones por cambio de nivel enuna línea del Puerto B, por ello, las entradas deben conectarse a la parte alta del Puerto B. .............................. 224

14.11.- RTS23_11.asm SISTEMA DE GOBIERNO DESDE ORDENADOR:Desde el teclado de un ordenador se deseacomandar el movimiento de una estructura móvil. .............. 227

7

Page 8: Entren Adores

14.12.- RS232_RT.INC Librería de transmisión-recepción serie asíncronasegún normas RS-232. ......................................................... 230

14.13.- RS232MEN.INC Librería de transmisión de mensajes desde elmicrocontrolador hacia el ordenador a través del puertoserie RS232. ......................................................................... 232

15.- Entrenador Básico 11. ................................................................................................... 234

15.1.- Int_T_01.asm Onda cuadrada de 10 kHz aproximadamente, mediante la interrupción por desbordamientodel Timer 0. ........................................................................... 235

15.2.- Int_T_02.asm Onda cuadrada de 10 kHz exactos, mediante lainterrupción por desbordamiento del Timer 0. ...................... 236

15.3.- Int_T_03.asm Led ON/OFF 500 ms utilizando la interrupciónpor desbordamiento del Timer 0. .......................................... 238

15.4.- Int_T_04.asm Led ON (800 ms) Led OFF (500 ms), utilizando la interrupción por desbordamiento del Timer 0. ...................... 240

15.5.- Int_T_05.asm Sistema multitarea ( Mostrar mensajes en elLCD y LED ON/OFF (500 ms). ……………………………….. 242

15.6.- Int_T_06.asm Mostrar mensajes en el LCD fijo en la primera línea e intermitente en lasegunda línea utilizando

la interrupción del Timer 0. ................................................... 244

15.7.- Int_C_01.asm Generar una señal cuadrada por PB2, de frecuenciavariable en función de PB7. El modulo LCD visualizadicha frecuencia. .................................................................. 246

15.8.- Int_C_02.asm Generar una señal cuadrada por PB2, de frecuencia variable desde 300Hz hasta 4000Hz. .................................. 250

15.9.- Int_C_03.asm Encender y apagar una sirena en función de RB7 y RB6, mostrar en el modulo LCD como esta la sirena. ......... 252

15.10.- Int_C_04.asm Control del Ciclo de Trabajo de un señal cuadrada. ............ 256

15.11.- Int_Re_01.asm Reloj digital en tiempo real sin puesta en hora utilizando la interrupción del Timer 0. .................................. 260

15.12.- Int_Re_04.asm Reloj digital en tiempo real con puesta en hora. .................. 264

15.13.- Int_Temp.asm Temporizador digital de precisión. ....................................... 270

8

Page 9: Entren Adores
Page 10: Entren Adores

1.- Entrenador Básico 0

4

Page 11: Entren Adores

1.1.- Ejemplo1.asm (Entrenador Básico 0)

Diagrama de Flujo

Leer el Puerto C

y transferirlo al

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; Registros

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de ConfiguraciónORG 0x05 ; Inicio de Programa

COMIENZO RP0 1 ; Ir al Banco 1 TRISC 11111111 B ; Poner el Puerto C como entrada de datos. TRISB 00000000 B ; Poner el Puerto B como salida de datos. RP0 0 ; Ir al Banco 0

; Principal

PORTB PORTC

5

Page 12: Entren Adores

title " Leer el Puerto C y transferirlo al Puerto B "

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;************* Asignación de nombres de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ***********************************************************************

;**************************** Registros ************************************************************************

;**************************** Sección Código de Reset *******************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración ******************************************************

ORG 0x05 ; Inicio de Programa ;(Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP0MOVLW B'11111111' ; Poner el Puerto C como entrada de datos.MOVWF TRISCCLRF TRISB ; Poner el Puerto B como salida de datos.BCF STATUS,RP0

;**************************** Principal **************************************************************************

SEG1 MOVF PORTC,W ; Leer el Puerto C y llevarlo al Acumulador.MOVWF PORTB ; Transferir el dato del Acumulador al Puerto BGOTO SEG1END

6

Page 13: Entren Adores

1.2.- Ejemplo2.asm (Entrenador Básico 0)

Diagrama de Flujo

Leer el Puerto C complementarlo y

transferirlo al Puerto B

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; Registros

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de Configuración

ORG 0x05 ; Inicio de Programa

COMIENZO RP0 1 ; Ir al Banco 1 TRISC 11111111 B ; Poner el Puerto C como entrada de datos. TRISB 00000000 B ; Poner el Puerto B como salida de datos. RP0 0 ; Ir al Banco 0

; Principal

PORTB PORTC

7

Page 14: Entren Adores

title " Leer el Puerto C, complementarlo y transferirlo al Puerto B "

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC *********************************************************************

list p=16f877, f=inhx32

;**************************** Asignación de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ***********************************************************************

;**************************** Registros ************************************************************************

;**************************** Sección Código de Reset *******************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *******************************************************

ORG 0x05 ; Inicio de Programa; (Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP0MOVLW B'11111111' ; Poner el Puerto C como entrada de datos.MOVWF TRISCCLRF TRISB ; Poner el Puerto B como salida de datos.BCF STATUS,RP0

;**************************** Inicio *******************************************************************************

INICIO COMF PORTC,W ; Complementar el Puerto C y llevarlo al Acumulador.

MOVWF PORTB ; Transferir el dato del Acumulador al Puerto BGOTO INICIOEND

8

Page 15: Entren Adores

1.3.- Ejemplo3.asm (Entrenador Básico 0)

Diagrama de Flujo

Parpadeo de un Led

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

DATO1 EQU 0X10DATO2 EQU 0X64DATO3 EQU 0X64

; Registros

REG1 EQU 0X22REG2 EQU 0X23REG3 EQU 0X24

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de Configuración

ORG 0x05 ; Inicio de Programa

COMIENZO RP0 1 ; Ir al Banco 1 TRISB 00000000 B ; Poner el Puerto B como salida de datos. RP0 0 ; Ir al Banco 0 PORTB 00000000 B ; Limpiar el Puerto B

; Principal

PB0 1 ; Encender el Led de PB0

SEGUNDO

PB0 0 ; Apagar el Led de PB0

SEGUNDO

Subrutina de Tiempo

REG3 # DATO3

REG2 # DATO2

REG1 # DATO1

REG1 REG1 - 1

¿ REG1 = 0 ?

REG2 REG2 - 1

¿ REG2 = 0 ?

¿ REG3 = 0 ?

RETUR

SI

SI

SI

NO

NO

NO

REG3 REG3 - 1

9

Page 16: Entren Adores

title " Parpadeo de un Led "

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC *********************************************************************

list p=16f877, f=inhx32

;**************************** Asignación de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ***********************************************************************

DATO1 EQU 0X10

DATO2 EQU 0X64

DATO3 EQU 0X64

;**************************** Registros ************************************************************************

REG1 EQU 0X22

REG2 EQU 0X23

REG3 EQU 0X24

;**************************** Sección Código de Reset *******************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *******************************************************

ORG 0x05 ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP1BSF STATUS,RP0CLRF TRISB ; Configuramos el Puerto B como salidasBCF STATUS,RP0CLRF PORTB

;**************************** Inicio ****************************************************************************

SEGUIR BSF PORTB,0CALL SEGUNDO

10

Page 17: Entren Adores

BCF PORTB,0CALL SEGUNDOGOTO SEGUIR

;**************************** Subrutina de perdida de tiempo de 1 Segundo ******************************

SEGUNDO MOVLW DATO3MOVWF REG3

SEG7 MOVLW DATO2MOVWF REG2

SEG6 MOVLW DATO1MOVWF REG1

SEG5 DECFSZ REG1,FGOTO SEG5DECFSZ REG2,FGOTO SEG6DECFSZ REG3,FGOTO SEG7RETURN

END

11

Page 18: Entren Adores

1.4.- Ejemplo3A.asm (Entrenador Básico 0)

Diagrama de Flujo

Parpadeo de un LedUtilizando una librería de

Tiempo

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; Registros

CBLOCK 0X20

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de Configuración

ORG 0x05 ; Inicio de Programa

COMIENZO RP0 1 ; Ir al Banco 1 TRISB 00000000 B ; Poner el Puerto B como salida de datos. RP0 0 ; Ir al Banco 0 PORTB 00000000 B ; Limpiar el Puerto B

; Principal

PB0 1 ; Encender el Led de PB0

SEGUNDO

PB0 0 ; Apagar el Led de PB0

SEGUNDO

Librería de TiempoRETART_1S.INC

SEGUNDO REG3 # DATO3

REG2 # DATO2

REG1 # DATO1

REG1 REG1 - 1

¿ REG1 = 0 ?

REG2 REG2 - 1

¿ REG2 = 0 ?

¿ REG3 = 0 ?

RETUR

SI

SI

SI

NO

NO

NO

; Igualdades

DATO1 EQU 0X10DATO2 EQU 0X64DATO3 EQU 0X64

; Registros

CBOCK

REG1 REG2 REG3

ENDC

REG3 REG3 - 1

12

Page 19: Entren Adores

title " Parpadeo de un Led utilizando una librería llamada RETAR_1S.INC "

;Programa para PIC 16F877a.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************************** Asignación de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ************************************************************************

;*************************** Registros **************************************************************************

CBLOCK 0X20ENDC

;**************************** Sección Código de Reset *******************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *******************************************************

ORG 0x05 ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP0CLRF TRISB ; Configuramos el Puerto B como salidasBCF STATUS,RP0CLRF PORTB

;**************************** Inicio *******************************************************************************

SEGUIR BSF PORTB,0CALL SEGUNDOBCF PORTB,0CALL SEGUNDOGOTO SEGUIR

;********************************** Librerías *********************************************************************

INCLUDE <RETAR_1S.INC>

END

1.5.- Ejemplo3B.asm (Entrenador Básico 0)

13

Page 20: Entren Adores

title " Parpadeo de un Led utilizando una librería llamada RETARDOS.INC del libro de Desarrollo de Proyectos"

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************************** Asignación de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ************************************************************************

;*************************** Comienzo de registros ************************************************************

CBLOCK 0X20ENDC

;**************************** Sección Código de Reset ********************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración ********************************************************

ORG 0x05 ; Inicio de Programa (Una posición detrás del vector de Interrupción

COMIENZO BSF STATUS,RP0CLRF TRISB ; Configuramos el Puerto B como salidasBCF STATUS,RP0CLRF PORTB

;**************************** Inicio *******************************************************************************

SEGUIR BSF PORTB,0CALL Retardo_1sBCF PORTB,0CALL Retardo_1sGOTO SEGUIR

;**************************** Librerías ***************************************************************************

INCLUDE <RETARDOS.INC>END

1.6.- Ejemplo4.asm (Entrenador Básico 0)

14

Page 21: Entren Adores

Diagrama de Flujo

title " Simular las luces del Coche Fantástico "

Simular las luces del Coche Fantástico

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; Registros

CBLOCK 0X20

CONTADORDATO

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de Configuración

ORG 0x05 ; Inicio de Programa

COMIENZO CONTADOR 00000000 B ; Resetear CONTADOR RP0 1 ; Ir al Banco 1 TRISB 00000000 B ; Poner el Puerto B como

salida de datos. RP0 0 ; Ir al Banco 0

DATO 10000000 B ; Encendemos el Led PB7 y guardamos el código en un Registro.

1

1

PORTB DATO

CONTADOR CONTADOR + 1

Retardo_100ms

¿ CONTADOR = 8 ?

CY 0

CY 7 DATO 0

CY 7 DATO 0

CONTADOR 00000000 B

CY 0

PORTB DATO

Retardo_100ms

CONTADOR CONTADOR + 1

¿ CONTADOR = 7 ?

CONTADOR 00000001 B

SI

NO

SI

NO

15

Page 22: Entren Adores

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************************** Asignación de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ***********************************************************************

;*************************** Registros **************************************************************************

CBLOCK 0X20

CONTADORDATO

ENDC

;**************************** Sección Código de Reset ********************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración ********************************************************

ORG 0x05 ; Inicio de Programa (Una posición detrás del vector de Interrupción

COMIENZO CLRF CONTADORBCF STATUS,RP1 ; Selecciono la pagina 1 de la memoriaBSF STATUS,RP0 MOVLW B'00000000' ; Configuro el PB salidas .MOVWF TRISBBCF STATUS,RP0 ; Selecciono la pagina 0 de la memoria

;*************************** Principal *************************************************************************

SEGUIR MOVLW B'10000000' ; Encendemos el Led PB7 MOVWF DATO ; Guardamos el código en un Registro.

16

Page 23: Entren Adores

SEG1 MOVF DATO,W ;Transferimos la información del registro DATO MOVWF PORTB ; al Puerto B.

INCF CONTADOR ; Incrementamos CONTADOR.

CALL Retardo_100ms ; Llamamos a la Subrutina de Retardo TIEMPO.

MOVF CONTADOR,W ; Preguntamos si CONTADOR = 8XORLW 0X08BTFSC STATUS,ZGOTO SEG2

SEG4 BCF STATUS,C ; Si CONTADOR <> 8 ponemos el Cy=0 y rotamos haciaRRF DATO,F ; la Derecha el registro DATO.GOTO SEG1 ; Seguimos hacia la Derecha.

SEG2 CLRF CONTADOR ; Si CONTADOR = 8 ponemos el CONTADOR=0, Cy=0 ySEG3 BCF STATUS,C ; rotamos hacia la Izquierda el registro DATO.

RLF DATO,F

MOVF DATO,W ; Transferimos la información del registro DATO MOVWF PORTB ; al Puerto B.

CALL Retardo_100ms ; Llamamos a la Subrutina de Retardo TIEMPO.

INCF CONTADOR ; Preguntamos si CONTADOR = 7MOVF CONTADOR,WXORLW 0X07BTFSS STATUS,ZGOTO SEG3 ; Seguimos hacia la Izquierda.

MOVLW 0X01 ; Ponemos el CONTADOR = 1 y volvemos hacia la izquierda.MOVWF CONTADORGOTO SEG4

;*************************** Subrutinas **********************************************************************

INCLUDE <RETARDOS.INC>

END

1.7.- Ejemplo5.asm (Entrenador Básico 0)

17

Page 24: Entren Adores

Diagrama de Flujo

title " Simular el Coche Fantástico, controlado por PC0"

NO

Simular las luces del Coche Fantástico

controlado por PCO

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; Registros

CBLOCK 0X20

CONTADORDATO

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de Configuración

ORG 0x05 ; Inicio de Programa

COMIENZO CONTADOR 00000000 B ; Resetear CONTADOR RP0 1 ; Ir al Banco 1 TRISB 00000000 B ; Poner el Puerto B como

salida de datos. RP0 0 ; Ir al Banco 0 TRIRC (0) 1 ; Poner PC0 como salida de

datos

DATO 10000000 B ; Encendemos el Led PB7 y guardamos el código en un Registro.

1

¿ PCO = 1 ?

SI

NO

SI

1

PORTB DATO

CONTADOR CONTADOR + 1

Retardo_100ms

¿ CONTADOR = 8 ?

CY 0

CY 7 DATO 0

CY 7 DATO 0

CONTADOR 00000000 B

CY 0

PORTB DATO

Retardo_100ms

CONTADOR CONTADOR + 1

¿ CONTADOR = 7 ?

CONTADOR 00000001 B

SI

NO

¿ PC0 = 1 ?

SI

NO

¿ PC0 = 1 ?

SI

NO

18

Page 25: Entren Adores

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************************** Asignación de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ***********************************************************************

;**************************** Registros ************************************************************************

CBLOCK 0X20

CONTADORDATO

ENDC

;**************************** Sección Código de Reset *******************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *******************************************************

ORG 0x05 ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO CLRF CONTADORBCF STATUS,RP1 ; Selecciono la pagina 1 de la memoriaBSF STATUS,RP0 MOVLW B'00000000' ; Configuro el PB salidas .MOVWF TRISBBSF TRISC,0BCF STATUS,RP0 ; Selecciono la pagina 0 de la memoria

;*************************** Principal ***************************************************************************

SEGUIR BTFSS PORTC,0GOTO SEGUIRMOVLW B'10000000' ; Encendemos el Led PB7 MOVWF DATO ; Guardamos el código en un Registro.

19

Page 26: Entren Adores

SEG1 MOVF DATO,W ; Transferimos la información del registro DATO MOVWF PORTB ; al Puerto B.

PARAR1 BTFSS PORTC,0GOTO PARAR1INCF CONTADOR ; Incrementamos CONTADOR.

CALL Retardo_100ms ; Llamamos a la Subrutina de Retardo TIEMPO.

MOVF CONTADOR,W ; Preguntamos si CONTADOR = 8XORLW 0X08BTFSC STATUS,ZGOTO SEG2

SEG4 BCF STATUS,C ; Si CONTADOR <> 4 ponemos el Cy=0 y rotamos haciaRRF DATO,F ; la Izquierda el registro DATO.GOTO SEG1 ; Seguimos hacia la Izquierda.

SEG2 CLRF CONTADOR ; Si CONTADOR = 4 ponemos el CONTADOR=0,Cy=0 ySEG3 BCF STATUS,C ; rotamos hacia la Derecha el registro DATO.

RLF DATO,F

MOVF DATO,W ; Transferimos la información del registro DATO MOVWF PORTB ; al Puerto B.

PARAR2 BTFSS PORTC,0GOTO PARAR2INCF CONTADOR ; Preguntamos si CONTADOR = 7

CALL Retardo_100ms ; Llamamos a la Subrutina de Retardo TIEMPO.

MOVF CONTADOR,WXORLW 0X07BTFSS STATUS,ZGOTO SEG3 ; Seguimos hacia la Derecha.

MOVLW 0X01 ; Ponemos el CONTADOR = 1 y volvemos hacia la izquierda.MOVWF CONTADORGOTO SEG4

;*************************** Librerías ***************************************************************************

INCLUDE <RETARDOS.INC>

END

1.8.- Nom_disp.asm (Entrenador Básico 0)

20

Page 27: Entren Adores

Diagrama de Flujo

title " Poner el NOMBRE en el Display "

Poner el Nombre en el Display

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

Numero_de_caracteres EQU D '5'

; Registros

CBLOCK 0X20

CONTADOR

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de Configuración

ORG 0x05 ; Inicio de Programa

COMIENZO RP0 1 ; Ir al Banco 1 TRISD 00000000 B ; Poner el Puerto D como

salida de datos. RP0 0 ; Ir al Banco 0

1

¿ CONTADOR =

Numero_de_caracteres

SINO

1

CONTADOR 00000000 B

W CONTADOR

BINARIO_CARACTER

PORTD W

Retardo_500ms

CONTADOR CONTADOR + 1

BINARIO_CARACTER

PCL PCL + W

RETLW B'01110011' ;Retorna con W cargado con PRETLW B'01111001' ;Retorna con W cargado con ERETLW B'01011110' ;Retorna con W cargado con d

RETLW B'01010000' ;Retorna con W cargado con rRETLW B'01011100' ;Retorna con W cargado con o

21

Page 28: Entren Adores

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;************* Asignación de etiquetas de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ************************************************************************

Numero_de_caracteres EQU D'5'

;**************************** Registros *************************************************************************

CBLOCK 0X20

CONTADOR

ENDC

;**************************** Sección Código de Reset *******************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *******************************************************

ORG 0x05 ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP0 ; Selecciono la pagina 1 de la memoriaCLRF TRISD ; Configuro el Puerto D como salidaBCF STATUS,RP0 ; Selecciono la pagina 0 de la memoria

;*************************** Principal ***************************************************************************

SEG2 CLRF CONTADORSEG1 MOVF CONTADOR,W

CALL BINARIO_CARACTERMOVWF PORTDCALL Retardo_500msINCF CONTADOR,FMOVF CONTADOR,WSUBLW Numero_de_caracteresBTFSS STATUS,ZGOTO SEG1GOTO SEG2

22

Page 29: Entren Adores

;***************************** Subrutina de BINARIO_CARACTER *******************************************

BINARIO_CARACTER ADDWF PCL,F ;Suma el Contador del Programa con el contenido; de W y lo deja en el PC.

RETLW B'01110011' ;Retorna con W cargado con PRETLW B'01111001' ;Retorna con W cargado con ERETLW B'01011110' ;Retorna con W cargado con dRETLW B'01010000' ;Retorna con W cargado con rRETLW B'01011100' ;Retorna con W cargado con o

;***************************** Librerías ***************************************************************************

INCLUDE <RETARDOS.INC>

END

1.9.- Sum_Nibl.asm (Entrenador Básico 0)

23

Page 30: Entren Adores

Diagrama de Flujo

title " Sumar los nibles del Puerto C y llevarlos al Puerto B ";Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

Sumar los nibles del Puerto C y llevarlos al

Puerto B

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; Registros

CBLOCK 0X20Numero_bajoNumero_altoENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de Configuración

ORG 0x05 ; Inicio de Programa

COMIENZO RP0 1 ; Ir al Banco 1 TRISB 00000000 B ; Poner el Puerto B como

salida de datos. TRISC 11111111 B ; Poner el Puerto C como

entrada de datos. RP0 0 ; Ir al Banco 0

1

1

W PORTC

W 00001111 B AND W

Numero_bajo W

W PORTC

W 11110000 B AND W

Numero_alto W

Numero_alto Numero_alto ( 7..4 ) ( 3..0 )

W Numero_alto

W W + Numero_bajo

PORTB W

24

Page 31: Entren Adores

;**************************** Elegimos PIC *********************************************************************

list p=16f877, f=inhx32

;************* Asignación de etiquetas de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ************************************************************************

;**************************** Registros **************************************************************************

CBLOCK 0X20

Numero_bajoNumero_alto

ENDC

;**************************** Sección Código de Reset ********************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración ********************************************************

ORG 0x05 ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP0 ; Selecciono la pagina 1 de la memoriaCLRF TRISB ; Configuro el Puerto B como salidaMOVLW B'11111111'MOVWF TRISCBCF STATUS,RP0 ; Selecciono la pagina 0 de la memoria

;**************************** Inicio *******************************************************************************

SEG1 COMF PORTC,WANDLW B'00001111'MOVWF Numero_bajoCOMF PORTC,WANDLW B'11110000'MOVWF Numero_altoSWAPF Numero_alto,FMOVF Numero_alto,WADDWF Numero_bajo,WMOVWF PORTBGOTO SEG1

END

1.10.- Dir_ind.asm (Entrenador Básico 0)

25

Page 32: Entren Adores

Diagrama de Flujo

title "Direccionamiento indirecto "

Direccionamiento Indirecto

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; RegistrosCBLOCK 0X20

REG1REG2REG3

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Principal

ORG 0x05 ; Inicio de Programa

COMIENZO FSR # REG1 (FSR) D’1’

FSR FSR + 1

(FSR) D’2’

FSR FSR + 1

(FSR) D’3’

FSR FSR + 1

FIN

26

Page 33: Entren Adores

;Programa para PIC 16F876a.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC *********************************************************************

list p=16f876, f=inhx32

;************* Asignación de etiquetas de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ************************************************************************

;*************************** Registros **************************************************************************

CBLOCK 0X20

REG1REG2REG3

ENDC

;**************************** Sección Código de Reset *******************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Principal **************************************************************************

ORG 0x05 ; Inicio de Programa (Una posición detrás del vector de Interrupción).

COMIENZO MOVLW REG1MOVWF FSR ; Cargas la dirección del Registro REG1 “20H” en el Puntero FSR.

MOVLW D'1'MOVWF INDF ; Cargas donde apunta el Puntero (FSR) el dato 1. (20H) 1.INCF FSR ; Incrementas el Puntero FSR “21H”.

MOVLW D'2'MOVWF INDF ; Cargas donde apunta el Puntero (FSR) el dato 2. (21H) 2.INCF FSR ; Incrementas el Puntero FSR “22H”.

MOVLW D'3'MOVWF INDF ; Cargas donde apunta el Puntero (FSR) el dato 3. (22H) 3.INCF FSR ; Incrementas el Puntero FSR “23H”.

END

1.11.- Pagina1.asm (Entrenador Básico 0)

27

Page 34: Entren Adores

Diagrama de Flujo

title " Trabajar con la Pagina 1 de memoria de Programa "

Trabajar con la Pagina 1 de memoria de

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; Registros

CBLOCK 0X20

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de Configuración ORG 0X05

COMIENZO RP0 1 ; Ir al Banco 1 TRISB 00000000 B ; Poner el Puerto B como

salida de datos. TRISC 11111111 B ; Poner el Puerto C como

entrada de datos. RP0 0 ; Ir al Banco 0

; Cambio a la Página1

PCLATCH3 1PCLATCH4 0

PAGINA1

Subrutina Prueba Pagina1

ORG 0800H

PORTC PORTB

; Cambio a la Página0

PCLATCH3 0

RETURN

28

Page 35: Entren Adores

;Programa para PIC 16F876a.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f876, f=inhx32

;************ Asignación de etiquetas de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ***********************************************************************

;**************************** Registros *************************************************************************

;**************************** Sección Código de Reset ******************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración ******************************************************

ORG 0x05 ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP0MOVLW B'11111111'MOVWF TRISCCLRF TRISBBCF STATUS,RP0

;**************************** Inicio *****************************************************************************

SEG1 BSF PCLATH,3 ;Ir a la Pagina1 de memoria de ProgramaBCF PCLATH,4

CALL PAGINA1GOTO SEG1

;****************************Subrutina Prueba Pagina1 *******************************************************

ORG 0800H

PAGINA1 MOVF PORTC,WMOVWF PORTB ;Ir a la Pagina0 de memoria de ProgramaBCF PCLATH,3RETURN

END

1.12.- RETARDO_1S.INC (Entrenador Básico 0)

29

Page 36: Entren Adores

;*********************** Librería Casera de Retardo 1 Segundo **********************************************

;*********************** Igualdades ******************************************************************************

DATO1 EQU D'100'

DATO2 EQU D'100'

DATO3 EQU D'20'

;*********************** Registros ********************************************************************************

CBLOCK

REG1

REG2

REG3

ENDC

;*********************** Subrutina SEGUNDO *****************************************************************

SEGUNDO MOVLW DATO3MOVWF REG3

SEG7 MOVLW DATO2MOVWF REG2

SEG6 MOVLW DATO1MOVWF REG1

SEG5 DECFSZ REG1,FGOTO SEG5DECFSZ REG2,FGOTO SEG6DECFSZ REG3,FGOTO SEG7

RETURN

1.13.- RETARDOS.INC (Entrenador Básico 0)

30

Page 37: Entren Adores

;**************************** Librería "RETARDOS.INC" *****************************************************;; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================;; Librería con múltiples subrutinas de retardos, desde 4 microsegundos hasta 20 segundos. ; Además se pueden implementar otras subrutinas muy fácilmente.;; Se han calculado para un sistema microcontrolador con un PIC trabajando con un cristal; de cuarzo a 4 MHz. Como cada ciclo máquina son 4 ciclos de reloj, resulta que cada; ciclo máquina tarda 4 x 1/4MHz = 1 µs.;; En los comentarios, "cm" significa "ciclos máquina".;; ZONA DE DATOS *************************************************************************************

CBLOCKR_ContA ; Contadores para los retardos.R_ContBR_ContCENDC

;; RETARDOS de 4 hasta 10 microsegundos -------------------------------------------------------------------;; A continuación retardos pequeños teniendo en cuenta que para una frecuencia de 4 MHZ,; la llamada a subrutina "call" tarda 2 ciclos máquina, el retorno de subrutina; "return" toma otros 2 ciclos máquina y cada instrucción "nop" tarda 1 ciclo máquina.;Retardo_10micros ; La llamada "call" aporta 2 ciclos máquina.

nop ; Aporta 1 ciclo máquina.nop ; Aporta 1 ciclo máquina.nop ; Aporta 1 ciclo máquina.nop ; Aporta 1 ciclo máquina.nop ; Aporta 1 ciclo máquina.

Retardo_5micros ; La llamada "call" aporta 2 ciclos máquina.nop ; Aporta 1 ciclo máquina.

Retardo_4micros ; La llamada "call" aporta 2 ciclos máquina.return ; El salto del retorno aporta 2 ciclos máquina.

;; RETARDOS de 20 hasta 500 microsegundos -----------------------------------------------------------------;Retardo_500micros ; La llamada "call" aporta 2 ciclos máquina.

nop ; Aporta 1 ciclo máquina.movlw d'164' ; Aporta 1 ciclo máquina. Este es el valor de "K".goto RetardoMicros ; Aporta 2 ciclos máquina.

Retardo_200micros ; La llamada "call" aporta 2 ciclos máquina.nop ; Aporta 1 ciclo máquina.movlw d'64' ; Aporta 1 ciclo máquina. Este es el valor de "K".goto RetardoMicros ; Aporta 2 ciclos máquina.

Retardo_100micros ; La llamada "call" aporta 2 ciclos máquina.movlw d'31' ; Aporta 1 ciclo máquina. Este es el valor de "K".goto RetardoMicros ; Aporta 2 ciclos máquina.

Retardo_50micros ; La llamada "call" aporta 2 ciclos máquina.nop ; Aporta 1 ciclo máquina.movlw d'14' ; Aporta 1 ciclo máquina. Este es el valor de "K".goto RetardoMicros ; Aporta 2 ciclos máquina.

Retardo_20micros ; La llamada "call" aporta 2 ciclos máquina.

31

Page 38: Entren Adores

movlw d'5' ; Aporta 1 ciclo máquina. Este es el valor de "K".;; El próximo bloque "RetardoMicros" tarda:; 1 + (K-1) + 2 + (K-1)x2 + 2 = (2 + 3K) ciclos máquina.;RetardoMicros

movwf R_ContA ; Aporta 1 ciclo máquina.Rmicros_Bucle

decfsz R_ContA,F ; (K-1)x1 cm (cuando no salta) + 2 cm (al saltar).goto Rmicros_Bucle ; Aporta (K-1)x2 ciclos máquina.return ; El salto del retorno aporta 2 ciclos máquina.

;;En total estas subrutinas tardan:; - Retardo_500micros: 2 + 1 + 1 + 2 + (2 + 3K) = 500 cm = 500 µs. (para K=164 y 4 MHz).; - Retardo_200micros: 2 + 1 + 1 + 2 + (2 + 3K) = 200 cm = 200 µs. (para K= 64 y 4 MHz).; - Retardo_100micros: 2 + 1 + 2 + (2 + 3K) = 100 cm = 100 µs. (para K= 31 y 4 MHz).; - Retardo_50micros : 2 + 1 + 1 + 2 + (2 + 3K) = 50 cm = 50 µs. (para K= 14 y 4 MHz).; - Retardo_20micros : 2 + 1 + (2 + 3K) = 20 cm = 20 µs. (para K= 5 y 4 MHz).;; RETARDOS de 1 ms hasta 200 ms. ------------------------------------------------------------------------------;Retardo_200ms ; La llamada "call" aporta 2 ciclos máquina.

movlw d'200' ; Aporta 1 ciclo máquina. Este es el valor de "M".goto Retardos_ms ; Aporta 2 ciclos máquina.

Retardo_100ms ; La llamada "call" aporta 2 ciclos máquina.movlw d'100' ; Aporta 1 ciclo máquina. Este es el valor de "M".goto Retardos_ms ; Aporta 2 ciclos máquina.

Retardo_50ms ; La llamada "call" aporta 2 ciclos máquina.movlw d'50' ; Aporta 1 ciclo máquina. Este es el valor de "M".goto Retardos_ms ; Aporta 2 ciclos máquina.

Retardo_20ms ; La llamada "call" aporta 2 ciclos máquina.movlw d'20' ; Aporta 1 ciclo máquina. Este es el valor de "M".goto Retardos_ms ; Aporta 2 ciclos máquina.

Retardo_10ms ; La llamada "call" aporta 2 ciclos máquina.movlw d'10' ; Aporta 1 ciclo máquina. Este es el valor de "M".goto Retardos_ms ; Aporta 2 ciclos máquina.

Retardo_5ms ; La llamada "call" aporta 2 ciclos máquina.movlw d'5' ; Aporta 1 ciclo máquina. Este es el valor de "M".goto Retardos_ms ; Aporta 2 ciclos máquina.

Retardo_2ms ; La llamada "call" aporta 2 ciclos máquina.movlw d'2' ; Aporta 1 ciclo máquina. Este es el valor de "M".goto Retardos_ms ; Aporta 2 ciclos máquina.

Retardo_1ms ; La llamada "call" aporta 2 ciclos máquina.movlw d'1' ; Aporta 1 ciclo máquina. Este es el valor de "M".

;; El próximo bloque "Retardos_ms" tarda:; 1 + M + M + KxM + (K-1)xM + Mx2 + (K-1)Mx2 + (M-1) + 2 + (M-1)x2 + 2 =; = (2 + 4M + 4KM) ciclos máquina. Para K=249 y M=1 supone 1002 ciclos máquina; que a 4 MHz son 1002 µs = 1 ms.;Retardos_ms

movwf R_ContB ; Aporta 1 ciclo máquina.R1ms_BucleExterno

movlw d'249' ; Aporta Mx1 ciclos máquina. Este es el valor de "K".movwf R_ContA ; Aporta Mx1 ciclos máquina.

R1ms_BucleInternonop ; Aporta KxMx1 ciclos máquina.decfsz R_ContA,F ; (K-1)xMx1 cm (cuando no salta) + Mx2 cm (al saltar).goto R1ms_BucleInterno ; Aporta (K-1)xMx2 ciclos máquina.decfsz R_ContB,F ; (M-1)x1 cm (cuando no salta) + 2 cm (al saltar).

32

Page 39: Entren Adores

goto R1ms_BucleExterno ; Aporta (M-1)x2 ciclos máquina.return ; El salto del retorno aporta 2 ciclos máquina.

;;En total estas subrutinas tardan:; - Retardo_200ms: 2 + 1 + 2 + (2 + 4M + 4KM) = 200007 cm = 200 ms. (M=200 y K=249).; - Retardo_100ms: 2 + 1 + 2 + (2 + 4M + 4KM) = 100007 cm = 100 ms. (M=100 y K=249).; - Retardo_50ms : 2 + 1 + 2 + (2 + 4M + 4KM) = 50007 cm = 50 ms. (M= 50 y K=249).; - Retardo_20ms : 2 + 1 + 2 + (2 + 4M + 4KM) = 20007 cm = 20 ms. (M= 20 y K=249).; - Retardo_10ms : 2 + 1 + 2 + (2 + 4M + 4KM) = 10007 cm = 10 ms. (M= 10 y K=249).; - Retardo_5ms : 2 + 1 + 2 + (2 + 4M + 4KM) = 5007 cm = 5 ms. (M= 5 y K=249).; - Retardo_2ms : 2 + 1 + 2 + (2 + 4M + 4KM) = 2007 cm = 2 ms. (M= 2 y K=249).; - Retardo_1ms : 2 + 1 + (2 + 4M + 4KM) = 1005 cm = 1 ms. (M= 1 y K=249).;; RETARDOS de 0.5 hasta 20 segundos --------------------------------------------------------------------------;Retardo_20s ; La llamada "call" aporta 2 ciclos máquina.

movlw d'200' ; Aporta 1 ciclo máquina. Este es el valor de "N".goto Retardo_1Decima ; Aporta 2 ciclos máquina.

Retardo_10s ; La llamada "call" aporta 2 ciclos máquina.movlw d'100' ; Aporta 1 ciclo máquina. Este es el valor de "N".goto Retardo_1Decima ; Aporta 2 ciclos máquina.

Retardo_5s ; La llamada "call" aporta 2 ciclos máquina.movlw d'50' ; Aporta 1 ciclo máquina. Este es el valor de "N".goto Retardo_1Decima ; Aporta 2 ciclos máquina.

Retardo_2s ; La llamada "call" aporta 2 ciclos máquina.movlw d'20' ; Aporta 1 ciclo máquina. Este es el valor de "N".goto Retardo_1Decima ; Aporta 2 ciclos máquina.

Retardo_1s ; La llamada "call" aporta 2 ciclos máquina.movlw d'10' ; Aporta 1 ciclo máquina. Este es el valor de "N".goto Retardo_1Decima ; Aporta 2 ciclos máquina.

Retardo_500ms ; La llamada "call" aporta 2 ciclos máquina.movlw d'5' ; Aporta 1 ciclo máquina. Este es el valor de "N".

;; El próximo bloque "Retardo_1Decima" tarda:; 1 + N + N + MxN + MxN + KxMxN + (K-1)xMxN + MxNx2 + (K-1)xMxNx2 +; + (M-1)xN + Nx2 + (M-1)xNx2 + (N-1) + 2 + (N-1)x2 + 2 =; = (2 + 4M + 4MN + 4KM) ciclos máquina. Para K=249, M=100 y N=1 supone 100011; ciclos máquina que a 4 MHz son 100011 µs = 100 ms = 0,1 s = 1 décima de segundo.;Retardo_1Decima

movwf R_ContC ; Aporta 1 ciclo máquina.R1Decima_BucleExterno2

movlw d'100' ; Aporta Nx1 ciclos máquina. Este es el valor de "M".movwf R_ContB ; Aporta Nx1 ciclos máquina.

R1Decima_BucleExternomovlw d'249' ; Aporta MxNx1 ciclos máquina. Este es el valor de "K".movwf R_ContA ; Aporta MxNx1 ciclos máquina.

R1Decima_BucleInterno nop ; Aporta KxMxNx1 ciclos máquina.decfsz R_ContA,F ; (K-1)xMxNx1 cm (si no salta) + MxNx2 cm (al saltar).goto R1Decima_BucleInterno ; Aporta (K-1)xMxNx2 ciclos máquina.decfsz R_ContB,F ; (M-1)xNx1 cm (cuando no salta) + Nx2 cm (al saltar).goto R1Decima_BucleExterno ; Aporta (M-1)xNx2 ciclos máquina.decfsz R_ContC,F ; (N-1)x1 cm (cuando no salta) + 2 cm (al saltar).goto R1Decima_BucleExterno2 ; Aporta (N-1)x2 ciclos máquina.return ; El salto del retorno aporta 2 ciclos máquina.

;;En total estas subrutinas tardan:; - Retardo_20s: 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 20000807 cm = 20 s.; (N=200, M=100 y K=249).

33

Page 40: Entren Adores

; - Retardo_10s: 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 10000407 cm = 10 s.; (N=100, M=100 y K=249).; - Retardo_5s: 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 5000207 cm = 5 s.; (N= 50, M=100 y K=249).; - Retardo_2s: 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 2000087 cm = 2 s.; (N= 20, M=100 y K=249).; - Retardo_1s: 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 1000047 cm = 1 s.; (N= 10, M=100 y K=249).; - Retardo_500ms: 2 + 1 + (2 + 4N + 4MN + 4KMN) = 500025 cm = 0,5 s.; (N= 5, M=100 y K=249).

; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================

34

Page 41: Entren Adores

2.- Entrenador Básico 1

35

Page 42: Entren Adores

2.1.- Ejemplo6.asm (Entrenador Básico 1)

Diagrama de Flujo

Encender displays dependiendo de PC0

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; Registros

CBLOCK 0X20

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de Configuración ORG 0X05

COMIENZO RP0 1 ; Ir al Banco 1 TRISD 00000000 B ; Poner el Puerto D como

salida de datos. TRISC (0) 1 ; Poner PC0 como entrada de

Datos ADCON1 00000110 B ; Configuro las patillas de los

PUERTOS A y D como señalesdigitales.

TRISE 00000000 B ; Poner el Puerto E como salida de datos.

RP0 0 ; Ir al Banco 0

PORTD 11111111 B

¿ PCO = 1?

; Encender Display de UNIDADES

PORTE 00000001 B

; Encender Display de DECENAS

PORTE 00000010 B

SI

NO

36

Page 43: Entren Adores

title " Encender displays dependiendo de PC0 "

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;************** Asignación de etiquetas de Registros de Funciones especiales a direcciones **********

#include <p16f877.inc> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ************************************************************************

;**************************** Registros *************************************************************************

;**************************** Sección Código de Reset *******************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *******************************************************

ORG 0x05 ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO BCF STATUS,RP1 ; Selecciono la pagina 1 de la memoriaBSF STATUS,RP0 MOVLW B'00000000' ; Configuro el PD como salidas.MOVWF TRISDBSF TRISC,0CLRF PORTE ; Configuro el PE como salidas.BCF STATUS,RP0 ; Selecciono la pagina 0 de la memoria

;*************************** Principal ***************************************************************************

SEGUIR MOVLW B'11111111'MOVWF PORTD

SEG1 BTFSS PORTC,0GOTO DECENAS

UNIDADES MOVLW B'00000001'MOVWF PORTEGOTO SEG1

DECENAS MOVLW B'00000010'MOVWF PORTEGOTO SEG1

37

Page 44: Entren Adores

END

2.2.- Ejemplo7.asm (Entrenador Básico 1)

Diagrama de Flujo

Contar pulsos procedentes de PC0 y llevarlos al Display de

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; IgualdadesNMAYOR EQU 0X0A

; Registros

CBLOCK 0X20

CONTADOR

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1 TRISD 00000000 B ; Poner el Puerto D como

salida de datos. TRISC (0) 1 ; Poner PC0 como entrada de

Datos ADCON1 00000110 B ; Configuro las patillas de los

PUERTOS A y D como señalesdigitales.

TRISE 00000000 B ; Poner el Puerto E como salida de datos.

RP0 0 ; Ir al Banco 0

;Poner el Display de Unidades a cero

PORTD 00111111 B

1

¿ PCO = 0?

CONTADOR 00000001 B

PORTE 00000001 B

SI

NO

1

W CONTADOR

TABLA

PORT D W

CONTADOR CONTADOR +1

¿ CONTADOR = NMAYOR ?

CONTADOR 00000000 B

NOSI

Subrutina TABLA

PCL PCL + W

RETLW B'00111111' ;Retorna con W cargado con 00HRETLW B'00000110' ;Retorna con W cargado con 01HRETLW B'01011011' ;Retorna con W cargado con 02HRETLW B'01001111' ;Retorna con W cargado con 03HRETLW B'01100110' ;Retorna con W cargado con 04H

38

Page 45: Entren Adores

title " Contar pulsos procedentes de PC0 y llevarlos al Display de Unidades "

;Programa para PIC 16F877.;Velocidad del Reloj:20 MHz.;Reloj instrucción: 1 MHz = 200 nS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;************ Asignación de etiquetas de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ************************************************************************

NMAYOR EQU 0X0A

;**************************** Registros **************************************************************************

CBLOCK 0X20

CONTADOR

ENDC

;**************************** Sección Código de Reset ********************************************************

ORG 00h ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *********************************************************

ORG 05h ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP0 ; Selecciono la pagina 1 de la memoriaCLRF TRISD ; Configuro el Puerto D como salida de datos.MOVLW 0X06 ; Configuro el Puerto A y D como patillas digitales.MOVWF ADCON1

CLRF TRISE ; Configuro el puerto E como salida de datos.BSF PORTC,0 ; Configuro la patilla PC0 como entrada de datos.

BCF STATUS,RP0 ; Selecciono la pagina 0 de la memoria

CLRF CONTADORMOVLW B'00111111'MOVWF PORTD ; Poner el DISPLAY de unidades a cero.

39

Page 46: Entren Adores

INCF CONTADOR

MOVLW B'00000001'MOVWF PORTE

;*************************** Principal *****************************************************************************

SEGUIR BTFSC PORTC,0GOTO SEGUIR

MOVF CONTADOR,WCALL TABLA

INCF CONTADOR,FMOVWF PORTDMOVF CONTADOR,WXORLW NMAYORBTFSS STATUS,ZGOTO SEG1CLRF CONTADOR

SEG1 BTFSS PORTC,0GOTO SEG1GOTO SEGUIR

;***************************** Subrutina de Tabla ***************************************************************

TABLA ADDWF PCL,F ;Suma el Contador del Programa con el contenido;de W y lo deja en el PC.

RETLW B'00111111' ;Retorna con W cargado con 00HRETLW B'00000110' ;Retorna con W cargado con 01HRETLW B'01011011' ;Retorna con W cargado con 02HRETLW B'01001111' ;Retorna con W cargado con 03HRETLW B'01100110' ;Retorna con W cargado con 04HRETLW B'01101101' ;Retorna con W cargado con 05HRETLW B'01111101' ;Retorna con W cargado con 06HRETLW B'00000111' ;Retorna con W cargado con 07HRETLW B'01111111' ;Retorna con W cargado con 08HRETLW B'01101111' ;Retorna con W cargado con 09H

END

40

Page 47: Entren Adores

2.3.- Ejemplo8.asm (Entrenador Básico 1)

Diagrama de Flujo

Contar pulsos procedentes de PC0 y llevarlos al Display de Unidades y Decenas

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

NMAYOR EQU D’100’

; Registros

CBLOCK 0X20

CONTADOR

DISPLAY

UNIDADESDECENASCENTENAS

DIVIDENDODIVISORCOCIENTERESTO

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

1

1

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1

ADCON1 00000110 B ; Configuro las patillas de los PUERTOS A y D como señalesdigitales.

TRISD 00000000 B ; Poner el Puerto D como salida de datos.

TRISE 00000000 B ; Poner el Puerto E como salida de datos.

TRISC 11111111 B ; Poner Puerto C como entrada de datos

RP0 0 ; Ir al Banco 0 PULSOS 00000000 B ; Resetear el registro PULSOS, es

un registro que contiene el numero de pulsaciones.

CONTADOR 00000001 B ; Iniciar el CONTADOR a 1

¿ PCO = 0?

SI

NO

PULSOS CONTADOR

CONTADOR CONTADOR +1

¿ CONTADOR = NMAYOR ?

CONTADOR 00000000 B

NO

SI

MOSTRAR_DISPLAY

MOSTRAR_DISPLAY

¿ PCO = 1?SI

N0

41

Page 48: Entren Adores

Subrutina de DIVIDIR

COCIENTE 00000000 B

DIVIDENDO W

RESTO DIVIDENDO

DIVIDENDO DIVIDENDO - DIVISOR

¿ DIVIDENDO < 0 ?

COCIENTE COCIENTE + 1

RETURN

SI

NO

Subrutina de BIN_BCD

DIVISOR D’100’

W PULSOS

DIVIDIR

CENTENAS COCIENTE

DIVISOR D’10’

W RESTO

DIVIDIR

DECENAS COCIENTE

UNIDADES RESTO

RETURN

Subrutina BCD_7SEG

PCL PCL + W

RETLW B'00111111' ;Retorna con W cargado con 00HRETLW B'00000110' ;Retorna con W cargado con 01HRETLW B'01011011' ;Retorna con W cargado con 02HRETLW B'01001111' ;Retorna con W cargado con 03HRETLW B'01100110' ;Retorna con W cargado con 04HRETLW B'01101101' ;Retorna con W cargado con 05HRETLW B'01111101' ;Retorna con W cargado con 06HRETLW B'00000111' ;Retorna con W cargado con 07HRETLW B'01111111' ;Retorna con W cargado con 08H

BIN_BCD

Subrutina de MOSTRAR_DISPLAY

; Habilitar display de las DECENAS

PORTE 00000010 B

; Temporizar. Perder tiempo con dos NOP

; Deshabilitar display de las UNIDADES y DECENAS

PORTE 00000000 B

RETURN

; Habilitar display de las UNIDADES

PORTE 00000001 B

; Temporizar. Perder tiempo con dos NOP

; Deshabilitar display de las UNIDADES y DECENAS

PORTE 00000000 B

W UNIDADES BCD_7SEG PORTD W

W DECENAS BCD_7SEG PORTD W

42

Page 49: Entren Adores

title " Contar pulsos procedentes de PC0 y llevarlos al Display de Unidades y Decenas "

;Programa para PIC 16F877.;Velocidad del Reloj:20 MHz.;Reloj instrucción: 1 MHz = 200 nS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC *********************************************************************

list p=16f877, f=inhx32

;************* Asignación de etiquetas del Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ***********************************************************************

NMAYOR EQU D'100'

;**************************** Registros *************************************************************************

CBLOCK 0X20

CONTADOR

PULSOS

UNIDADES DECENAS CENTENAS

DIVIDENDO DIVISOR COCIENTE RESTO

ENDC

;**************************** Sección Código de Reset **************************************************

ORG 0x00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *************************************************

ORG 0x05 ; Inicio de Programa (Una posición detrás del vector de Interrupción

COMIENZO BSF STATUS,RP0 ; Selecciono la pagina 1 de la memoriaMOVLW 0X06

43

Page 50: Entren Adores

MOVWF ADCON1CLRF TRISD ; Configuro el Puerto D como salidaCLRF TRISE ; Configuro el Puerto E como salidaMOVLW B'11111111' ; Configuro el puerto PC como entrada.MOVWF TRISC

BCF STATUS,RP0 ; Selecciono la pagina 0 de la memoriaCLRF PULSOS; Resetear el registro PULSOS, es un registro que

contiene el numero de pulsaciones.MOVLW B’00000001’ ; Inicializamos el CONTADOR con 1.MOVWF CONTADOR ;

;*************************** Principal ****************************************************************************

SEGUIR CALL MOSTRAR_DISPLAYBTFSC PORTC,0GOTO SEGUIR

MOVF CONTADOR,WMOVWF PULSOS

INCF CONTADOR,FMOVF CONTADOR,WXORLW NMAYORBTFSS STATUS,ZGOTO SEG1CLRF CONTADOR

SEG1 CALL MOSTRAR_DISPLAYBTFSS PORTC,0GOTO SEG1GOTO SEGUIR

;***************************** Subrutina de BCD_7SEG ***************************************************************

BCD_7SEG ADDWF PCL,F ;Suma el Contador del Programa con el contenido ;de W y lo deja en el PC.

RETLW B'00111111' ;Retorna con W cargado con 00HRETLW B'00000110' ;Retorna con W cargado con 01HRETLW B'01011011' ;Retorna con W cargado con 02HRETLW B'01001111' ;Retorna con W cargado con 03HRETLW B'01100110' ;Retorna con W cargado con 04HRETLW B'01101101' ;Retorna con W cargado con 05HRETLW B'01111101' ;Retorna con W cargado con 06HRETLW B'00000111' ;Retorna con W cargado con 07HRETLW B'01111111' ;Retorna con W cargado con 08HRETLW B'01101111' ;Retorna con W cargado con 09H

;****************************** Subrutina de MOSTRAR_DISPLAY *********************************************

MOSTRAR_DISPLAY CALL BIN_BCDMOVF UNIDADES,WCALL BCD_7SEGMOVWF PORTDMOVLW B'00000001'MOVWF PORTENOPNOPMOVLW B'00000000'MOVWF PORTE

44

Page 51: Entren Adores

NOPNOPMOVF DECENAS,WCALL BCD_7SEGMOVWF PORTDMOVLW B'00000010'MOVWF PORTENOPNOPMOVLW B'00000000'MOVWF PORTENOPNOPRETURN

;***************************** Subrutina de Binario a BCD ********************************************************

BIN_BCD movlw D’100’ ; Cargamos divisor con 100movwf DIVISORmovf PULSOS,wcall DIVIDIRmovf COCIENTE,wmovwf CENTENAS

movlw D’10’ ; Cargamos divisor con 10movwf DIVISORmovf RESTO,wcall DIVIDIR

movf COCIENTE,wmovwf DECENASmovf RESTO,wmovwf UNIDADESreturn

;****************************** Subrutina de DIVIDIR **************************************************************

DIVIDIR clrf COCIENTEmovwf DIVIDENDO

seg2 movf DIVIDENDO,w movwf RESTO movf DIVISOR,w

subwf DIVIDENDO,fbtfss STATUS,Cgoto seg3incf COCIENTEgoto seg2

seg3 RETURN

END

45

Page 52: Entren Adores

3.- Entrenador Básico 2

46

Page 53: Entren Adores

3.1.- Ejemplo9.asm (Entrenador Básico 2)

Diagrama de Flujo

Contar pulsos procedentes de PC0 y llevarlos al Display de Unidades y Decenas

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

NMAYOR EQU D’100’

; Registros

CBLOCK 0X20

CONTADOR

DISPLAY

UNIDADESDECENASCENTENAS

DIVIDENDODIVISORCOCIENTERESTO

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

1

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1

ADCON1 00000110 B ; Configuro las patillas de los PUERTOS A y D como señalesdigitales.

TRISD 00000000 B ; Poner el Puerto D como salida de datos.

TRISE 00000000 B ; Poner el Puerto E como salida de datos.

TRISB 00000000 B ; Poner el Puerto B como salida de datos.

TRISC 11111111 B ; Poner Puerto C como entrada de datos

CONTADOR 00000000 B ; Resetear el CONTADOR

PORTD 00111111 B ; Poner los dispays a cero. PORTB 00111111 B PORTE 00000011 B

CONTADOR CONTADOR +1

RP0 0 ; Ir al Banco 0

1

¿ PCO = 0?

SI

NO

PULSOS CONTADOR

CONTADOR CONTADOR +1

¿ CONTADOR = NMAYOR ?

CONTADOR 00000000 B

NO

SI

¿ PCO = 1?SI

N0

MOSTRAR_DISPLAY

47

Page 54: Entren Adores

Subrutina de BIN_BCD

DIVISOR D’100’

W PULSOS

DIVIDIR

CENTENAS COCIENTE

DIVISOR D’10’

W RESTO

DIVIDIR

DECENAS COCIENTE

UNIDADES RESTO

RETURN

Subrutina de DIVIDIR

COCIENTE 00000000 B

DIVIDENDO W

RESTO DIVIDENDO

DIVIDENDO DIVIDENDO - DIVISOR

¿ DIVIDENDO < 0 ?

COCIENTE COCIENTE + 1

RETURN

SI

NO

Subrutina BCD_7SEG

PCL PCL + W

RETLW B'00111111' ;Retorna con W cargado con 00HRETLW B'00000110' ;Retorna con W cargado con 01HRETLW B'01011011' ;Retorna con W cargado con 02HRETLW B'01001111' ;Retorna con W cargado con 03HRETLW B'01100110' ;Retorna con W cargado con

BIN_BCD

W UNIDADES

Subrutina de MOSTRAR_DISPLAY

BCD_7SEG

W DECENAS

RETURN

PORTD W

BCD_7SEG

PORTB W

48

Page 55: Entren Adores

title " Contar pulsos procedentes de PC0 y llevarlos al Display de Unidades y Decenas "

;Programa para PIC 16F877.;Velocidad del Reloj:20 MHz.;Reloj instrucción: 1 MHz = 200 nS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC **********************************************************************

list p=16f877, f=inhx32

;*************** Asignación de etiquetas de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades *************************************************************************

NMAYOR EQU D'100'

;**************************** Registros **************************************************************************

CBLOCK 0X20

CONTADOR

PULSOS

UNIDADES DECENAS CENTENAS

DIVIDENDO DIVISOR COCIENTE RESTO

ENDC

;**************************** Sección Código de Reset **********************************************************

ORG 00h ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *********************************************************

ORG 05h ; Inicio de Programa (Una posición detrás del vector de Interrupción

COMIENZO BSF STATUS,RP0 ; Selecciono la pagina 1 de la memoriaMOVLW 0X06

49

Page 56: Entren Adores

MOVWF ADCON1CLRF TRISD ; Configuro el Puerto D como salidaCLRF TRISECLRF TRISBMOVLW B'11111111' ; Configuro el puerto PC como entrada.MOVWF TRISC

BCF STATUS,RP0 ; Selecciono la pagina 0 de la memoriaCLRF CONTADORMOVLW B'00111111'MOVWF PORTD ; Poner el Puerto D a cero.MOVWF PORTB ; Poner el Puerto B a cero.MOVLW B'00000011'MOVWF PORTEINCF CONTADOR

;************************************ Principal *****************************************************************

SEGUIR BTFSC PORTC,0 ; Preguntamos si hemos pulsado “PC0”GOTO SEGUIR

MOVF CONTADOR,WMOVWF PULSOSCALL MOSTRAR_DISPLAY ; Mostramos los datos en los DisplaysINCF CONTADOR,F ; Incrementamos el CONTADOR de Pulsos.MOVF CONTADOR,WXORLW NMAYOR ; Preguntamos si hemos llegado al máximo pulso a contar.BTFSS STATUS,ZGOTO SEG1CLRF CONTADOR ; Reseteamos CONTADOR

SEG1 BTFSS PORTC,0 ; Preguntamos si sigue pulsado “PC0”GOTO SEG1GOTO SEGUIR

;****************************** Subrutina de MOSTRAR_DISPLAY ******************************************

MOSTRAR_DISPLAY CALL BIN_BCDMOVF UNIDADES,wCALL BCD_7SEG MOVWF PORTDMOVF DECENAS,wCALL BCD_7SEG MOVWF PORTBRETURN

;***************************** Subrutina de Binario a BCD ********************************************************

BIN_BCD movlw D'100' ; Cargamos divisor con 100movwf DIVISORmovf PULSOS,wcall DIVIDIRmovf COCIENTE,wmovwf CENTENAS

movlw D'10' ; Cargamos divisor con 10movwf DIVISORmovf RESTO,wcall DIVIDIR

movf COCIENTE,wmovwf DECENAS

50

Page 57: Entren Adores

movf RESTO,wmovwf UNIDADESRETURN

;****************************** Subrutina de Dividir **************************************************************

DIVIDIR clrf COCIENTEmovwf DIVIDENDO

seg2 movf DIVIDENDO,w movwf RESTO movf DIVISOR,w

subwf DIVIDENDO,fbtfss STATUS,Cgoto seg3incf COCIENTEgoto seg2

seg3 RETURN

;***************************** Subrutina de BCD_7SEG ********************************************************

BCD_7SEG ADDWF PCL,F ;Suma el Contador del Programa con el contenido de W y lo deja en el PC.

RETLW B'00111111' ;Retorna con W cargado con 00HRETLW B'00000110' ;Retorna con W cargado con 01HRETLW B'01011011' ;Retorna con W cargado con 02HRETLW B'01001111' ;Retorna con W cargado con 03HRETLW B'01100110' ;Retorna con W cargado con 04HRETLW B'01101101' ;Retorna con W cargado con 05HRETLW B'01111101' ;Retorna con W cargado con 06HRETLW B'00000111' ;Retorna con W cargado con 07HRETLW B'01111111' ;Retorna con W cargado con 08HRETLW B'01101111' ;Retorna con W cargado con 09H

END

51

Page 58: Entren Adores

4.- Entrenador Básico 2A

52

Page 59: Entren Adores

4.1.- PWM_1.asm (Entrenador Básico 2A)

Diagrama de Flujo

Control de un Servomotor de

Posición con PWM a través del Puerto

Elegimos PICList p=16f876 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f876.inc>

; Igualdades

PERIODO EQU D’255’

; Representa el Periodo de la señal de PWM.

; Registros

CBLOCK 0X20

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

1

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1

TRISB 11111111 B ; Poner Puerto B como entrada de datos

TRISC (2) 0 ;Habilitamos PC2 como salida para atacar el Servomotor 1.

PR2 #PERIODO ; Cargamos el Periodo de la

señal de PWM RP0 0 ; Ir al Banco 0 T2CON 00000111 B ; Cargamos el valor preescalar

del PWM Interno, para fijar el periodo.

CCP1CON 00001100 B ;Cargamos los 2 BIT menos significativos del nivel alto de la Señal PWM y configuramos y lanzamos PWM.

Salida de señal por RC2

1

; Leer el Puerto B complementarlo y cargarlo en el registro CCPR1L.Este registro fija el tiempo en el nivel alto de la señal PWM.

CCPR1L PORTB

Retardo 20ms

53

Page 60: Entren Adores

title " Control de un Servomotor de Posición con PWM a través del Puerto B "

;Programa para PIC 16F876a.;Velocidad del Reloj = 1 MHz.;Reloj instrucción: 250 kHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC **********************************************************************

list p=16f876, f=inhx32

;*************** Asignación de etiquetas de Registros de Funciones especiales a direcciones ***********

#include <p16f876.inc> ; Este fichero contiene los nombres y direcciones de los ; registros de funciones especiales.

; Este fichero esta localizado en el directorio ; con el nombre MPASM.

;**************************** Igualdades *************************************************************************

PERIODO EQU 0xFF ; Representa el Periodo de la señal de PWM.

;**************************** Registros **************************************************************************CBLOCK 0X20

ENDC;**************************** Sección Código de Reset ********************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *******************************************************

ORG 0X05 ;Inicio de Programa ;(Una posición detrás del vector de Interrupción).

COMIENZO BSF STATUS,RP0 ; Banco1 BCF STATUS,RP1

MOVLW B'11111111'MOVWF TRISBBCF TRISC,2 ; Habilitamos PC2 como salida para atacar el Servomotor 1.MOVLW PERIODO ; Cargamos el Periodo de la señal de PWM.MOVWF PR2BCF STATUS,RP0

MOVLW B'00000111' ;Cargamos el valor preescalar. (PWM INTERNO)MOVWF T2CON MOVLW B'00001100' ;Cargamos los 2 BIT menos significativos del nivel

;Alto de la Señal PWM y configuramos y lanzamos PWM.MOVWF CCP1CON ;Salida de señal por RC2

;*************************** Principal *****************************************************************************

SEG1 COMF PORTB,WMOVWF CCPR1L ; Nivel Alto de la señal PWM (Salida por RC2).CALL Retardo_20ms ; Tiene que transcurrir un periodo antes de refrescar

; el nivel alto de la señal.GOTO SEG1

;************************** Librerias *******************************************************************************

INCLUDE <RETARDOS.INC>

END

54

Page 61: Entren Adores

4.2.- PWM_CAD.asm (Entrenador Básico 2A)

Diagrama de Flujo

Control de un Servomotor de Posición con PWM a través de un

Potenciómetro

Elegimos PICList p=16f876 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f876.inc>

; Igualdades

PERIODO EQU D’255’

; Representa el Periodo de la señal de PWM.

; Registros

CBLOCK 0X20

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

1

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1

TRISB 00000000 B ; Poner Puerto B como salida de dato

;Configuración del Conversor Analogico/Digital.

TRISA (5) 1 ADCON1 00000000

RP0 0 ; Ir al Banco 0 ADCON0 00100001

RP0 1 ; Ir al Banco 1

;Configuración del PWM.

TRISC (2) 0 ;Habilitamos PC2 como salida para atacar el Servomotor 1.

PR2 #PERIODO ; Cargamos el Periodo de la

señal de PWM RP0 0 ; Ir al Banco 0 T2CON 00000111 B ; Cargamos el valor preescalar

del PWM Interno, para fijar el periodo.

CCP1CON 00001100 B ;Cargamos los 2 BIT menos significativos del nivel alto de la Señal PWM y configuramos y lanzamos PWM.

Salida de señal por RC2

1

; Lanzamos el Conversor Analógico / Digital

GO_DONE 1 ; Es un BIT que está en el registro ADCON0

¿ GO_DONE = 0 ?

; Cargamos el registro que contiene el dato digital, en el registro que contiene el nivel alto de la señal de PWM.

CCPR1L ADRESH

; Cargamos el registro que contiene el dato digital en el Puerto B

PORTB ADRESH

SI

NO

Retardo_20ms

55

Page 62: Entren Adores

title " Control de un Servomotor de Posición con PWM a través de un Potenciómetro "

;Programa para PIC 16F876a.;Velocidad del Reloj = 1 MHz.;Reloj instrucción: 250 kHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC *****************************************************************

list p=16f876, f=inhx32

;************ Asignación de etiquetas de Registros de Funciones especiales a direcciones *********

#include <p16f876.inc> ; Este fichero contiene los nombres y direcciones de los ; registros de funciones especiales.

; Este fichero esta localizado en el directorio ; con el nombre MPASM.

;**************************** Igualdades *********************************************************************

PERIODO EQU 0xFF ;(Datos). Representa el Periodo de la señal de PWM.

;**************************** Registros ***********************************************************************

CBLOCK 0X20

ENDC

;**************************** Sección Código de Reset *****************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *****************************************************

ORG 0X05 ;Inicio de Programa ;(Una posición detrás del vector de Interrupción).

COMIENZO BSF STATUS,RP0 ;Banco1 BCF STATUS,RP1

MOVLW B'00000000'MOVWF TRISB

BSF TRISA,5 ;Configuración del Conversor Analogico/Digital.MOVLW B'00000000'MOVWF ADCON1BCF STATUS,RP0MOVLW B'00100001'MOVWF ADCON0

BSF STATUS,RP0 ;Configuración del PWM.

56

Page 63: Entren Adores

BCF TRISC,2 ;Habilitamos PC2 como salida para atacar el Servomotor 1.

MOVLW PERIODO ;Cargamos el Periodo de la señal de PWM.MOVWF PR2

BCF STATUS,RP0

MOVLW B'00000111' ;Cargamos el Valor Preescalar.(PWM INTERNO)MOVWF T2CON

MOVLW B'00001100' ;Cargamos los 2 BIT menos significativos del nivel;Alto de la señal PWM y configuramos y lanzamos PWM.

MOVWF CCP1CON ;Salida de señal por RC2

;*************************** Principal ********************************************************************

SEG2 CALL Retardo_20ms ; Esperar un tiempo de adquisicion de 20 mS.(PERIODO DE LA; SEÑAL), valido para el C A/D y para refrescar CCPR1L

BSF ADCON0,GO_DONESEG1 BTFSC ADCON0,GO_DONE

GOTO SEG1MOVF ADRESH,WMOVWF CCPR1L ; Nivel Alto de la señal PWM (Salida por RC2).COMF ADRESH,WMOVWF PORTBGOTO SEG2

;*************************** Librerías ********************************************************************

INCLUDE <RETARDOS.INC>

END

57

Page 64: Entren Adores

5.- Entrenador Básico 3

58

Page 65: Entren Adores

5.1.- Ejempl10.asm ( Entrenador Básico 3 )

Diagrama de Flujo

Interrupción Externa

Elegimos PICList p=16f876 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

TABLAD = 40NDATOS = 8NDATOS1 = D’10’TIEMPOH = 0XC0TIEMPOL = 0X00

; Registros

CBLOCK 0X20

CONTADORW_TEMPSTATUS_TEMPPIR1_TEMPPORTB_TEMP TMR1H_TEMPTMR1L_TEMP T1CON_TEMPCONTADOR1

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

1

Vector de Interrupción

ORG 04HGOTO INTERRU

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1

TRISB 00000001 B ; Poner Puerto B como salida de datos excepto PB0 que es la patilla INT

TRISE (2) 0 ; Poner PE2 como salida de datos. TRISC 00000000 B ; Poner Puerto C como salida de datos. INTEDG 0 ; Está en el registro OPTION_REG

; Activa la patilla INT con flanco de bajada. RP0 0 ; Ir al Banco 0

PORTB 00000000 B ; Apagar los Led del Puerto B. PORTE (2) 1 INTCON 10010000 B ; Habilitar la Interrupción “INT”.

; Resetear el registro CONTADOR

CONTADOR 00000000 B

; Cargar el Puntero

FSR #TABLAD

W CONTADOR

TABLA

;Cargar el contenido del Acumulador donde haya apuntado el Puntero FSR

(FSR) W

PORTC W

TIEMPO

; Incrementar el Puntero

FSR FSR +1

; Incrementar CONTADOR

CONTADOR CONTADOR +1

¿ CONTADOR = NDATOS ?

SINO

1

59

Page 66: Entren Adores

Subrutina de TABLA

PCL PCL + W

RETLW B'11111110' ;Retorna con W cargado con 01HRETLW B'11111101' ;Retorna con W cargado con 02HRETLW B'11111011' ;Retorna con W cargado con 04HRETLW B'11110111' ;Retorna con W cargado con 08HRETLW B'11101111' ;Retorna con W cargado con 01HRETLW B'11011111' ;Retorna con W cargado con 02HRETLW B'10111111' ;Retorna con W cargado con 04H

Subrutina de TIEMPO

; Cargar cuenta Inicial

TMR1H #TIEMPOHTMR1L #TIEMPOL

; Configurar el TIMER1 “Este proceso se debe de realizar en la Sección de Configuración

T1CON 00110001 B

¿ TMR1IF = 1 ?

; Borrar Flag

TMR1IF 0

RETURN

SI

NO

Rutina de InterrupciónINTERRU

¿ INTF = 1?

; Salvar Registros

W W_TEMPSTATUS STATUS_TEMP PIR1_TEMP PIR1PORTB_TEMP PORTBTMR1H_TEMP TMR1HTMR1L_TEMP TMR1LT1CON_TEMP T1CON

RETFIE

; Resetear CONTADOR1

CONTADOR1 00000000 B

; Poner un dato en el Puerto B

PORTB 00001110 B

TIEMPO

TIEMPO

; Limpiar el Puerto B

PORTB 00000000 B

NO

SI

TIEMPO

TIEMPO

; Incrementar CONTADOR1

CONTADOR1 CONTADOR1 +1

¿ CONTADOR1 = NDATOS1 ?

; Recuperar Registros

T1CON T1CON_TEMPTMR1L TMR1L_TEMPTMR1H TMR1H_TEMPPORTB PORTB_TEMPPIR1 PIR1_TEMPSTATUS STATUS_TEMP W W_TEMP

; Borrar Flag de la INT

INTF 0

RETFIE

SI

NO

60

Page 67: Entren Adores

title " Interrupción Externa "; Un Programa Principal transfiere una Tabla de datos de memoria EPROM a RAM y Puerto B; utilizando como subrutina de tiempo el TIMER 1 para la cadencia entre dato y dato.; Cuando Pulsamos INT deja de ejecutar el Programa Principal y pasa a ejecutar la rutina; de interrupción. Esta enciende y apaga los led 10 veces con el doble de cadencia anterior.

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;************** Asignación de etiquetas a Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ; Este fichero contiene los nombres y direcciones de los ; registros de funciones especiales. ; Este fichero esta localizado en el directorio

; con el nombre MPASM.

;**************************** Igualdades ************************************************************************

TABLAD EQU 40

NDATOS EQU 8NDATOS1 EQU 0A

TIEMPOH EQU 0XC0TIEMPOL EQU 0X00

;***************************** Registros *************************************************************************

CBLOCK 0X20

CONTADOR

W_TEMPSTATUS_TEMP PIR1_TEMPPORTB_TEMP TMR1H_TEMPTMR1L_TEMP T1CON_TEMP

CONTADOR1

ENDC

;**************************** Sección Código de Reset ********************************************************

ORG 00h ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

61

Page 68: Entren Adores

;**************************** Vector de Interrupción ************************************************************

ORG 04H

GOTO INTERRU

;**************************** Sección de Configuración ********************************************************

ORG 05h ; Inicio de Programa (Una posición detrás del vector de Interrupción

COMIENZO BSF STATUS,RP0 ; Selecciono la pagina 1 de la memoriaMOVLW 0X01MOVWF TRISBBCF TRISE,2CLRF TRISC

BCF OPTION_REG,INTEDGBCF STATUS,RP0 ; Selecciono la pagina 0 de la memoriaCLRF PORTBBSF PORTE,2MOVLW B’10010000’ MOVWF INTCON

;*************************** Principal ****************************************************************************

RESETEO CLRF CONTADOR ; Encender los Led del Puerto C hacia la Izquierda.MOVLW TABLADMOVWF FSR

SEGUIR MOVF CONTADOR,W

CALL TABLA

MOVWF INDFMOVWF PORTC

CALL TIEMPO

INCF FSRINCF CONTADOR

MOVF CONTADOR,WXORLW NDATOSBTFSC STATUS,ZGOTO RESETEOGOTO SEGUIR

;***************************** Subrutina de Tabla *************************************************************

TABLA ADDWF PCL,F ;Suma el Contador del Programa con el contenido ;de W y lo deja en el PC.

RETLW B'11111110' ;Retorna con W cargado con 01HRETLW B'11111101' ;Retorna con W cargado con 02HRETLW B'11111011' ;Retorna con W cargado con 04HRETLW B'11110111' ;Retorna con W cargado con 08HRETLW B'11101111' ;Retorna con W cargado con 01HRETLW B'11011111' ;Retorna con W cargado con 02HRETLW B'10111111' ;Retorna con W cargado con 04HRETLW B'01111111' ;Retorna con W cargado con 08H

62

Page 69: Entren Adores

;***************************** Subrutina de Tiempo utilizando el TIMER1********************************* TIEMPO MOVLW TIEMPOH

MOVWF TMR1HMOVLW TIEMPOLMOVWF TMR1L

MOVLW B’00110001’MOVWF T1CON

SEG1 BTFSS PIR1,TMR1IFGOTO SEG1BCF PIR1,TMR1IF

RETURN

;**************************** Rutina de Interrupción ********************************************************

INTERRU BTFSS INTCON,INTFRETFIEMOVWF W_TEMPSWAPF STATUS,WMOVWF STATUS_TEMPMOVF PIR1,WMOVWF PIR1_TEMPMOVF PORTB,WMOVWF PORTB_TEMPMOVF TMR1H,WMOVWF TMR1H_TEMP MOVF TMR1L,WMOVWF TMR1L_TEMP MOVF T1CON,WMOVWF T1CON_TEMP

CLRF CONTADOR1

SEGUIR1 MOVLW B’00001110’MOVWF PORTB

CALL TIEMPOCALL TIEMPOCLRF PORTBCALL TIEMPOCALL TIEMPO

INCF CONTADOR1MOVF CONTADOR1,WXORLW NDATOS1BTFSC STATUS,ZGOTO SEGUIR2GOTO SEGUIR1

SEGUIR2 BCF INTCON,INTF

MOVF T1CON_TEMP,W MOVWF T1CON MOVF TMR1L_TEMP,W MOVWF TMR1LMOVF TMR1H_TEMP,W MOVWF TMR1H MOVF PORTB_TEMP,W MOVWF PORTB MOVF PIR1_TEMP,W MOVWF PIR1

SWAPF STATUS_TEMP,W MOVWF STATUS

63

Page 70: Entren Adores

SWAPF W_TEMP,FSWAPF W_TEMP,W RETFIE

END

5.2.- Ejemp_11.asm ( Entrenador Básico 3 )

Diagrama de Flujo

Conversión Analógica / Digital

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; Registros

CBLOCK 0X20

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

1; Cargamos los 8 bits más significativos que están en ADRESH en el Puerto B

PORTB ADRESH

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1

TRISA (0) 1 ; Poner PORTA(0) como entrada. TRISE(2) 1 ;Poner PORTE(2)como salida de datos. TRISB 00000000 B ; Poner Puerto B como salida

de dato TRISC 00000000 B ; Poner Puerto C como salida

de dato ADCON1 00001110 B ;Seleccionar PA0 como entrada analógica

;Los 8 BIT mas significativos se quedan en ARDES y los 2 BIT memos significativos se quedan en ADRESL.

RP0 0 ; Ir al Banco 0 ADCON0 00000001B ; Elegimos PA0 y habilitamos el Conversor

PORTC 11111111 B ;Apagar Leds del PUERTO C PORTE(2) 1

1

; Lanzamos el Conversor Analógico / Digital

GO_DONE 1 ; Es un BIT que está en el registro ADCON0

¿ GO_DONE = 0 ?

SI

NO

; Cargamos los 2 bits menos significativos que están en ADRESL en el Puerto C

PORTC ADRESL

; Esperar un tiempo de adquisición de 20 uS.

Retardo_10micros

Retardo_10micros

64

Page 71: Entren Adores

title " Conversión Analogico/Digital "

;Programa para PIC 16F877.;Velocidad del Reloj:20 MHz.;Reloj instrucción: 1 MHz = 200 nS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC *****************************************************************

list p=16f877, f=inhx32

;********** Asignación de etiquetas de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los ; registros de funciones especiales.

; Este fichero esta localizado en el directorio ; con el nombre MPASM.

;**************************** Igualdades ********************************************************************

;**************************** Registros **********************************************************************

;**************************** Sección Código de Reset ****************************************************

ORG 00h ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración ****************************************************

ORG 05h ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP0 ;Ir al Banco 1BSF TRISA,0 ;Poner PORTA(0)como entrada. BCF TRISE,2 ;Poner PORTE(2)como salida de datos.CLRF TRISB ;Poner PORTB como salida de datos.CLRF TRISC ;Poner PORTC como salida de datos.MOVLW B'00001110' ;Seleccionar PA0 como entrada analógicaMOVWF ADCON1 ;Los 8 BIT mas significativos se quedan en ADRESH.

;Los 2 BIT memos significativos se quedan en ADRESL.BCF STATUS,RP0 ;Ir al Banco 0MOVLW B'11111111' ;Apagar Leds del PUERTO C MOVWF PORTCBSF PORTE,2MOVLW B'00000001' ;Elegimos PA0 y habilitamos el ConversorMOVWF ADCON0

;*************************** Principal *************************************************************************

SEG2 BSF ADCON0,GO_DONE ;Lanzamos el Conversor

65

Page 72: Entren Adores

SEG1 CALL Retardo_10micros ; Esperar un tiempo de adquisición de 20 uS.CALL Retardo_10microsBTFSC ADCON0,GO_DONE ;Si GO_DONE es 0 la muestra esta digitalizada.GOTO SEG1MOVF ADRESH,W ;En ADRESH se depositan los 8 BIT mas significativos.MOVWF PORTB BSF STATUS,RP0COMF ADRESL,W ;En ADRESL se depositan los 2 BIT menos significativos.BCF STATUS,RP0MOVWF PORTCGOTO SEG2

;*************************** Librerías ********************************************************************

INCLUDE <RETARDOS.INC>

END

5.3.- Ejemp_12.asm ( Entrenador Básico 3 )

Diagrama de Flujo

Contar pulsos del exterior utilizando

el TIMER0

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

NDATOS = D'15'

; Registros

CBLOCK 0X20

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

1

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1 TRISB 00000000 B ; Poner Puerto B como salida

de dato ADCON1 00000110 B ; Seleccionar PORTA y PORTE como entrada digitales.

TRISA (4) 1 ; Poner PORTA(4) como entrada. OPTION_REG B'00111000' ; Configurar el TIMER0 como contador

de pulsos y la cuenta se realiza por flanco de bajada en la patilla R4/T0CKI y sin preescalar.

TRISE 00000000 B ; Poner Puerto E como salida de dato RP0 0 ; Ir al Banco 0 PORTB 00000000 B ;Apagar Leds del PUERTO B

PORTE(2) 1 ;Habilitar los Leds del Puerto B

1

; Cargar la cuenta inicial en el registro TMR0

TMR0 D’00’

¿ TMR0 = NDATOS ?

SI

NO

; Cargar el registro TMR0 en el PORTB.

PORTB TMR0

FIN

66

Page 73: Entren Adores

title " Contar pulsos del exterior utilizando un Temporizador TIMER 0 "

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************************** Asignación de Registros de Funciones especiales a direcciones ***********

#include <p16f877.inc> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ***********************************************************************

NDATOS EQU D'15'

;**************************** Registro *************************************************************************

;**************************** Sección Código de Reset ******************************************************

ORG 00h ;Dirección del Vector ResetGOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *****************************************************

ORG 05h ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP0 ; Selecciono la pagina 1 de la memoriaCLRF TRISB ; Configuro el Puerto B como salida

MOVLW B'00000110' ;Selecciono PORTA y PORTE como entrada digitales.MOVWF ADCON1MOVLW 0x10 ;Selecciono RA4 como entrada de datos.MOVWF TRISAMOVLW B'00111000' ; Configuro el TIMER0 como contador de pulsosMOVWF OPTION_REG ; y la cuenta se realiza por flanco de bajada en

; la patilla RA4/T0CKI y sin preescalar.CLRF TRISE ; Selecciono PORTE como salida de datos.

BCF STATUS,RP0 ; Selecciono la pagina 0 de la memoriaCLRF PORTB ; Limpio Puerto B.BSF PORTE,2 ; Habilito los Led del PORTE

;*************************** Principal ***************************************************************************

SEGUIR MOVLW D’00’ ; Cargar la cuenta inicial en el registro TMR0MOVWF TMR0

SEGUIR1 MOVF TMR0,W ; Cargar el registro TMR0 en el PORTB.MOVWF PORTBXORLW NDATOS ; Si TMR0 = NDATOS ir a FINAL.BTFSC STATUS,ZGOTO FINALGOTO SEGUIR1

FINAL GOTO FINAL

67

Page 74: Entren Adores

5.4.- Ejemp_13.asm ( Entrenador Básico 3 )

Diagrama de Flujo

Transferir una Tabla de datos de memoria EPROM a RAM y Puerto

Butilizando como subrutina de

tiempo el TIMER0 y el

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

TABLAD = 30HNDATOS = D’05’TIEMPO1 = D'00'TIEMPO2 = D'20'

; Registros

CBLOCK 0X20CONTADORCONT_TIENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1 TRISB 00000000 B ; Poner Puerto B como salida

de dato ADCON1 00000110 B ; Seleccionar PORTA y PORTE como entrada digitales. TRISE 00000000 B ; Poner Puerto E como salida de dato OPTION_REG B'00000111' ; Configurar el TIMER0 como

Temporizador y con preescalar de 256.

RP0 0 ; Ir al Banco 0

PORTB 00000000 B ;Apagar Leds del PUERTO B PORTE(2) 1 ;Habilitar los Leds del Puerto B

CONTADOR 00000000B ; Limpiar CONTADOR. FSR #TABLAD ; Cargar el Puntero.

1

¿ CONTADOR = NDATOS ?

CONT_TI CONT_TI -1

1

W CONTADOR

TABLA

;Cargar el Acumulador donde apunta el

puntero FSR

(FSR) W

;Cargar el Acumulador en el PORTB.

PORTB W

;Cargar el registro CONT_TI con el dato

TIEMPO2

CONT_TI #TIEMPO2

TIEMPO

¿ CON_TI = 0 ?

SI

NO

; Incrementar Puntero

FSR FSR +1

FIN

SINO

; Incrementar CONTADOR

CONTADOR CONTADOR +1

68

Page 75: Entren Adores

title " Transferir una Tabla de datos de memoria EPROM a RAM y Puerto Btitle " utilizando como subrutina de tiempo el TIMER 0 "title " direccionamiento indirecto "

;Programa para PIC 16F877.;Velocidad del Reloj:20 MHz.;Reloj instrucción: 1 MHz = 200 nS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;************ Asignación de etiquetas de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ; Este fichero contiene los nombres y direcciones de los ; registros de funciones especiales.

; Este fichero esta localizado en el directorio ; con el nombre MPASM.

;**************************** Igualdades ***********************************************************************

TABLAD EQU 30H

NDATOS EQU 5

TIEMPO1 EQU D'00'TIEMPO2 EQU D'20'

;*************************** Registros *************************************************************************

Subrutina de TABLA

PCL PCL + W

RETLW B'00000010' ;Retorna con W cargado con 02HRETLW B'00000100' ;Retorna con W cargado con 04HRETLW B'00001000' ;Retorna con W cargado con 08HRETLW B'00000100' ;Retorna con W cargado con 04HRETLW B'00000010' ;Retorna con W cargado con 02H

¿ T0IF = 1 ?

SI

NO

; Cargar el dato TIEMPO1 en el registro TMR0

TMR0 #TIEMPO1

RETURN

Subrutina de TIEMPO

; Borrar flag

T0IF 0

69

Page 76: Entren Adores

CBLOCK 0X20

CONTADOR CONT_TI

ENDC;**************************** Sección Código de Reset ******************************************************

ORG 00h ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *******************************************************

ORG 05h ; Inicio de Programa (Una posición detrás del vector de Interrupción

COMIENZO BSF STATUS,RP0 ; Selecciono la pagina 1 de la memoriaCLRF TRISB ; Configuro el Puerto B como salidaMOVLW B'00000110' ;Selecciono PORTA y PORTE como entrada digitales.MOVWF ADCON1

CLRF TRISE ; Selecciono PORTE como salida de datos.MOVLW B'00000111' ; Configurar el TIMER0 como TemporizadorMOVWF OPTION_REG ; y con preescalar de 256.

BCF STATUS,RP0 ; Selecciono la pagina 0 de la memoriaCLRF PORTB ; Apagar los LEDS del Puerto B.BSF PORTE,2 ; Habilitar los Led del PORTE.CLRF CONTADOR ; Limpiar CONTADOR.MOVLW TABLAD ; Cargar el Puntero con TABLAD.MOVWF FSR

;*************************** Principal ************************************************************************

SEGUIR MOVF CONTADOR,W ;Cargar el CONTADOR en el Acumulador.

CALL TABLA ;Devuelve en el Acumulador un Dato.

MOVWF INDF ;Cargar el Acumulador donde apunta el puntero FSR.MOVWF PORTB ;Cargar el Acumulador en el PORTB.

MOVLW TIEMPO2 ;Cargar en el registro CONT_TI el dato TIEMPO2.MOVWF CONT_TI

SEG2 CALL TIEMPO ;Llamar a la subrutina de TIEMPO.DECFSZ CONT_TI,F ;Se decrementa CONT_TI si CONT_TI<>0 ir a SEG2.GOTO SEG2

INCF FSR ;Incrementar el puntero FSR.INCF CONTADOR ;Incrementar el CONTADOR.

MOVF CONTADOR,W ;Si CONTADOR <> NDATOS ir a SEGUIR.XORLW NDATOSBTFSC STATUS,ZGOTO $ ;Parar.GOTO SEGUIR

;***************************** Subrutina de Tabla ***************************************************************

70

Page 77: Entren Adores

TABLA ADDWF PCL,F ;Suma el Contador del Programa con el contenido de W y lo deja en el PC.RETLW 01H ;Retorna con W cargado con 01HRETLW 02H ;Retorna con W cargado con 02HRETLW 04H ;Retorna con W cargado con 04HRETLW 08H ;Retorna con W cargado con 08HRETLW 04H ;Retorna con W cargado con 04HRETLW 02H ;Retorna con W cargado con 02H

;***************************** Subrutina de Tiempo **********************************************************

TIEMPO MOVLW TIEMPO1 ;Cargar el dato TIEMPO1 en el registro TMR0

MOVWF TMR0SEG1 BTFSS INTCON,T0IF ;Si el flag T0IF <> 1 ir a SEG1

GOTO SEG1BCF INTCON,T0IF ;Borrar flag T0IFRETURN

END

5.5.- Ejemp_14.asm ( Entrenador Básico 3 )

Diagrama de Flujo

Detectar el número mayor de una tabla de datos

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

N_DATOS = D’5’ ; Asignamos el Número de datos de la tabla

; Registros

CBLOCK 0X20

DIGITO MAYOR REGISTRO

ENDC

1

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

1

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1 TRISB 00000000 B ; Poner Puerto B como salida

de dato ADCON1 00000110 B ; Seleccionar PORTA y PORTE como entrada digitales. TRISE 00000000 B ; Poner Puerto E como salida de dato

RP0 0 ; Ir al Banco 0

PORTB 00000000 B ;Apagar Leds del PUERTO B PORTE(2) 1 ;Habilitar los Leds del Puerto B

2

2

;Resetear el registro DIGITO

DIGITO 00000000 B

;Cargar el contenido del registro DIGITO en W.

W DIGITO

;Cargar datos de la subrutina TABLA

;Subrutina que detecta el número mayor

DE_MAYOR

;Incrementar el registro DIGITO

DIGITO DIGITO +1

¿ N_DATOS = 0 ?

;Decrementar el registro N_DATOS

N_DATOS N_DATOS - 1

;Sacar el número mayor a el Puerto B

PORTB MAYOR

FIN

SI

NOSubrutina de TABLA

PCL PCL + W

RETLW 3FH ;Retorna con W cargado con 3FHRETLW 06H ;Retorna con W cargado con 06HRETLW 5BH ;Retorna con W cargado con 5BHRETLW 4FH ;Retorna con W cargado con 4FHRETLW 06H ;Retorna con W cargado con 66H

71

Page 78: Entren Adores

title " Detectar el numero mayor de una Tabla "

Subrutina de detectar el número mayor de una tabla

DE_MAYOR

¿ REGISTRO >

RETURN

MAYOR REGISTRO

SI

NO

72

Page 79: Entren Adores

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;************ Asignación de etiquetas de Registros de Funciones especiales a direcciones ************

#include <p16f877.inc> ; Este fichero contiene los nombres y direcciones de los ; registros de funciones especiales.

; Este fichero esta localizado en el directorio ; con el nombre MPASM.

;**************************** Igualdades ***********************************************************************

N_DATOS EQU D'5' ; Asignamos el Numero de Datos.

;**************************** Registros ************************************************************************

CBLOCK 0X20

DIGITO ; Creamos un registro llamado DIGITO en la dirección 20h; de memoria de datos.

MAYOR ; Creamos un registro llamado MAYOR en la dirección 21h; de memoria de datos.

REGISTRO ; Creamos un registro llamado REGISTRO1 en la dirección 22h; de memoria de datos.

ENDC

;**************************** Sección Código de Reset *******************************************************

ORG 00h ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración *******************************************************

ORG 05h ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP0 ; Selecciono la pagina 1 de la memoriaCLRF TRISB ; Configuro el Puerto B como salidaMOVLW B’00000110’ ; Selecciono PORTA y PORTE como entrada digitalesMOVWF ADCON1CLRF TRISE

BCF STATUS,RP0 ; Selecciono la pagina 0 de la memoriaCLRF PORTB ; Limpiar Puerto B.BSF PORTE,2

;*************************** Principal ****************************************************************************

RESET CLRF DIGITO ;Comienzo contador con el numero digito = 0.

SEGUIR MOVF DIGITO,W ;Cargo el contenido de DIGITO en W.

73

Page 80: Entren Adores

CALL TABLA ;Llamo a la subrutina de cargar datos de la TABLA.CALL DE_MAYOR ;Detecta el número mayor.

INCF DIGITO,F ;Incremento el contenido del registroMOVF DIGITO,W ;Cargamos el contenido del Registro DIGITO a WXORLW N_DATOS ;Hacemos una XOR para afectar el flag ZBTFSS STATUS,Z ;Preguntamos si Z es igual a 1, si cumple salta la siguiente

instrucción.GOTO SEGUIR ;Va a SEGUIR

MOVF MAYOR,WMOVWF PORTB ;Saca el valor Mayor Puerto B.

PARAR GOTO PARAR

;***************************** TABLA ****************************************************************************

TABLA ADDWF PCL,F ;Suma el Contador del Programa con el contenido de W y lo deja en el PC.

RETLW 3FH ;Retorna con W cargado con 3FHRETLW 06H ;Retorna con W cargado con 06HRETLW 5BH ;Retorna con W cargado con 5BHRETLW 4FH ;Retorna con W cargado con 4FHRETLW 06H ;Retorna con W cargado con 66H

;***************************** Detectar Mayor ********************************************************************

DE_MAYOR MOVWF REGISTROSUBWF MAYOR,W ; W F-W ( Si F >= W el BIT de carry C=0

y si F < W el BIT de carry C=1 )BTFSC STATUS,CGOTO RETORNOMOVF REGISTRO,WMOVWF MAYOR

RETORNO RETURN

END

74

Page 81: Entren Adores

6.- Entrenador Básico 4

75

Page 82: Entren Adores

6.1.- T_S_A.asm ( Entrenador Básico 4 )

Diagrama de Flujo

Transmisión Serie Asíncrona

Elegimos PICList p=16f876 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f876.inc>

; Igualdades

NUMERO_TRANSMISIONES = D’5’

; Registros

CBLOCK 0X20

CONTADORDATO_ANTERIOR

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1 TRISB 11111111 B ; Poner Puerto B como entrada

de dato SPBRG D’10’ ; Cargar la velocidad de transmisión

de datos Baud Rate = Fosc/(64(X+1))Baud Rate = 1MHz/(64(10+1)) =1420 BIT por segundo

TXSTA 00100000 B ; Configuración de la transmisión

serie de datos (Modo Asíncrono y baja velocidad.

RP0 0 ; Ir al Banco 0

SPEN 1 ;Activamos la Puerta Serie (TX)

1

1

; Lanzar 5 veces la transmisión serie

CONTADOR NUMERO_TRANSMISIONES

; Leer los datos del PORTB

DATO_ANTERIOR PORTB

;Comienzo de la transmisión de los datos serie

TXREG PORTB

¿ Ha terminado la transmisión ?

¿ TRMT = 1 ?

; Decrementamos CONTADOR

CONTADOR CONTADOR -1

¿ CONTADOR = 0 ?

Si el PORTB no cambia

no se transmite

¿ PORTB = DATO_ANTERIOR ?

SI

SI

NO

NO

NO

SI

76

Page 83: Entren Adores

title " Transmisor SERIE asíncrona ";************ Leer el Puerto B y transmitirlo vía SERIE ***********************************************

;Programa para PIC 16F876.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250KHz = 4uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC **************************************************************

list p=16f876, f=inhx32

;********** Asignación de etiquetas de Registros de Funciones especiales a direcciones ********

#include <p16f876.inc> ; Este fichero contiene los nombres y direcciones de los ; registros de funciones especiales.

; Este fichero esta localizado en el directorio ; con el nombre MPASM.

;***************************** Igualdades ***************************************************************

NUMERO_TRANSMISIONES EQU D'05'

;***************************** Registros *****************************************************************

CBLOCK 0X20

CONTADOR DATO_ANTERIOR

ENDC

;**************************** Sección Código de Reset ***********************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración ***********************************************

ORG 0X05 ; Inicio de Programa ;(Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP0 ;Banco 1

MOVLW B'11111111' ; Poner el Puerto B como entrada de Datos MOVWF TRISB

MOVLW 0X0A MOVWF SPBRG ; Cargar la Velocidad de Transmisión de Datos.

MOVLW B'00100000'

77

Page 84: Entren Adores

MOVWF TXSTA ; Configuración de la Transmisión Serie.

BCF STATUS,RP0 BSF RCSTA,SPEN ;Activamos la Puerta Serie (TX).

;*************************** Principal *********************************************************************

SEG0 MOVLW NUMERO_TRANSMISIONES ; Lanzar 5 veces la transmisión serie.MOVWF CONTADOR

SEG1 MOVF PORTB,W ; Leer los datos del PORTBMOVWF DATO_ANTERIORMOVWF TXREG ; Comienzo de la transmisión de datos en Serie.BSF STATUS,RP0

SEG2 BTFSS TXSTA,TRMT ; Preguntamos si se ha transmitido el dato.GOTO SEG2BCF STATUS,RP0

DECFSZ CONTADOR,F ; Decrementamos CONTADOR y si es 0 salta una GOTO SEG1 ; instrucción.

SEG3 MOVF PORTB,W ; Si el PORTB no cambia no se transmite.SUBWF DATO_ANTERIOR,WBTFSC STATUS,ZGOTO SEG3 GOTO SEG0

END

78

Page 85: Entren Adores

6.2.- R_S_A.asm ( Entrenador Básico 4 )

Diagrama de Flujo

Recepción Serie Asíncrona( 8 BIT )

Elegimos PICList p=16f876 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f876.inc>

; Igualdades

; Registros

CBLOCK 0X20

DATOW_TEMPSTATUS_TEMP ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

1

Vector de Interrupción

ORG 04HGOTO INTERRU

Rutina de InterrupciónINTERRU

¿ RCIF = 1?

; Salvar Registros

W_TEMP W STATUS_TEMP STATUS

RETFIE

; Cargar el dato recibido en el registro RCREG en el

registro DATO

DATO RCREG

NO

SI

; Recuperar Registros

STATUS STATUS_TEMPW W_TEMP

; Borrar Flag de la recepción

RCIF 0

RETFIE

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1 TRISB 00000000 B ; Poner Puerto B como salida

de dato BRGH 0 ;Trabajar con velocidad baja de

recepción. SPBRG D’10’ ; Cargar la velocidad de transmisión

de datos Baud Rate = Fosc/(64(X+1))Baud Rate = 1MHz/(64(10+1)) =1420 BIT por segundo

SYNC 0 ; Habilitamos la recepción asíncrona.

INTCON 11000000 B ; Habilitar la Interrupción serie PIE1 00100000 B ; Habilitar la Interrupción serie

RP0 0 ; Ir al Banco 0

RCSTA 10010000 B ; Configurar y lanzar la recepción serie (Habilitar puerto serie, 8 BIT y

recepción continua).

1

; Cargar el registro DATO en el PORTB

PORTB DATO

79

Page 86: Entren Adores

title " Receptor SERIE asíncrona ";Programa para PIC 16F876a.;Velocidad del Reloj = 1 MHz.;Reloj instrucción: 250 kHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ****************************************************************

list p=16f876, f=inhx32

;********* Asignación de etiquetas de Registros de Funciones especiales a direcciones ************

#include <p16f876.inc> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades *******************************************************************

;***************************** Registros ********************************************************************

CBLOCK 0X20

DATO

W_TEMP ;Registro de salvaguarda de la Rutina de Interr.STATUS_TEMP

ENDC

;**************************** Sección Código de Reset ***************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de Interrupción *******************************************************

ORG 0X04

GOTO INTERRU ;Vector de Interrupción.

;**************************** Sección de Configuración ***************************************************

ORG 0X05 ;Inicio de Programa ;(Una posición detrás del vector de Interrupción).

COMIENZO BSF STATUS,RP0 ; Banco 1BCF STATUS,RP1CLRF TRISBBCF TXSTA,BRGH ;Trabajar con velocidad baja de recepción.

MOVLW 0X0A ; Cargar la Velocidad de Recepción de Datos. MOVWF SPBRG BCF TXSTA,SYNC ; Habilitamos la recepción asíncrona.

80

Page 87: Entren Adores

MOVLW B'11000000' ;Habilitar Interrupción SerieMOVWF INTCONMOVLW B'00100000' ;Habilitar Interrupción SerieMOVWF PIE1

BCF STATUS,RP0MOVLW B'10010000' ;Configurar y lanzar la Recepción Serie MOVWF RCSTA

;*************************** Principal *********************************************************************** PRINCIPAL COMF DATO,W

MOVWF PORTB

GOTO PRINCIPAL

;**************************** Rutina de Interrupción ******************************************************

ORG 40

INTERRU BTFSS PIR1,RCIF ; Detectamos si ha interrumpido la Recepción Serie.RETFIE

SALVAR MOVWF W_TEMP ; Salvamos RegistrosSWAPF STATUS,WMOVWF STATUS_TEMP

MOVF RCREG,W ;Cargamos el dato del registro RCREG en el registro DATO.MOVWF DATO

RECUPERAR SWAPF STATUS_TEMP,W ;Recuperamos Registros.MOVWF STATUS SWAPF W_TEMP,FSWAPF W_TEMP,W

BCF PIR1,RCIF ;Borrar flag de recepción

RETFIE ;Retorno de Interrupción.

END

81

Page 88: Entren Adores

6.3.- T1_S_RF.asm ( Entrenador Básico 4 )

Diagrama de Flujo

Transmisión Serie AsíncronaUtilizando la Librería de

Elegimos PICList p=16f876 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f876.inc>

; Igualdades

; Registros

CBLOCK 0X20

DATO_ANTERIOR

ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

1

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1 TRISB 11111111 B ; Poner Puerto B como entrada

de dato RP0 0 ; Ir al Banco 0

CONFIGURACION_TRANS_SERIE

1

; Leer PORTB

W PORTB

LANZAR_DATO_SERIE

Si el PORTB no cambia

no se transmite

¿ PORTB = DATO_ANTERIOR ?

SINO

; Guardar el PORTB en un registro

DATO_ANTERIOR PORTB

82

Page 89: Entren Adores

title " Transmisor SERIE asíncrona utilizando Librería de Transmisión T_S_RF.INC "

;************ Leer el Puerto B y transmitirlo vía SERIE ***************************************************

;Programa para PIC 16F876.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250KHz = 4uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ******************************************************************

list p=16f876, f=inhx32

;********** Asignación de etiquetas de Registros de Funciones especiales a direcciones ************

#include <p16f876.inc> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;***************************** Igualdades ********************************************************************

;***************************** Registros **********************************************************************

CBLOCK 0X20

DATO_ANTERIOR

ENDC

;**************************** Sección Código de Reset *****************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuración ******************************************************

ORG 0X05 ; Inicio de Programa ;(Una posición detrás del vector de Interrupción)

COMIENZO BSF STATUS,RP0 ; Ir al banco 1MOVLW B'11111111' ; Poner el Puerto B como entrada de Datos

MOVWF TRISBBCF STATUS,RP0 ; Ir al banco 0

CALL CONFIGURACION_TRANS_SERIE

;*************************** Principal **************************************************************************

SEG1 MOVF PORTB,W ;Leer PORTBMOVWF DATO_ANTERIOR

83

Page 90: Entren Adores

CALL LANZAR_DATO_SERIE

SEG2 MOVF PORTB,W ;Si el PORTB no cambia no se transmite.SUBWF DATO_ANTERIOR,WBTFSC STATUS,ZGOTO SEG2 GOTO SEG1

;*************************** Librerías **************************************************************************INCLUDE <T_S_RF.INC>

END

6.4.- RE1_S_RF.asm ( Entrenador Básico 4 )

Diagrama de Flujo

Recepción Serie AsíncronaUtilizando la Librería de Recepción R_S_RF.INC

Elegimos PICList p=16f876 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f876.inc>

; Igualdades

; Registros

CBLOCK 0X20W_TEMPSTATUS_TEMPENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

1

Vector de Interrupción

ORG 04HGOTO INTERRU

Sección de Configuración ORG 0X05H

COMIENZO RP0 1 ; Ir al Banco 1

TRISB 00000000 B ; Poner Puerto B como salida de dato

RP0 0 ; Ir al Banco 0

1

CONFIGURACION_RECEP_SERIE

; Cargar el registro DATO en el PORTB

PORTB DATO_SERIE_VALIDO

Rutina de InterrupciónINTERRU

¿ RCIF = 1?

; Salvar Registros

W_TEMP W STATUS_TEMP STATUS

RETFIE

NO

SI

; Recuperar Registros

STATUS STATUS_TEMPW W_TEMP

RETFIE

El Dato se queda cargado en el registro DATO_SERIE_VALIDO

RECEPCION_DATO_SERIE

84

Page 91: Entren Adores

title " Receptor SERIE asíncrona utilizando Librería de Recepción R_S_RF.INC "

;Programa para PIC 16F876a.;Velocidad del Reloj = 1 MHz.;Reloj instrucción: 250 kHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;**************************** Elegimos PIC ******************************************************************

list p=16f876, f=inhx32

;*************** Asignación de etiquetas de Registros de Funciones especiales a direcciones *******

#include <p16f876.inc> ; Este fichero contiene los nombres y direcciones de los ; registros de funciones especiales.

; Este fichero esta localizado en el directorio ; con el nombre MPASM.

;**************************** Igualdades ********************************************************************

;***************************** Registros *********************************************************************

CBLOCK 0X20

W_TEMP ; Registro de salvaguarda de la Rutina de Interr.STATUS_TEMP

ENDC

;**************************** Sección Código de Reset ****************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de Interrupción *******************************************************

ORG 0X04

GOTO INTERRUPCION ;Vector de Interrupción.

;**************************** Sección de Configuración ***************************************************

ORG 0X05 ;Inicio de Programa ;(Una posición detrás del vector de Interrupción).

COMIENZO BSF STATUS,RP0 ;Configuramos el PORTB como salida de datos.CLRF TRISBBCF STATUS,RP0

CALL CONFIGURACION_RECEP_SERIE

85

Page 92: Entren Adores

;*************************** Principal ************************************************************************ PRINCIPAL COMF DATO_SERIE_VALIDO,W

MOVWF PORTB

GOTO PRINCIPAL

;**************************** Rutina de Interrupción *******************************************************

INTERRUPCION BTFSS PIR1,RCIF ; Detectamos si ha interrumpido la Recepción Serie.RETFIE

SALVAR MOVWF W_TEMP ; Salvamos RegistrosSWAPF STATUS,WMOVWF STATUS_TEMP

CALL RECEPCION_DATO_SERIE ; El Dato se queda cargado en DATO_SERIE_VALIDO RECUPERAR SWAPF STATUS_TEMP,W ;Recuperamos Registros.

MOVWF STATUS SWAPF W_TEMP,FSWAPF W_TEMP,W

RETFIE ;Retorno de Interrupción.

;***************************** Librerias **********************************************************************

INCLUDE <R_S_RF.INC>

END

86

Page 93: Entren Adores

6.5.- T_S_RF.INC ( Entrenador Básico 4 )

Diagrama de Flujo

Librería de Transmisión de datos(Carga en el W el dato a transmitir)

(Tiene una llave de entrada asociada)

T_S_RF.INC

; Igualdades

TODOCERO = 00000000 BLLAVE_ENTRADA = 01011010 B

; Registros

CBLOCK

DATO_TRANSMITIDOCONTADOR_TRANSMISIÓN

ENDC

;Sección de Configuración

CONFIGURACION_TRANS_SERIE RPO 1 ; Ir al Banco 1

SPBRG 0X0A ; Cargar la Velocidad de Transmisión de Datos

Baud Rate = Fosc/(64(X+1))Baud Rate = 1MHz/(64(10+1)) = 1420 BIT por segundo

TXSTA 00100000 B ; Configuración de la transmisión

serie de datos (Modo Asíncrono y baja velocidad.

RP0 0 ; Ir al Banco 0

SPEN 1 ;Activamos la Puerta Serie (TX)

RETURN

1

87

Page 94: Entren Adores

1

LANZAR_DATO_SERIE DATO _ TRANSMITIDO W

; Cargar el número de transmisión

CONTADOR_TRANSMISIÓN D’10’

; Lanzar TODOCERO

TXREG #TODOCERO

¿ Ha terminado la transmisión ?

¿ TRMT = 1 ?

SI

NO

; Lanzar LLAVE_ENTRADA

TXREG #LLAVE_ENTRADA

¿ Ha terminado la transmisión ?

¿ TRMT = 1 ?

NO

SI

; Lanzar DATO_TRANSMITIDO

TXREG #DATO_TRANSMITIDO

¿ Ha terminado la transmisión ?

¿ TRMT = 1 ?

SINO

; Decrementar el registro CONTADOR_TRANSMISION

CONTADOR_TRANSMISION CONTADOR_TRANSMISIÓN - 1

¿ CONTADOR_TRANSMISIÓN = 0 ?

RETURN

NO

SI

88

Page 95: Entren Adores

; Librería Transmisor SERIE vía Radiofrecuencia para una Tarjeta; Emisora SAW para Datos 433,92 MHz. ( CEBEK C-0503 ); Llave fija; Cargar en W el dato a transmitir;***************************** Igualdades *********************************************************************

TODOCERO EQU B'00000000' ;(Dato). Llave para iniciar un código, la tarjeta de; transmisión de datos necesita el pulso de STOP para; transmitir un código.

LLAVE_ENTRADA EQU B'01011010' ;(Dato). Llave Común.

;***************************** Registros ***********************************************************************CBLOCK

DATO_TRANSMITIDO CONTADOR_TRANSMISION

ENDC

;**************************** Sección de Configuración *****************************************************

CONFIGURACION_TRANS_SERIE BCF STATUS,RP1 ; Ir al Banco 1.BSF STATUS,RP0

MOVLW 0X0A MOVWF SPBRG ; Cargar la Velocidad de Transmisión de

Datos.

MOVLW B'00100000'MOVWF TXSTA ; Configuración de la Transmisión Serie.

BCF STATUS,RP0 ; Ir al Banco 0.BCF STATUS,RP1

BSF RCSTA,SPEN ;Activamos la Puerta Serie (TX).

RETURN ;*************************** Lanzar Llaves y Muestra Digital *********************************************** LANZAR_DATO_SERIE MOVWF DATO_TRANSMITIDO

MOVLW d'10' MOVWF CONTADOR_TRANSMISION

MOVLW TODOCERO ;Lanzar llave TODOCERO.MOVWF TXREG ;Transmisión de Datos en Serie.BSF STATUS,RP0

SEG1_TRANSMISION BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato.GOTO SEG1_TRANSMISION

REPETIR_TRANSMISION BCF STATUS,RP0 ;Lanzar llave LLAVE_ENTRADA.MOVLW LLAVE_ENTRADAMOVWF TXREG ;Transmisión de Datos en Serie.

89

Page 96: Entren Adores

BSF STATUS,RP0SEG2_TRANSMISION BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato.

GOTO SEG2_TRANSMISIONBCF STATUS,RP0 ;Lanzar DATO_TRANSMITIDO.MOVF DATO_TRANSMITIDO,WMOVWF TXREG ;Transmisión de Datos en Serie.BSF STATUS,RP0

SEG3_TRANSMISION BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato.GOTO SEG3_TRANSMISION

BCF STATUS,RP0DECFSZ CONTADOR_TRANSMISION,FGOTO REPETIR_TRANSMISION

RETURN

6.6.- R_S _RF.INC ( Entrenador Básico 4 )

Diagrama de Flujo R_S_RF.INC

; Igualdades

LLAVE_ENTRADA = B'01011010' ; Llave Común.

; Registros

CBLOCK

DATO_SERIE1DATO_SERIE2DATO_SERIE_VALIDO

ENDC

Sección de Configuración

CONFIGURACION_RECEP_SERIE RP0 1 ; Ir al Banco 1

BRGH 0 ;Trabajar con velocidad baja de recepción.

SPBRG D’10’ ; Cargar la velocidad de Transmisión de datos

Baud Rate = Fosc/(64(X+1))Baud Rate = 1MHz/(64(10+1)) =1420 BIT por segundo

SYNC 0 ; Habilitamos la recepción

asíncrona.

INTCON 11000000 B ; Habilitar la Interrupción serie PIE1 00100000 B ; Habilitar la Interrupción serie

RP0 0 ; Ir al Banco 0

RCSTA 10010000 B ; Configurar y lanzar la recepción serie (Habilitar puerto serie, 8 BIT y

recepción continua).

RETURN

1 90

Page 97: Entren Adores

SI

;Validamos los datos recibidos

DATO_SERIE_VALIDO DATO_SERIE1

RETURN

;Borramos flag de Recepción

RCIF 0

; Guardamos el dato segundo

DATO_SERIE2 RCREG

¿ Son iguales los datos recibidos ?

¿ DATO_SERIE1 =

DATO_SERIE2 ?

¿ Ha llegado un

nuevo dato ?

¿ RCIF = 1 ?

SI

; Guardamos el dato primero

DATO_SERIE1 RCREG

; Borramos flag de Recepción

RCIF 0

¿ Ha llegado la llave de entrada ?

¿ RCREG =

; Borramos flag de Recepción

RCIF 0

SI

1

¿ Ha llegado la llave de entrada ?

¿ W = LLAVE_ENTRADA ?

; Borramos flag de Recepción

RCIF 0

¿ Ha llegado un

nuevo dato ?

¿ RCIF = 1 ?

SI

NO

NO

NO

NO

SI

NO

RECEPCION_DATO_SERIE W RCREG

91

Page 98: Entren Adores

; Librería Receptor SERIE vía Radiofrecuencia para una Tarjeta Emisora ; SAW para Datos 433,92 MHz. ( CEBEK C-0504 ); Llave de entrada fija.; Los datos se validan si llegan dos datos idénticos consecutivos.; El dato recibido se carga en el registro DATO_SERIE_VALIDO

; Esta configurada la Interrupción en Recepción Serie. Es necesario cargar el Vector de interrupción

; ORG 0X04; GOTO INTERRUPCION

; La Subrutina de Recepción Serie devuelve el dato valido en el Registro DATO_SERIE_VALIDO

;**************************** Igualdades *************************************************************************

LLAVE_ENTRADA EQU B'01011010' ;(Dato). Llave Común.

;**************************** Registros****************************************************************************

CBLOCK

DATO_SERIE1DATO_SERIE2DATO_SERIE_VALIDO

ENDC

;**************************** Sección de Configuración *********************************************************

CONFIGURACION_RECEP_SERIE BSF STATUS,RP0 ; Banco 1

BCF STATUS,RP1

BCF TXSTA,BRGH ;Trabajar con velocidad baja de recepción. MOVLW 0X0A ; Cargar la Velocidad de Recepción

de Datos. MOVWF SPBRG

BCF TXSTA,SYNC

MOVLW B'11000000' ;Habilitar Interrupción SerieMOVWF INTCON

MOVLW B'00100000' ;Habilitar Interrupción SerieMOVWF PIE1

BCF STATUS,RP0 ; Banco 0BCF STATUS,RP1

MOVLW B'10010000' ;Configurar y lanzar la Recepción Serie MOVWF RCSTA

RETURN

92

Page 99: Entren Adores

;****************************** Subrutina de Recepción Serie *********************************************

;Tiene que estar dentro de la Rutina de INTERRUPCION

RECEPCION_DATO_SERIE MOVF RCREG,W ;Preguntamos si ha llegado la Llave "LLAVE_ENTRADA".

XORLW LLAVE_ENTRADABTFSS STATUS,Z ;Si es correcta la Llave volvemos a

preguntar.GOTO SALIR _ SERIE ;No es correcta la Llave volvemos al PP

previa recuperación de registros.

BCF PIR1,RCIF ;Borramos Flag de la Recepción.NO_DATO_SERIE1 BTFSS PIR1,RCIF ;Preguntamos si hemos recibido una nuevo

DATO.GOTO NO_DATO_SERIE1MOVF RCREG,WMOVWF DATO_SERIE1 ;Guardamos el Dato Primero

BCF PIR1,RCIF ;Borramos Flag de la Recepción.NO_LLAVE_ENTRADA BTFSS PIR1,RCIF ;Preguntamos si ha llegado la Llave

"LLAVE_ENTRADA".GOTO NO_LLAVE_ENTRADAMOVF RCREG,W ;Preguntamos si ha llegado la Llave

"LLAVE_ENTRADA".XORLW LLAVE_ENTRADABTFSS STATUS,Z ;Si es correcta la Llave volvemos a

preguntar.GOTO SALIR _ SERIE ;No es correcta la Llave volvemos al PP

previa recuperación de registros.

BCF PIR1,RCIF ;Borramos Flag de la Recepción.NO_DATO_SERIE2 BTFSS PIR1,RCIF ;Preguntamos si hemos recibido una nuevo

DATO.GOTO NO_DATO_SERIE2MOVF RCREG,WMOVWF DATO_SERIE2 ;Guardamos el Dato Segundo

MOVF DATO_SERIE1,W ;Si ambos datos son Iguales validamos el dato serie recibido.

SUBWF DATO_SERIE2,FBTFSS STATUS,ZGOTO SALIR _ SERIE

VALIDAR_DATO_SERIE MOVF DATO_SERIE1,WMOVWF DATO_SERIE_VALIDO ; El Dato se queda cargado en el Registro

DATO_SERIE_VALIDO SALIR_SERIE BCF PIR1,RCIF

RETURN

END

93

Page 100: Entren Adores

6.7.- T_M_S_RF.INC ( Entrenador Básico 4 )

Diagrama de Flujo

Librería de Transmisión de datos(Carga en el W el dato a transmitir)

(Cargar la llave de entrada en el registro LLAVE_ENTRADA)

; Igualdades

TODOCERO = 00000000 B

; Registros

CBLOCK

DATO_TRANSMITIDOCONTADOR_TRANSMISIÓNLLAVE-ENTRADA

ENDC

;Sección de Configuración

CONFIGURACION_TRANS_SERIE RPO 1 ; Ir al Banco 1

SPBRG D’39’ ; Cargar la Velocidad de Transmisión de Datos

Baud Rate = Fosc/(64(X+1))Baud Rate = 1MHz/(64(39+1)) = 1562,5 BIT por segundo

TXSTA 00100000 B ; Configuración de la transmisión

serie de datos (Modo Asíncrono y baja velocidad.

RP0 0 ; Ir al Banco 0

SPEN 1 ;Activamos la Puerta Serie (TX)

RETURN

1

94

Page 101: Entren Adores

1

LANZAR_DATO_SERIE DATO _ TRANSMITIDO W

; Cargar el número de transmisión

CONTADOR_TRANSMISIÓN D’10’

; Lanzar TODOCERO

TXREG #TODOCERO

¿ Ha terminado la transmisión ?

¿ TRMT = 1 ?

SI

NO

; Lanzar LLAVE_ENTRADA

TXREG #LLAVE_ENTRADA

¿ Ha terminado la transmisión ?

¿ TRMT = 1 ?

NO

SI

; Lanzar DATO_TRANSMITIDO

TXREG #DATO_TRANSMITIDO

¿ Ha terminado la transmisión ?

¿ TRMT = 1 ?

SINO

; Decrementar el registro CONTADOR_TRANSMISION

CONTADOR_TRANSMISION CONTADOR_TRANSMISIÓN - 1

¿ CONTADOR_TRANSMISIÓN = 0 ?

RETURN

NO

SI

95

Page 102: Entren Adores

; Librería de Transmisor SERIE vía Radiofrecuencia para una Tarjeta ; Emisora SAW para Datos 433,92 MHz. ( CEBEK C-0503 ) ; Cargar la llave de entrada en el registro LLAVE_ENTRADA; Cargar en W el dato a transmitir

;***************************** Igualdades ****************************************************************

TODOCERO EQU B'00000000' ;(Dato). Llave para iniciar un código, la tarjeta de; transmisión de datos necesita el pulso de STOP para; transmitir un código.

;***************************** Registros *******************************************************************

CBLOCK

DATO_TRANSMITIDO CONTADOR_TRANSMISIONLLAVE_ENTRADA

ENDC

;**************************** Sección de Configuración *************************************************

CONFIGURACION_TRANS_SERIE BCF STATUS,RP1 ; Ir al Banco 1.BSF STATUS,RP0

MOVLW D'39' MOVWF SPBRG ; Cargar la Velocidad de Transmisión de

Datos. ; BR = (Fosc/64(X+1)) BR = (4MHz/64(39+1)) = 1562,5 Hz

MOVLW B'00100000'MOVWF TXSTA ; Configuración de la Transmisión Serie.

BCF STATUS,RP0 ; Ir al Banco 0.BCF STATUS,RP1

BSF RCSTA,SPEN ;Activamos la Puerta Serie (TX).

RETURN

;*************************** Lanzar Llaves y Muestra Digital ****************************************** LANZAR_DATO_SERIE MOVWF DATO_TRANSMITIDO

MOVLW d'10' MOVWF CONTADOR_TRANSMISION

MOVLW TODOCERO ;Lanzar llave TODOCERO.MOVWF TXREG ;Transmisión de Datos en Serie.BSF STATUS,RP0

SEG1_TRANSMISION BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato.GOTO SEG1_TRANSMISION

96

Page 103: Entren Adores

REPETIR_TRANSMISION BCF STATUS,RP0 ;Lanzar llave LLAVE_ENTRADA.MOVF LLAVE_ENTRADA,WMOVWF TXREG ;Transmisión de Datos en Serie.BSF STATUS,RP0

SEG2_TRANSMISION BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato.GOTO SEG2_TRANSMISION

BCF STATUS,RP0 ;Lanzar DATO_TRANSMITIDO.MOVF DATO_TRANSMITIDO,WMOVWF TXREG ;Transmisión de Datos en Serie.BSF STATUS,RP0

SEG3_TRANSMISION BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato.GOTO SEG3_TRANSMISION

BCF STATUS,RP0DECFSZ CONTADOR_TRANSMISION,FGOTO REPETIR_TRANSMISION

RETURN

97

Page 104: Entren Adores

6.8.- R_M_S_RF.INC ( Entrenador Básico 4 )

Diagrama de Flujo

R_S_M_RF.INC

; Igualdades

; Registros

CBLOCK

DATO_SERIE1DATO_SERIE2DATO_SERIE_VALIDOLLAVE_ENTRADA

ENDC

Sección de Configuración

CONFIGURACION_RECEP_SERIE RP0 1 ; Ir al Banco 1

BRGH 0 ;Trabajar con velocidad baja de recepción.

SPBRG D’39’ ; Cargar la velocidad de Transmisión de datos

Baud Rate = Fosc/(64(X+1))Baud Rate = 1MHz/(64(39+1)) = 1562,5 BIT por segundo

SYNC 0 ; Habilitamos la recepción asíncrona.

INTCON 11000000 B ; Habilitar la Interrupción serie PIE1 00100000 B ; Habilitar la Interrupción serie

RP0 0 ; Ir al Banco 0

RCSTA 10010000 B ; Configurar y lanzar la recepción serie (Habilitar puerto serie, 8 BIT y

recepción continua).

RETURN

1

98

Page 105: Entren Adores

SI

;Validamos los datos recibidos

DATO_SERIE_VALIDO DATO_SERIE1

RETURN

;Borramos flag de Recepción

RCIF 0

; Guardamos el dato segundo

DATO_SERIE2 RCREG

¿ Son iguales los datos recibidos ?

¿ DATO_SERIE1 =

DATO_SERIE2 ?

¿ Ha llegado un

nuevo dato ?

¿ RCIF = 1 ?

SI

; Guardamos el dato primero

DATO_SERIE1 RCREG

; Borramos flag de Recepción

RCIF 0

¿ Ha llegado la llave de entrada ?

¿ RCREG =

; Borramos flag de Recepción

RCIF 0

SI

1

¿ Ha llegado un

nuevo dato ?

¿ RCIF = 1 ?

NO

NO

NO

SI

NO

RECEPCION_DATO_SERIE RCIF 0 ; Borramos flag de Recepción

99

Page 106: Entren Adores

; Librería Receptor SERIE vía Radiofrecuencia para una Tarjeta Emisora ; SAW para Datos 433,92 MHz. ( CEBEK C-0504 ); La Llave de entrada aleatoria.; Los datos se validan si llegan dos datos idénticos consecutivos.; El dato recibido se carga en el registro DATO_SERIE_VALIDO

; ;Si se reciben dos datos consecutivos se valida el dato.; Esta configurada la Interrupción en Recepción Serie. Es necesario cargar el Vector de interrupción

; ORG 0X04; GOTO INTERRUPCION

; Se pregunta primero en la rutina de interrupción serie que llave de entrada ha llegado y se carga la llave de entrada que corresponda. (Ejemplo Proyecto de Transmisión de datos)

; La Subrutina de Recepción Serie devuelve el dato valido en el Registro DATO_SERIE_VALIDO

;**************************** Igualdades ***********************************************************************

;**************************** Registros*************************************************************************CBLOCK

DATO_SERIE1DATO_SERIE2DATO_SERIE_VALIDOLLAVE_ENTRADA

ENDC

;**************************** Sección de Configuración ******************************************************

CONFIGURACION_RECEP_SERIE BSF STATUS,RP0 ; Banco 1BCF STATUS,RP1

BCF TXSTA,BRGH ;Trabajar con velocidad baja de recepción.

BSF TRISC,7 MOVLW D'39' ; Cargar la Velocidad de

Recepción de Datos. MOVWF SPBRG

BCF TXSTA,SYNC

MOVLW B'11000000' ;Habilitar Interrupción SerieMOVWF INTCON

MOVLW B'00100000' ;Habilitar Interrupción SerieMOVWF PIE1

BCF STATUS,RP0 ; Banco 0BCF STATUS,RP1

MOVLW B'10010000' ;Configurar y lanzar la Recepción Serie MOVWF RCSTA

RETURN

100

Page 107: Entren Adores

;****************************** Subrutina de Recepción Serie ********************************************************

;Tiene que estar dentro de la Rutina de INTERRUPCION

RECEPCION_DATO_SERIE BCF PIR1,RCIF ;Borramos Flag de la Recepción.

NO_DATO_SERIE1 BTFSS PIR1,RCIF ;Preguntamos si hemos recibido una nuevoDATO.

GOTO NO_DATO_SERIE1MOVF RCREG,WMOVWF DATO_SERIE1 ;Guardamos el Dato Primero

BCF PIR1,RCIF ;Borramos Flag de la Recepción.NO_LLAVE_ENTRADA BTFSS PIR1,RCIF ;Preguntamos si ha llegado la Llave

"LLAVE_ENTRADA".GOTO NO_LLAVE_ENTRADAMOVF RCREG,W ;Preguntamos si ha llegado la Llave

"LLAVE_ENTRADA".XORWF LLAVE_ENTRADA,WBTFSS STATUS,Z ;Si es correcta la Llave volvemos a

preguntar.GOTO SALIR_SERIE ;No es correcta la Llave volvemos al PP

previa recuperación de registros.

BCF PIR1,RCIF ;Borramos Flag de la Recepción.NO_DATO_SERIE2 BTFSS PIR1,RCIF ;Preguntamos si hemos recibido una nuevo

DATO.GOTO NO_DATO_SERIE2MOVF RCREG,WMOVWF DATO_SERIE2 ;Guardamos el Dato Segundo

MOVF DATO_SERIE1,W ;Si ambos datos son Iguales validamos el dato serie recibido.

SUBWF DATO_SERIE2,FBTFSS STATUS,ZGOTO SALIR_SERIE

VALIDAR_DATO_SERIE MOVF DATO_SERIE1,WMOVWF DATO_SERIE_VALIDO ; El Dato se queda cargado en el

Registro DATO_SERIE_VALIDO SALIR_SERIE BCF PIR1,RCIF

RETURN

101

Page 108: Entren Adores

7.- Entrenador Básico 5

102

Page 109: Entren Adores

7.1.- Tecla0.asm ( Entrenador Básico 5 )

Diagrama de Flujo

Manejo del Teclado utilizando la técnica

de polling

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; Registros

CBLOCK 0x20ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de ConfiguraciónORG 0x05 ; Inicio de Programa

COMIENZO RP0 1 ; Ir al Banco 1 TRISC 00000000 B ; Poner el Puerto C como salida de datos. RP0 0 ; Ir al Banco 0

PORTC 00000000 B ; Limpiar el PORTC

; Configura las líneas del teclado.

Teclado_Inicializa

1

1

; Obtiene el valor hexadecimal de la tecla pulsada.

Teclado_LeeHex

¿Se ha pulsadoalguna tecla?

¿Cy = 1?

; Obtiene el valor hexadecimal de la tecla pulsada.

Teclado_LeeHex

RETURN

SI

NO

; Llevar el dato a el Puerto C.

PORTC W

103

Page 110: Entren Adores

title " Manejo del Teclado utilizando la técnica de polling ";Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;********************* Asignación de nombres de Registros de Funciones especiales a direcciones *************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ************************************************************************

CBLOCK 0x20ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0x00 ;Dirección del Vector ResetGOTO COMIENZO ;Comienzo del Programa

;*************************************** Sección de Configuración *****************************************************

ORG 5 ; Inicio de Programa

COMIENZO BCF STATUS,RP1 ; Ir al Banco 1BSF STATUS,RP0CLRF TRISC ; Poner el PORTC como salida de datos.BCF STATUS,RP0 ; Ir al Banco 0CLRF PORTC ; Limpiar el PORTCCALL Teclado_Inicializa ; Configura las líneas del teclado.

;************************************* Principal **************************************************************************

;SEG1 CALL Teclado_LeeOrdenTecla ; Obtiene el orden de la tecla pulsada.SEG1 CALL Teclado_LeeHex ; Obtiene el valor hexadecimal de la tecla pulsada.

BTFSS STATUS,C ; Preguntamos si se ha pulsado una tecla.GOTO SEG1MOVWF PORTC ; Llevar el dato a el Puerto C.CALL Teclado_EsperaDejePulsar ; Para que no se repita el mismo carácter

GOTO SEG1

;*********************************************** Librerías ****************************************************************

INCLUDE <TECLADO.INC>INCLUDE <RETARDOS.INC>END

104

Page 111: Entren Adores

7.2.- Tecl_01.asm ( Entrenador Básico 5 )

Diagrama de Flujo

Manejo del Teclado utilizando la técnica

de polling

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; Registros

CBLOCK 0x20ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

Sección de ConfiguraciónORG 0x05 ; Inicio de Programa

COMIENZO RP0 1 ; Ir al Banco 1 TRISC 00000000 B ; Poner el Puerto C como salida de datos. RP0 0 ; Ir al Banco 0

PORTC 00000000 B ; Limpiar el PORTC

INTCON 10001000 B ; Habilita la interrupción RBI y la general.

; Configura las líneas del teclado.

Teclado_Inicializa

ORG O4H ; Dirección del vector de InterrupciónGOTO INTERRUP

; Espera en modo bajo consumo que pulse teclado.

SLEEP

Rutina de Interrupción

INTERRUP

; Obtiene el valor hexadecimal de la tecla pulsada.

Teclado_LeeHex

; Obtiene el valor hexadecimal de la tecla pulsada.

Teclado_LeeHex

RETFIE

; Llevar el dato a el Puerto C.

PORTC W

; Limpia flag de la Interrupción.

RBIF 0

105

Page 112: Entren Adores

title " Manejo del Teclado utilizando la técnica de interrupción del programa principal ";***************************************************** Tecl_01.asm *****************************************************;; Los LEDS visualizan el valor hexadecimal de la tecla pulsada. Para la lectura del; teclado se utiliza la interrupción RBI o por cambio en las líneas <RB7:RB4> del Puerto B.;; **************************************************************************************************************************

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ************************************************************************

CBLOCK 0x20ENDC

;************************************** Sección Código de Reset ******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*************************************** Vector de Interrupción *********************************************************ORG 4

GOTO INTERRUP

;*********************************** Sección de Configuración *********************************************************ORG 5

COMIENZO BCF STATUS,RP1 ; Ir al Banco 1BSF STATUS,RP0CLRF TRISC ; Poner el PORTC como salida de datos.BCF STATUS,RP0 ; Ir al Banco 0CLRF PORTC ; Limpiar el Puerto CCALL Teclado_Inicializa ; Configura las líneas del teclado.MOVLW B'10001000' ; Habilita la interrupción RBI y la general.MOVWF INTCON

106

Page 113: Entren Adores

;************************************* Principal **************************************************************************

PRINCIPAL SLEEP ; Espera en modo bajo consumo que pulse teclado.GOTO PRINCIPAL

;************************************ Rutina de Interrupción ************************************************************

INTERRUP CALL Teclado_LeeHex ; Obtiene el valor hexadecimal de la tecla pulsada.MOVWF PORTC ; Llevar el Acumulador al Puerto C.CALL Teclado_EsperaDejePulsar ; Para que no se repita el mismo carácter

; mientras permanece pulsado.BCF INTCON,RBIF ; Limpia flag de la Interrupción.RETFIE

;*********************************************** Librerías ****************************************************************

INCLUDE <TECLADO.INC> ; Subrutinas de control del teclado.INCLUDE <RETARDOS.INC>

END

107

Page 114: Entren Adores

7.3.- Tecl_02.asm ( Entrenador Básico 5 )

Diagrama de FlujoManejo del Teclado utilizando la técnica

de polling

Elegimos PICList p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include <p16f877.inc>

; Igualdades

; Registros

CBLOCK 0x20ENDC

Sección de código de Reset

ORG OOH ; Dirección del vector de ResetGOTO COMIENZO ;Comienzo del Programa

ORG O4H ; Dirección del vector de InterrupciónGOTO INTERRUP

; Espera en modo bajo consumo que pulse teclado.

SLEEP

Sección de ConfiguraciónORG 0x05 ; Inicio de Programa

COMIENZO RP0 1 ; Ir al Banco 1 TRISC 00000000 B ; Poner el Puerto C como salida de datos.

ADCON1 00000111 B ; Habilitar el PORTE como señales digitales. TRISE 00000000 B ; Poner el Puerto E como salida de datos. TRISD 00000000 B ; Poner el Puerto D como salida de datos. RP0 0 ; Ir al Banco 0

PE0 1 ; Habilitar el display de las unidades. PORTC 00000000 B ; Limpiar el PORTC

INTCON 10001000 B ; Habilita la interrupción RBI y la general.

; Configura las líneas del teclado.

Teclado_Inicializa

Rutina de Interrupción

INTERRUP

; Obtiene el valor hexadecimal de la tecla pulsada.

Teclado_LeeHex

; Obtiene el valor hexadecimal de la tecla pulsada.

Teclado_LeeHex

RETFIE

; Llevar el dato a el Puerto C.

PORTC W

; Limpia flag de la Interrupción.

RBIF 0

; Transformar el código Hexadecimal en código de 7 segmentos.

HEX_7SEG

; Llevar el dato a el Puerto D.

PORTD W

108

Page 115: Entren Adores

title " Manejo del Teclado utilizando la técnica de interrupción del programa principal y llevando los datos al display de 7 segmentos";************************************** Tecl_02.asm ********************************************************************;; El display y los LEDS visualiza el valor hexadecimal de la tecla pulsada. Para la lectura del; teclado se utiliza la interrupción RBI o por cambio en las líneas <RB7:RB4> del Puerto B.

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

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ************************************************************************

CBLOCK 0x20ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*************************************** Vector de Interrupción *********************************************************

ORG 4

GOTO INTERRUP

;*********************************** Sección de Configuración *********************************************************

ORG 5

COMIENZO BCF STATUS,RP1 ; Ir al Banco 1BSF STATUS,RP0CLRF TRISC ; Poner el PORTC como salida de datos.MOVLW 0X07 ; Habilitar el PORTE como señales digitales.MOVWF ADCON1CLRF TRISE ; Poner el PORTE como salida de datos.CLRF TRISD ; Poner el PORTD como salida de datos.

109

Page 116: Entren Adores

BCF STATUS,RP0 ; Ir al Banco 0BSF PORTE,0 ; Habilitar el display de las unidades.CLRF PORTC ; Limpiar el Puerto CCALL Teclado_Inicializa ; Configura las líneas del teclado.MOVLW B'10001000' ; Habilita la interrupción RBI y la general.MOVWF INTCON

;************************************* Principal **************************************************************************

PRINCIPAL SLEEP ; Espera en modo bajo consumo.GOTO PRINCIPAL

;************************************ Rutina de Interrupción ************************************************************

INTERRUP CALL Teclado_LeeHex ; Obtiene el valor hexadecimal de la tecla pulsada.MOVWF PORTC ; Llevar el Acumulador al Puerto C.CALL HEX_7SEG ; Transformar el código Hexadecimal en código

de 7 segmentos.MOVWF PORTD ; Llevar el código al PORTD.CALL Teclado_EsperaDejePulsar ; Para que no se repita el mismo carácter

; mientras permanece pulsado.BCF INTCON,RBIF ; Limpia flag.RETFIE

;*********************************************** Librerías ****************************************************************

INCLUDE <HEX_7SEG.INC> ; Librería de conversión de Hexadecimal a 7 Segmentos.INCLUDE <TECLADO.INC> ; Librería de control del teclado.INCLUDE <RETARDOS.INC> ; Librería de Retardos.

END

7.4.- HEX_7SEG.INC ( Entrenador Básico 5 )

Diagrama de Flujo

Librería HEX_7SEG.INC

HEX_7SEG PCL PCL + W

RETLW 3Fh ; El código 7 segmentos para el "0".RETLW 06h ; El código 7 segmentos

RETLW 5Bh ; El código 7 segmentos

RETLW 4Fh ; El código 7 segmentos

RETLW 66h ; El código 7 segmentos

RETLW 6Dh ; El código 7 segmentos

RETLW 7Dh ; El código 7 segmentos

RETLW 07h ; El código 7 segmentos

RETLW 7Fh ; El código 7 segmentos

110

Page 117: Entren Adores

Librería HEX_7SEG.INC;************************************ HEX_7SEG.INC ******************************************************************

; Transforma un código hexadecimal en 7 segmentos.

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

HEX_7SEG ADDWF PCL,F

RETLW 3Fh ; El código 7 segmentos para el "0".RETLW 06h ; El código 7 segmentos para el "1".RETLW 5Bh ; El código 7 segmentos para el "2".RETLW 4Fh ; El código 7 segmentos para el "3".RETLW 66h ; El código 7 segmentos para el "4".RETLW 6Dh ; El código 7 segmentos para el "5".RETLW 7Dh ; El código 7 segmentos para el "6".RETLW 07h ; El código 7 segmentos para el "7".RETLW 7Fh ; El código 7 segmentos para el "8".RETLW 67h ; El código 7 segmentos para el "9".RETLW 77h ; El código 7 segmentos para el "A".RETLW 7Ch ; El código 7 segmentos para el "B".RETLW 39h ; El código 7 segmentos para el "C".RETLW 5Eh ; El código 7 segmentos para el "D".RETLW 79h ; El código 7 segmentos para el "E".RETLW 71h ; El código 7 segmentos para el "F".

7.5.-TECLADO.INC ( Entrenador Básico 5 );****************************************** Librería "TECLADO.INC" ***************************************************;; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================;; Librería de subrutinas para la gestión de un teclado organizado en una matriz de 4 x 4 y ; conectado al Puerto B según la disposición siguiente y explicada en la figura 19-2 del libro:;; RB4 RB5 RB6 RB7; ^ ^ ^ ^; |------|------|------|------|; RB0 -->| 0 | 1 | 2 | 3 |; |------|------|------|------|; RB1 -->| 4 | 5 | 6 | 7 |; |------|------|------|------|; RB2 -->| 8 | 9 | 10 | 11 |; |------|------|------|------|; RB3 -->| 12 | 13 | 14 | 15 |; |------|------|------|------|;; Los números que se han dibujado dentro de cada cuadrado son el orden de las teclas

111

Page 118: Entren Adores

; que no tienen por qué coincidir con lo serigrafiado sobre ellas. El paso del número de orden; de la tecla al valor que hay serigrafiado sobre la misma se hace con una tabla de conversión.

;************************************** ZONA DE DATOS **************************************************************

CBLOCK

Tecl_TeclaOrden ; Orden de la tecla a chequear.

ENDC

Tecl_UltimaTecla EQU d'15' ; Valor de orden de la última tecla utilizada.

;*****************************Subrutina "Teclado_LeeHex" ************************************************************;; Cada tecla tiene asignado un número de orden que es contabilizado en la variable; Tecl_TeclaOrden. Para convertir a su valor según el tipo de teclado en concreto se; utiliza una tabla de conversión. ; A continuación se expone la relación entre el número de orden de la tecla y los; valores correspondientes para el teclado hexadecimal más utilizado.;; ORDEN DE TECLA: TECLADO HEX. UTILIZADO:; 0 1 2 3 1 2 3 F; 4 5 6 7 4 5 6 E; 8 9 10 11 7 8 9 D; 12 13 14 15 A 0 B C;; Así, en este ejemplo, la tecla "7" ocupa el orden 8, la tecla "F" ocupa el orden 3 y la; tecla "9" el orden 10.

; Si cambia el teclado también hay cambiar de tabla de conversión.;; Entrada: En (W) el orden de la tecla pulsada.; Salida: En (W) el valor hexadecimal para este teclado concreto.

Teclado_LeeHex call Teclado_LeeOrdenTecla ; Lee el Orden de la tecla pulsada.btfss STATUS,C ; ¿Pulsa alguna tecla?, ¿C=1?goto Tecl_FinLeeHex ; No, por tanto sale.call Tecl_ConvierteOrdenEnHex ; Lo convierte en su valor real mediante

tabla.bsf STATUS,C ; Vuelve a posicionar el Carry, porque la

Tecl_FinLeeHex return ; instrucción "addwf PCL,F" lo pone a "0".

;Tecl_ConvierteOrdenEnHex addwf PCL,F ; Según el teclado utilizado resulta:

DT 7h,8h,9h,0Fh ; Primera fila del teclado.DT 4h,5h,6h,0Eh ; Segunda fila del tecladoDT 1h,2h,3h,0Dh ; Tercera fila del teclado.DT 0Ah,0h,0Bh,0Ch ; Cuarta fila del teclado.

Teclado_FinTablaHex

; Esta tabla se sitúa al principio de la librería con el propósito de que no supere la; posición 0FFh de memoria ROM de programa. De todas formas, en caso que así fuera ; visualizaría el siguiente mensaje de error en el proceso de ensamblado:

112

Page 119: Entren Adores

;IF (Teclado_FinTablaHex > 0xFF)

ERROR "Atención: La tabla ha superado el tamaño de la página de los"MESSG "primeros 256 bytes de memoria ROM. NO funcionará correctamente."

ENDIF

;*************************************** Subrutina "Teclado_Inicializa" ************************************************;; Esta subrutina configura las líneas del Puerto B según la conexión del teclado realizada; y comprueba que no hay pulsada tecla alguna al principio.

Teclado_Inicializa bsf STATUS,RP0 ; Configura las líneas del puerto:movlw b'11110000' ; <RB7:RB4> entradas, <RB3:RB0> salidasmovwf PORTBbcf OPTION_REG,NOT_RBPU ; Habilita resistencia de Pull-Up del Puerto B.bcf STATUS,RP0 ; Acceso al banco 0.

; call Teclado_EsperaDejePulsar; return;; ************************************Subrutina "Teclado_EsperaDejePulsar" ***************************************;;Permanece en esta subrutina mientras siga pulsada la tecla.;Teclado_Comprobación EQU b'11110000'

Teclado_EsperaDejePulsar

movlw Teclado_Comprobacion; Pone a cero las cuatro líneas de salida del movwf PORTB ; Puerto B.

Teclado_SigueEsperando

call Retardo_20ms ; Espera a que se estabilicen los niveles de tensión.movf PORTB,W ; Lee el Puerto B.sublw Teclado_Comprobacion; Si es lo mismo que escribió es que ya no pulsa btfss STATUS,Z ; tecla alguna.goto Teclado_SigueEsperando

return

;*********************************** Subrutina "Teclado_LeeOrdenTecla" ********************************************;; Lee el teclado, obteniendo el orden de la tecla pulsada. ;; Salida: En (W) el número de orden de la tecla pulsada. Además Carry se pone a "1" si; se pulsa una tecla ó a "0" si no se pulsa tecla alguna.

Teclado_LeeOrdenTecla:

clrf Tecl_TeclaOrden ; Todavía no ha empezado a chequear el teclado.movlw b'11111110' ; Va a chequear primera fila.

Tecl_ChequeaFila ; (Ver esquema de conexión).

movwf PORTB ; Activa la fila correspondiente.

Tecl_Columna1

btfss PORTB,4 ; Chequea la 1ª columna buscando un cero. goto Tecl_GuardaValor ; Sí, es cero y por tanto guarda su valor y sale.

113

Page 120: Entren Adores

incf Tecl_TeclaOrden,F ; Va a chequear la siguiente tecla.

Tecl_Columna2 ; Repite proceso para las siguientes

btfss PORTB,5 ; columnas.goto Tecl_GuardaValorincf Tecl_TeclaOrden,F

Tecl_Columna3

btfss PORTB,6goto Tecl_GuardaValorincf Tecl_TeclaOrden,F

Tecl_Columna4

btfss PORTB,7goto Tecl_GuardaValorincf Tecl_TeclaOrden,F

;; Comprueba si ha chequeado la última tecla, en cuyo caso sale. Para ello testea si; el contenido del registro Tecl_TeclaOrden es igual al número de teclas del teclado.

Tecl_TerminaColumnas

movlw Tecl_UltimaTeclasubwf Tecl_TeclaOrden,W ; (W) = (Tecl_TeclaOrden)-Tecl_UltimaTecla.btfsc STATUS,C ; ¿C=0?, ¿(W) negativo?, ¿(Tecl_TeclaOrden)<15?goto Tecl_NoPulsada ; No, se ha llegado al final del chequeo.bsf STATUS,C ; Sí. Va a chequear la siguiente fila.rlf PORTB,W ; Apunta a la siguiente fila.goto Tecl_ChequeaFila

Tecl_NoPulsada

bcf STATUS,C ; Posiciona C=0, indicando que no ha pulsadogoto Tecl_FinTecladoLee ; tecla alguna y sale.

Tecl_GuardaValor

movf Tecl_TeclaOrden,W ; El orden de la tecla pulsada en (W) y sale.bsf STATUS,C ; Como hay tecla tecla pulsada, pone C=1.

Tecl_FinTecladoLee

return

; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================

114

Page 121: Entren Adores

8.- Entrenador Básico 6

115

Page 122: Entren Adores

8.1.- LCD_01.asm ( Entrenador Básico 6 ) title " Visualización de un mensaje en el LCD carácter a carácter"

;************************************** LCD_01.asm ********************************************************************

; El modulo LCD visualiza el mensaje "Hola".

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;******************* Asignación de nombres de Registros de Funciones especiales a direcciones ***************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ************************************************************************

CBLOCK 0x20ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************ORG 5

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

;************************************* Principal **************************************************************************

PRINCIPAL movlw 'H' ; Escribimos el carácter en el donde apunta call LCD_Caracter ; el Cursor del LCD e incrementa el cursor.movlw 'o'call LCD_Caractermovlw 'l'

116

Page 123: Entren Adores

call LCD_Caractermovlw 'a'call LCD_Caractersleep ; Entra en modo de bajo consumo.

;*********************************************** Librerías ****************************************************************

INCLUDE <LCD_4BIT.INC> ; Subrutinas de control del módulo LCD.INCLUDE <RETARDOS.INC> ; Subrutinas de retardo.

END ; Fin del programa.

8.2.- LCD_02.asm ( Entrenador Básico 6 )

title " Visualización de un mensaje en el LCD carácter a carácter "title " con retardo de 500 ms, borrar pantalla y comenzar de nuevo "

;************************************** LCD_02.asm *******************************************************************

; El modulo LCD visualiza el mensaje "Hola". La escritura de cada letra se realiza cada; 500 mS. Después se borra y comienza de nuevo. ; *************************************************************************************************************************

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;************** Asignación de nombres de Registros de Funciones especiales a direcciones ********************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ************************************************************************

CBLOCK 0x20ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

117

Page 124: Entren Adores

;*********************************** Sección de Configuración *********************************************************ORG 5

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

;************************************* Principal **************************************************************************

Principal movlw 'H' ; Escribimos el carácter en el donde apuntacall LCD_Caracter ; el Cursor del LCD e incrementa el cursor.call Retardo_500msmovlw 'o'call LCD_Caractercall Retardo_500msmovlw 'l'call LCD_Caractercall Retardo_500msmovlw 'a'call LCD_Caractercall Retardo_500mscall LCD_Borra ; Borra la pantalla y sitúa el cursor en el principio.call Retardo_500msgoto Principal

;*********************************************** Librerías ****************************************************************

INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

8.3.- LCD_03.asm ( Entrenador Básico 6 )

title " Programa ejemplo para comprender la utilización de las subrutinas "title "LCD_ByteCompleto, LCD_Byte, LCD_Nibble y LCD_DosEspaciosBlancos"

;************************************** LCD_03.asm *******************************************************************;; Programa ejemplo para comprender la utilización de las subrutinas "LCD_ByteCompleto",; "LCD_Byte", "LCD_Nibble" y "LCD_DosEspaciosBlancos";; Para ello se van a utilizar sucesivamente y en este orden las subrutinas: ; "LCD_ByteCompleto", "LCD_DosEspaciosBlancos", "LCD_Byte",; "LCD_DosEspaciosBlancos" y "LCD_Nibble" para dos números que serán:;; - En la primera línea del LCD un numero con el nibble alto no cero. Por ejemplo: 1Dh.; - En la segunda línea del LCD un numero con el nibble alto igual a cero. Ejemplo: 0Dh.;; Así por ejemplo, para los números "1D" y "0D" se visualizaría (donde "#" viene a significar; espacio en blanco):

; "1D##1D##D" (Primera línea).; "0D###D##D" (Segunda línea). ; *************************************************************************************************************************

118

Page 125: Entren Adores

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

Numero_NoCeroAlto EQU 0x1D ; Numero ejemplo nibble alto no cero.Numero_CeroAlto EQU 0x0D ; Numero ejemplo nibble alto cero.

;************************************** Registros ************************************************************************

CBLOCK 0x20ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

ORG 5

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

;************************************* Principal **************************************************************************

Principal movlw Numero_NoCeroAlto ;Visualizamos en el LCD Byte completo.call LCD_ByteCompleto

call LCD_DosEspaciosBlancos ;Escribimos en el LCD dos espacios en blanco.

movlw Numero_NoCeroAlto ;Visualizamos en el LCD Byte completocall LCD_Byte si el nible alto no es cero.

call LCD_DosEspaciosBlancos ;Escribimos en el LCD dos espacios en blanco.

119

Page 126: Entren Adores

movlw Numero_NoCeroAlto ;Visualizamos en el LCD nible bajo.call LCD_Nibble

call LCD_Linea2 ;Se sitúa el cursor en la segunda línea.

movlw Numero_CeroAlto ;Visualizamos en el LCD Byte completo.call LCD_ByteCompleto

call LCD_DosEspaciosBlancos ;Escribimos en el LCD dos espacios en blanco.

movlw Numero_CeroAlto ;Visualizamos en el LCD nible bajocall LCD_Byte ya que el nible alto es cero.

call LCD_DosEspaciosBlancos ;Escribimos en el LCD dos espacios en blanco.

movlw Numero_CeroAlto ;Visualizamos en el LCD nible bajo.call LCD_Nibble

sleep ; Entra en modo de bajo consumo.

;*********************************************** Librerías ****************************************************************

INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

8.4.- LCD_04.asm ( Entrenador Básico 6 ) title " Visualización en el LCD un contador descendente "

;************************************** LCD_04.asm ********************************************************************

; El modulo LCD visualiza un contador descendente que cuenta desde 59 hasta 0 y vuelve a; repetir la cuenta ininterrumpidamente. En cada valor estará unos 500 ms en pantalla.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;************** Asignación de nombres de Registros de Funciones especiales a direcciones ********************

#include <p16f877.inc> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

120

Page 127: Entren Adores

NumeroCarga EQU D'59' ; Cuenta inicial.

;************************************** Registros ************************************************************************

CBLOCK 0x20

Contador

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

ORG 5

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

;************************************* Principal **************************************************************************

Principal movlw NumeroCarga ; Realiza carga inicial.movwf Contador

Visualiza call VisualizaContador ; Visualiza el valor del Contador.decfsz Contador,F ; Decrementa el contador hasta llegar a cero.goto Visualiza ; Si no ha llegado a cero visualiza el siguiente.call VisualizaContador ; Ahora también debe visualizar el cero.call LCD_Borra ; Borra la pantallacall Retardo_5s ; durante 5 segundo.goto Principal ; Repite el proceso.

;*********************************** Subrutina "VisualizaContador" ***************************************************

VisualizaContador call LCD_Linea1 ; Se sitúa en la primera posición de la línea 1.movf Contador,W ; Lo pasa a BCD.call BIN_a_BCDcall LCD_Byte ; Visualiza el dato numérico.call Retardo_500ms ; Durante este tiempo.

return

;*********************************************** Librerias ****************************************************************

INCLUDE <RETARDOS.INC>INCLUDE <BIN_BCD.INC>INCLUDE <LCD_4BIT.INC>

END

8.5.- LCD_05.asm ( Entrenador Básico 6 )

121

Page 128: Entren Adores

title " Visualizar en la pantalla del LCD los pulsos generados del exterior "

;************************************************* LCD_05.asm *********************************************************

; Cada vez que presiona el pulsador conectado al pin RA4 incrementa un contador; visualizado en el centro de la primera línea de la pantalla.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

#DEFINE Pulsador PORTA,4 ; Línea donde se conecta el pulsador.

;************************************** Registros ************************************************************************

CBLOCK 0x20

Contador

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

ORG 5

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bsf Pulsador ; Línea del pulsador se configura como entrada. bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

122

Page 129: Entren Adores

clrf Contador ; Inicializa contador y los visualiza por primera vez.call Visualiza

;************************************* Principal **************************************************************************

Principal btfss Pulsador ; Lee el pulsador.call IncrementaVisualiza ; Si pulsa salta a incrementar y visualizar elgoto Principal ; contador

;**************************** Subrutina "IncrementaVisualiza" *********************************************************

IncrementaVisualiza call Retardo_20ms ; Espera a que se estabilicen los niveles de tensión.btfsc Pulsador ; Vuelve a leer el pulsador.goto Fin_Incrementaincf Contador,F ; Incrementa el contador y después lo visualiza.

Visualiza movlw D'7' ; Se sitúa en el centro de la línea 1.call LCD_PosicionLinea1movf Contador,Wcall BIN_a_BCD ; Se debe visualizar en decimal.call LCD_Byte

EsperaDejePulsar btfss Pulsadorgoto EsperaDejePulsar

Fin_Incrementa return

;*********************************************** Librerías ****************************************************************

INCLUDE <RETARDOS.INC>INCLUDE <BIN_BCD.INC>INCLUDE <LCD_4BIT.INC>

END

8.6.- LCD_06.asm ( Entrenador Básico 6 ) title " Visualizar en la pantalla del LCD los pulsos generados del exterior "title " hasta un número máximo, se resetea y comienza de nuevo la cuenta "

;************************************** LCD_06.asm ********************************************************************

; Cada vez que presiona el pulsador conectado al pin RA4, incrementa un contador que se ; visualiza en la pantalla. Cuando llegue a su valor máximo (por ejemplo 6) se resetea y; comienza de nuevo la cuenta.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

123

Page 130: Entren Adores

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

#DEFINE Pulsador PORTA,4 ; Línea donde se conecta el pulsador.

ValorMaximo EQU D'6' ; Valor máximo de la cuenta.

;************************************** Registros ************************************************************************

CBLOCK 0x20

Contador

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

ORG 5

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bsf Pulsador ; Línea del pulsador se configura como entrada. bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

clrf Contador ; Inicializa contador y los visualiza por primera vez.call Visualiza

;************************************* Principal **************************************************************************

Principal btfss Pulsador ; Lee el pulsador.call IncrementaVisualiza ; Si pulsa salta a incrementar y visualizar elgoto Principal ; contador

;**************************** Subrutina "IncrementaVisualiza" *********************************************************

IncrementaVisualiza call Retardo_20ms ; Espera a que se estabilice el nivel de tensión.btfsc Pulsador ; Vuelve a leer el pulsador.goto Fin_Incrementacall IncrementaContador ; Incrementa el contador y después lo visualiza.

Visualiza movlw D'7' ; Se sitúa en el centro de la línea 1.call LCD_PosicionLinea1movf Contador,Wcall BIN_a_BCD ; Debe visualizar en decimal.call LCD_Byte

124

Page 131: Entren Adores

EsperaDejePulsar btfss Pulsadorgoto EsperaDejePulsar

Fin_Incrementa return

;****************************** Subrutina "IncrementaContador" ******************************************************

; Incrementa el valor de la variable Contador. Si llega al valor máximo lo resetea.

IncrementaContador incf Contador,F ; Incrementa el contadormovf Contador,W ; Ha superado su valor máximo?sublw ValorMaximo ; (W)<- #ValorMaximo-(Contador).btfss STATUS,C ; Si C =1 salta una instrucción. (Contador)> #ValorMaximoclrf Contador ; Lo inicializa si ha superado su valor máximo.

return

;*********************************************** Librerías ****************************************************************

INCLUDE <LCD_4BIT.INC> ; Subrutinas de control del LCD.INCLUDE <RETARDOS.INC> ; Subrutinas de retardo.INCLUDE <BIN_BCD.INC> ; Subrutina BIN_a_BCD.

END ; Fin del programa.

8.7.- LCD_07.asm ( Entrenador Básico 6 ) title " Mientras se mantenga presionado el pulsador conectado al pin RA4, incrementa un contador"title " que se visualiza en la pantalla del LCD."

;************************************************* LCD_07.asm *********************************************************

; Mientras se mantenga presionado el pulsador conectado al pin RA4, incrementa un contador; que se visualiza en la pantalla. Cuando llegue a su valor máximo (por ejemplo 59) se resetea; y comienza de nuevo la cuenta. Se mantiene 200 ms en cada cuenta.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;******************** Asignación de nombres de Registros de Funciones especiales a direcciones **************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

125

Page 132: Entren Adores

;************************************** Igualdades ***********************************************************************

#DEFINE Pulsador PORTA,4 ; Línea donde se conecta el pulsador.

ValorMaximo EQU D'59' ; Valor máximo de la cuenta.

;************************************** Registros ************************************************************************

CBLOCK 0x20

Contador

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

ORG 5

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bsf Pulsador ; Línea del pulsador se configura como entrada. bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

clrf Contador ; Inicializa contador y los visualiza por primera vez.call Visualiza

;************************************* Principal **************************************************************************

Principal btfss Pulsador ; Lee el pulsador.call IncrementaVisualiza ; Si pulsa salta a incrementar y visualizar elgoto Principal ; contador

;**************************** Subrutina "IncrementaVisualiza" *********************************************************

IncrementaVisualiza call Retardo_20ms ; Espera a que se estabilice el nivel de tensión.btfsc Pulsador ; Vuelve a leer el pulsador.goto Fin_Incrementacall IncrementaContador ; Incrementa el contador y después lo visualiza.

Visualiza movlw D'7' ; Se sitúa en el centro de la línea 1.call LCD_PosicionLinea1movf Contador,Wcall BIN_a_BCD ; Debe visualizar en decimal.call LCD_Bytecall Retardo_200ms ; Se mantiene durante este tiempo.

Fin_Incrementa return

;****************************** Subrutina "IncrementaContador" ******************************************************

126

Page 133: Entren Adores

; Incrementa el valor de la variable Contador. Si llega al valor máximo lo resetea.

IncrementaContador incf Contador,F ; Incrementa el contadormovf Contador,W ; Ha superado su valor máximo?sublw ValorMaximo ; (W)<- #ValorMaximo-(Contador).btfss STATUS,C ; Si C =1 salta una instrucción. (Contador)> #ValorMaximoclrf Contador ; Lo inicializa si ha superado su valor máximo.

return

;*********************************************** Librerías ****************************************************************

INCLUDE <LCD_4BIT.INC> ; Subrutinas de control del LCD.INCLUDE <RETARDOS.INC> ; Subrutinas de retardo.INCLUDE <BIN_BCD.INC> ; Subrutina BIN_a_BCD.

END ; Fin del programa.

8.8.- LCD_08.asm ( Entrenador Básico 6 ) title " Mientras se mantenga presionado el pulsador conectado al pin RA4, incrementa un contador"title " que se visualiza en la pantalla del LCD en formato decimal ,Hexadecimal y binario."

;************************************** LCD_08.asm ********************************************************************

; Mientras se mantenga presionado el pulsador conectado al pin RA4, se incrementa un contador; visualizado en la pantalla en tres formatos: decimal, hexadecimal y binario. Un ejemplo:; Primera Línea: "CE 206"; Segunda Línea: "11001110"

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

#DEFINE Pulsador PORTA,4 ; Línea donde se conecta el pulsador.

;************************************** Registros ************************************************************************

127

Page 134: Entren Adores

CBLOCK 0x20

ContadorAuxiliarDesplaza

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

ORG 5

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bsf Pulsador ; Línea del pulsador se configura como entrada. bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

clrf Contador ; Inicializa contador y call VisualizaContador ; lo visualiza.

;************************************* Principal **************************************************************************

Principal btfsc Pulsador ; Lee el pulsador.goto Fin ; Si no pulsa salta a final.call Retardo_20ms ; Espera a que se estabilicen los niveles de tensión.btfsc Pulsador ; Vuelve a leer el pulsador.goto Finincf Contador,F ; Incrementa el contador.call VisualizaContadorcall Retardo_200ms ; Se incrementara de nuevo cuando pase este

Fin goto Principal ; tiempo.

;********************************** Subrutina "VisualizaContador" *****************************************************

VisualizaContador call LCD_Borra ; Borra la pantalla.movf Contador,W ; A continuación visualiza el contador.

call LCD_ByteCompleto ; Visualiza en HEXADECIMAL.call LCD_TresEspaciosBlancos ; Como separador.

movf Contador,W ; Ahora se visualiza en DECIMAL.call BIN_a_BCD ; Primero se convierte a BCD.movwf Auxiliar ; Guarda las decenas y unidades.movf BCD_Centenas,W ; Visualiza centenas.call LCD_Nibblemovf Auxiliar,W ; Visualiza las decenas y unidades.call LCD_ByteCompleto

call LCD_Linea2 ; En la segunda línea para visualizar en BINARIO.movlw D'8' ; Utiliza el registro auxiliar como contador del

128

Page 135: Entren Adores

movwf Auxiliar ; numero de bits que se va visualizando por la movf Contador,W ; pantalla.movwf Desplaza

VisualizaBit rlf Desplaza,F ; El BIT a visualizar pasa al Carry .movlw '1' ; En principio supone que es un uno.btfss STATUS,C ; Comprueba su valor.movlw '0' ; Ha sido cero.call LCD_Caracter ; Lo visualiza.decfsz Auxiliar,F ; Ha terminado de visualizar los 8 bits?goto VisualizaBit ; No, sigue visualizando otro bit.

return

;*********************************************** Librerias ****************************************************************

INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>INCLUDE <BIN_BCD.INC>

END

8.9.- Mens_01.asm ( Entrenador Básico 6 )

title " Visualización de un mensaje fijo utilizando la librería LCD_4BIT.INC "

;************************************ Mens_01.asm *********************************************************************

; En la pantalla del modulo LCD se visualiza un mensaje de menos de 16 caracteres grabado; en la memoria ROM mediante la directiva DT.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************;************************************** Registros ************************************************************************

CBLOCK 0x20

LCD_ApuntaCaracter ; Indica la posición del carácter a visualizar; respecto del comienzo de todos los mensajes; (posición de la etiqueta "Mensajes").

129

Page 136: Entren Adores

LCD_ValorCaracter ; Valor del código ASCII del carácter a ; visualizar.

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************ORG 5

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.clrf LCD_ApuntaCaracter ; Se visualizara la primera posición del mensaje.

;************************************* Principal **************************************************************************

LCD_VisualizaOtroCaracter movf LCD_ApuntaCaracter,Wcall Mensajes ; Obtiene el código ASCII del

carácter apuntado.movwf LCD_ValorCaracter ; Guarda el valor de carácter.movf LCD_ValorCaracter,F ; Lo único que hace es posicionar

flag Z. En casobtfsc STATUS,Z ; que sea "0x00", que es código

indicador finalgoto Fin ; de mensaje, sale fuera.

LCD_NoUltimoCaracter call LCD_Caracter ; Visualiza el carácter ASCII leído.incf LCD_ApuntaCaracter,F ; Apunta a la posición del siguiente

carácter goto LCD_VisualizaOtroCaracter ; dentro del mensaje.

Fin sleep ; Pasa a modo bajo consumo.

;********************************* Subrutina "Mensajes" ***************************************************************

Mensajes addwf PCL,F

Mensaje0 DT "Hola!, que tal? ", 0x00 ; Posición inicial del mensaje.

;*********************************************** Librerías ****************************************************************

INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

8.10.- Mens_02.asm ( Entrenador Básico 6 ) title " Visualización de un mensaje fijo utilizando la librería LCD_MENS.INC "

;************************************ Mens_02.asm *********************************************************************; En la pantalla del modulo LCD se visualiza un mensaje de menos de 16 caracteres grabado; en la memoria ROM mediante la directiva DT. Utiliza la subrutina LCD_Mensaje de la

130

Page 137: Entren Adores

; librería LCD_MENS.INC

;**************************************************************************************************************************;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ************************************************************************

CBLOCK 0x20

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

ORG 5

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como senales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

;************************************* Principal **************************************************************************

Principal movlw Mensaje0 ; Apunta donde se encuentra el mensaje.call LCD_Mensaje ; Visualiza el mensaje.sleep ; Pasa a modo bajo consumo.

;********************************* Subrutina "Mensajes" ****************************************************************

Mensajes addwf PCL,F

Mensaje0 DT "Hola!, que tal? ", 0x00 ; Posición inicial del mensaje.

;*********************************************** Librerías ****************************************************************

131

Page 138: Entren Adores

INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <RETARDOS.INC>

END

8.11.- Mens_03.asm ( Entrenador Básico 6 ) title " Visualización de varios mensajes fijo utilizando la librería LCD_MENS.INC "

;************************************ Mensaje_03.asm ******************************************************************

; En la pantalla se visualizan varios mensajes, uno detrás de otro. Cada mensaje permanece; durante 2 segundos. Entre mensaje y mensaje la pantalla se apaga durante unos 200 ms.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ************************************************************************

CBLOCK 0x20

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa;*********************************** Sección de Configuración *********************************************************

ORG 5

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.

132

Page 139: Entren Adores

movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

;************************************* Principal **************************************************************************

Principal movlw Mensaje0 ; Apunta al mensaje 0.call Visualizamovlw Mensaje1 ; Apunta al mensaje 1.call Visualizamovlw Mensaje2 ; Apunta al mensaje 2.call Visualizacall Retardo_5s ; Permanece apagada durante este tiempo.goto Principal ; Repite la visualización de todos los mensajes.

;************************************ Subrutina "Visualiza" *************************************************************

Visualiza call LCD_Mensajecall Retardo_2s ; Visualiza el mensaje durante este tiempo.call LCD_Borra ; Borra la pantalla y se mantiene así durante call Retardo_200ms ; este tiempo.

return

;********************************* Subrutina "Mensajes" ****************************************************************

Mensajes addwf PCL,F

Mensaje0 DT "Estudia PIC, es", 0x00 ; Posición inicial del mensaje 0.Mensaje1 DT "bueno.", 0x00 ; Posición inicial del mensaje 1.Mensaje2 DT "IES JOAN MIRO", 0x00 ; Posición inicial del mensaje 2.

;*********************************************** Librerías ****************************************************************

INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <RETARDOS.INC>

END

8.12.- Mens_03B.asm ( Entrenador Básico 6 ) title " Visualización de varios mensajes fijo utilizando la librería LCD_MENS.INC "title " Cuando se visualiza el ultimo mensaje el proceso se repite "

;************************************ Mens_03B.asm *******************************************************************

; En la pantalla se visualizan varios mensajes, uno detrás de otro. Cada mensaje permanece; durante 2 segundos. Entre mensaje y mensaje la pantalla se apaga durante unos 200 mS.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

133

Page 140: Entren Adores

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

ValorMaximo EQU D'6' ; Numero de mensajes a visualizar

;************************************** Registros ************************************************************************

CBLOCK 0x20

Contador

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

ORG 5

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.clrf Contador ; Inicializa el registro Contador.

;************************************* Principal **************************************************************************

Principal movlw ValorMaximo ; Comprueba que Contador no haya llegado al máximo.subwf Contador,W ; (W) <- (Contador)-ValorMaximobtfss STATUS,C ; Si C=1 salta una instrucción. ValorMaximo > (Contador)goto Visualiza ; No. El contador todavía no ha llegado al máximo.clrf Contador ; Sí. Inicializa el contador y lo visualiza.call LCD_Borra ; Pantalla apagada durante unos instantes call Retardo_5s ; para señalar el último mensaje de la lista.

Visualiza call LCD_Borra ; Borra la pantalla y se sitúa en la línea 1.call Retardo_200msmovf Contador,W ; Apunta al mensaje que se va a visualizar.call ApuntaMensajecall LCD_Mensaje ; Lo visualiza.call Retardo_2s ; Se visualiza el mensaje durante este tiempo.

134

Page 141: Entren Adores

incf Contador,F ; Incrementa el contador.goto Principal ; Repite el proceso.

;************************************ Subrutina "ApuntaMensaje" ******************************************************

ApuntaMensaje addwf PCL,F

retlw Mensaje0retlw Mensaje1retlw Mensaje2retlw Mensaje3retlw Mensaje4retlw Mensaje5

;********************************* Subrutina "Mensajes" ****************************************************************

Mensajes addwf PCL,F

Mensaje0 DT "Estudia PIC, es", 0x00; ; Posición inicial del mensaje 0.

Mensaje1 DT "muy divertido.", 0x00 ; Posición inicial del mensaje 1.

Mensaje2 DT "IES JOAN MIRO", 0x00 ; Posición inicial del mensaje 2.

Mensaje3 DT "S.S. de los Reyes", 0x00 ; Posición inicial del mensaje 3.

Mensaje4 DT " Estudia ", 0x00 ; Posición inicial del mensaje 4.

Mensaje5 DT " ELECTRONICA ", 0x00 ; Posición inicial del mensaje 5.

;*********************************************** Librerías ****************************************************************

INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <RETARDOS.INC>

END

8.13.- Mens_04.asm ( Entrenador Básico 6 ) title " Visualización de mensajes parpadeantes en dos líneas del LCD "

;************************************ Mens_04.asm *********************************************************************

; En las dos líneas de la pantalla apareceren dos mensajes parpadeantes.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

135

Page 142: Entren Adores

list p=16f877, f=inhx32

;********************* Asignación de nombres de Registros de Funciones especiales a direcciones *************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ************************************************************************

CBLOCK 0x20

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

;************************************* Principal **************************************************************************

Principal movlw Mensaje0 ; Apunta al mensaje de la primera línea ycall LCD_Mensaje ; lo visualiza.call LCD_Linea2 ; Pasa a la segunda línea.movlw Mensaje1 ; Apunta al mensaje de la segunda línea.call LCD_Mensaje ; Lo visualiza.call Retardo_500ms ; Durante este tiempo.call LCD_Borra ; Borra la pantalla.call Retardo_500ms ; Durante este tiempo, produciendo un efecto degoto Principal ; parpadeo.

;********************************* Subrutina "Mensajes" ****************************************************************

Mensajes addwf PCL,F

Mensaje0 DT " Estudia un", 0x00 ; Posición inicial del mensaje 0.

Mensaje1 DT "Ciclo Formativo", 0x00 ; Posición inicial del mensaje 1.

;*********************************************** Librerías ****************************************************************

136

Page 143: Entren Adores

INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <RETARDOS.INC>

END

8.14.- Mens_05.asm ( Entrenador Básico 6 )

title " Visualización de un mensaje fijo y parpadeantes "

;*************************************** Mens_05.asm ******************************************************************

; En la primera línea de la pantalla aparece un mensaje fijo. En la segunda linea aparece; un mensaje parpadeante.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ************************************************************************

CBLOCK 0x20

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.

137

Page 144: Entren Adores

bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

;************************************* Principal **************************************************************************

Principal movlw MensajeFijo ; Apunta al mensaje fijo y lo visualiza.call LCD_Mensaje

seguir call LCD_Linea2 ; Pasa a la segunda línea.movlw MensajeParpadeante ; Apunta al mensaje parpadeante.call LCD_Mensaje ; Lo visualiza.call Retardo_500ms ; Durante este tiempo.call LCD_Linea2 ; Vuelve a situarse al principio de la línea 2.call LCD_LineaEnBlanco ; Visualiza línea en blanco.call Retardo_500ms ; Durante este tiempo, produciendo un efecto degoto seguir ; parpadeo.

;********************************* Subrutina "Mensajes" ****************************************************************

Mensajes addwf PCL,F

MensajeFijo DT " Estudia ", 0x00;MensajeParpadeante DT " ELECTRONICA ", 0x00

;*********************************************** Libreras ****************************************************************

INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <RETARDOS.INC>

END

8.15.- Mens_06.asm ( Entrenador Básico 6 )

title " Visualización de mensajes en función de un pulsador "

;************************************** Mens_06.asm *******************************************************************

; En el modulo LCD se pueden visualizar varios mensajes diferentes. El paso de uno; a otro se realiza al actuar sobre un pulsador conectado a la línea RA4.; En pantalla aparecere por ejemplo:; " Mensaje 2 " (primera línea).; "S.S. de los Reyes." (segunda línea).

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

138

Page 145: Entren Adores

list p=16f877, f=inhx32

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

#DEFINE Pulsador PORTA,4 ; Línea donde se conecta el pulsador.ValorMaximo EQU D'4' ; Numero de mensajes.

;************************************** Registros ************************************************************************

CBLOCK 0x20

Contador ; El contador a visualizar.

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bsf Pulsador ; Línea del pulsador configurada como entrada. bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.clrf Contadorcall Visualiza ; Inicializa contador y los visualiza por primera vez.

;************************************* Principal **************************************************************************

Principal btfsc Pulsador ; Lee el pulsador.goto Fincall Retardo_20ms ; Espera estabilicen niveles de tensión.btfsc Pulsador ; Vuelve a leer el pulsador.goto Fincall IncrementaContador ; Incrementa el contador.call Visualiza ; Visualiza el mensaje correspondiente.

EsperaDejePulsar btfss Pulsadorgoto EsperaDejePulsar

Fin goto Principal

;********************************** Subrutina "IncrementaContador" **************************************************

; Incrementa el valor de la variable Contador. Si llega al valor máximo lo resetea.

IncrementaContador incf Contador,F ; Incrementa el contador.

139

Page 146: Entren Adores

movf Contador,W ; Ha superado su valor máximo? sublw ValorMaximo-1 ; (W)<- ValorMaximo-(Contador).btfss STATUS,C ; Si C=1 salta una instrucción.

(Contador)> #ValorMaximoclrf Contador ; Lo inicializa si ha superado su valor máximo.return

;************************************** Subrutina "Visualiza" **********************************************************

Visualiza call LCD_Borra ; Borra la pantalla y se sitúa en la línea 1.movlw MensajeN ; Apunta a este mensaje.call LCD_Mensaje ; Lo visualiza.movf Contador,W ; A continuación visualiza el contador.call BIN_a_BCD ; Se debe visualizar en BCD.call LCD_Bytecall LCD_Linea2 ; Al principio de la segunda línea del LCD.movf Contador,Wcall ApuntaMensaje ; Apunta al mensaje que se va a visualizar.call LCD_Mensaje ; Lo visualiza.return

;************************************** Subrutina "ApuntaMensaje" ****************************************************

ApuntaMensajeaddwf PCL,F

retlw Mensaje0retlw Mensaje1retlw Mensaje2retlw Mensaje3

;***************************************** Subrutina "Mensajes" ********************************************************

Mensajes addwf PCL,F

Mensaje0 DT " DESARROLLO DE ",0x00 ; Posición inicial del mensaje 0.Mensaje1 DT " PROYECTOS ", 0x00 ; Posición inicial del mensaje 1.Mensaje2 DT "S.S. SEBASTIAN", 0x00 ; Posición inicial del mensaje 2.Mensaje3 DT "de los Reyes", 0x00 ; Posición inicial del mensaje 3.

MensajeN DT " Mensaje ", 0x00 ; Posición inicial del mensaje primera línea del LCD.

;*********************************************** Librerías ****************************************************************

INCLUDE <LCD_MENS.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>INCLUDE <BIN_BCD.INC>

END

8.16.- Mens_07.asm ( Entrenador Básico 6 ) title " El modulo LCD visualiza un mensaje largo (más de 16 caracteres) que se desplaza "

;**************************************************** Mens_07.asm *****************************************************;; El modulo LCD visualiza un mensaje largo (más de 16 caracteres) que se desplaza a lo largo; de la pantalla. Se utiliza la subrutina LCD_MensajeMovimiento de la librería LCD_MENS.INC.

140

Page 147: Entren Adores

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;*********** Asignación de nombres de Registros de Funciones especiales a direcciones ***********************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ************************************************************************

CBLOCK 0x20

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

;************************************* Principal **************************************************************************

Principal movlw Mensaje0 ; Apunta al mensaje.call LCD_MensajeMovimientogoto Principal ; Repite la visualización.

;***************************************** Subrutina "Mensajes" ********************************************************

Mensajes addwf PCL,F

Mensaje0 DT " " ; Posición inicial del mensaje.; Espacios en blanco al principio para mejor

DT "Estudia un Ciclo Formativo " ; visualización.DT "de ELECTRONICA."DT " ", 0x0 ; Espacios en blanco al final.

141

Page 148: Entren Adores

;*********************************************** Librerías ****************************************************************

INCLUDE <LCD_MENS.INC> ; Subrutina LCD_MensajeMovimiento.INCLUDE <LCD_4BIT.INC> ; Subrutinas de control del LCD.INCLUDE <RETARDOS.INC> ; Subrutinas de retardos.

END ; Fin del programa.

8.17.- Mens_08.asm ( Entrenador Básico 6 ) title " Juego de la Quiniela "

;*********************************************** Mens_08.asm **********************************************************

; Programa para el juego de la Quiniela: Al presionar sobre el pulsador conectado al pin RA4; se incrementara en pantalla aparecerá rápidamente "1", "X", "2". Cuando se suelta el pulsador; permanece el signo seleccionado.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;************** Asignación de nombres de Registros de Funciones especiales a direcciones ********************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

#DEFINE Pulsador PORTA,4 ; Línea donde se conecta el pulsador.

;************************************** Registros ************************************************************************

CBLOCK 0x20

Contador

ENDC;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.

142

Page 149: Entren Adores

movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bsf Pulsador ; Línea del pulsador que se configura como entrada. bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

movlw MensajeQuinielacall LCD_Mensaje

;************************************* Principal **************************************************************************

Principal btfss Pulsador ; Lee el pulsador.call IncrementaVisualiza ; Si pulsa salta a incrementar y visualizar elgoto Principal ; contador

;************************************** Subrutina "IncrementaVisualiza" ***********************************************

IncrementaVisualiza incf Contador,Fmovlw D'7' ; Se sitúa en el centro de la línea 2.call LCD_PosicionLinea2movf Contador,Wandlw b'00011111' ; Se queda con las 5 líneas bajas: 32 posibilidadescall SignoQuiniela ; Lo convierte a signo de la quiniela.call LCD_Caracter ; Lo visualiza.

return

;******************************************** Subrutina "SignoQuiniela" ************************************************

SignoQuiniela addwf PCL,F

DT "1X121X121X121X1X1X121X121X121X12" ; 50% de "1", 28% de "X" y 21% de "2".

;***************************************** Subrutina "Mensajes" ********************************************************

Mensajes addwf PCL,F

MensajeQuiniela DT " Quiniela:", 0x00

;*********************************************** Librerías ****************************************************************

INCLUDE <RETARDOS.INC>INCLUDE <BIN_BCD.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>

END

8.18.- Mens_09.asm ( Entrenador Básico 6 ) title " La pantalla del LCD visualiza un mensaje en función de un pulsador "

;*********************************************** Mens_09.asm **********************************************************

; En pantalla visualiza "Cerrado" o "Abierto" según si un pulsador esta presionado o no.

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

;Programa para PIC 16F877.

143

Page 150: Entren Adores

;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

#DEFINE Pulsador PORTA,4 ; Línea donde se conecta el pulsador.

;************************************** Registros ************************************************************************

CBLOCK 0x20

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bsf Pulsador ; Línea del pulsador que se configura como entrada. bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

movlw MensajePulsadorcall LCD_Mensaje

;************************************* Principal **************************************************************************

Principal call LCD_Linea2movlw MensajeCerrado ; En principio considera que está presionado.btfsc Pulsador ; Lee el pulsador.movlw MensajeAbierto ; No, estaba en reposo.call LCD_Mensaje ; Visualiza el resultado.goto Principal

;*********************************** Subrutina "Mensajes" **************************************************************

144

Page 151: Entren Adores

Mensajes addwf PCL,F

MensajePulsador DT " Pulsador"MensajeAbierto DT " abIERto", 0x00MensajeCerrado DT " CErraDO", 0x00

;*********************************************** Librerías ****************************************************************

INCLUDE <RETARDOS.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>

END

8.19.- BIN_BCD.INC ( Entrenador Básico 6 )

;******************************************** Librería "BIN_BCD.INC" **************************************************;; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================;; Un número binario natural de 8 bits es convertido a BCD. El resultado se guarda en tres; posiciones de memorias llamadas: BCD_Centenas, BCD_Decenas y BCD_Unidades.;; El procedimiento utilizado es mediante restas de 10, tal como se explicó en el capítulo 9.;; Entrada: En el registro W el número binario natural a convertir.; Salidas: En (BCD_Centenas), (BCD_Decenas) y (BCD_Unidades).; En el registro W también las decenas (nibble alto) y unidades (nibble bajo).

;******************************************** Subrutina "BIN_a_BCD" **************************************************

CBLOCK ; En las subrutinas no se debe fijar la direcciónBCD_Centenas ; de la RAM de usuario. Se toma a continuación deBCD_Decenas ; la última asignada.BCD_UnidadesENDC

BIN_a_BCD clrf BCD_Centenas ; Carga los registros con el resultado inicial.clrf BCD_Decenas ; En principio las centenas y decenas a cero.movwf BCD_Unidades ; Se carga el número binario a convertir.

BCD_Resta10 movlw .10 ; A las unidades se les va restando 10 en cadasubwf BCD_Unidades,W ; pasada. (W)=(BCD_Unidades) -10.btfss STATUS,C ; ¿C = 1?, ¿(W) positivo?, ¿(BCD_Unidades)>=10?goto BIN_BCD_Fin ; No, es menor de 10. Se acabó.

BCD_IncrementaDecenas movwf BCD_Unidades ; Recupera lo que queda por restar.incf BCD_Decenas,F ; Incrementa las decenas y comprueba si ha movlw .10 ; llegado a 10. Lo hace mediante una resta.subwf BCD_Decenas,W ; (W)=(BCD_Decenas)-10).btfss STATUS,C ; ¿C = 1?, ¿(W) positivo?,

¿(BCD_Decenas)>=10?goto BCD_Resta10 ; No. Vuelve a dar otra pasada, restándole

; 10 a las unidades.BCD_IncrementaCentenas

clrf BCD_Decenas ; Pone a cero las decenas incf BCD_Centenas,F ; e incrementa las centenas.

145

Page 152: Entren Adores

goto BCD_Resta10 ; Otra pasada: Resta 10 al número a convertir.

BIN_BCD_Fin swapf BCD_Decenas,W ; En el nibble alto de (W) también las decenas.

addwf BCD_Unidades,W ; En el nibble bajo de (W) las unidades.return ; Vuelve al programa principal.

; La directiva "END" se debe poner en el programa principal no aquí.

8.20.- LCD_4BIT.INC ( Entrenador Básico 6 ) ; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================

;*********************************************** Librería "LCD_4BIT.INC" **********************************************;; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================;; Estas subrutinas permiten realizar las tareas básicas de control de un módulo LCD de 2; líneas por 16 caracteres, compatible con el modelo LM016L.;; El visualizador LCD está conectado al Puerto B del PIC mediante un bus de 4 bits. Las; conexiones son:; - Las 4 líneas superiores del módulo LCD, pines <DB7:DB4> se conectan a las 4; líneas superiores del Puerto B del PIC, pines <RB7:RB4>.; - Pin RS del LCD a la línea RA0 del PIC.; - Pin R/W del LCD a la línea RA1 del PIC, o a masa.; - Pin Enable del LCD a la línea RA2 del PIC.;; Se utilizan llamadas a subrutinas de retardo de tiempo localizadas en la librería RETARDOS.INC.;;***************************************************** Registros *********************************************************

CBLOCK

LCD_DatoLCD_GuardaDatoLCD_GuardaTRISBLCD_Auxiliar1LCD_Auxiliar2

ENDC

;***************************************************** Igualdades ********************************************************

LCD_CaracteresPorLinea EQU D’16’ ; Número de caracteres por línea de la pantalla.

#DEFINE LCD_PinRS PORTA,0#DEFINE LCD_PinRW PORTA,1#DEFINE LCD_PinEnable PORTA,2

146

Page 153: Entren Adores

#DEFINE LCD_BusDatos PORTB

; ********************************************* Subrutina "LCD_Inicializa" **********************************************

; Inicialización del módulo LCD: Configura funciones del LCD, produce reset por software,; borra memoria y enciende pantalla. El fabricante especifica que para garantizar la; configuración inicial hay que hacerla como sigue:;LCD_Inicializa bsf STATUS,RP0 ; Configura las líneas conectadas al pines RS,

bcf LCD_PinRS ; R/W y E.bcf LCD_PinEnablebcf LCD_PinRWbcf STATUS,RP0bcf LCD_PinRW ; En caso de que esté conectado le indica

; que se va a escribir en el LCD.bcf LCD_PinEnable ; Impide funcionamiento del LCD poniendo E=0.bcf LCD_PinRS ; Activa el Modo Comando poniendo RS=0.call Retardo_20msmovlw b'00110000'call LCD_EscribeLCD ; Escribe el dato en el LCD.call Retardo_5msmovlw b'00110000'call LCD_EscribeLCDcall Retardo_200microsmovlw b'00110000'call LCD_EscribeLCDmovlw b'00100000' ; Interface de 4 bits.call LCD_EscribeLCD

; Ahora configura el resto de los parámetros:

call LCD_2Lineas4Bits5x7 ; LCD de 2 líneas y caracteres de 5x7 puntos.call LCD_Borra ; Pantalla encendida y limpia. Cursor al principiocall LCD_CursorOFF ; de la línea 1. Cursor apagado.call LCD_CursorIncr ; Cursor en modo incrementar.

return

;***************************************** Subrutina "LCD_EscribeLCD" **********************************************

; Envía el dato del registro de trabajo W al bus de dato y produce un pequeño pulso en el pin; Enable del LCD. Para no alterar el contenido de las líneas de la parte baja del Puerto B que; no son utilizadas para el LCD (pines RB3:RB0), primero se lee estas líneas y después se; vuelve a enviar este dato sin cambiarlo.

LCD_EscribeLCD andlw b'11110000' ; Se queda con el nibble alto del dato que es elmovwf LCD_Dato ; que hay que enviar y lo guarda.movf LCD_BusDatos,W ; Lee la información actual de la parte bajaandlw b'00001111' ; del Puerto B, que no se debe alterar.iorwf LCD_Dato,F ; Enviará la parte alta del dato de entrada

; y en la parte baja lo que había antes.bsf STATUS,RP0 ; Acceso al Banco 1.movf TRISB,W ; Guarda la configuración que tenía antes TRISB.movwf LCD_GuardaTRISBmovlw b'00001111' ; Las 4 líneas inferiores del Puerto B se dejan andwf PORTB,F ; como estaban y las 4 superiores como salida.bcf STATUS,RP0 ; Acceso al Banco 0.

movf LCD_Dato,W ; Recupera el dato a enviar.

147

Page 154: Entren Adores

movwf LCD_BusDatos ; Envía el dato al módulo LCD.bsf LCD_PinEnable ; Permite funcionamiento del LCD mediante un

pequeño

bcf LCD_PinEnable ; pulso y termina impidiendo el funcionamiento del LCD.

bsf STATUS,RP0 ; Acceso al Banco 1. Restaura el antiguo valor enmovf LCD_GuardaTRISB,W ; la configuración del Puerto B.movwf PORTB ; Realmente es TRISB.bcf STATUS,RP0 ; Acceso al Banco 0.

return

; *******************************Subrutinas variadas para el control del módulo LCD *******************************

;Los comandos que pueden ser ejecutados son:

LCD_CursorIncr movlw b'00000110' ; Cursor en modo incrementar.goto LCD_EnviaComando

LCD_Linea1 movlw b'10000000' ; Cursor al principio de la Línea 1.goto LCD_EnviaComando ; Dirección 00h de la DDRAM

LCD_Linea2 movlw b'11000000' ; Cursor al principio de la Línea 2.goto LCD_EnviaComando ; Dirección 40h de la DDRAM

LCD_PosicionLinea1 iorlw b'10000000' ; Cursor a posición de la Línea 1, a partir de lagoto LCD_EnviaComando ; dirección 00h de la DDRAM más el valor del

; registro W.

LCD_PosicionLinea2 iorlw b'11000000' ; Cursor a posición de la Línea 2, a partir de lagoto LCD_EnviaComando ; dirección 40h de la DDRAM más el valor del

; registro W.

LCD_OFF movlw b'00001000' ; Pantalla apagada.goto LCD_EnviaComando

LCD_CursorON movlw b'00001110' ; Pantalla encendida y cursor encendido.goto LCD_EnviaComando

LCD_CursorOFF movlw b'00001100' ; Pantalla encendida y cursor apagado.goto LCD_EnviaComando

LCD_Borra movlw b'00000001' ; Borra toda la pantalla, memoria DDRAM y pone el goto LCD_EnviaComando ; cursor a principio de la línea 1.

LCD_2Lineas4Bits5x7 movlw b'00101000' ; Define la pantalla de 2 líneas, con caracteresgoto LCD_EnviaComando ; de 5x7 puntos y conexión al PIC mediante bus de

; 4 bits.

; *************************** Subrutinas "LCD_EnviaComando" y "LCD_Caracter" **********************************

; "LCD_EnviaComando". Escribe un comando en el registro del módulo LCD. La palabra de; comando ha sido entregada a través del registro W. Trabaja en Modo Comando.; "LCD_Caracter". Escribe en la memoria DDRAM del LCD el carácter ASCII introducido a; a través del registro W. Trabaja en Modo Dato.

LCD_EnviaComando bcf LCD_PinRS ; Activa el Modo Comando, poniendo RS=0.goto LCD_Envia

148

Page 155: Entren Adores

LCD_Carácter bsf LCD_PinRS ; Activa el "Modo Dato", poniendo RS=1.call LCD_CodigoCGROM ; Obtiene el código para correcta visualización.

LCD_Envia movwf LCD_GuardaDato ; Guarda el dato a enviar.call LCD_EscribeLCD ; Primero envía el nibble alto.swapf LCD_GuardaDato,W ; Ahora envía el nibble bajo. Para ello pasa el

; nibble bajo del dato a enviar a parte alta del byte.call LCD_EscribeLCD ; Se envía al visualizador LCD.btfss LCD_PinRS ; Debe garantizar una correcta escritura

call Retardo_2ms ; manteniendo 2 ms en modo comandocall Retardo_50micros ; y 50 µs en modo carácter.

return

;************************************** Subrutina "LCD_CodigoCGROM **********************************************

; A partir del carácter ASCII número 127 los códigos de los caracteres definidos en la; tabla CGROM del LM016L no coinciden con los códigos ASCII. Así por ejemplo, el código; ASCII de la "Ñ" en la tabla CGRAM del LM016L es EEh.;; Esta subrutina convierte los códigos ASCII de la "Ñ", "º" y otros, a códigos CGROM para que; que puedan ser visualizado en el módulo LM016L.; ; Entrada: En (W) el código ASCII del carácter que se desea visualizar.; Salida: En (W) el código definido en la tabla CGROM.

LCD_CodigoCGROM movwf LCD_Dato ; Guarda el valor del carácter y comprueba si es; un carácter especial.

LCD_EnheMinuscula sublw 'ñ' ; ¿Es la "ñ"?btfss STATUS,Zgoto LCD_EnheMayuscula ; No es "ñ".movlw b'11101110' ; Código CGROM de la "ñ".movwf LCD_Datogoto LCD_FinCGROM

LCD_EnheMayuscula movf LCD_Dato,W ; Recupera el código ASCII de entrada.sublw 'Ñ' ; ¿Es la "Ñ"?btfss STATUS,Zgoto LCD_Grado ; No es "Ñ".movlw b'11101110' ; Código CGROM de la "ñ". (No hay símbolo paramovwf LCD_Dato ; la "Ñ" mayúscula en la CGROM).goto LCD_FinCGROM

LCD_Grado movf LCD_Dato,W ; Recupera el código ASCII de entrada.sublw 'º' ; ¿Es el símbolo "º"?btfss STATUS,Zgoto LCD_FinCGROM ; No es "º".movlw b'11011111' ; Código CGROM del símbolo "º".movwf LCD_Dato

LCD_FinCGROM movf LCD_Dato,W ; En (W) el código buscado.

return

; ************************* Subrutina "LCD_DosEspaciosBlancos" y "LCD_LineaBlanco" **************************

; Visualiza espacios en blanco.

149

Page 156: Entren Adores

LCD_LineaEnBlanco movlw LCD_CaracteresPorLineagoto LCD_EnviaBlancos

LCD_UnEspacioBlanco movlw .1goto LCD_EnviaBlancos

LCD_DosEspaciosBlancos movlw .2goto LCD_EnviaBlancos

LCD_TresEspaciosBlancos movlw .3

LCD_EnviaBlancos movwf LCD_Auxiliar1 ; (LCD_Auxiliar1) se utiliza como contador.

LCD_EnviaOtroBlanco movlw ' ' ; Esto es un espacio en blanco.call LCD_Caracter ; Visualiza tanto espacios en blanco como decfsz LCD_Auxiliar1,F ; se haya cargado en (LCD_Auxiliar1).goto LCD_EnviaOtroBlanco

return

; **************************** Subrutinas "LCD_ByteCompleto" y "LCD_Byte" ***************************************

; Subrutina "LCD_ByteCompleto", visualiza el byte que almacena el registro W en el; lugar actual de la pantalla. Por ejemplo, si (W)=b'10101110' visualiza "AE".;; Subrutina "LCD_Byte" igual que la anterior, pero en caso de que el nibble alto sea cero ; visualiza en su lugar un espacio en blanco. Por ejemplo si (W)=b'10101110' visualiza "AE"; y si (W)=b'00001110', visualiza " E" (un espacio blanco delante).;; Utilizan la subrutina "LCD_Nibble" que se analiza más adelante.

LCD_Byte movwf LCD_Auxiliar2 ; Guarda el valor de entrada.andlw b'11110000' ; Analiza si el nibble alto es cero.btfss STATUS,Z ; Si es cero lo apaga.goto LCD_VisualizaAlto ; No es cero y lo visualiza.movlw ' ' ; Visualiza un espacio en blanco.call LCD_Caractergoto LCD_VisualizaBajo

LCD_ByteCompleto movwf LCD_Auxiliar2 ; Guarda el valor de entrada.

LCD_VisualizaAlto swapf LCD_Auxiliar2,W ; Pone el nibble alto en la parte baja.call LCD_Nibble ; Lo visualiza.

LCD_VisualizaBajo movf LCD_Auxiliar2,W ; Repite el proceso con el nibble bajo.call LCD_Nibble ; Lo visualiza.

return

; **************************************** Subrutina "LCD_Nibble" *****************************************************

; Visualiza en el lugar actual de la pantalla, el valor hexadecimal que almacena en el nibble; bajo del registro W. El nibble alto de W no es tenido en cuenta. Ejemplos:; - Si (W)=b'01010110', se visualizará "6". ; - Si (W)=b'10101110', se visualizará "E".

LCD_Nibble andlw b'00001111' ; Se queda con la parte baja.movwf LCD_Auxiliar1 ; Lo guarda.sublw 0x09 ; Comprueba si hay que representarlo con

150

Page 157: Entren Adores

btfss STATUS,C ; letra.goto LCD_EnviaByteLetramovf LCD_Auxiliar1,Waddlw '0' ; El número se pasa a carácter ASCII goto LCD_FinVisualizaDigito ; sumándole el ASCII del cero y lo visualiza.

LCD_EnviaByteLetra movf LCD_Auxiliar1,Waddlw 'A'-0x0A ; Sí, por tanto, se le suma el ASCII de la 'A'.

LCD_FinVisualizaDigitogoto LCD_Caracter ; Y visualiza el carácter. Se hace con un "goto"; para no sobrecargar la pila.

; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================

8.21.- LCD_MENS.INC ( Entrenador Básico 6 )

;******************************************** Librería "LCD_MENS.INC" ***********************************************;; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================;; Librería de subrutinas para el manejo de mensajes a visualizar en un visualizador LCD.

CBLOCKLCD_ApuntaCaracter ; Indica la posición del carácter a visualizar

; respecto del comienzo de todos los mensajes,; (posición de la etiqueta "Mensajes").

LCD_ValorCaracter ; Código ASCII del carácter a ENDC ; visualizar.

; Los mensajes tienen que estar situados dentro de las 256 primeras posiciones de la ; memoria de programa, es decir, no pueden superar la dirección 0FFh.

; *********************************************Subrutina "LCD_Mensaje" **********************************************;; Visualiza por pantalla el mensaje apuntado por el registro W.;; Los mensajes deben localizarse dentro de una zona encabezada por la etiqueta "Mensajes" y que; tenga la siguiente estructura:;; Mensajes addwf PCL,F ; ¡Etiqueta obligatoria!

; Mensaje0 DT ".. ..", 0x00 ; Posición inicial del mensaje.; ; Mensaje terminado en 0x00.; Mensaje1; ...; ...; FinMensajes;; La llamada a esta subrutina se realizará siguiendo este ejemplo:;

151

Page 158: Entren Adores

; movlw Mensaje0 ; Carga la posición del mensaje.; call LCD_Mensaje ; Visualiza el mensaje.;

LCD_Mensajemovwf LCD_ApuntaCaracter ; Posición del primer carácter del mensaje.movlw Mensajes ; Halla la posición relativa del primer caráctersubwf LCD_ApuntaCaracter,F ; del mensaje respecto de etiqueta "Mensajes".decf LCD_ApuntaCaracter,F ; Compensa la posición que ocupa "addwf PCL,F".

LCD_VisualizaOtroCaracter

movf LCD_ApuntaCaracter,Wcall Mensajes ; Obtiene el código ASCII del carácter apuntado.movwf LCD_ValorCaracter ; Guarda el valor de carácter.movf LCD_ValorCaracter,F ; Lo único que hace es posicionar flag Z. En casobtfsc STATUS,Z ; que sea "0x00", que es código indicador finalgoto LCD_FinMensaje ; de mensaje, sale fuera.

LCD_NoUltimoCaracter

call LCD_Caracter ; Visualiza el carácter ASCII leído.incf LCD_ApuntaCaracter,F ; Apunta a la posición del siguiente carácter goto LCD_VisualizaOtroCaracter ; dentro del mensaje.

LCD_FinMensaje

return ; Vuelve al programa principal.

; ******************************* Subrutina "LCD_MensajeMovimiento" ***********************************************;; Visualiza un mensaje de mayor longitud que los 16 caracteres que pueden representarse; en una línea, por tanto se desplaza a través de la pantalla.;; En el mensaje debe dejarse 16 espacios en blanco, al principio y al final para; conseguir que el desplazamiento del mensaje sea lo más legible posible.;

CBLOCKLCD_CursorPosicion ; Contabiliza la posición del cursor dentro de laENDC ; pantalla LCD

LCD_MensajeMovimiento

movwf LCD_ApuntaCaracter ; Posición del primer carácter del mensaje.movlw Mensajes ; Halla la posición relativa del primer caráctersubwf LCD_ApuntaCaracter,F ; del mensaje respecto de la etiqueta "Mensajes".decf LCD_ApuntaCaracter,F ; Compensa la posición que ocupa "addwf PCL,F".

LCD_PrimeraPosicion

clrf LCD_CursorPosicion ; El cursor en la posición 0 de la línea.call LCD_Borra ; Se sitúa en la primera posición de la línea 1 y

; borra la pantalla.LCD_VisualizaCaracter

movlw LCD_CaracteresPorLinea ; ¿Ha llegado a final de línea?subwf LCD_CursorPosicion,Wbtfss STATUS,Zgoto LCD_NoEsFinalLinea

152

Page 159: Entren Adores

LCD_EsFinalLinea

call Retardo_100ms ; Lo mantiene visualizado durante este tiempo.; call Retardo_200ms

movlw LCD_CaracteresPorLinea-1 ; Apunta a la posición del segundo caráctersubwf LCD_ApuntaCaracter,F ; visualizado en pantalla, que será el primero en la goto LCD_PrimeraPosicion ; siguiente visualización de línea, para producir el

; efecto de desplazamiento hacia la izquierda.

LCD_NoEsFinalLinea

movf LCD_ApuntaCaracter,Wcall Mensajes ; Obtiene el ASCII del carácter apuntado.movwf LCD_ValorCaracter ; Guarda el valor de carácter.movf LCD_ValorCaracter,F ; Lo único que hace es posicionar flag Z. En casobtfsc STATUS,Z ; que sea "0x00", que es código indicador finalgoto LCD_FinMovimiento ; de mensaje, sale fuera.

LCD_NoUltimoCaracter2

call LCD_Caracter ; Visualiza el carácter ASCII leído.incf LCD_CursorPosicion,F ; Contabiliza el incremento de posición del

; cursor en la pantalla.incf LCD_ApuntaCaracter,F ; Apunta a la siguiente posición por visualizar.goto LCD_VisualizaCaracter ; Vuelve a visualizar el siguiente carácter

; de la línea.LCD_FinMovimiento

return ; Vuelve al programa principal.

; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================

153

Page 160: Entren Adores

9.- Entrenador Básico 7

154

Page 161: Entren Adores

9.1.- Tecla_01.asm ( Entrenador Básico 7 ) title " La pantalla del LCD visualiza el orden de la tecla pulsada utilizando la técnica de polling"

;************************************** Tecla_01.asm *******************************************************************

; El modulo LCD visualiza el orden de la tecla pulsada expresado en decimal. Utiliza ; técnica Polling o lectura constante del puerto al que esta conectado el teclado.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;******************* Asignación de nombres de Registros de Funciones especiales a direcciones ***************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ************************************************************************

CBLOCK 0x20

GUARDA_TECLA ; Registro que guarda el orden de la tecla pulsada.

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración ********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.call Teclado_Inicializa ; Configura las líneas del teclado.

;************************************* Principal **************************************************************************

155

Page 162: Entren Adores

Principal call Teclado_LeeOrdenTecla ; Lee el teclado.btfss STATUS,C ; Si se pulsa alguna tecla el Cy=1 y salta una

instrucción.goto Fin ; No, por tanto sale.

movwf GUARDA_TECLA ; Guarda el orden de la tecla pulsada.call Teclado_EsperaDejePulsar ; No sale hasta que levante el dedo.

movf GUARDA_TECLA,Wcall BIN_a_BCD ; Lo pasa a BCD.

call LCD_ByteCompleto ; Visualiza en pantalla.

Fin goto Principal

;*********************************************** Librerías ****************************************************************

INCLUDE <TECLADO.INC>INCLUDE <BIN_BCD.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

9.2.- Tecla_02.asm ( Entrenador Básico 7 ) title " La pantalla del LCD visualiza el valor hexadecimal de la tecla pulsada utilizando la técnica de polling"

;************************************** Tecla_02.asm *******************************************************************

; En pantalla aparece el valor hexadecimal de la tecla pulsada. Se esta leyendo constantemente; el teclado mediante técnica Polling.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ***********************************************************************

156

Page 163: Entren Adores

CBLOCK 0x20

GUARDA_TECLA ; Registro que guarda el valor de la tecla pulsada.

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.call Teclado_Inicializa ; Configura las líneas del teclado.

;************************************* Principal **************************************************************************Principal call Teclado_LeeHex ; Lee el teclado hexadecimal.

btfss STATUS,C ; Si se pulsa alguna tecla el Cy=1 y salta una instrucción.

goto Fin ; No, por tanto, sale.

movwf GUARDA_TECLA ; Guarda el valor de la tecla pulsada.call Teclado_EsperaDejePulsar ; No sale hasta que levante el dedo.

movf GUARDA_TECLA,Wcall LCD_Nibble ; Visualiza el valor en pantalla.

Fin goto Principal

;*********************************************** Librerías ****************************************************************

INCLUDE <TECLADO.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

9.3.- Tecl_03.asm ( Entrenador Básico 7 ) title " La pantalla del LCD visualiza el valor hexadecimal de la tecla pulsada utilizando técnicas de interrupción "

;************************************************* Tecl_03.asm *********************************************************

; El modulo LCD visualiza el valor hexadecimal de la tecla pulsada. Para la lectura del; teclado se utiliza la interrupción RBI o por cambio en las líneas <RB7:RB4> del Puerto B.

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

;Programa para PIC 16F877.

157

Page 164: Entren Adores

;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ************************************************************************

CBLOCK 0x20

GUARDA_TECLA ; Registro que guarda el valor de la tecla pulsada.

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;************************************* Vector de Interrupción ***********************************************************

ORG 4 ;Dirección del Vector de Interrupción.

GOTO Interrup ;Ir a rutina de Interrupción

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.call Teclado_Inicializa ; Configura las líneas del teclado.movlw b'10001000' ; Habilita la interrupción RBI y la general.movwf INTCON

;************************************* Principal **************************************************************************

Principal sleep ; Espera en modo bajo consumo que pulse teclado. goto Principal

;************************************ Rutina de Interrupción "Interrup" *************************************************

Interrupcall Teclado_LeeHex ; Obtiene el valor hexadecimal de la tecla pulsada.

158

Page 165: Entren Adores

movwf GUARDA_TECLA ; Guarda el valor de la tecla pulsada.call Teclado_EsperaDejePulsar ; Para que no se repita el mismo carácter movf GUARDA_TECLA,Wcall LCD_Nibble ; Visualiza el valor en pantalla.movf PORTB,w ; Necesario en proteus para limpiar flag.bcf INTCON,RBIF ; mientras permanece pulsado. Limpia flag.retfie

;*********************************************** Librerías ****************************************************************

INCLUDE <TECLADO.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

9.4.- Tecla_04.asm ( Entrenador Básico 7 ) title " La pantalla del LCD visualiza caracteres españoles en función de la tecla pulsada "

;************************************************** Tecla_04.asm *******************************************************

; Supone un teclado con los 16 primeros caracteres del alfabeto español. Por tanto hay; que cambiar la tabla respecto de los ejercicios anteriores. Lo que se va escribiendo por ; el teclado aparece en pantalla como si fuera un teclado alfabético.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;*************************************** Registros ***********************************************************************

CBLOCK 0x20

GUARDA_TECLA ; Registro que guarda el valor de la tecla pulsada.

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

159

Page 166: Entren Adores

GOTO COMIENZO ;Comienzo del Programa

;************************************* Vector de Interrupción ***********************************************************

ORG 4 ;Dirección del Vector de Interrupción.

GOTO Interrup ;Ir a rutina de Interrupción

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.call Teclado_Inicializa ; Configura las líneas del teclado.movlw b'10001000' ; Habilita la interrupción RBI y la general.movwf INTCON

;************************************* Principal **************************************************************************

Principal sleep ; Espera en modo bajo consumo que pulse teclado. goto Principal

;************************************ Rutina de Interrupción "Interrup" ************************************************

; La subrutina de atención a la interrupción obtiene el valor ASCII de la tecla pulsada.; A continuación se expone la relaci0n entre el numero de orden de la tecla y los valores; correspondientes para el teclado supuesto.

; ORDEN DE TECLA: TECLADO UTILIZADO:; 0 1 2 3 A B C D; 4 5 6 7 E F G H; 8 9 10 11 I J K L; 12 13 14 15 M N O P

Interrupcall Teclado_LeeOrdenTecla ; Lee el Orden de la tecla pulsadamovwf GUARDA_TECLA ; Guarda el orden de la tecla pulsada.call Teclado_EsperaDejePulsar ; Para que no se repita el mismo carácter.movf GUARDA_TECLA,Wcall Tecl_ConvierteOrdenEnASCII ; Lo convierte en su valor ASCII mediantecall LCD_Caracter ; una tabla, y lo visualiza.

movf PORTB,W ; Necesario en proteus para limpiar flag.bcf INTCON,RBIF ; Limpia flag.retfie

;************************************ Subrutina " Tecl_ConvierteOrdenEnASCII " ************************************

Tecl_ConvierteOrdenEnASCII addwf PCL,F ; Según el teclado utilizado resulta

DT "ABCD" ; Primera fila del teclado.DT "EFGH" ; Segunda fila del teclado.DT "IJKL" ; Tercera fila del teclado.DT "MNÑO" ; Cuarta fila del teclado.

;*********************************************** Librerías ****************************************************************

INCLUDE <TECLADO.INC>

160

Page 167: Entren Adores

INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

9.5.- Tecla_05.asm ( Entrenador Básico 7 ) title " La pantalla del LCD aparece un mensaje en movimiento y fijo en la primera línea "title " y en la segunda línea visualiza la tecla pulsada "

;************************************************* Tecla_05.asm ********************************************************

; Primero aparece un mensaje de presentación en movimiento. Luego en la primera línea aparece; un mensaje estático y lo que se va escribiendo por el teclado aparece en la segunda fila.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;*************** Asignación de nombres de Registros de Funciones especiales a direcciones *******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;*************************************** Registros ***********************************************************************

CBLOCK 0x20

GUARDA_TECLA ; Registro que guarda el valor de la tecla pulsada.

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;************************************* Vector de Interrupción ***********************************************************

ORG 4 ;Dirección del Vector de Interrupción.

GOTO Interrup ;Ir a rutina de Interrupción;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.

161

Page 168: Entren Adores

bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

movlw Mensaje presentación ; Visualiza el mensaje en movimiento.call LCD_MensajeMovimientocall LCD_Borra ; Borra la pantalla y se sitúa en la primera línea.movlw MensajePulsa ; Visualiza el mensaje fijo de la primera línea.call LCD_Mensajecall LCD_Linea2 ; Pasa a la segunda línea.

call Teclado_Inicializa ; Configura las líneas del teclado.movlw b'10001000' ; Habilita la interrupción RBI y la general.movwf INTCON

;************************************* Principal **************************************************************************

Principal sleep ; Espera en modo bajo consumo que pulse teclado. goto Principal

;************************************ Rutina de Interrupción "Interrup" *************************************************

Interrupcall Teclado_LeeHex ; Obtiene el valor hexadecimal de la tecla pulsada.movwf GUARDA_TECLA ; Guarda el valor de la tecla pulsada.call Teclado_EsperaDejePulsar ; Para que no se repita el mismo carácter.

movf GUARDA_TECLA,Wcall LCD_Nibble ; Visualiza el valor en pantalla.

movf PORTB,W ; Necesario en proteus para limpiar flag.bcf INTCON,RBIFretfie

;******************************************* Subrutina de "Mensajes" **************************************************

Mensajes addwf PCL,F

MensajePresentacion DT " "DT "Estudia Desarrollo de Productos Electrónicos"DT " ", 0x00

MensajePulsa DT "LUCAS, pulsa:", 0x00

;*********************************************** Librerías ****************************************************************

INCLUDE <TECLADO.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <RETARDOS.INC>

END

9.6.- Tecla_06.asm ( Entrenador Básico 7 ) title " La pantalla del LCD aparece la tecla pulsada primero "title " la línea 1 y después en la línea 2 repitiéndose el proceso "

162

Page 169: Entren Adores

;************************************************* Tecla_06.asm ********************************************************

; En pantalla aparecen el código de las teclas que se van pulsando. Cuando llega al final de la primera; línea, pasa a la segunda línea. Cuando llega al final de la segunda línea borra todo y; comienza de nuevo al principio de la línea 1.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

CaracteresUnaLinea EQU d'16' ; Numero de caracteres de una línea.CaracteresDosLineas EQU d'32' ; Numero de caracteres de dos líneas.

;************************************** Registros ***********************************************************************

CBLOCK 0x20

GuardaTecla ; Guarda el valor de la tecla pulsada.ContadorCaracteres ; Guarda el numero de caracteres pulsados.

ENDC

;*********************************** Sección Código de Reset *********************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;************************************* Vector de Interrupción ***********************************************************

ORG 4 ;Dirección del Vector de Interrupción.

GOTO Interrup ;Ir a rutina de Interrupción

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1

163

Page 170: Entren Adores

bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

call Teclado_Inicializa ; Configura las líneas del teclado.movlw b'10001000' ; Habilita la interrupción RBI y la general.movwf INTCON

clrf ContadorCaracteres ; En principio no hay caracteres escritos.

;************************************* Principal **************************************************************************

Principal sleep ; Espera en modo bajo consumo que pulse teclado. goto Principal

;************************************ Rutina de Interrupción "Interrup" *************************************************

Interrup call Teclado_LeeHex ; Obtiene el valor de la tecla pulsada.movwf GuardaTecla ; Reserva el valor de la tecla pulsada.call Teclado_EsperaDejePulsar ; Para que no se repita el mismo carácter.movf GuardaTecla,Wmovlw CaracteresUnaLinea ; Comprueba si ha llegado al numero máximo desubwf ContadorCaracteres,W ; caracteres de una línea.btfsc STATUS,Zcall LCD_Linea2 ; Se sitúa en la segunda línea.movlw CaracteresDosLineas ; Comprueba si ha llegado al numero máximo desubwf ContadorCaracteres,W ; caracteres de dos líneas.btfss STATUS,Zgoto EscribeCaracter ; No, por tanto, sigue escribiendo.call LCD_Borra ; Si, borra pantalla e inicializa el contador.clrf ContadorCaracteres

EscribeCaracter incf ContadorCaracteres,F ; Un nuevo carácter escrito.movf GuardaTecla,Wcall LCD_Nibble ; Visualiza el carácter en pantalla.

movf PORTB,W ; Necesario en proteus para limpiar flag.bcf INTCON,RBIF ; Limpia flag.

retfie

;*********************************************** Librerías ****************************************************************

INCLUDE <TECLADO.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

9.7.- Tecla_07.asm ( Entrenador Básico 7 ) title " La pantalla del LCD aparece la tecla pulsada si esta es decimal "title " si se pulsa otra tecla borra pantalla "

164

Page 171: Entren Adores

;***************************************** Tecla_07.asm ****************************************************************

; Los valores decimales que va escribiendo por el teclado aparecen en pantalla. Si pulsa cualquier; otra tecla que no sea un numero decimal lo interpreta como tecla de borrado de pantalla.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;********************* Asignación de nombres de Registros de Funciones especiales a direcciones *************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;*************************************** Registros ***********************************************************************

CBLOCK 0x20

GuardaValor

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;************************************* Vector de Interrupción ***********************************************************

ORG 4 ;Dirección del Vector de Interrupción.

GOTO Interrup ;Ir a rutina de Interrupción

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

call Teclado_Inicializa ; Configura las líneas del teclado.movlw b'10001000' ; Habilita la interrupción RBI y la general.

165

Page 172: Entren Adores

movwf INTCON

;************************************* Principal **************************************************************************Principal sleep ; Espera en modo bajo consumo que pulse teclado.

goto Principal

;************************************ Rutina de Interrupción "Interrup" *************************************************

Interrup call Teclado_LeeHex ; Obtiene el valor hexadecimal de la tecla pulsada.movwf GuardaValor ; Guarda el valor leído.call Teclado_EsperaDejePulsar ; Para que no se repita el mismo carácter.movf GuardaValor,Wsublw 0x09 ; Comprueba si es mayor de 9.btfss STATUS,Cgoto BorraPantalla ; Si no es un carácter numérico salta a borrar.movf GuardaValor,W ; Recupera el valor leído y locall LCD_Nibble ; visualiza en la pantalla.goto limpiar_flag

BorraPantalla call LCD_Borra ; Borra la pantalla.

limpiar_flag movf PORTB,W ; Necesario en proteus para limpiar flag.bcf INTCON,RBIFretfie

;*********************************************** Librerías ****************************************************************

INCLUDE <TECLADO.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

9.8.- Tecla_08.asm ( Entrenador Básico 7 ) title " Suma el valor de tres teclas y aparece en el LCD "title " en decimal y hexadecimal "

;***************************************** Tecla_08.asm ****************************************************************

; Suma el valor de tres teclas pulsadas consecutivamente. En la primera línea de la pantalla del; modulo LCD aparece en hexadecimal y en la segunda en decimal. Así por ejemplo, si pulsa; "A", "6" y "F" en pantalla aparece:

; Hex: A+6+F=1F (Primera Línea); Dec: 10+06+15=31 (Segunda Línea)

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

166

Page 173: Entren Adores

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

;************************************** Registros ***********************************************************************

CBLOCK 0x20

ContadorTeclasPulsadasGuardaValorOperando1Operando2Operando3Resultado

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;************************************* Vector de Interrupción ***********************************************************

ORG 4 ;Dirección del Vector de Interrupción.

GOTO Interrup ;Ir a rutina de Interrupción

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.

call Teclado_Inicializa ; Configura las líneas del teclado.clrf ContadorTeclasPulsadas ; Resetea este contador.movlw b'10001000' ; Habilita la interrupción RBI y la general.movwf INTCON

;************************************* Principal **************************************************************************

Principal sleep ; Espera en modo bajo consumo que pulse teclado. goto Principal

;******************************* Macro "VisualizaHex" ******************************************************************

VisualizaHex MACRO Operando,Caracter

movf GuardaValor,W ; Recupera el valor y lo visualiza.movwf Operando ; Lo guarda para sumar después.call LCD_Nibble ; Visualiza el valor en la pantalla

167

Page 174: Entren Adores

movlw Caractercall LCD_Caracter ; Visualiza el signo '+' o '-' según corresponda.incf ContadorTeclasPulsadas,F

ENDM

;******************************* Macro "VisualizaDec" ******************************************************************

VisualizaDec MACRO Operando,Caracter

movf Operando,W ; (Operando) -> (W)call BIN_a_BCD ; Lo pasa a BCD.call LCD_ByteCompleto ; Visualiza en pantalla.movlw Caracter ; A continuación signo '+' o '=' según corresponda.call LCD_Caracter

ENDM

;************************************ Rutina de Interrupción "Interrup" ************************************************

Interrupcall Teclado_LeeHex ; Obtiene el valor hexadecimal de la tecla pulsada.movwf GuardaValor ; Guarda el valor leído.call Teclado_EsperaDejePulsar ; Para que no se repita el mismo carácter.movf ContadorTeclasPulsadas,W ; Según el numero de tecla pulsada realiza unaaddwf PCL,F ; función distinta.goto PrimeraTeclaPulsadagoto SegundaTeclaPulsadagoto TerceraTeclaPulsada

PrimeraTeclaPulsada call LCD_Borra ; Borra la pantalla anterior.movlw MensajeHex ; En pantalla el mensaje "Hex:"call LCD_MensajeVisualizaHex Operando1,'+'goto FinInterrupcion

SegundaTeclaPulsada VisualizaHex Operando2,'+'goto FinInterrupcion

TerceraTeclaPulsada VisualizaHex Operando3,'='movf Operando1,W ; Procede a la suma de los tres valores.addwf Operando2,Waddwf Operando3,Wmovwf Resultadocall LCD_Byte ; Visualiza el resultado.

call LCD_Linea2 ; Ahora visualiza la segunda línea.movlw MensajeDec ; En pantalla el mensaje "Dec:"call LCD_MensajeVisualizaDec Operando1,'+'VisualizaDec Operando2,'+'VisualizaDec Operando3,'='VisualizaDec Resultado,' 'clrf ContadorTeclasPulsadas ; Resetea este contador.

FinInterrupcion movf PORTB,W ; Necesario en proteus para limpiar flag.bcf INTCON,RBIFretfie

;************************************ Subrutina "Mensajes" *************************************************************

Mensajes addwf PCL,F

168

Page 175: Entren Adores

MensajeHex DT "Hex: ", 0x0MensajeDec DT "Dec: ", 0x0

;*********************************************** Librerías ****************************************************************

INCLUDE <TECLADO.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <RETARDOS.INC>INCLUDE <BIN_BCD.INC>

END

9.8.- Tecla_09.asm ( Entrenador Básico 7 )

title " Cerradura Electrónica "

;******************************************** Tecla_09.asm ************************************************************

; Cerradura Electrónica: la salida se activa cuando una clave de varios dígitos introducida; por teclado sea correcta.; Tiene una salida "CerraduraSalida" que, cuando se habilita, activa durante unos segundos; el electroimán de la cerradura permitiendo la apertura de la puerta:

; - Si (CerraduraSalida) = 1, la puerta se puede abrir.; - Si (CerraduraSalida) = 0, la puerta no se puede abrir.

;Funcionamiento:

; - En pantalla visualiza "Introduzca CLAVE". Según se va escribiendo, visualiza asteriscos '*'.; - Cuando termine de escribir la clave pueden darse dos posibilidades:

; - Si la clave es incorrecta la cerradura sigue inactivada, en pantalla aparece el mensaje; "Clave INCORRECTA" durante unos segundos y tiene que repetir de nuevo el proceso.

; - Si la clave es correcta la cerradura se activa durante unos segundos y la puerta; puede ser abierta. En pantalla aparece: "Clave CORRECTA" (primera línea) y "Abra; la puerta" (segunda línea). Pasados unos segundos, se repite el proceso.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32;************** Asignación de nombres de Registros de Funciones especiales a direcciones ********************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

169

Page 176: Entren Adores

;************************************** Igualdades ***********************************************************************

; La clave puede tener cualquier tamaño y su longitud se calcula:

#DEFINE LongitudClave (FinClaveSecreta-ClaveSecreta)

#DEFINE CerraduraSalida PORTA,3

;************************************** Registros ***********************************************************************

CBLOCK 0x20

ContadorCaracteresGuardaClaveTecleada

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;************************************* Vector de Interrupción ***********************************************************

ORG 4 ;Dirección del Vector de Interrupción.

GOTO Interrup ;Ir a rutina de Interrupción.

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1bcf CerraduraSalida ; Define como salida.bcf STATUS,RP0 ; Ir al Banco 0.call LCD_Inicializa ; Inicializar el LCD.call InicializaTodo ; Inicializa el resto de los registros.call Teclado_Inicializa ; Configura las líneas del teclado.movlw b'10001000' ; Habilita la interrupción RBI y la general.movwf INTCON

;************************************* Principal **************************************************************************

Principal sleep ; Espera en modo bajo consumo que pulse teclado. goto Principal

;************************************ Rutina de Interrupción "Interrup" *************************************************

Interrup call Teclado_LeeHex ; Obtiene el valor hexadecimal de la tecla pulsada.

; Según va introduciendo los dígitos de la clave, estos van siendo almacenados a partir de; las posiciones RAM "ClaveTecleada" mediante direccionamiento indirecto y utilizando el ; FSR como apuntador. Por cada dígito leído en pantalla se visualiza un asterisco.

movwf INDF ; Almacena ese digito en memoria RAM con; con direccionamiento indirecto apuntado por FSR.

call Teclado_EsperaDejePulsarmovlw '*' ; Visualiza asterisco.

170

Page 177: Entren Adores

call LCD_Caracterincf FSR,F ; Apunta a la próxima posición de RAM.incf ContadorCaracteres,F ; Cuenta el numero de teclas pulsadas.movlw LongitudClave ; Comprueba si ha introducido tantos caracteressubwf ContadorCaracteres,W ; como longitud tiene la clave secreta.btfss STATUS,C ; Ha terminado de introducir caracteres?goto Fin_Interr ; No, pues lee el siguiente carácter tecleado.

; Si ha llegado aquí es porque ha terminado de introducir el máximo de dígitos. Ahora; procede a comprobar si la clave es correcta. Para ello va comparando cada uno de los; dígitos almacenados en las posiciones RAM a partir de "ClaveTecleada" con el valor; correcto de la clave almacenado en la posición ROM "ClaveSecreta".

; Para acceder a las posiciones de memoria RAM a partir de "ClaveTecleada" utiliza; direccionamiento indirecto siendo FSR el apuntador.

; Para acceder a memoria ROM "ClaveSecreta" se utiliza direccionamiento indexado con el; el registro ContadorCaracteres como apuntador.

call LCD_Borra ; Borra la pantalla.clrf ContadorCaracteres ; Va a leer el primer carácter almacenado en ROM.movlw ClaveTecleada ; Apunta a la primera posición de RAM donde se hamovwf FSR ; guardado la clave tecleada.

Comp_Claves movf INDF,W Lee la clave tecleada y guardada en RAM.movwf GuardaClaveTecleada ; La guarda para compararla después.movf ContadorCaracteres,W ; Apunta al carácter de ROM a leer.call LeeClaveSecreta ; En (W) el carácter de la clave secreta.subwf GuardaClaveTecleada,W ; Se comparan.btfss STATUS,Z ; Son iguales?, Z=1?goto ClaveIncorr ; No, pues la clave tecleada es incorrecta.incf FSR,F ; Apunta a la próxima posición de RAM.incf ContadorCaracteres,F ; Apunta a la próxima posición de ROM.movlw LongitudClave ; Comprueba si ha comparado tantos caracteressubwf ContadorCaracteres,W ; como longitud tiene la clave secreta.btfss STATUS,C ; Ha terminado de comparar caracteres?goto Comp_Claves ; No, pues compara el siguiente carácter.

ClaveCorrecta movlw MensajeClaveCorrecta ; La clave ha sido correcta. Aparecen los mensajescall LCD_Mensaje ; correspondientes y permite la apertura de la

; puerta durante unos segundos.call LCD_Linea2movlw MensajeAbraPuertacall LCD_Mensajebsf CerraduraSalida ; Activa la cerradura durante unos

segundos.goto Retardo

ClaveIncorr movlw MensajeClaveIncorrectacall LCD_Mensajegoto Retardo1

Retardo call Retardo_2sRetardo1 call Retardo_500ms

call InicializaTodo

Fin_Interr movf PORTB,Wbcf INTCON,RBIF

171

Page 178: Entren Adores

retfie

;*********************************** Subrutina "InicializaTodo" ********************************************************

InicializaTodo bcf CerraduraSalida ; Desactiva la cerradura.clrf ContadorCaracteres ; Inicializa este contador.movlw ClaveTecleada ; FSR apunta a la primera dirección de la RAMmovwf FSR ; donde se va a almacenar la clave tecleada.call LCD_Borra ; Borra la pantalla.movlw MensajeTeclee ; Aparece el mensaje para que introduzca la clave. call LCD_Mensajecall LCD_Linea2 ; Los asteriscos se visualizan en la segunda línea.

return

;************************************ Subrutina "Mensajes" *************************************************************

Mensajes addwf PCL,F

MensajeTeclee DT "Teclee CLAVE:", 0x00MensajeClaveCorrecta DT "Clave CORRECTA", 0x00MensajeAbraPuerta DT "Abra la puerta", 0x00MensajeClaveIncorrecta DT "Clave INCORRECTA", 0x00

;************************************ Subrutina "LeeClaveSecreta" ****************************************************

LeeClaveSecreta addwf PCL,F

ClaveSecreta DT 4h,5h,6h,1h ; Ejemplo de clave secreta.DT 7h,8h

FinClaveSecreta

;*********************************************** Librerías ****************************************************************

INCLUDE <TECLADO.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <RETARDOS.INC>

;***************************************** Dirección de comienzo del puntero FSR ***********************************

; Las posiciones de memoria RAM donde se guardara la clave leída se definen al final, después; de las Librerías, ya que van a ocupar varias posiciones de memoria mediante el ; direccionamiento indirecto utilizado.

CBLOCK

ClaveTecleada

ENDC

END ; Fin del programa.

172

Page 179: Entren Adores

10.- Entrenador Básico 7-1

173

Page 180: Entren Adores

10.1.- Tecla_10.asm ( Entrenador Básico 7-1 )

title " Cerradura Electrónica activando un motor PAP"

;******************************************** Tecla_09.asm *************************************************************; Cerradura Electrónica: la salida se activa cuando una clave de varios dígitos introducida; por teclado sea correcta.

; Tiene una salida "CerraduraSalida" que, cuando se habilita, activa durante unos segundos; el electroimán de la cerradura permitiendo la apertura de la puerta:

; - Si (CerraduraSalida) = 1, la puerta se puede abrir.; - Si (CerraduraSalida) = 0, la puerta no se puede abrir.

;Funcionamiento:

; - En pantalla visualiza "Introduzca CLAVE". Según se va escribiendo, visualiza asteriscos '*'.; - Cuando termine de escribir la clave pueden darse dos posibilidades:

; - Si la clave es incorrecta la cerradura sigue inactivada, en pantalla aparece el mensaje; "Clave INCORRECTA" durante unos segundos y tiene que repetir de nuevo el proceso.

; - Si la clave es correcta la cerradura se activa durante unos segundos y la puerta; puede ser abierta. En pantalla aparece: "Clave CORRECTA" (primera línea) y "Abra; la puerta" (segunda línea). Pasados unos segundos, se repite el proceso.

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

;Programa para PIC 16F877.;Velocidad del Reloj:1 MHz.;Reloj instrucción: 250 KHz = 4 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;****************** Asignación de nombres de Registros de Funciones especiales a direcciones ****************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

; La clave puede tener cualquier tamaño y su longitud se calcula:

#DEFINE LongitudClave (FinClaveSecreta-ClaveSecreta)

;************************************** Registros ***********************************************************************

; Las posiciones de memoria RAM donde se guardara la clave leída, se inicializa con una posición fija ; "ClaveTecleada", antes de las reservadas con las seudoinstrucciones CBLOCK, ya que van a ; ocupar varias posiciones de memoria mediante el direccionamiento indirecto.

174

Page 181: Entren Adores

ClaveTecleada equ 0x20

CBLOCK 0x30

ContadorCaracteresGuardaClaveTecleadaContadorPAP

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;************************************* Vector de Interrupción ***********************************************************

ORG 4 ;Dirección del Vector de Interrupción.

GOTO Interrup ;Ir a rutina de Interrupción.

;*********************************** Sección de Configuración *********************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como señales digitales.movwf ADCON1clrf TRISD ; Poner el PORTD como salida de datos.clrf TRISC ; Poner el PORTC como salida de datos.bcf STATUS,RP0 ; Ir al Banco 0.movlw D'09' ; Inicializar el motor PAP en una posición inicial.movwf PORTCclrf ContadorPAPcall LCD_Inicializa ; Inicializar el LCD.call InicializaTodo ; Inicializa el resto de los registros.call Teclado_Inicializa ; Configura las líneas del teclado.movlw b'10001000' ; Habilita la interrupción RBI y la general.movwf INTCON

;************************************* Principal **************************************************************************

Principal sleep ; Espera en modo bajo consumo que pulse teclado. goto Principal

;************************************ Rutina de Interrupción "Interrup" *************************************************

Interrupcall Teclado_LeeHex ; Obtiene el valor hexadecimal de la tecla pulsada.

; Según va introduciendo los dígitos de la clave, estos van siendo almacenados a partir de; las posiciones RAM "ClaveTecleada" mediante direccionamiento indirecto y utilizando el ; FSR como apuntador. Por cada digito leído en pantalla se visualiza un asterisco.

movwf INDF ; Almacena ese digito en memoria RAM con; con direccionamiento indirecto apuntado por FSR.

call Teclado_EsperaDejePulsarmovlw '*' ; Visualiza asterisco.call LCD_Caracterincf FSR,F ; Apunta a la próxima posición de RAM.

175

Page 182: Entren Adores

incf ContadorCaracteres,F ; Cuenta el numero de teclas pulsadas.movlw LongitudClave ; Comprueba si ha introducido tantos caracteressubwf ContadorCaracteres,W ; como longitud tiene la clave secreta.btfss STATUS,C ; Ha terminado de introducir caracteres?goto Fin_Interr ; No, pues lee el siguiente carácter tecleado.

; Si ha llegado aquí es porque ha terminado de introducir el máximo de dígitos. Ahora; procede a comprobar si la clave es correcta. Para ello va comparando cada uno de los; dígitos almacenados en las posiciones RAM a partir de "ClaveTecleada" con el valor; correcto de la clave almacenado en la posición ROM "ClaveSecreta".

; Para acceder a las posiciones de memoria RAM a partir de "ClaveTecleada" utiliza; direccionamiento indirecto siendo FSR el apuntador.

; Para acceder a memoria ROM "ClaveSecreta" se utiliza direccionamiento indexado con el; el registro ContadorCaracteres como apuntador.

call LCD_Borra ; Borra la pantalla.clrf ContadorCaracteres ; Va a leer el primer carácter almacenado en ROM.movlw ClaveTecleada ; Apunta a la primera posición de RAM donde se hamovwf FSR ; guardado la clave tecleada.

Comp_Claves movf INDF,W ; Lee la clave tecleada y guardada en RAM.movwf GuardaClaveTecleada ; La guarda para compararla después.movf ContadorCaracteres,W ; Apunta al carácter de ROM a leer.call LeeClaveSecreta ; En (W) el carácter de la clave secreta.subwf GuardaClaveTecleada,W ; Se comparan.btfss STATUS,Z ; Son iguales?, Z=1?goto ClaveIncorr ; No, pues la clave tecleada es incorrecta.incf FSR,F ; Apunta a la próxima posición de RAM.incf ContadorCaracteres,F ; Apunta a la próxima posición de ROM.movlw LongitudClave ; Comprueba si ha comparado tantos caracteressubwf ContadorCaracteres,W ; como longitud tiene la clave secreta.btfss STATUS,C ; Ha terminado de comparar caracteres?goto Comp_Claves ; No, pues compara el siguiente carácter.

ClaveCorrecta movlw MensajeClaveCorrecta ; La clave ha sido correcta. Aparecen los mensajescall LCD_Mensaje ; correspondientes y permite la apertura de la

; puerta durante unos segundos.call LCD_Linea2 ; Mostrar mensaje "Espere por favor"movlw MensajeEsperarcall LCD_Mensaje

Abrir_puerta movf ContadorPAP,W ; Abrir puertacall codigos_PAPmovwf PORTCcall Retardo_100msmovlw D'08'subwf ContadorPAP,Wbtfss STATUS,Zgoto inc_cont_papgoto esperar

inc_cont_pap incf ContadorPAP,Fgoto Abrir_puerta

esperar bcf PORTD,1 ; Marcar el LED de Abierto.bsf PORTD,0call LCD_Linea1movlw MensajeAbraPuerta ; Mostrar mensaje "Abra la puerta"

176

Page 183: Entren Adores

call LCD_Mensajecall LCD_Linea2movlw Tiempo1 ; Mostrar mensaje "Tienes 10 Seg."call LCD_Mensajecall Retardo_2s ; Retardo de 10 Seg.call LCD_Borra

Cerrar_puerta bsf PORTD,1 ; Cerrar la puerta bcf PORTD,0 ; Marcar el LED de Cerrado.decf ContadorPAP,F

sigui_codigo movf ContadorPAP,Wcall codigos_PAPmovwf PORTCcall Retardo_100msdecfsz ContadorPAP,Fgoto sigui_codigomovf ContadorPAP,Wcall codigos_PAPmovwf PORTCcall Retardo_100msgoto ir_inicializar

ClaveIncorr movlw MensajeClaveIncorrecta ; Mostrar mensaje "Clave INCORRECTA"call LCD_Mensajecall Retardo_500ms

ir_inicializar call InicializaTodo ; Inicializar proceso.movlw B'11110000' ; Necesario en proteus para que el teclado pueda

interrumpir.movwf PORTB

Fin_Interrmovf PORTB,W ; Necesario en proteus para borrar el flag.bcf INTCON,RBIF

retfie

;*********************************** Subrutina "InicializaTodo" ********************************************************

InicializaTodo bsf PORTD,1 ; Marcar el LED de Cerrado.bcf PORTD,0clrf ContadorCaracteres ; Inicializa este contador.movlw ClaveTecleada ; FSR apunta a la primera direccion de la RAMmovwf FSR ; donde se va a almacenar la clave tecleada.call LCD_Borra ; Borra la pantalla.movlw MensajeTeclee ; Aparece el mensaje para que introduzca la clave. call LCD_Mensajecall LCD_Linea2 ; Los asteriscos se visualizan en la segunda linea.

return

;************************************ Subrutina "Mensajes" *************************************************************

Mensajes addwf PCL,F

MensajeTeclee DT "Teclee CLAVE:", 0x00MensajeClaveCorrecta DT "Clave CORRECTA", 0x00MensajeAbraPuerta DT "Abra la puerta", 0x00MensajeEsperar DT "Espere por favor", 0x00MensajeClaveIncorrecta DT "Clave INCORRECTA", 0x00

177

Page 184: Entren Adores

Tiempo1 DT "Tienes 10 Seg. ", 0x00

;************************************ Subrutina "LeeClaveSecreta" ****************************************************

LeeClaveSecreta addwf PCL,F

ClaveSecreta DT 4h,5h,6h,1h ; Ejemplo de clave secreta.DT 7h,8h

FinClaveSecreta

;****************************************** Subrutina "Motor_PAP" *****************************************************

codigos_PAP addwf PCL,F

DT 09h,08h,0Ch,04h,06h,02h,03h,01h ; Secuencia de códigos para hacer ; funcionar el Motor PAP a medio paso.

;*********************************************** Librerías ****************************************************************

INCLUDE <TECLADO.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <RETARDOS.INC>

END ; Fin del programa.

178

Page 185: Entren Adores

11.- Entrenador Básico 8

179

Page 186: Entren Adores
Page 187: Entren Adores

11.1.- I2C1.asm ( Entrenador Básico 8 )

title " Leer un dato del circuito integrado expansor de bus PCF8476 y transmitirlo a través "title " del bus I2C al microprocesador. Transferir el dato del microprocesador a otro C.I. PCF8476"

;******************************************** I2C1.asm ******************************************************************

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;********** Asignación de nombres de Registros de Funciones especiales a direcciones ************************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

ESCLAVO1 EQU B'01000001' ; Escribimos la dirección del Esclavo1 receptor.ESCLAVO2 EQU B'01001000' ; Escribimos la dirección del Esclavo2 transmisor.

;**************************** Registros **********************************************************************************

CBLOCK 0X20

GUARDAR_DATO

ENDC

;********************************* Sección Código de Reset ***********************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;******************************************* Sección de Configuración *************************************************

ORG 0X05 ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO CALL Config_transmisión_I2C ; Configuracion Bus_I2C

;**************************************************** Principal **********************************************************

RECIBIR CALL Bit_start_I2C ; Llamar a la subrutina de Comienzo.

MOVLW ESCLAVO1 ; Seleccionar esclavo de recepción. ( 0100,A2,A1,A0,1 )

179

Page 188: Entren Adores

CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.; (A2,A1,A0)=(000) por hardware. ; El ultimo BIT a 1 para poner el C.I. PCF8476 como ; receptor.

CALL Recibir_dato_I2C ; Llamar a la subrutina de recepción de datos.MOVWF GUARDAR_DATO ; Guardar dato recibido en el registro GUARDAR_DATO.

CALL ReStart_I2C ; Llamar a la subrutina de comenzar sin pasar por parada.

TRANSMITIR MOVLW ESCLAVO2 ; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(100) por hardware. ; El ultimo BIT a 0 para poner el C.I. PCF8476 como ; transmisor.

COMF GUARDAR_DATO,W ; Complementar el contenido del registro GUARDAR_DATO; y guardarlo en W.

CALL Transmitir_dato_I2C ; Llamar a la subrutina de transmisión de datos.

CALL Bit_stop_I2C ; Llamar a la subrutina de parada.

GOTO RECIBIR ; Repetir proceso.

;*************************************************** LIBRERIAS *********************************************************

INCLUDE <I2C.INC> ; Librería de control de bus I2C.

END

11.2.- I2C2.asm ( Entrenador Básico 8 ) title " Leer un dato del circuito integrado expansor de bus PCF8476 y transmitirlo a través "title " del bus I2C al microprocesador. Transferir el dato del microprocesador a otro C.I. PCF8476"title " interrumpiendo un programa principal "

;******************************************** I2C2.asm ******************************************************************

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;************** Asignación de nombres de Registros de Funciones especiales a direcciones ********************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

180

Page 189: Entren Adores

;************************************** Igualdades ***********************************************************************

ESCLAVO1 EQU B'01000001' ; Escribimos la dirección del Esclavo1 receptor.ESCLAVO2 EQU B'01001000' ; Escribimos la dirección del Esclavo2 transmisor.

;**************************** Registros **********************************************************************************CBLOCK 0X20

GUARDAR_DATO

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************************** Vector de Interrupción ********************************************************

ORG 0X04

GOTO INTERRUP ; Ir a la rutina de Interrupción.

;********************************************** Sección de Configuracion **********************************************

ORG 0X05 ; Inicio de Programa (Una posición detrás del vector de Interrupción)

COMIENZO CALL Config_transmisión_I2C ; Configuracion Bus_I2C

BSF STATUS,RP0 ; Ir al Banco 1.

BCF OPTION_REG,INTEDG ; Interrupción por flanco descendente.BCF OPTION_REG,7 ; Activamos las resistencias PULL-UP del PORTBBSF INTCON,INTF ; Ponemos a 1 la Bandera de Interrupción de las Patilla INT.BSF INTCON,INTE ; Permitimos la interrupción INT.BSF INTCON,GIE ; Activamos todas las interrupciones.

BCF STATUS,RP0 ; Ir al Banco 0.

;**************************************************** Principal **********************************************************

SLEEP ; Entra el microcontrolador en modo sueño.

Goto $-1

;********************************************** Rutina de Interrupción **************************************************

INTERRUP CALL Bit_start_I2C ; Llamar a la subrutina de Comienzo.

MOVLW ESCLAVO1 ; Seleccionar esclavo de recepción. ( 0100,A2,A1,A0,1 )CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(000) por hardware. ; El ultimo BIT a 1 para poner el C.I. PCF8476 como

receptor.

CALL Recibir_dato_I2C ; Llamar a la subrutina de recepción de datos.MOVWF GUARDAR_DATO ; Guardar dato recibido en el registro GUARDAR_DATO.

181

Page 190: Entren Adores

CALL ReStart_I2C ; Llamar a la subrutina de comenzar sin pasar por parada.

TRANSMITIR MOVLW ESCLAVO2 ; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(100) por hardware. ; El ultimo BIT a 0 para poner el C.I. PCF8476 como ; transmisor.

COMF GUARDAR_DATO,W ; Complementar el contenido del registro GUARDAR_DATO ;y guardarlo en W.

CALL Transmitir_dato_I2C ; Llamar a la subrutina de transmisión de datos.

CALL Bit_stop_I2C ; Llamar a la subrutina de parada.

BCF INTCON,INTF ; Ponemos a 0 la Bandera de Interrupción de la Patilla INT.

RETFIE

;*************************************************** LIBRERIAS *********************************************************

INCLUDE <I2C.INC> ; Librería de control de bus I2C.

END

11.3.- I2C3.asm ( Entrenador Básico 8 )

title " Realizar una conversión Analógica / Digital y transmitirla a los expansores de bus PCF8476 "

;******************************************** I2C3.asm ******************************************************************

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

ESCLAVO1 EQU B'01000000' ; Escribimos la dirección del Esclavo1 transmisor.ESCLAVO2 EQU B'01001000' ; Escribimos la dirección del Esclavo2 transmisor.

;**************************** Registros **********************************************************************************

182

Page 191: Entren Adores

CBLOCK 0X20

GUARDAR_DATO

ENDC

;************************************* Sección Código de Reset *******************************************************

ORG 0 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;************************************* Sección de Configuracion *******************************************************

ORG 0X05 ; Inicio de Programa (Una posición detrás del vector de Interrupción).

COMIENZO BSF STATUS,RP0 ; Ir al Banco 1.BSF TRISA,5 ; Configuracion del Conversor Analogico/Digital.MOVLW B'00000000'MOVWF ADCON1BCF STATUS,RP0MOVLW B'00100001'MOVWF ADCON0

CALL Config_transmision_I2C ; Configuracion Bus_I2C

;**************************************************** Principal **********************************************************

SEG2 CALL Retardo_100ms ; Esperar un tiempo de adquisición de 100 mS.

BSF ADCON0,GO_DONE ; Lanzar el Conversor Analogico/Digital.SEG1 BTFSC ADCON0,GO_DONE

GOTO SEG1

MOVF ADRESH,W ; Preguntamos si el dato convertido es idéntico al anterior.SUBWF GUARDAR_DATO,WBTFSC STATUS,ZGOTO SEG2MOVF ADRESH,W ; Guardamos dato nuevo.MOVWF GUARDAR_DATO

CALL Bit_start_I2C ; Llamar a la subrutina de Comienzo.

MOVLW ESCLAVO2 ; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 )CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(100) por hardware. ; El ultimo BIT a 0 para poner el C.I. PCF8476 como; transmisor.

MOVF GUARDAR_DATO,W ; Guardar el contenido del registro GUARDAR_DATO en W.CALL Transmitir_dato_I2C ; Llamar a la subrutina de transmisión de datos.

CALL Bit_stop_I2C ; Llamar a la subrutina de parada.

CALL Bit_start_I2C ; Llamar a la subrutina de Comienzo.

MOVLW ESCLAVO1 ; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(000) por hardware.

183

Page 192: Entren Adores

; El ultimo BIT a 0 para poner el C.I. PCF8476 como; transmisor.

COMF GUARDAR_DATO,W ; Complementar el contenido del registro GUARDAR_DATO; y guardarlo en W.

CALL Transmitir_dato_I2C ; Llamar a la subrutina de transmisión de datos.

CALL Bit_stop_I2C ; Llamar a la subrutina de parada.

GOTO SEG2

;************************************************** LIBRERIAS **********************************************************

INCLUDE <I2C.INC>INCLUDE <Retardos.INC>

END

184

Page 193: Entren Adores
Page 194: Entren Adores

12.- Entrenador Básico 8-1

186

Page 195: Entren Adores

12.1.- I2C4.asm ( Entrenador Básico 8-1 )title " Leer datos cada vez que activamos un Pulsador, de circuitos integrados expansores title " de bus PCF8476 y transmitirlo a través del bus I2C al microprocesador. "title " Transferir los datos del microprocesador a otros C.I. PCF8476"

;******************************************** I2C4.asm ******************************************************************

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;*************** Asignación de nombres de Registros de Funciones especiales a direcciones *******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

ESCLAVO1 EQU B'01000001' ; Escribimos la dirección del Esclavo1 receptor.ESCLAVO2 EQU B'01000011' ; Escribimos la dirección del Esclavo2 receptor.ESCLAVO3 EQU B'01001000' ; Escribimos la dirección del Esclavo3 transmisor.ESCLAVO4 EQU B'01001100' ; Escribimos la dirección del Esclavo4 transmisor.

;**************************** Registros *********************************************************************************

CBLOCK 0X20

GUARDAR_DATO

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Sección de Configuracion ****************************************************************

ORG 0X05 ; Inicio de Programa (Una posición detrás del vector de Interrupción).

COMIENZO CALL Config_transmisión_I2C ; Configuracion Bus_I2C

BSF STATUS,RP0 ; Ir al Banco 1BSF TRISB,0 ; Poner PB0 como entrada de datos.BCF STATUS,RP0 ; Ir al Banco 0

;**************************************************** Principal **********************************************************

187

Page 196: Entren Adores

SEG1 BTFSC PORTB,0 ; Se pregunta si esta pulsado PB0.GOTO SEG1

CALL Bit_start_I2C ; Llamar a la subrutina de Comienzo.

MOVLW ESCLAVO1 ; Seleccionar esclavo de recepción. ( 0100,A2,A1,A0,1 )CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(000) por hardware. ; El ultimo BIT a 1 para poner el C.I. PCF8476 como; receptor.

CALL Recibir_dato_I2C ; Llamar a la subrutina de recepción de datos.MOVWF GUARDAR_DATO ; Guardar dato recibido en el registro GUARDAR_DATO.

CALL ReStart_I2C ; Llamar a la subrutina de comenzar sin pasar por parada.

MOVLW ESCLAVO3 ; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(100) por hardware. ; El ultimo BIT a 0 para poner el C.I. PCF8476 como; transmisor.

MOVF GUARDAR_DATO,W ; Guardar el contenido del registro GUARDAR_DATO en W.CALL Transmitir_dato_I2C ; Llamar a la subrutina de transmisión de datos.

CALL Bit_stop_I2C ; Llamar a la subrutina de parada.

CALL Bit_start_I2C ; Llamar a la subrutina de Comienzo.

MOVLW ESCLAVO2 ; Seleccionar esclavo de recepción. ( 0100,A2,A1,A0,1 )CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(001) por hardware. ; El ultimo BIT a 1 para poner el C.I. PCF8476 como ; receptor.

CALL Recibir_dato_I2C ; Llamar a la subrutina de recepción de datos.MOVWF GUARDAR_DATO ; Guardar dato recibido en el registro GUARDAR_DATO.

CALL ReStart_I2C ; Llamar a la subrutina de comenzar sin pasar por parada.

MOVLW ESCLAVO4 ; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(110) por hardware. ; El ultimo bit a 0 para poner el C.I. PCF8476 como; transmisor.

MOVF GUARDAR_DATO,W ; Guardar el contenido del registro GUARDAR_DATO en W.CALL Transmitir_dato_I2C ; Llamar a la subrutina de transmisión de datos.

CALL Bit_stop_I2C ; Llamar a la subrutina de parada.

SEG2 BTFSS PORTB,0 ; Si sigue pulsado PB0 no retornar.GOTO SEG2GOTO SEG1

;**************************************************** LIBRERIAS ********************************************************

INCLUDE <I2C.INC> ; Libreria de control de bus I2C.

END

12.2.- I2C5.asm ( Entrenador Básico 8-1 )

188

Page 197: Entren Adores

title " Leer datos de circuitos integrados expansores de bus PCF8476title " y transmitirlo a través del bus I2C al microprocesador. "title " Transferir los datos del microprocesador a otros C.I. PCF8476"title " interrumpiendo un programa principal "

;******************************************** I2C5.asm ******************************************************************

;Programa para PIC 16F877.;Velocidad del Reloj:4 MHz.;Reloj instrucción: 1 MHz = 1 uS.;Perro Guardián deshabilitado.;Tipo de Reloj XT.;Protección de Código: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f877, f=inhx32

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f877.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

ESCLAVO1 EQU B'01000001' ; Escribimos la dirección del Esclavo1 receptor.ESCLAVO2 EQU B'01000011' ; Escribimos la dirección del Esclavo2 receptor.ESCLAVO3 EQU B'01001000' ; Escribimos la dirección del Esclavo3 transmisor.ESCLAVO4 EQU B'01001100' ; Escribimos la dirección del Esclavo4 transmisor.

;**************************** Registros *********************************************************************************

CBLOCK 0X20

GUARDAR_DATO

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************************** Vector de Interrupción ********************************************************

ORG 0X04

GOTO INTERRUP ; Ir a la Rutina de Interrupción

;*************************************** Sección de Configuracion *****************************************************

ORG 0X05 ; Inicio de Programa (Una posición detrás del vector de Interrupción

COMIENZO CALL Config_transmision_I2C ; Configuracion Bus_I2C

189

Page 198: Entren Adores

BSF STATUS,RP0 ; Ir al Banco 1BCF OPTION_REG,INTEDG ; Interrupción por flanco descendente.BCF OPTION_REG,7 ; Activamos las resistencias PULL-UP del PORTBBSF INTCON,RBIF ; Ponemos a 1 la Bandera de Interrupción de

; las Patilla (RB7..RB4).BSF INTCON,RBIE ; Permitimos las Interrupciones de las Patilla (RB7..RB4).BSF INTCON,GIE ; Activamos todas las Interrupciones.BCF STATUS,RP0 ; Ir al Banco 0

;**************************************************** Principal **********************************************************

SLEEP ; Poner el microcontrolador rn modo sueño.

Goto $-1

;****************************************** Rutina de Interrupción ******************************************************

INTERRUP CALL Bit_start_I2C ; Llamar a la subrutina de Comienzo.

MOVLW ESCLAVO1 ; Seleccionar esclavo de recepción. ( 0100,A2,A1,A0,1 )CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(000) por hardware. ; El ultimo BIT a 1 para poner el C.I. PCF8476 como; receptor.

CALL Recibir_dato_I2C ; Llamar a la subrutina de recepción de datos.MOVWF GUARDAR_DATO ; Guardar dato recibido en el registro GUARDAR_DATO.

CALL ReStart_I2C ; Llamar a la subrutina de comenzar sin pasar por parada.

MOVLW ESCLAVO3 ; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(100) por hardware. ; El ultimo BIT a 0 para poner el C.I. PCF8476 como; transmisor.

MOVF GUARDAR_DATO,W ; Guardar el contenido del registro GUARDAR_DATO en W.CALL Transmitir_dato_I2C ; Llamar a la subrutina de transmisión de datos.

CALL Bit_stop_I2C ; Llamar a la subrutina de parada.

CALL Bit_start_I2C ; Llamar a la subrutina de Comienzo.

MOVLW ESCLAVO2 ; Seleccionar esclavo de recepción. ( 0100,A2,A1,A0,1 )CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(001) por hardware. ; El ultimo BIT a 1 para poner el C.I. PCF8476 como; receptor.

CALL Recibir_dato_I2C ; Llamar a la subrutina de recepción de datos.MOVWF GUARDAR_DATO ; Guardar dato recibido en el registro GUARDAR_DATO.

CALL ReStart_I2C ; Llamar a la subrutina de comenzar sin pasar por parada.

MOVLW ESCLAVO4 ; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) CALL Transmitir_dato_I2C ; (0100) identifica al C.I. PCF8476.

; (A2,A1,A0)=(110) por hardware. ; El ultimo BIT a 0 para poner el C.I. PCF8476 como

190

Page 199: Entren Adores

; transmisor.

MOVF GUARDAR_DATO,W ; Guardar el contenido del registro GUARDAR_DATO en W.CALL Transmitir_dato_I2C ; Llamar a la subrutina de transmisión de datos.

CALL Bit_stop_I2C ; Llamar a la subrutina de parada.

MOVF PORTB,W ; Necesario en proteus para limpiar flag.BCF INTCON,RBIF ; mientras permanece pulsado. Limpia flag.

RETFIE

;************************************************** LIBRERIAS *********************************************************

INCLUDE <I2C.INC> ; Librería de control de bus I2C.

END

191

Page 200: Entren Adores

13.- Entrenador Básico 9

192

Page 201: Entren Adores

13.1.- I2C6.asm ( Entrenador Básico 9 )title " Leer constantemente la entrada analogica ANI0 del Esclavo 1 (PCF8591) "title " y visualiza la tension en la pantalla del modulo LCD."

;******************************************** I2C6.asm ******************************************************************

;Programa para PIC 16F876.;Velocidad del Reloj:1 MHz.;Reloj instruccion: 250 KHz = 4 uS.;Perro Guardian deshabilitado.;Tipo de Reloj XT.;Proteccion de Codigo: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f876, f=inhx32

;******************** Asignacion de nombres de Registros de Funciones especiales a direcciones **************

#include <p16f876.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

Esclavo1_Escritura_sensor EQU b'10011110'Esclavo1_Lectura_sensor EQU b'10011111'

;**************************** Registros *********************************************************************************

CBLOCK 0X20

Auxiliar

ENDC

;**************************** Seccion Codigo de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*************************************** Seccion de Configuracion *****************************************************

ORG 0X05 ; Inicio de Programa (Una posicion detras del vector de Interrupcion

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como senales digitales.movwf ADCON1bcf STATUS,RP0

call LCD_Inicializa ; Inicializar el LCD.

193

Page 202: Entren Adores

call Config_transmision_I2C ; Configuracion Bus_I2C

call Bit_start_I2C ; Llamar a la subrutina de Comienzo de I2C.

movlw Esclavo1_Escritura_sensor ; Seleccionar PCF8591 Transmisor. ( 1001,A2,A1,A0,0 )

call Transmitir_dato_I2C ;(1001) identifica al C.I. PCF8591.;(A2,A1,A0)=(111) por hardware. ;El ultimo bit a 0 para poner el C.I. PCF8591 como transmisor.

movlw b'00000000' ; Carga la palabra de control utilizando la call Transmitir_dato_I2C ; entrada AIN0 en modo simple.

call ReStart_I2C ; Llamar a la subrutina de comenzar sin pasar por parada.

movlw Esclavo1_Lectura_sensor ; Seleccionar PCF8591 Receptor. (1001,A2,A1,A0,1)call Transmitir_dato_I2C ;(1001) identifica al C.I. PCF8591.

;(A2,A1,A0)=(111) por hardware. ;El ultimo bit a 1 para poner el C.I. PCF8591 como receptor.

call Recibir_dato_I2C ; Llamar a la subrutina de recepcion de datos y leemos la entrada analógica.; La primera lectura es incorrecta y por lo tanto la desecha.

call Bit_stop_I2C ; Llamar a la subrutina de parada.

call LCD_Linea1 ; Se sitúa al principio de la primera línea.movlw Mensaje1 ; Visualiza el Mensaje1call LCD_Mensaje

;**************************************************** Principal **********************************************************

Principal call Bit_start_I2C ; Llamar a la subrutina de Comienzo de I2C.movlw Esclavo1_Lectura_sensor ; Seleccionar PCF8591 Receptor. (1001,A2,A1,A0,1)CALL Transmitir_dato_I2C ;(1001) identifica al C.I. PCF8591.

;(A2,A1,A0)=(111) por hardware. ;El ultimo bit a 1 para poner el C.I. PCF8591 como receptor.

call Recibir_dato_I2C ; Llamar a la subrutina de recepción de datos y leemos la entrada analógica.

call Bit_stop_I2C ; Llamar a la subrutina de parada.

call Visualiza ; LLamar a la subrutina Visualiza.

goto Principal

;********************************************** Subrutinas "Visualiza" **************************************************

; Visualiza el valor que se le introduce por el registro de trabajo W en formato de tensión.; Hay que tener en cuenta que el PCF8591 del esquema trabaja con una resolución de; LSB=10mV, el valor de entrada será 10 veces menor que la tensión real expresada en; milivoltios. Así por ejemplo, si (W)=147 el valor de la tensión será igual a:; VAIN = LSB x Digital = 10 x 147 = 1470 mV = 1,47 V, que es lo que se debe visualizar; en la pantalla.

; En conclusión:

194

Page 203: Entren Adores

; - Las centenas del valor de entrada corresponden a las unidades de voltio.; - Las decenas del valor de entrada corresponden a las décimas de voltio.; - Las unidades del valor de entrada corresponden a las centésimas de voltios.

Visualiza movwf Auxiliar ; Lo guarda.call LCD_Linea2 ; Se sitúa al principio de la primera línea.movlw MensajeTension ; Visualiza la tensión deseada.call LCD_Mensajemovf Auxiliar,W ; Recupera el dato a visualizar y locall BIN_a_BCD ; pasa a BCD.movf BCD_Centenas,W ; Visualiza las centenas que corresponden a lascall LCD_Nibble ; unidades de voltios.movlw '.' ; Visualiza el punto decimal.call LCD_Caractermovf BCD_Decenas,W ; Visualiza las decenas que corresponden a lascall LCD_Nibble ; décimas de voltios.movf BCD_Unidades,W ; Visualiza las unidades que corresponden a lascall LCD_Nibble ; centésimas de voltios.movlw MensajeVoltioscall LCD_Mensaje

return

;*********************************** Subrutina "Mensajes" **************************************************************

Mensajes addwf PCL,F

MensajeTension DT " Ve = ", 0x00MensajeVoltios DT " V ", 0x00Mensaje1 DT "Señal del Sensor", 0X00

;**************************************************** LIBRERIAS ********************************************************

INCLUDE <RETARDOS.INC>INCLUDE <BIN_BCD.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <I2C.INC>

END

13.2.- I2C7.asm ( Entrenador Básico 9 )

195

Page 204: Entren Adores

title " En la salida analogica del Esclavo 2 (PCF8591) que trabaja como DAC se obtiene una tension seleccionada "

title " por un pulsador conectado a la linea RB6 del PIC. La tension varia entre 0,50 y 2,50 V en "

title " saltos de 0,25 V y se visualiza en el modulo LCD."

;******************************************** I2C7.asm ******************************************************************

;Programa para PIC 16F876.;Velocidad del Reloj:1 MHz.;Reloj instruccion: 250 KHz = 4 uS.;Perro Guardian deshabilitado.;Tipo de Reloj XT.;Proteccion de Codigo: OFF.

;************************************** Elegimos PIC ********************************************************************

list p=16f876, f=inhx32

;****************** Asignacion de nombres de Registros de Funciones especiales a direcciones ****************

#include <p16f876.inc> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

PCF8591_DireccionEscritura EQU b'10010010'

#DEFINE IncrementarPulsador PORTB,6

;**************************** Registros *********************************************************************************

CBLOCK 0X20

ENDC

;**************************** Seccion Codigo de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de Interrupcion ********************************************************************

ORG 0x04

GOTO Interrup

;**************************** Libreria de Mensajes *********************************************************************

196

Page 205: Entren Adores

ORG 0X05 ; Inicio de Programa (Una posicion detras del vector de Interrupcion)

Mensajes addwf PCL,F

MensajeTension DT "Tension: ", 0x00MensajeVoltios DT " V. ", 0x00

;*************************************** Seccion de Configuracion *****************************************************

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como senales digitales.movwf ADCON1

bcf STATUS,RP0

call LCD_Inicializacall Config_transmision_I2C ; Configuracion Bus_I2C

bsf STATUS,RP0bsf IncrementarPulsador ; Se configura como entrada.bcf STATUS,RP0

call CargaInicialContador ; Realiza la carga inicial del contador.call PCF8591_DAC ; Lo envia al DAC para su conversion.call Visualiza ; Y lo visualiza en la pantalla.

movlw b'10001000' ; Activa interrupcion por cambio en lasmovwf INTCON ; lineas del Puerto B (RBIE) y la general (GIE).

;**************************************************** Principal **********************************************************

Principal sleep ; Pasa a modo de reposo.goto Principal

;*********************************************Rutina de Interrupcion ****************************************************

; Incrementa el registro Contador cada vez que se presiona el pulsador "INCREMENTAR".

; Como el PCF8591 del esquema trabaja con una resolucion de LSB=10mV el valor del (Contador); sera 10 veces menor que la tension analogica deseada a la salida expresada en milivoltios.; Asi por ejemplo, si (Contador)=147 el valor de la tension de salida sera igual a:; VOUT = LSB x Digital = 10 x 147 = 1470 mV = 1,47 V.

Interrupcall Retardo_20ms ; Espera a que se estabilicen los niveles de tension.btfsc IncrementarPulsador ; Si es un rebote sale fuera.goto FinInterrupcion

IncrementarTensionDeseada call IncrementaContador ; Aumenta el valor del contador.call PCF8591_DAC ; Lo envia al DAC para su

conversion.call Visualiza ; Visualiza mientras espera que dejecall Retardo_100ms ; de pulsar durante este tiempo.btfss IncrementarPulsador ; Mientras permanezca pulsadogoto IncrementarTensionDeseada ; incrementara el digito.

FinInterrupcion movf PORTB,W

197

Page 206: Entren Adores

bcf INTCON,RBIFretfie

;**************************************** Subrutina "PCF8591_DAC" **************************************************

; Escribe en el PCF8591 con el dato del registro W para su conversion a tension analagica.

CBLOCKPCF8591_Dato ; Guarda el dato que tiene que enviar.ENDC

PCF8591_DAC movwf PCF8591_Dato ; Guarda el dato a enviar.

call Bit_start_I2C ; Llamar a la subrutina de Comienzo de I2C.movlw PCF8591_DireccionEscritura ; Apunta al dispositivo.CALL Transmitir_dato_I2C

movlw b'01000000' ; Carga la palabra de control activando la call Transmitir_dato_I2C ; salida analogica.

movf PCF8591_Dato,W ; Escribe el dato dos veces para que lacall Transmitir_dato_I2C ; conversion sea correcta tal como se indica

en el manual.movf PCF8591_Dato,W ; los cronogramas del fabricante.call Transmitir_dato_I2Ccall Bit_stop_I2C

movf PCF8591_Dato,W ; En (W) se recupera de nuevo el dato de entrada.

return

;************************** Subrutinas "IncrementaContador" y "CargaInicialContador" ****************************

CBLOCKContadorENDC

ValorMinimo EQU d'50' ; El valor minimo de tension sera 0,5 V.ValorMaximo EQU d'250' ; El valor maximo de tension sera 2,5 V.SaltoIncremento EQU d'25' ; El incremento se producira en saltos de 0,25 V.

IncrementaContador movlw SaltoIncremento ; Incrementa el valor deseado.addwf Contador,Fbtfsc STATUS,C ; Si se desborda realiza la carga inicial.goto CargaInicialContadormovf Contador,W ; Ha llegado a su valor maximo ?sublw ValorMaximo ; (W) <- ValorMaximo - (Contador).btfsc STATUS,C ; Si ValorMaximo<(Contador) C=0 y (W) negativogoto FinIncrementar ; No, resulta ValorMaximo>=(Contador) y sale.

CargaInicialContador movlw ValorMinimo ; Si, entonces inicializa el registro.movwf Contador

FinIncrementar movf Contador,W ; En (W) el resultado.return

;****************************************** Subrutinas "Visualiza" *****************************************************

; Visualiza el valor que se le introduce por el registro de trabajo W en formato de tension.; Hay que tener en cuenta que el PCF8591 del esquema trabaja con una resolucion de LSB=10mV,; el valor de entrada sera 10 veces menor que la tension real expresada en milivoltios.; Asi por ejemplo, si (W)=147 el valor de la tension sera igual a: VOUT = LSB x Digital =

198

Page 207: Entren Adores

; = 10 x 147 = 1470 mV = 1,47 V, que es lo que se debe visualizar en la pantalla.

; En conclusion:

; - Las centenas del valor de entrada corresponden a las unidades de voltio.; - Las decenas del valor de entrada corresponden a las decimas de voltio.; - Las unidades del valor de entrada corresponden a las centesimas de voltios.

CBLOCKAuxiliarENDC

Visualiza movwf Auxiliar ; Lo guarda.call LCD_Linea1 ; Se situa al principio de la primera linea.movlw MensajeTension ; Visualiza la tension deseada.call LCD_Mensajemovf Auxiliar,W ; Recupera el dato a visualizar y locall BIN_a_BCD ; pasa a BCD.movf BCD_Centenas,W ; Visualiza las centenas que corresponden a lascall LCD_Nibble ; unidades de voltios.movlw '.' ; Visualiza el punto decimal.call LCD_Caractermovf BCD_Decenas,W ; Visualiza las decenas que corresponden a lascall LCD_Nibble ; decimas de voltios.movf BCD_Unidades,W ; Visualiza las unidades que corresponden a lascall LCD_Nibble ; centesimas de voltios.movlw MensajeVoltioscall LCD_Mensajereturn

;**************************************************** LIBRERIAS ********************************************************

INCLUDE <I2C1.INC>INCLUDE <RETARDOS.INC>INCLUDE <BIN_BCD.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>

END

13.3.- I2C8.asm ( Entrenador Básico 9 )title " Leer constantemente la entrada analogica ANI0 del Esclavo 1(PCF8591),

llevarla al Esclavo 2(PCF8591) "title " y visualiza la tension en la pantalla del modulo LCD."

;******************************************** I2C8.asm ******************************************************************

;Programa para PIC 16F876.;Velocidad del Reloj:1 MHz.;Reloj instruccion: 250 KHz = 4 uS.;Perro Guardian deshabilitado.;Tipo de Reloj XT.;Proteccion de Codigo: OFF.

;************************************** Elegimos PIC ********************************************************************

199

Page 208: Entren Adores

list p=16f876, f=inhx32

;**************** Asignacion de nombres de Registros de Funciones especiales a direcciones ******************

#include <p16f876.inc> ;Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;************************************** Igualdades ***********************************************************************

Esclavo1_Escritura_sensor EQU b'10011110'Esclavo1_Lectura_sensor EQU b'10011111'

Esclavo2_Escritura EQU b'10010010'

;**************************** Registros *********************************************************************************

CBLOCK 0X20

AuxiliarDato_ADCDato_DAC

ENDC

;**************************** Seccion Codigo de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*************************************** Seccion de Configuracion *****************************************************

ORG 0X05 ; Inicio de Programa (Una posicion detras del vector de Interrupcion

COMIENZO clrf PORTA ; Reseteamos el PORTA.bsf STATUS,RP0 ; Ir al Banco 1.movlw 0x06 ; Poner el PORTA como senales digitales.movwf ADCON1bcf STATUS,RP0

call LCD_Inicializa ; Inicializar el LCD.

call Config_transmision_I2C ; Configuracion Bus_I2C

call Bit_start_I2C ; Llamar a la subrutina de Comienzo de I2C.

movlw Esclavo1_Escritura_sensor ;Seleccionar PCF8591 Transmisor. ( 1001,A2,A1,A0,0 )

call Transmitir_dato_I2C ;(1001) identifica al C.I. PCF8591.;(A2,A1,A0)=(111) por hardware. ;El ultimo bit a 0 para poner el C.I. PCF8591 como transmisor.

200

Page 209: Entren Adores

movlw b'00000000' ; Carga la palabra de control utilizando la call Transmitir_dato_I2C ; entrada AIN0 en modo simple.

call ReStart_I2C ; Llamar a la subrutina de comenzar sin pasar por parada.

movlw Esclavo1_Lectura_sensor ; Seleccionar PCF8591 Receptor. (1001,A2,A1,A0,1)call Transmitir_dato_I2C ; (1001) identifica al C.I. PCF8591.

; (A2,A1,A0)=(111) por hardware. ; El ultimo bit a 1 para poner el C.I. PCF8591 como receptor.

call Recibir_dato_I2C ; Llamar a la subrutina de recepcion de datos y leemos la entrada analogica.; La primera lectura es incorrecta y por lo tanto la desecha.

call Bit_stop_I2C ; Llamar a la subrutina de parada.

call LCD_Linea1 ; Se situa al principio de la primera linea.movlw Mensaje1 ; Visualiza el Mensaje1call LCD_Mensaje

;**************************************************** Principal **********************************************************

Principal call Bit_start_I2C ; Llamar a la subrutina de Comienzo de I2C.movlw Esclavo1_Lectura_sensor ; Seleccionar PCF8591 Receptor. (1001,A2,A1,A0,1)CALL Transmitir_dato_I2C ; (1001) identifica al C.I. PCF8591.

; (A2,A1,A0)=(111) por hardware. ; El ultimo bit a 1 para poner el C.I. PCF8591 como receptor.

call Recibir_dato_I2C ; Llamar a la subrutina de recepcion de datos y leemos la entrada analogica.

call Bit_stop_I2C ; Llamar a la subrutina de parada.movwf Dato_ADC call Visualiza ; LLamar a la subrutina Visualiza.movf Dato_ADC,w call Esclavo2_DACgoto Principal

;********************************************** Subrutinas "Visualiza" **************************************************

; Visualiza el valor que se le introduce por el registro de trabajo W en formato de tension.; Hay que tener en cuenta que el PCF8591 del esquema trabaja con una resolucion de; LSB=10mV, el valor de entrada sera 10 veces menor que la tension real expresada en; milivoltios. Asi por ejemplo, si (W)=147 el valor de la tension sera igual a:; VAIN = LSB x Digital = 10 x 147 = 1470 mV = 1,47 V, que es lo que se debe visualizar; en la pantalla.

; En conclusion:

; - Las centenas del valor de entrada corresponden a las unidades de voltio.; - Las decenas del valor de entrada corresponden a las décimas de voltio.; - Las unidades del valor de entrada corresponden a las centésimas de voltios.

Visualiza movwf Auxiliar ; Lo guarda.call LCD_Linea2 ; Se situa al principio de la primera linea.movlw MensajeTension ; Visualiza la tension deseada.

201

Page 210: Entren Adores

call LCD_Mensajemovf Auxiliar,W ; Recupera el dato a visualizar y locall BIN_a_BCD ; pasa a BCD.movf BCD_Centenas,W ; Visualiza las centenas que corresponden a lascall LCD_Nibble ; unidades de voltios.movlw '.' ; Visualiza el punto decimal.call LCD_Caractermovf BCD_Decenas,W ; Visualiza las decenas que corresponden a lascall LCD_Nibble ; décimas de voltios.movf BCD_Unidades,W ; Visualiza las unidades que corresponden a lascall LCD_Nibble ; centésimas de voltios.movlw MensajeVoltioscall LCD_Mensaje

return

;*********************************** Subrutina "Mensajes" **************************************************************Mensajes addwf PCL,F

MensajeTension DT " Ve = ", 0x00MensajeVoltios DT " V ", 0x00Mensaje1 DT "Señal del Sensor", 0X00

;**************************************** Subrutina "Esclavo2_DAC " **************************************************

; Escribe en el Esclavo 2 con el dato del registro W para su conversion a tension analagica.

Esclavo2_DAC movwf Dato_DAC ; Guarda el dato a enviar.

call Bit_start_I2C ; Llamar a la subrutina de Comienzo de I2C.movlw Esclavo2_Escritura ; Apunta al dispositivo.CALL Transmitir_dato_I2C

movlw b'01000000' ; Carga la palabra de control activando la call Transmitir_dato_I2C ; salida analogica.

movf Dato_DAC,W ; Escribe el dato dos veces para que lacall Transmitir_dato_I2C ; conversion sea correcta tal como se indica

movf Dato_DAC,W ; los cronogramas del fabricante.call Transmitir_dato_I2Ccall Bit_stop_I2C

return

;*************************************************** LIBRERIAS *********************************************************

INCLUDE <RETARDOS.INC>INCLUDE <BIN_BCD.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <I2C1.INC>

END

13.4.- I2C.INC ( Entrenador Básico 9 )

202

Page 211: Entren Adores

title "Libreria de Transmision y recepcion de datos con I2C "

Config_transmision_I2C BSF STATUS,RP0 ; Seleciono la pagina 1 de la memoria

BSF TRISC,4BSF TRISC,3

MOVLW 0X09MOVWF SSPADD ; Cargas 09H en el registro SSPADD La velocidad de

Transmision sera de 100 KHz

BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoria

BCF PIR1,SSPIFBSF SSPCON,SSPM3 ; I2C en modo maestro con una

F de Tr. = Fosc/(4*(SSPADD+1))BCF SSPCON,SSPM2BCF SSPCON,SSPM1BCF SSPCON,SSPM0

BSF SSPCON,SSPEN ; Permites la configuracion serie de los pines SDA y SCL.

GOTO VOLVER

Bit_start_I2C BSF STATUS,RP0 ; Seleciono la pagina 1 de la memoriaBSF SSPCON2,SEN ; Lanzamos el bit de START.

BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoriaBTFSS PIR1,SSPIFGOTO $-1BCF PIR1,SSPIF

GOTO VOLVER

Transmitir_dato_I2C MOVWF SSPBUF ; Transmitimos el dato al Esclavo

BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoriaBTFSS PIR1,SSPIFGOTO $-1BCF PIR1,SSPIF

BSF STATUS,RP0 ; Seleciono la pagina 1 de la memoria

BTFSS SSPCON2,ACKSTAT ; Si el esclavo pone ACKSTAT = 0 la transmision es correcta,; Si no hay respuesta del esclavo enviamos STOP.

GOTO Trans_correcta

GOTO Bit_stop_I2C

Trans_correcta BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoriaGOTO VOLVER

Recibir_dato_I2C BSF STATUS,RP0 ; Seleciono la pagina 1 de la memoriaBSF SSPCON2,RCEN ; Permito la Recepcion de datos

203

Page 212: Entren Adores

BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoria

BTFSS PIR1,SSPIFGOTO $-1BCF PIR1,SSPIF

MOVF SSPBUF,W ; Dato recibido en el registro SSPBUF

BSF STATUS,RP0 ; Seleciono la pagina 1 de la memoria

BSF SSPCON2,ACKDT ; Pone el maestro el bit de reconocimiento de que ha llegado el Dato.

BSF SSPCON2,ACKEN ; Permito que el bit de reconocimiento este activo.

BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoria

BTFSS PIR1,SSPIFGOTO $-1BCF PIR1,SSPIF

GOTO VOLVER

Bit_stop_I2C BSF STATUS,RP0 ; Seleciono la pagina 1 de la memoriaBSF SSPCON2,PEN

BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoria

BTFSS PIR1,SSPIFGOTO $-1BCF PIR1,SSPIF

GOTO VOLVER

ReStart_I2C BSF STATUS,RP0BSF SSPCON2,RSENBCF STATUS,RP0BTFSS PIR1,SSPIFGOTO $-1BCF PIR1,SSPIF

VOLVER RETURN

13.5.- I2C1.INC ( Entrenador Básico 9 )

204

Page 213: Entren Adores

title " Libreria de Transmision y recepcion de datos con I2C1 "title " En la subrutina (Transmitir_dato_I2C) el Esclavo no confirma la transmision "

Config_transmision_I2C BSF STATUS,RP0 ; Seleciono la pagina 1 de la memoria

BSF TRISC,4BSF TRISC,3

MOVLW 0X09MOVWF SSPADD ; Cargas 09H en el registro SSPADD La velocidad de

Transmision sera de 100 KHz

BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoria

BCF PIR1,SSPIFBSF SSPCON,SSPM3 ; I2C en modo maestro con una

F de Tr. = Fosc/(4*(SSPADD+1))BCF SSPCON,SSPM2BCF SSPCON,SSPM1BCF SSPCON,SSPM0

BSF SSPCON,SSPEN ; Permites la configuracion serie de los pines SDA y SCL.

GOTO VOLVER

Bit_start_I2C BSF STATUS,RP0 ; Seleciono la pagina 1 de la memoriaBSF SSPCON2,SEN ; Lanzamos el bit de START.

BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoriaBTFSS PIR1,SSPIFGOTO $-1BCF PIR1,SSPIF

GOTO VOLVER

Transmitir_dato_I2C MOVWF SSPBUF ; Transmitimos el dato al Esclavo

BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoriaBTFSS PIR1,SSPIFGOTO $-1BCF PIR1,SSPIF

GOTO VOLVER

Recibir_dato_I2C BSF STATUS,RP0 ; Seleciono la pagina 1 de la memoriaBSF SSPCON2,RCEN ;Permito la Recepcion de datos

BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoria

BTFSS PIR1,SSPIFGOTO $-1BCF PIR1,SSPIF

MOVF SSPBUF,W ; Dato recibido en el registro SSPBUF

BSF STATUS,RP0 ; Seleciono la pagina 1 de la memoria

205

Page 214: Entren Adores

BSF SSPCON2,ACKDT ; Pone el maestro el bit de reconocimiento de que ha llegado el Dato.

BSF SSPCON2,ACKEN ; Permito que el bit de reconocimiento este activo.

BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoria

BTFSS PIR1,SSPIFGOTO $-1BCF PIR1,SSPIF

GOTO VOLVER

Bit_stop_I2C BSF STATUS,RP0 ; Seleciono la pagina 1 de la memoriaBSF SSPCON2,PEN

BCF STATUS,RP0 ; Seleciono la pagina 0 de la memoria

BTFSS PIR1,SSPIFGOTO $-1BCF PIR1,SSPIF

GOTO VOLVER

ReStart_I2C BSF STATUS,RP0BSF SSPCON2,RSENBCF STATUS,RP0BTFSS PIR1,SSPIFGOTO $-1BCF PIR1,SSPIF

VOLVER RETURN

206

Page 215: Entren Adores

14.- Entrenador Básico 10

207

Page 216: Entren Adores

14.1.- RTS232_1.asm ( Entrenador Básico 10 )

title " En la pantalla del modulo LCD se visualizaran los caracteres que se reciban "title " a través del puerto serie del ordenador. Lo que se escriba por el teclado del "title " ordenador aparecerá en la pantalla del sistema con microcontrolador."

;************************************************* RTS232_1.asm ******************************************************

; Se utilizara un programa de comunicaciones para que el ordenador pueda enviar datos a través; de su puerto serie. Este programa puede ser el Hyperterminal de Windows o alguno similar.

; Programa para PIC 16F876a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F876

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

INCLUDE <P16F876.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Registros *********************************************************************************

CBLOCK 0x20

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*************************************** Sección de Configuración *****************************************************

ORG 0X05 ; Inicio de Programa (Una posicion detras del vector de Interrupcion)

COMIENZO BSF STATUS,RP0 ; Poner el Puerto A como señales digitales.MOVLW D'06'MOVWF ADCON1BCF STATUS,RP0call LCD_Inicializa ; Inicializa el LCD y las líneas que secall RS232_Inicializa ; van a utilizar en la comunicación con el puerto

; serie RS232.

208

Page 217: Entren Adores

;**************************************************** Principal **********************************************************

Principal call RS232_LeeDato ; Espera recibir un caracter.call LCD_Caracter ; Lo visualiza.goto Principal ; Repite el proceso.

;*************************************************** LIBRERIAS *********************************************************

INCLUDE <RS232_RT.INC> ; Subrutinas de control de la comunicación con elINCLUDE <LCD_4BIT.INC> ; puerto serie RS232 del ordenador.INCLUDE <RETARDOS.INC>

END

14.2.- RTS232_2.asm ( Entrenador Básico 10 )title " En el modulo LCD se visualizan los caracteres que se escriban en el teclado "title " del ordenador y se transmiten a través de su puerto serie. Estos datos "title " volverán a ser enviados por el microcontrolador al ordenador, para que setitle " visualicen en su monitor." ;************************************************** RTS232_2.asm *****************************************************

; Se utilizara un programa de comunicaciones para que el ordenador pueda enviar datos; a través de su puerto serie, como el HyperTerminal de Windows o alguno similar.

; Concluyendo, lo que se escriba en el teclado del ordenador aparecerá en la pantalla del; modulo LCD y en el monitor del HyperTerminal.

; Programa para PIC 16F876a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F876

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

INCLUDE <P16F876.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Registros *********************************************************************************

CBLOCK 0x20

GuardaDato

ENDC

209

Page 218: Entren Adores

;************************* Sección Código de Reset *******************************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;************************************* Sección de Configuración *******************************************************

ORG 0X05 ; Inicio de Programa (Una posicion detras del vector de Interrupcion)

COMIENZO BSF STATUS,RP0 ; Poner el Puerto A como señales digitales.MOVLW D'06'MOVWF ADCON1BCF STATUS,RP0call LCD_Inicializa ; Inicializa el LCD y las líneas que secall RS232_Inicializa ; van a utilizar en la comunicación con el puerto

; serie RS232.

;**************************************************** Principal **********************************************************

Principal call RS232_LeeDato ; Espera recibir un caracter.movwf GuardaDato ; Guarda el dato recibido.call LCD_Caracter ; Lo visualiza.

movf GuardaDato,W ; Y ahora lo reenvía otra vez al ordenador.call RS232_EnviaDatogoto Principal ; Repite el proceso.

;*************************************************** LIBRERIAS *********************************************************

INCLUDE <RS232_RT.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

14.3.- RTS232_3.asm ( Entrenador Básico 10 )

title " Lo que se escriba por el teclado se visualiza en el LCD y en el monitor del "title " ordenador, pero en este ultimo se visualiza un solo carácter por línea."

;************************************************ RTS232_3.asm *******************************************************

; Programa para PIC 16F876a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F876

210

Page 219: Entren Adores

;*************** Asignación de nombres de Registros de Funciones especiales a direcciones *******************

INCLUDE <P16F876.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

RetornoCarro EQU d'13' ; Codigo de tecla "Enter" o "Retorno de Carro".

;**************************** Registros *********************************************************************************

CBLOCK 0x20

GuardaDato

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*************************************** Sección de Configuración *****************************************************

ORG 0X05 ; Inicio de Programa (Una posicion detras del vector de Interrupcion)

COMIENZO BSF STATUS,RP0 ; Poner el Puerto A como señales digitales.MOVLW D'06'MOVWF ADCON1BCF STATUS,RP0call LCD_Inicializa ; Inicializa el LCD y las líneas que secall RS232_Inicializa ; van a utilizar en la comunicación con el puerto

; serie RS232.

;**************************************************** Principal **********************************************************

Principal call RS232_LeeDato ; Espera recibir un caracter.movwf GuardaDato ; Guarda el dato recibido.call LCD_Caracter ; Lo visualiza.

movf GuardaDato,W ; Y ahora lo reenvía otra vez al ordenador.call RS232_EnviaDatomovlw RetornoCarro ; Ahora el cursor se sitúa al principio de lacall RS232_EnviaDato ; línea siguiente en la pantalla del ordenador.

goto Principal

;**************************************************** LIBRERIAS ********************************************************

INCLUDE <RS232_RT.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

211

Page 220: Entren Adores

14.4.- RTS232_4.asm ( Entrenador Básico 10 )

title " En el modulo LCD se visualizan los caracteres que se escriben en el teclado "title " del ordenador. Si pulsa la tecla Enter se comienza a escribir en la segunda "title " línea de la pantalla del modulo LCD. "

;************************************************ RTS232_4.asm *******************************************************

; Programa para PIC 16F876a.; Velocidad del Reloj:1 MHz.; Reloj instruccion: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F876

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

INCLUDE <P16F876.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

RetornoCarro EQU d'13' ; Codigo la de tecla "Enter".CambioLinea EQU d'10' ; Codigo para el "Cambio de linea".

;**************************** Registros *********************************************************************************

CBLOCK 0x20

GuardaDato

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*************************************** Sección de Configuración *****************************************************

ORG 0X05 ; Inicio de Programa (Una posicion detras del vector de Interrupcion)

COMIENZO BSF STATUS,RP0 ; Poner el Puerto A como señales digitales.MOVLW D'06'MOVWF ADCON1BCF STATUS,RP0call LCD_Inicializacall RS232_Inicializa

212

Page 221: Entren Adores

;**************************************************** Principal **********************************************************

Principal call RS232_LeeDato ; Espera recibir un caracter.movwf GuardaDato ; Guarda el dato recibido.sublw RetornoCarro ; Comprueba si ha pulsado la tecla Enter.btfsc STATUS,Zgoto SaltaLinea2 ; Si, es Enter y por tanto salta a la linea 2.movf GuardaDato,W ; No es Enter y por tanto lo visualizacall LCD_Caracter ; en el LCD.goto Env_Carac_a_Ordenador

SaltaLinea2 call LCD_Linea2 ; Situar el Cursor en la Lina 2 del LCD.call RS232_EnviaDatomovlw CambioLinea ; no lo visualiza en el LCD. En el monitor del call RS232_EnviaDato ; ordenador se debe apreciar también un cambio

; de línea.

Env_Carac_a_Ordenador movf GuardaDato,W ; Y ahora lo reenvía otra vez al ordenador.call RS232_EnviaDatogoto Principal

;**************************************************** LIBRERIAS ********************************************************

INCLUDE <RS232_RT.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

14.5.- RTS232_5.asm ( Entrenador Básico 10 )title " Este programa envía un mensaje grabado en la memoria de programa del "title " microcontrolador al ordenador. Es decir, en el monitor del ordenador "title " aparecerá el mensaje grabado en el PIC."

;************************************************** RTS232_5.asm *****************************************************

; Programa para PIC 16F876a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F876

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

INCLUDE <P16F876.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

213

Page 222: Entren Adores

;**************************** Igualdades ********************************************************************************

RetornoCarro EQU d'13' ; Codigo de tecla "Enter" o "Retorno de Carro".

;**************************** Registros *********************************************************************************

CBLOCK 0x20

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*************************************** Sección de Configuración *****************************************************

ORG 0X05 ; Inicio de Programa (Una posicion detras del vector de Interrupcion)

COMIENZO call LCD_Inicializa ; Inicializa el modulo LCD y las líneas que se van a call RS232_Inicializa ; utilizar en la comunicación con el puerto serie RS232.

;**************************************************** Principal **********************************************************

Principal movlw Mensaje0 ; Carga la primera posicion del mensaje.call RS232_Mensaje ; Lo visualiza en el ordenador.call Retardo_1sgoto Principal

;********************************************* Subrutina de "Mensajes" ************************************************

Mensajes addwf PCL,F

Mensaje0 DT RetornoCarro DT " En el I.E.S. Joan Miro de San Sebastián de los Reyes"DT RetornoCarroDT " se puede estudiar el Ciclo Formativo"DT RetornoCarroDT " DESARROLLO de PRODUCTOS ELECTRONICOS."DT RetornoCarro, 0x00

;**************************************************** LIBRERIAS ********************************************************

INCLUDE <RS232_RT.INC>INCLUDE <RS232MEN.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>

END

214

Page 223: Entren Adores

14.6.- RTS232_6.asm ( Entrenador Básico 10 )

title " Este programa envía varios mensajes grabados en la memoria de programa "title " del microcontrolador al ordenador. Cada mensaje permanecerá en pantalla "title " durante unos segundos hasta que sea sustituido por el siguiente."

;************************************************** RTS232_6.asm *****************************************************

; Programa para PIC 16F876a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F876

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

INCLUDE <P16F876.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

RetornoCarro EQU d'13' ; Codigo de tecla "Enter" o "Retorno de Carro".

;**************************** Registros *********************************************************************************

CBLOCK 0x20

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************************** Subrutina de "Mensajes" *****************************************************

ORG 0X05 ; Inicio de Programa (Una posicion detras del vector de Interrupcion)

Mensajes addwf PCL,F ; Los mensajes se ponen al principio para no; superar la posición 0xFF de memoria de programa.

Mensaje0 DT " ¿Quieres trabajar en dos años?."DT RetornoCarroDT "¿Quieres aprender hacer estos mensajes?",0x00

Mensaje1 DT " ¡Pues estudia CICLOS FORMATIVOS!.",0x00

215

Page 224: Entren Adores

Mensaje2 DT "En el I.E.S. Joan Miro de San Sebastian de los Reyes"DT RetornoCarroDT " se puede estudiar el Ciclo Formativo "DT RetornoCarroDT " DESARROLLO de PRODUCTOS ELECTRONICOS.", 0x00

FinMensajesIF (FinMensajes > 0xFF)

ERROR "ATENCION: La tabla ha superado el tamano de la pagina de los"MESSG "primeros 255 bytes de memoria ROM. NO funcionara

correctamente."

ENDIF

;*************************************** Sección de Configuración *****************************************************

COMIENZO call RS232_Inicializa ; Inicializa las lineas que se van a ; utilizar en la comunicación con el puerto serie RS232.

;**************************************************** Principal **********************************************************

Principal movlw Mensaje0 ; Carga la primera posición del mensaje.call VisualizaMensaje ; Lo visualiza en el ordenador.movlw Mensaje1 ; El mismo procedimiento para las siguientes.call VisualizaMensajemovlw Mensaje2call VisualizaMensajegoto Principal

;***************************************** Subrutina "VisualizaMensaje" ***********************************************

VisualizaMensaje call RS232_Mensaje ; Lo visualiza en el ordenador.call RS232_LineasBlanco ; Visualiza unas lineas en blanco despues delcall Retardo_1s ; mensaje durante este tiempo.call RS232_LineasBlanco ; Líneas en blanco al principio del próximo mensaje.

return

;**************************************************** LIBRERIAS ********************************************************

INCLUDE <RS232MEN.INC>INCLUDE <RS232_RT.INC>INCLUDE <RETARDOS.INC>

END

216

Page 225: Entren Adores

14.7.- RTS232_7.asm ( Entrenador Básico 10 )

title " En el monitor del ordenador se visualizan mensajes grabados en la memoria "title " de programa del microcontrolador. El cambio de mensaje se ejecuta cada "title " vez que se pulse la tecla Enter."

;************************************************* RTS232_7.asm ******************************************************

; Programa para PIC 16F876a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F876

;********************* Asignación de nombres de Registros de Funciones especiales a direcciones *************

INCLUDE <P16F876.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

RetornoCarro EQU d'13' ; Codigo de tecla "Enter" o "Retorno de Carro".

;**************************** Registros *********************************************************************************

CBLOCK 0x20

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Dirección del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************************** Subrutina de "Mensajes" *****************************************************

ORG 0X05 ; Inicio de Programa (Una posicion detras del vector de Interrupcion)

Mensajes addwf PCL,F ; Los mensajes se ponen al principio para no; superar la posición 0xFF de memoria de programa.

Mensaje0 DT " ¿Quieres trabajar en dos años?."DT RetornoCarroDT "¿Quieres aprender hacer estos mensajes?",0x00

Mensaje1 DT " ¡Pues estudia CICLOS FORMATIVOS!.",0x00

217

Page 226: Entren Adores

Mensaje2 DT "En el I.E.S. Joan Miro de San Sebastian de los Reyes"DT RetornoCarroDT " se puede estudiar el Ciclo Formativo "DT RetornoCarroDT " DESARROLLO de PRODUCTOS ELECTRONICOS.", 0x00

FinMensajesIF (FinMensajes > 0xFF)

ERROR "ATENCION: La tabla ha superado el tamano de la pagina de los"MESSG "primeros 255 bytes de memoria ROM. NO funcionara

correctamente."

ENDIF

;*************************************** Sección de Configuración *****************************************************

COMIENZO call RS232_Inicializa ; Inicializa las lineas que se van a ; utilizar en la comunicación con el puerto serie RS232.

call RS232_LineasBlanco ; Visualiza unas cuantas líneas en blanco.

;**************************************************** Principal **********************************************************

Principal movlw Mensaje0 ; Carga la primera posicion del mensaje.call Visualiza_y_Espera ; Lo visualiza en el ordenador y esperamovlw Mensaje1 ; pulse "Enter".call Visualiza_y_Esperamovlw Mensaje2call Visualiza_y_Esperagoto Principal

;******************************************** Subrutina "Visualiza_y_Espera" *****************************************

Visualiza_y_Espera call RS232_Mensaje ; Lo visualiza en el ordenador.call RS232_LineasBlanco ; Visualiza unas líneas en blanco.

EsperaPulseEnter call RS232_LeeDato ; Lee el teclado del ordenador.xorlw RetornoCarro ; Si no ha pulsado el "Enter" vuelve a btfss STATUS,Z ; leer de nuevogoto EsperaPulseEnter

return

;**************************************************** LIBRERIAS ********************************************************

INCLUDE <RS232MEN.INC>INCLUDE <RS232_RT.INC>INCLUDE <RETARDOS.INC>

END

218

Page 227: Entren Adores

14.8.- RTS232_8.asm ( Entrenador Básico 10 )title " Programa que visualiza en el modulo LCD el código ASCII en formato "title " hexadecimal de la tecla pulsada y también en el monitor del ordenador "title " en formato decimal. "

;************************************************ RTS232_8.asm *******************************************************

; Por ejemplo:

; - Monitor del ordenador: " k-107", donde la "k" es la tecla pulsada y el "107" el; código ASCII en formato decimal.; - Pantalla del LCD: " k-6B", donde la "k" es la tecla pulsada y el "6B" el; código ASCII en formato hexadecimal.

; Programa para PIC 16F876a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F876

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

INCLUDE <P16F876.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

;**************************** Registros *********************************************************************************

CBLOCK 0x20

GuardaDato

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*************************************** Sección de Configuración *****************************************************

ORG 0X05

COMIENZO BSF STATUS,RP0 ; Poner el Puerto A como señales digitales.MOVLW D'06'MOVWF ADCON1

219

Page 228: Entren Adores

BCF STATUS,RP0call LCD_Inicializacall RS232_Inicializa

;**************************************************** Principal **********************************************************

Principal call RS232_LeeDato ; Espera recibir un caracter.movwf GuardaDato ; Guarda el dato recibido.call LCD_Borra ; Despeja la pantalla del visualizador LCD.movf GuardaDato,W ; Recupera el dato leIdo.call LCD_Caracter ; Visualiza el caracter de la tecla pulsada.movlw '-' ; Visualiza el guión.call LCD_Caractermovf GuardaDato,Wcall LCD_ByteCompleto ; Visualiza en el LCD el codigo ASCII.

movlw '-' ; Visualiza en el ordenador el guion.call RS232_EnviaDato

movf GuardaDato,W ; Lo pasa a BCD antes de visualizarlo.call BIN_a_BCDmovf BCD_Centenas,W ; Visualiza el resultado en la pantalla delcall RS232_EnviaNumero ; ordenador comenzando por las centenas.movf BCD_Decenas,Wcall RS232_EnviaNumeromovf BCD_Unidades,Wcall RS232_EnviaNumero

movlw ' ' ; Envia un espacio en blanco para separarlo delcall RS232_EnviaDato ; anterior.movlw ' ' ; Envia un espacio en blanco para separarlo delcall RS232_EnviaDato ; anterior

goto Principal

;**************************************************** LIBRERIAS ********************************************************

INCLUDE <RS232_RT.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>INCLUDE <BIN_BCD.INC>

END

14.9.- RTS232_9.asm ( Entrenador Básico 10 )title " SISTEMA DE MONITORIZACION: Se trata de leer el estado de las entradas "title " conectadas a las líneas <RB7:RB4> del Puerto B y se envia por el puerto "title " RS232 a un terminal para monitorizar el estado de los mismos. El estado de "title " las entradas se mostrara cada 1 segundos. "

;*************************************************** RTS232_9.asm ****************************************************

; Programa para PIC 16F876a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.

220

Page 229: Entren Adores

; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F876

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

INCLUDE <P16F876.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

RetornoCarro EQU d'13' ; Codigo de tecla "Enter" o "Retorno de Carro".CambioLinea EQU d'10' ; Codigo para el cambio de linea.

#DEFINE Entrada0 PORTB,4 ; Define donde se situan las entradas.#DEFINE Entrada1 PORTB,5#DEFINE Entrada2 PORTB,6#DEFINE Entrada3 PORTB,7

;**************************** Registros *********************************************************************************

CBLOCK 0x20

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Subrutina de "Mensajes" *****************************************************************

ORG 0X05

Mensajes addwf PCL,F ; Los mensajes no deben sobrepasar las 256 ; primeras posiciones de memoria de programa.

MensajeEntradas DT RetornoCarro, CambioLineaDT "Entrada 3 Entrada 2 Entrada 1 Entrada 0"DT RetornoCarro, CambioLineaDT "------------ ------------- ------------ ------------"DT RetornoCarro, CambioLinea, 0x00

MensajeAbierto DT " Abierto ", 0x00

MensajeCerrado DT " Cerrado ", 0x00

;*************************************** Sección de Configuración *****************************************************

COMIENZO call RS232_Inicializabsf STATUS,RP0 ; Configura como entrada las 4 lineas

correspondientesbsf Entrada0 ; del Puerto B respetando la configuracion del

221

Page 230: Entren Adores

bsf Entrada1 ; resto de las lineas.bsf Entrada2bsf Entrada3bcf OPTION_REG,NOT_RBPU ; Activa las resistencias de Pull_Up del

Puerto B.bcf STATUS,RP0call RS232_LineasBlanco ; Visualiza unas cuantas lineas en blanco.

;**************************************************** Principal **********************************************************

Principal call RS232_LineasBlanco ; Para limpiar la pantalla.call LeeEntradasVisualiza ; Lee las entradas y las visualiza.call Retardo_1s ; Cada cierto tiempo.goto Principal

;*************************************** Subrutina "LeeEntradasVisualiza" ********************************************

; Lee el estado de las entradas y las monitoriza en la pantalla del HyperTerminal.

LeeEntradasVisualiza call RS232_LineasBlanco ; Visualiza unas cuantas lineas en blanco.movlw MensajeEntradas ; Nombre de las entradas.call RS232_Mensaje ; Lo visualiza en el HyperTerminal.

LeeEntrada3 btfss Entrada3 ; Entrada = 1?, Entrada = Abierta?goto Entrada3Cerrado ; No, esta cerrada.call VisualizaAbiertogoto LeeEntrada2

Entrada3Cerrado call VisualizaCerrado

LeeEntrada2 btfss Entrada2 ; Se repite el procedimiento para lasgoto Entrada2Cerrado ; demas entradas.call VisualizaAbiertogoto LeeEntrada1

Entrada2Cerrado call VisualizaCerrado

LeeEntrada1 btfss Entrada1goto Entrada1Cerradocall VisualizaAbiertogoto LeeEntrada0

Entrada1Cerrado call VisualizaCerrado

LeeEntrada0 btfss Entrada0goto Entrada0Cerradocall VisualizaAbiertogoto FinVisualiza

Entrada0Cerrado call VisualizaCerrado

FinVisualiza call RS232_LineasBlanco

return

;*************************************** Subrutina "VisualizaAbierto" ************************************************

VisualizaAbierto movlw MensajeAbierto ; Visualiza el mensaje "Abierto"call RS232_Mensaje ; en el HyperTerminal.

return

222

Page 231: Entren Adores

;*************************************** Subrutina "VisualizaCerrado" ************************************************

VisualizaCerrado movlw MensajeCerrado ; Visualiza el mensaje "Cerrado"call RS232_Mensaje ; en el HyperTerminal.

return

;************************************** Librerias ********************************************************************

INCLUDE <RS232_RT.INC>INCLUDE <RS232MEN.INC>INCLUDE <RETARDOS.INC>

END

14.10.- RTS23_10.asm ( Entrenador Básico 10 )title " SISTEMA DE MONITORIZACION: Se trata de leer el estado de las entradas "title " conectadas a las líneas <RB7:RB4> del Puerto B y se envia por el puerto "title " RS232 a un terminal para monitorizar el estado de los mismos. "title " Se utilizara las interrupciones por cambio de nivel en una línea del Puerto B, "title " por ello, las entradas deben conectarse a la parte alta del Puerto B."

;*************************************************** RTS23_10.asm ****************************************************

; Programa para PIC 16F876a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F876

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

INCLUDE <P16F876.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

RetornoCarro EQU d'13' ; Codigo de tecla "Enter" o "Retorno de Carro".CambioLinea EQU d'10' ; Codigo para el cambio de linea.

#DEFINE Entrada0 PORTB,4 ; Define donde se situan las entradas.#DEFINE Entrada1 PORTB,5#DEFINE Entrada2 PORTB,6#DEFINE Entrada3 PORTB,7

223

Page 232: Entren Adores

;**************************** Registros *********************************************************************************

CBLOCK 0x20

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;*************************** Vector de Interrupción *********************************************************************

ORG 0X04

GOTO LeeEntradasVisualiza

;**************************** Subrutina de "Mensajes" *****************************************************************

ORG 0X05

Mensajes addwf PCL,F ; Los mensajes no deben sobrepasar las 256 ; primeras posiciones de memoria de programa.

MensajeEntradas DT RetornoCarro, CambioLineaDT "Entrada 3 Entrada 2 Entrada 1 Entrada 0"DT RetornoCarro, CambioLineaDT "------------ ------------- ------------ ------------"DT RetornoCarro, CambioLinea, 0x00

MensajeAbierto DT " Abierto ", 0x00

MensajeCerrado DT " Cerrado ", 0x00

;*************************************** Sección de Configuración *****************************************************

COMIENZO call RS232_Inicializabsf STATUS,RP0 ; Configura como entrada las 4 lineas correspondientesbsf Entrada0 ; del Puerto B respetando la configuracion delbsf Entrada1 ; resto de las lineas.bsf Entrada2bsf Entrada3bcf OPTION_REG,NOT_RBPU ; Activa las resistencias de Pull-Up del Puerto B.bcf STATUS,RP0call RS232_LineasBlanco ; Visualiza unas cuantas lineas en blancocall RS232_LineasBlanco ; para limpiar la pantalla.call LeeEntradasVisualiza ; Lee las entradas y visualiza por primera vez.movlw b'10001000' ; Habilita la interrupcion RBI y la general.movwf INTCON

;**************************************************** Principal **********************************************************

Principal sleep ; Espera en modo de bajo consumo que segoto Principal ; modifique una entrada.

;************************************* Rutina de Servicio a la Interrupción" *******************************************

224

Page 233: Entren Adores

; Lee el estado de las entradas y las monitoriza en la pantalla del HyperTerminal.

LeeEntradasVisualiza call RS232_LineasBlancomovlw MensajeEntradas ; Nombre de las entradas.call RS232_Mensaje ; Lo visualiza en el ordenador.

LeeEntrada3 btfss Entrada3 ; Entrada = 1?, Entrada = Abierta?goto Entrada3Cerrado ; No, esta cerrada.call VisualizaAbiertogoto LeeEntrada2

Entrada3Cerrado call VisualizaCerrado

LeeEntrada2 btfss Entrada2 ; Se repite el procedimiento para lasgoto Entrada2Cerrado ; demas entradas.call VisualizaAbiertogoto LeeEntrada1

Entrada2Cerrado call VisualizaCerrado

LeeEntrada1 btfss Entrada1goto Entrada1Cerrado call VisualizaAbiertogoto LeeEntrada0

Entrada1Cerrado call VisualizaCerrado

LeeEntrada0 btfss Entrada0goto Entrada0Cerradocall VisualizaAbiertogoto FinVisualiza

Entrada0Cerrado call VisualizaCerrado

FinVisualiza call RS232_LineasBlancobcf INTCON,RBIF ; Limpia el flag de reconocimiento de la

; interrupción.retfie

;*************************************** Subrutina "VisualizaAbierto" ************************************************

VisualizaAbierto movlw MensajeAbierto ; Visualiza el mensaje "Abierto"call RS232_Mensaje ; en el HyperTerminal.

return

;*************************************** Subrutina "VisualizaCerrado" ************************************************

VisualizaCerrado movlw MensajeCerrado ; Visualiza el mensaje "Cerrado"call RS232_Mensaje ; en el HyperTerminal.

return

;************************************** Librerias ********************************************************************

INCLUDE <RS232_RT.INC>INCLUDE <RS232MEN.INC>INCLUDE <RETARDOS.INC>

END

14.11.- RTS23_11.asm ( Entrenador Básico 10 )

225

Page 234: Entren Adores

title " SISTEMA DE GOBIERNO DESDE ORDENADOR: Desde el teclado de un "title " ordenador se desea comandar el movimiento de una estructura móvil. "

;************************************************* RTS23_11.asm ******************************************************

; La estructura móvil, obedece a la siguiente tabla:

; TECLA (Por ejemplo) MOVIMIENTO; ------------------- ----------; t Adelante; b Atras; a Izquierda; l Derecha; Espacio Parada

; La pulsación de cualquiera de estas teclas activa el estado de las salidas correspondiente; RB3 (Adelante), RB2 (Atras), RB1 (Izquierda), RB0 (Derecha) y apaga el resto.;; El movimiento que se esta realizando aparece reflejado en un mensaje en el visualizador LCD; del sistema y también en la pantalla del ordenador.;; El programa debe permitir modificar fácilmente en posteriores revisiones en el hardware de; la salida. Es decir, para activar las salidas conviene utilizar el direccionamiento por bit; en lugar de por byte (utilizar instrucciones "bsf" y "bcf", en lugar de "mov..").

; Programa para PIC 16F876a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F876

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

INCLUDE <P16F876.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

#DEFINE SalidaAdelante PORTB,3 ; Define donde se situan las salidas.#DEFINE SalidaAtras PORTB,2#DEFINE SalidaIzquierda PORTB,1#DEFINE SalidaDerecha PORTB,0

Numero_Espacios EQU D'5'

TeclaAdelante EQU 't' ; Codigo de las teclas utilizadas.TeclaAtras EQU 'b'TeclaIzquierda EQU 'a'TeclaDerecha EQU 'l'

226

Page 235: Entren Adores

TeclaParada EQU ' ' ; Codigo de la tecla espaciadora, (hay un espacio,; tened cuidado al teclear el programa).

Espacio EQU D'32'Retorno_de_carro EQU D'13'

;**************************** Registros *********************************************************************************

CBLOCK 0x20

TeclaPulsada ; Va a guardar el contenido de la tecla pulsada.MensajeApuntado ; Va a guarda la direccion del mensaje apuntado.Reg_Blancos

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Subrutina de "Mensajes" *****************************************************************

ORG 0X05

Mensajes addwf PCL,F

MensajeParado DT "Sistema PARADO", 0x00

MensajeAdelante DT "Marcha ADELANTE", 0x00

MensajeAtras DT "Marcha ATRAS", 0x00

MensajeIzquierda DT "Hacia IZQUIERDA", 0x00

MensajeDerecha DT "Hacia DERECHA", 0x00

Blanco DT " ",0x00

;*************************************** Sección de Configuración *****************************************************

COMIENZO BSF STATUS,RP0 ; Poner el Puerto A como señales digitales.MOVLW D'06'MOVWF ADCON1BCF STATUS,RP0call LCD_Inicializacall RS232_Inicializabsf STATUS,RP0 ; Configura como salidas las 4 lineas delbcf SalidaAdelante ; del Puerto B respetando la configuracion delbcf SalidaAtras ; resto de las lineas.bcf SalidaIzquierdabcf SalidaDerechabcf STATUS,RP0call Parado ; En principio todas las salidas deben estar apagadas.

;**************************************************** Principal **********************************************************

227

Page 236: Entren Adores

Principal call RS232_LeeDato ; Espera a recibir un caracter.call TesteaTecladogoto Principal

;******************************************* Subrutina "TesteaTeclado" ************************************************

; Testea el teclado y actúa en consecuencia.

TesteaTeclado movwf TeclaPulsada ; Guarda el contenido de la tecla pulsada.xorlw TeclaAdelante ; Es la tecla del movimiento hacia adelante?btfsc STATUS,Zgoto Adelante ; Si, se desea movimiento hacia adelante.

movf TeclaPulsada,W ; Recupera el contenido de la tecla pulsada.xorlw TeclaAtras ; Es la tecla del movimiento hacia atrás?btfsc STATUS,Zgoto Atras ; Si, se desea movimiento hacia atras.

movf TeclaPulsada,W ; Recupera el contenido de la tecla pulsada.xorlw TeclaIzquierda ; Es la tecla del movimiento hacia la izquierda?btfsc STATUS,Zgoto Izquierda ; Si, se desea movimiento hacia la izquierda.

movf TeclaPulsada,W ; Recupera el contenido de la tecla pulsada.xorlw TeclaDerecha ; Es tecla del movimiento hacia la derecha?btfsc STATUS,Zgoto Derecha ; Si, se desea movimiento hacia la derecha.

movf TeclaPulsada,W ; Recupera el contenido de la tecla pulsada.xorlw TeclaParada ; Es la tecla de parada?.btfss STATUS,Zgoto Fin ; No es ninguna tecla de movimiento y sale.

Parado bcf SalidaAdelante ; Como se ha pulsado la tecla de parada sebcf SalidaAtras ; desactivan todas las salidas.bcf SalidaIzquierdabcf SalidaDerechamovlw MensajeParadogoto Visualiza

Adelante bcf SalidaAtrasbsf SalidaAdelantebcf SalidaIzquierdabcf SalidaDerechamovlw MensajeAdelantegoto Visualiza

Atras bcf SalidaAdelantebsf SalidaAtrasbcf SalidaIzquierdabcf SalidaDerechamovlw MensajeAtrasgoto Visualiza

Izquierda bcf SalidaAdelantebcf SalidaAtrasbsf SalidaIzquierdabcf SalidaDerecha

228

Page 237: Entren Adores

movlw MensajeIzquierdagoto Visualiza

Derecha bcf SalidaAdelantebcf SalidaAtrasbcf SalidaIzquierdabsf SalidaDerechamovlw MensajeDerecha

; Según el estado de las salidas visualiza el estado del sistema en el visualizador LCD y en; el monitor del ordenador.

Visualiza movwf MensajeApuntado ; Guarda la posicion del mensaje.call LCD_Borra ; Borra la pantalla del modulo LCD.movf MensajeApuntado,W ; Visualiza el mensaje en la pantallacall LCD_Mensaje ; del visualizador LCD.

movlw Numero_Espacios ; Introducimos Espacios en Blanco.movwf Reg_Blancos

No_Fin_Blancos movlw Espaciocall RS232_EnviaDatodecfsz Reg_Blancos,fgoto No_Fin_Blancos

movf MensajeApuntado,Wcall RS232_Mensaje ; Lo visualiza en el HyperTerminal.

movlw Retorno_de_carro ; Saltamos de lineas.call RS232_EnviaDato

Fin return

;************************************** Librerías ********************************************************************

INCLUDE <RS232_RT.INC>INCLUDE <RS232MEN.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <RETARDOS.INC>

END

14.12.- RS232_RT.INC ( Entrenador Básico 10 )

title " Librería de transmisión-recepción serie asíncrona según normas RS-232."

;******************************************** Librería "RS232_RT.INC" ************************************************

; Utiliza las patillas propias del PIC 16f 876a para la transmisión/recepción serie que son:; RC6/TX/CK y RC7/RX/DT; Los parámetros adoptados para la comunicación son los siguientes:

; - Velocidad de transmisión de 1200 baudios.; - Un bit de inicio o Start a nivel bajo.; - Dato de 8 bits.

229

Page 238: Entren Adores

; - Sin paridad.; - 1 bits de final o Stop a nivel alto.

;************************************** Subrutina "RS232_Inicializa" **************************************************

RS232_Inicializa BSF STATUS,RP0 ; Banco 1

BCF TXSTA,BRGH ; Trabajar con velocidad alta de recepción, Baud Rate = Fosc/64(X+1)

MOVLW D'12' MOVWF SPBRG ; Cargar la Velocidad de transmisión de Datos.

; Baud Rate = Fosc/64(X+1)= 1MHz/64(12+1)=1200 Bit/Segundo.

BSF TXSTA,TXEN ; Habilitamos la Transmision serie.BCF TXSTA,SYNC ; Habilitamos modo asíncrono.

BCF STATUS,RP0 ; Banco 0

BSF RCSTA,SPEN ; Activamos la Puerta Serie ; (Configuramos las patillas RC7/RX/DT y RC6/TX/CK como serie).

BSF RCSTA,CREN ; Permitimos las recepciones múltiples

RETURN

;**************************** Subrutinas "RS232_EnviaDato" y "RS232_EnviaNumero" ****************************

; El microcontrolador envía un dato por la línea de salida comenzando por el bit de menor; peso. En dato enviado será el que le llegue a través del registro de trabajo W.

; Entrada: En (W) el dato a enviar.

RS232_EnviaNumero ADDLW '0' ; Envia el codigo ASCII de un numero.; Lo pasa a código ASCII sumándole el ASCII del 0.

RS232_EnviaDato MOVWF TXREG ; Comienzo de la transmision de datos en Serie.BSF STATUS,RP0

No_transmision BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato.GOTO No_transmisionBCF STATUS,RP0

RETURN

;*****************************************Subrutina "RS232_LeeDato" ************************************************

; El microcontrolador lee el dato por la línea de entrada comenzando por el bit de menor; peso. El dato leído se envía finalmente en el registro de trabajo W.

RS232_LeeDato BTFSS PIR1,RCIF ; Preguntamos si ha llegado el dato.GOTO RS232_LeeDatoMOVF RCREG,W ;Cargamos el dato del registro RCREG en el registro

DATO.BCF PIR1,RCIF ;Borrar flag de recepcion.

RETURN

14.13.- RS232MEN.INC ( Entrenador Básico 10 )

230

Page 239: Entren Adores

title " Librería de transmisión de mensajes desde el microcontrolador hacia el "title " ordenador a través del puerto serie RS232. "

;******************************************** Librería "RS232MEN.INC" *****************:*****************************

;****************************************** Subrutina "RS232_Mensaje" **********************************************

; envía por el puerto serie el mensaje apuntado por el registro W y grabado en memoria; de programa del PIC. El mensaje se visualizara en el monitor del ordenador. Esta; subrutina sigue la estructura de funcionamiento similar a la ya conocida "LCD_Mensaje"; para visualización de mensajes en pantallas de módulos LCD.

CBLOCK

RS232_ApuntaCaracter ; Apunta al caracter a visualizar.RS232_ValorCaracter ; Valor ASCII del caracter a visualizar.

ENDC

RS232_Mensaje movwf RS232_ApuntaCaracter ; Posicion del primer caracter del mensaje.movlw Mensajes ; Halla la posicion relativa del primer

subwf RS232_ApuntaCaracter,F ; caracter del mensaje respecto del; comienzo de todos los mensajes; (identificados mediante la etiqueta; "Mensajes").

decf RS232_ApuntaCaracter,F ; Para compensar la posicion que ocupa la; instrucción "addwf PCL,F".

RS232_VisualizaOtroCaracter movf RS232_ApuntaCaracter,W ; Apunta al caracter a visualizar.call Mensajes ; Obtiene el codigo ASCII del

; carácter apuntado.movwf RS232_ValorCaracter ; Guarda el valor de carácter.movf RS232_ValorCaracter,F ; Lo unico que hace es posicionar

; flag Z. En caso que sea "0x00",btfsc STATUS,Z ; que es codigo indicador finalgoto RS232_FinMensaje ; de mensaje, sale fuera.

RS232_NoUltimoCaracter call RS232_EnviaDato ; Visualiza el caracter ASCII leido.incf RS232_ApuntaCaracter,F ; Apunta a la posicion del siguiente goto RS232_VisualizaOtroCaracter ; caracter dentro del mensaje.

RS232_FinMensaje return

;**************************************** Subrutina "RS232_LineasBlanco" *******************************************

; Visualiza unas cuantas líneas en blanco en el monitor del ordenador.

CBLOCK

RS232_ContadorLineas

ENDC

RS232_LineasBlanco movlw d'10' ; Por ejemplo este número de lineas movwf RS232_ContadorLineas ; en blanco.

R232_LineasBlancoLazo movlw d'10' ; Codigo del salto de lineacall RS232_EnviaDatodecfsz RS232_ContadorLineas,F

231

Page 240: Entren Adores

goto R232_LineasBlancoLazomovlw d'13' ; Codigo del retorno de carro.call RS232_EnviaDato ; Finaliza con un retorno de carro.

return

232

Page 241: Entren Adores

15.- Entrenador Básico 11

233

Page 242: Entren Adores

15.1.- Int_T_01.asm ( Entrenador Básico 11 )title " Onda cuadrada de 10 kHz aproximadamente, mediante la

interrupción por desbordamiento del Timer 0 "

;************************************************** Int_T_01.asm *******************************************************

; Por la línea 3 del puerto B se genera una onda cuadrada de 10 kHz, cada semiperiodo dura; 50 us. Los tiempos de temporización se lograran mediante la interrupción por desbordamiento; del Timer 0. A la línea de salida se puede conectar un altavoz que producirá un pitido.

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

;*************** Asignación de nombres de Registros de Funciones especiales a direcciones *******************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

TMR0_Carga50us EQU d'50'#DEFINE Salida PORTB,2

;**************************** Registros *********************************************************************************

CBLOCK 0x0C

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto Timer0_interrupción

;*************************************** Sección de Configuración *****************************************************

ORG 0x05

COMIENZO bsf STATUS,RP0 ; Acceso al Banco 1.bcf Salida ; línea configurada como salida.

234

Page 243: Entren Adores

movlw b'00001000'movwf OPTION_REG ; Sin prescaler para TMR0 (se asigna al Watchdog).bcf STATUS,RP0 ; Acceso al Banco 0.movlw TMR0_Carga50us ; Carga el TMR0.movwf TMR0movlw b'10100000'movwf INTCON ; Autoriza interrupcion T0I y la general (GIE).

;**************************************************** Principal **********************************************************

Principal ; No puede pasar a modo de bajo consumogoto $ ; porque detendria el Timer 0.

;********************************* Rutina de interrupción "Timer0_interrupción" *************************************

; Como el PIC trabaja a una frecuencia de 4 MHz el TMR0 evoluciona cada microsegundo. Para; conseguir un retardo de 50 us con un prescaler de 1 el TMR0 tiene que contar 50 impulsos.; Efectivamente: 1 us x 50 x 1 = 50 us.

Timer0_interrupción movlw TMR0_Carga50usmovwf TMR0 ; Recarga el timer TMR0.btfsc Salida ; Testea el anterior estado de la salida.goto EstabaAlto

EstabaBajo bsf Salida ; Estaba bajo y lo pasa a alto.goto FinInterrupcion

EstabaAlto bcf Salida ; Estaba alto y lo pasa a bajo.

FinInterrupcion bcf INTCON,T0IF ; Repone flag del TMR0.retfie

; Comprobando con el simulador del MPLAB se obtienen unos tiempos para la onda cuadrada de ; 56 us para el nivel alto y de 55 us para el bajo.

END

15.2.- Int_T_02.asm ( Entrenador Básico 11 )title " Onda cuadrada de 10 kHz exactos, mediante la interrupción

por desbordamiento del Timer 0 "

;*********************************************** Int_T_02.asm **********************************************************

; Por la linea 3 del puerto B se genera una onda cuadrada de 10 kHz. Cada semiperiodo dura; 50 us exactos. Los tiempos de temporización se lograran mediante la interrupción del; Timer 0. A la línea de salida se puede conectar un altavoz que producirá un pitido.

; El calculo de la carga del TMR0 se realiza teniendo en cuenta los tiempos que tardan en; ejecutarse las instrucciones y saltos para conseguir tiempos exactos. Para calcular el valor; de carga del TMR0 se ayuda del simulador del MPLAB y de la ventana de reloj Stopwatch.

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.

235

Page 244: Entren Adores

; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

;*************** Asignación de nombres de Registros de Funciones especiales a direcciones *******************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

TMR0_Carga50us EQU d'43'#DEFINE Salida PORTB,3

;**************************** Registros *********************************************************************************

CBLOCK 0x0C

ENDC

;**************************** Sección Código de Reset ***************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto Timer0_interrupción

;*************************************** Sección de Configuración *****************************************************

ORG 0x05

COMIENZO bsf STATUS,RP0 ; Acceso al Banco 1.bcf Salida ; Esta línea se configura como salida.movlw b'00001000'movwf OPTION_REG ; Sin prescaler para TMR0 (se asigna al Watchdog).bcf STATUS,RP0 ; Acceso al Banco 0.movlw TMR0_Carga50us ; Carga el TMR0.movwf TMR0movlw b'10100000'movwf INTCON ; Autoriza interrupcion T0I y la general (GIE).

;**************************************************** Principal **********************************************************

Principal ; No puede pasar a modo de bajo consumogoto $ ; porque detendria el Timer 0.

236

Page 245: Entren Adores

;********************************* Rutina de interrupción "Timer0_interrupción" *************************************

; Como el PIC trabaja a una frecuencia de 4 MHz el TMR0 evoluciona cada microsegundo. Para; conseguir un retardo de 50 microsegundos con un prescaler de 1 el TMR0 tiene que contar ; 43 impulsos. Efectivamente: 1us x 1 x 43 + tiempo de los saltos y otros = 50 us. ;; Las instrucciones "nop" se ponen para ajustar el tiempo a 50 us exacto y lograr una onda; cuadrada perfecta. El simulador del MPLAB comprueba unos tiempos para la onda cuadrada de; 10 kHz exactos de 50 us para el nivel alto y otros 50 us para el bajo.

Timer0_interrupción nopmovlw TMR0_Carga50usmovwf TMR0 ; Recarga el TMR0.btfsc Salida ; Testea el anterior estado de la salida.goto EstabaAlto

EstabaBajo nopbsf Salida ; Estaba bajo y lo pasa a alto.goto FinInterrupcion

EstabaAlto bcf Salida ; Estaba alto y lo pasa a bajo.

FinInterrupcion bcf INTCON,T0IF ; Repone flag del TMR0.retfie ; Retorno de interrupcion

END

15.3.- Int_T_03.asm ( Entrenador Básico 11 )

title " Led ON/OFF 500 ms utilizando la interrupción por desbordamiento del Timer 0 "

;*********************************************** Int_T_03.asm **********************************************************

; Un LED conectado a la línea 1 del puerto de salida se enciende durante 500 ms y apaga; durante otros 500 ms. Los tiempos de temporización se realiza mediante la utilización; de la interrupción por desbordamiento del Timer 0 del PIC.

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

237

Page 246: Entren Adores

;**************************** Igualdades ********************************************************************************

Carga500ms EQU d'10'TMR0_Carga50ms EQU d'195'#DEFINE LED PORTB,1

;**************************** Registros *********************************************************************************

CBLOCK 0x0CRegistro50ms ; Registro auxiliar para conseguir una temporizacion mayor.ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto Timer0_interrupción

;*************************************** Sección de Configuración *****************************************************

ORG 0x05

COMIENZO bsf STATUS,RP0 ; Acceso al Banco 1.bcf LED ; Linea del LED configurada como salida.movlw b'00000111'movwf OPTION_REG ; Prescaler de 256 para el TMR0bcf STATUS,RP0 ; Acceso al Banco 0.movlw TMR0_Carga50ms ; Carga el TMR0.movwf TMR0movlw Carga500msmovwf Registro50msmovlw b'10100000'movwf INTCON ; Activa interrupcion del TMR0 (TOIE) y la general.

;**************************************************** Principal **********************************************************

Principal ; No se puede utilizar el modo bajo consumogoto $ ; porque el Timer se detiene.

;********************************* Rutina de interrupción "Timer0_interrupción" *************************************

; Como el PIC trabaja a una frecuencia de 4MHz, el TMR0 evoluciona cada microsegundo.; El bucle central se hace en un tiempo de 50 ms. Para ello se utiliza un prescaler; de 256 y el TMR0 tiene que contar 195 impulsos. Efectivamente:; 195 x 256 = 49929 us = 50 ms aproximadamente.

; Para conseguir una temporización de 500 ms, habrá que repetir 10 veces el lazo de 50 ms.

Timer0_interrupción movlw TMR0_Carga50msmovwf TMR0 ; Recarga el TMR0.decfsz Registro50ms,F ; Decrementa el contador.goto FinInterrupcionmovlw Carga500msmovwf Registro50ms ; Repone el contador nuevamente

238

Page 247: Entren Adores

btfsc LED ; Testea el ultimo estado del LED.goto EstabaEncendido

EstabaApagado bsf LED ; Estaba apagado y lo enciende.goto FinInterrupcion

EstabaEncendido bcf LED ; Estaba encendido y lo apaga.

FinInterrupcion bcf INTCON,T0IF ; Repone flag del TMR0.retfie

; Con el simulador del MPLAB se comprueba que los tiempos son: En alto 499261 us y en; bajo 499258 us.

END

15.4.- Int_T_04.asm ( Entrenador Básico 11 )title " Led ON (800 ms) Led OFF (500 ms), utilizando la

interrupción por desbordamiento del Timer 0 "

;********************************************** Int_T_04.asm ***********************************************************

; Un LED conectado a la línea 1 del puerto de salida se enciende durante 800 ms y apaga; durante otros 500 ms. Los tiempos de temporización se realizaran mediante la utilización; de la interrupción por desbordamiento del Timer 0 del PIC.

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

Carga500ms EQU d'10'Carga800ms EQU d'16'TMR0_Carga50ms EQU d'195'#DEFINE LED PORTB,1

;**************************** Registros *********************************************************************************

CBLOCK 0x0C

239

Page 248: Entren Adores

Registro50ms ; Registro auxiliar para conseguir una temporizacion mayor.

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto Timer0_interrupción

;*************************************** Sección de Configuración ****************************************************ORG 0x05

COMIENZO bsf STATUS,RP0 ; Acceso al Banco 1.bcf LED ; Linea del LED configurada como salida.movlw b'00000111'movwf OPTION_REG ; Prescaler de 256 asignado al TMR0bcf STATUS,RP0 ; Acceso al Banco 0.movlw TMR0_Carga50ms ; Carga el TMR0.movwf TMR0movlw Carga500msmovwf Registro50msmovlw b'10100000'movwf INTCON ; Autoriza interrupcion del TMR0 (T0IE) y la GIE.

;**************************************************** Principal **********************************************************

Principal ; No puede pasar a modo bajo consumo porquegoto $ ; el Timer 0 se detendria.

;********************************* Rutina de interrupción "Timer0_interrupción" *************************************

; Como el PIC trabaja a una frecuencia de 4 MHz el TMR0 evoluciona cada microsegundo.; El bucle central se hace en un tiempo de 50 ms. Para ello se utiliza un prescaler; de 256 y el TMR0 tiene que contar 195. Efectivamente 195 x 256 = 49929 us = 50 ms.; Para conseguir una temporización de 500 ms habrá que repetir 10 veces el lazo de 50 ms.; Para conseguir una temporización de 800 ms habrá que repetir 16 veces el lazo de 50 ms.

Timer0_interrupción movlw TMR0_Carga50msmovwf TMR0 ; Recarga el TMR0.decfsz Registro50ms,F ; Decrementa el contador.goto FinInterrupcionbtfsc LED ; Testea el ultimo estado del LED.goto EstabaEncendido

EstabaApagado bsf LED ; Estaba apagado y lo enciende.movlw Carga800ms ; Repone el contador nuevamente para que estegoto CargaRegistro50ms ; 800 ms encendido.

EstabaEncendido bcf LED ; Estaba encendido y lo apaga.movlw Carga500ms ; Repone el contador nuevamente para que este

; 500 ms apagado.

240

Page 249: Entren Adores

CargaRegistro50ms movwf Registro50ms

FinInterrupcion bcf INTCON,T0IF ; Repone flag del TMR0.retfie ; Retorno de interrupción.

END

15.5.- Int_T_05.asm ( Entrenador Básico 11 )title " Sistema multitarea ( Mostrar mensajes en el LCD y LED ON/OFF (500 ms) "

;********************************************** Int_T_05.asm ***********************************************************

; El modulo LCD visualiza constantemente un mensaje largo que se desplaza por la pantalla. ; Al mismo tiempo el diodo LED conectado a la línea RB1 se enciende durante 500 ms y se apaga; durante otros 500 ms a modo de segundero

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

Carga500ms EQU d'10'TMR0_Carga50ms EQU d'195'#DEFINE LED PORTB,1

;**************************** Registros *********************************************************************************

CBLOCK 0x0C

Registro50ms ; Registro auxiliar para conseguir una temporizacion mayor.Guarda_WGuarda_STATUS

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

241

Page 250: Entren Adores

;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto Timer0_interrupción

;*************************************** Sección de Configuración *****************************************************

ORG 0x05

COMIENZO call LCD_Inicializabsf STATUS,RP0bcf LEDmovlw b'00000111'movwf OPTION_REG ; Prescaler de 256 para el TMR0bcf STATUS,RP0movlw TMR0_Carga50ms ; Carga el Timer 0.movwf TMR0movlw Carga500msmovwf Registro50ms ; Número de veces a repetir la interrupcion.movlw b'10100000' ; Activa interrupcion del TMR0 (TOIE) y lamovwf INTCON ; general (GIE).

;**************************************************** Principal **********************************************************

Principal movlw MensajeLargocall LCD_MensajeMovimientogoto Principal

;********************************* Rutina de interrupción "Timer0_interrupción" *************************************

; La interrupción se produce cada 50 ms aproximadamente. Para conseguir una temporización; de 500 ms habrá que repetir 10 veces el lazo de 50 ms.; Como esta subrutina altera los valores del registro de trabajo W y del STATUS; habrá que preservar su valor previo y restaurarlos al final.

Timer0_interrupción movwf Guarda_W ; Guarda W y STATUS.swapf STATUS,W ; Ya que "movf STATUS,W" corrompe el bit Z.movwf Guarda_STATUSbcf STATUS,RP0 ; Para asegurarse de que trabaja con el banco 0.movlw TMR0_Carga50msmovwf TMR0 ; Recarga el TMR0.decfsz Registro50ms,F ; Decrementa el contador.goto FinInterrupcionmovlw Carga500ms ; Repone el contador nuevamente.movwf Registro50msbtfsc LED ; Pasa a conmutar el estado del LED.goto EstabaEncendido

EstabaApagado bsf LED ; Lo enciende.goto FinInterrupcion

EstabaEncendido bcf LED ; Lo apaga.

FinInterrupcion swapf Guarda_STATUS,W ; Restaura el STATUS.movwf STATUSswapf Guarda_W,F ; Restaura W como estaba antes de producirseswapf Guarda_W,W ; la interrupción.

242

Page 251: Entren Adores

bcf INTCON,T0IFretfie

;******************************************** Subrutina "Mensajes" ****************************************************

Mensajes addwf PCL,F

MensajeLargo DT " "DT "Estudia \"Desarrollo de Productos Electrónicos"."DT " ", 0x00

;******************************************** Librerías ***************************************************************

INCLUDE <LCD_MENS.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>END

15.6.- Int_T_06.asm ( Entrenador Básico 11 )title " Mostrar mensajes en el LCD fijo en la primera línea e intermitente en la "title " segunda línea utilizando la interrupción del Timer 0 "

;********************************************** Int_T_06.asm ***********************************************************

; En la línea superior de la pantalla aparece un mensaje fijo. En la línea inferior aparece; un mensaje intermitente que se enciende durante 500 ms y se apaga durante 300 ms.

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

Carga500ms EQU 10 ; 500 ms, ya que 50ms x 10 = 500ms Carga300ms EQU 6 ; 300ms, ya que 50ms x 6 = 300ms TMR0_Carga50ms EQU d'195' ; Para conseguir la interrupcion del

; Timer 0 cada 50 ms.

;**************************** Registros *********************************************************************************

CBLOCK 0x0C

Registro50ms

243

Page 252: Entren Adores

Intermitencia ; Si es cero se apaga en intermitencia. Para; cualquier otro valor se enciende.

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto Timer0_interrupción

;*************************************** Sección de Configuración *****************************************************

ORG 0x05

COMIENZO call LCD_Inicializamovlw MensajeFijo ; Visualiza mensaje fijo en la primeracall LCD_Mensaje ; linea.bsf STATUS,RP0movlw b'00000111' ; Prescaler de 256 para el TMR0.movwf OPTION_REGbcf STATUS,RP0movlw TMR0_Carga50ms ; Carga el TMR0.movwf TMR0movlw Carga500msmovwf Registro50msmovlw b'10100000'movwf INTCON

;**************************************************** Principal *********************************************************

Principalgoto $

;********************************* Rutina de interrupción "Timer0_interrupción" *************************************

Timer0_interrupción movlw TMR0_Carga50ms ; Carga el Timer 0.movwf TMR0decfsz Registro50ms,F ; Decrementa el contador.goto FinInterrupcioncomf Intermitencia,F ; Conmuta la intermitenciacall Visualiza

FinInterrupcion bcf INTCON,T0IFretfie

;*********************************************** Subrutina "Visualiza" **************************************************

; Visualiza, o no, un mensaje en función del contenido del registro Intermitencia.

Visualiza call LCD_Linea2 ; Se situa en la segunda linea.btfss Intermitencia,0 ; Apaga o enciende el mensaje en intermitencia?goto ApagaMensaje ; Apaga el mensaje.movlw MensajeIntermitente ; Visualiza el mensaje intermitente.call LCD_Mensaje

244

Page 253: Entren Adores

movlw Carga500ms ; Debe estar 500 ms encendido.movwf Registro50msgoto FinVisualiza

ApagaMensaje call LCD_LineaEnBlanco ; Visualiza una linea en blanco.movlw Carga300ms ; Debe estar 300 ms apagado.movwf Registro50ms

FinVisualiza return

;********************************************** Subrutina "Mensajes" ***************************************************

Mensajes addwf PCL,F

MensajeFijo DT " Estudia", 0x00

MensajeIntermitente DT " ELECTRONICA", 0x00

;******************************************** Librerías ***************************************************************

INCLUDE <RETARDOS.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>

END

15.7.- Int_C_01.asm ( Entrenador Básico 11 )

title " Generar una señal cuadrada por PB2, de frecuencia variable en "title " función de PB7. El modulo LCD visualiza dicha frecuencia "

;*************************************************** Int_C_01.asm ******************************************************

; Por la línea 2 del puerto B se genera una onda cuadrada. La frecuencia de la onda cuadrada cambia; mediante activación del pulsador conectado al pin 7 del puerto B, de la siguiente forma:;; PULSACION FRECUENCIA SEMIPERIODO; ----------------- -------------------- --------------------------------------; (Inicial) 10 kHz 50 us. = 1 x 50 us; Primera 5 kHz 100 us. = 2 x 50 us; Segunda 2 kHz 250 us. = 5 x 50 us; Tercera 1 kHz 500 us. = 10 x 50 us; Cuarta 500 Hz 1000 us. = 20 x 50 us; Quinta 200 Hz 2500 us. = 50 x 50 us; Sexta 100 Hz 5000 us. = 100 x 50 us; Septima 50 Hz 10000 us. = 200 x 50 us

; Al conectarlo por primera vez se genera una frecuencia de 10 kHz, al activar el; pulsador cambia a 5 kHz, al actuar una segunda vez cambia a 2 kHz, y así sucesivamente.

; El modulo LCD visualizara la frecuencia generada. A la línea de salida se puede conectar; un altavoz que producirá un pitido.

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.

245

Page 254: Entren Adores

; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

TMR0_Carga50us EQU d'42' ; El semiperiodo patron va a ser de 50 us.NumeroFrec EQU d'8' ; Ocho posibles frecuencias: 10 kHz, 5 kHz, 2 kHz,

; 1 kHz, 500 Hz, 200 Hz, 100 Hz y 50 Hz.#DEFINE Salida PORTB,2#DEFINE Pulsador PORTB,7

;**************************** Registros *********************************************************************************

CBLOCK 0x0C

ApuntadorFrecuenciaSemiperiodo

ENDC

;**************************** Sección Código de Reset ***************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto ServicioInterrupcion

;*********************************** Subrutina "CargaContador" *******************************************************

ORG 0x05

CargaContador addwf PCL,F

retlw d'1' ; Semiperiodo 1 x 50 = 50 us, frecuencia = 10 kHz.retlw d'2' ; Semiperiodo 2 x 50 = 100 us, frecuencia = 5 kHz.retlw d'5' ; Semiperiodo 5 x 50 = 250 us, frecuencia = 2 kHz.retlw d'10' ; Semiperiodo 10 x 50 = 500 us, frecuencia = 1 kHz.retlw d'20' ; Semiperiodo 20 x 50 = 1000 us, frecuencia = 500 Hz.retlw d'50' ; Semiperiodo 50 x 50 = 2500 us, frecuencia = 200 Hz.retlw d'100' ; Semiperiodo 100 x 50 = 5000 us, frecuencia = 100 Hz.retlw d'200' ; Semiperiodo 200 x 50 = 10000 us, frecuencia = 50 Hz.

;************************************* Subrutina "CargaMensaje" *****************************************************

CargaMensaje addwf PCL,F

246

Page 255: Entren Adores

retlw Mensaje10kHzretlw Mensaje5kHzretlw Mensaje2kHzretlw Mensaje1kHzretlw Mensaje500Hzretlw Mensaje200Hzretlw Mensaje100Hzretlw Mensaje50Hz

;**************************************** Subrutina "Mensajes" *********************************************************

Mensajes addwf PCL,F

MensajeFrecuencia DT "Frec.: ", 0x00Mensaje10kHz DT "10 kHz. ", 0x00Mensaje5kHz DT "5 kHz. ", 0x00Mensaje2kHz DT "2 kHz. ", 0x00Mensaje1kHz DT "1 kHz. ", 0x00Mensaje500Hz DT "500 Hz. ", 0x00Mensaje200Hz DT "200 Hz. ", 0x00Mensaje100Hz DT "100 Hz. ", 0x00Mensaje50Hz DT "50 Hz. ", 0x00

;*************************************** Sección de Configuración *****************************************************

COMIENZO call LCD_Inicializabsf STATUS,RP0bcf Salidabsf Pulsadormovlw b'00001000' ; TMR0 sin prescaler.movwf OPTION_REGbcf STATUS,RP0call EstadoInicial ; Visualiza la frecuencia inicial.movlw TMR0_Carga50us ; Carga el TMR0.movwf TMR0movlw b'10101000'movwf INTCON ; Activa interrupciones del TMR0, RBI y general.

;**************************************************** Principal *********************************************************

Principal goto Principal

;********************************* Rutina de interrupción "ServicioInterrupcion" **************************************

ServicioInterrupcion btfsc INTCON,T0IF ; Interrupcion por desbordamiento del TMR0?.call Timer0_interrupciónbtfsc INTCON,RBIF ; Interrupcion por cambio en el Puerto B?.call Pulsador_Interrupcionbcf INTCON,T0IF ; Repone flag del TMR0.bcf INTCON,RBIF ; Repone flag del RBI.

retfie

247

Page 256: Entren Adores

;**************************************** Subrutina "Pulsador_Interrupcion" *******************************************

; Subrutina de atención a la interrupción por cambio en la línea RB7 donde se ha; conectado un pulsador. ; Incrementa el registro (ApuntadorFrecuencia) desde b'00000000' (que corresponde a una; frecuencia de 10 kHz) hasta b'00000111' (que corresponde a una frecuencia de 50 Hz), según; la tabla especificada en el enunciado del ejercicio.

Pulsador_Interrupcion call Retardo_20msbtfsc Pulsadorgoto Fin_PulsadorInterrupcionincf ApuntadorFrecuencia,F ; Apunta a la siguiente frecuencia.movlw NumeroFrec ; Va a comprobar si ha llegado al

máximo.subwf ApuntadorFrecuencia,W ; (W)=(ApuntadorFrecuencia)-

NumeroFrecbtfsc STATUS,C ; Ha llegado a su maximo?

EstadoInicial clrf ApuntadorFrecuencia ; Si llega al maximo lo inicializa.movf ApuntadorFrecuencia,W ; Va a cargar el valor del factor decall CargaContador ; multiplicacion del semiperiodo movwf Semiperiodo ; segun la tabla.movwf Timer0_ContadorAcall Retardo_200mscall LCD_Linea1 ; Visualiza la frecuencia

seleccionada.movlw MensajeFrecuenciacall LCD_Mensajemovf ApuntadorFrecuencia,Wcall CargaMensajecall LCD_Mensaje

EsperaDejePulsar btfss Pulsadorgoto EsperaDejePulsar

Fin_PulsadorInterrupcion return

; ************************************** Subrutina "Timer0_interrupción" *********************************************

CBLOCKTimer0_ContadorAENDC

Timer0_interrupción movlw TMR0_Carga50usmovwf TMR0 ; Recarga el TMR0.decfsz Timer0_ContadorA,F ; Decrementa el contador.goto Fin_Timer0_interrupciónmovf Semiperiodo,W ; Repone el contador nuevamente.movwf Timer0_ContadorAbtfsc Salida ; Testea el ultimo estado de la salida.goto EstabaAlto

EstabaBajo bsf Salida ; Estaba bajo y lo pasa a alto.goto Fin_Timer0_interrupción

EstabaAlto bcf Salida ; Estaba alto y lo pasa a bajo.

Fin_Timer0_interrupción return

248

Page 257: Entren Adores

;******************************************** Librerías ***************************************************************

INCLUDE <LCD_MENS.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>END

15.8.- Int_C_02.asm ( Entrenador Básico 11 )

title " Generar una señal cuadrada por PB2, de frecuencia variabledesde 300Hz hasta 4000Hz "

;*************************************************** Int_C_02.asm ******************************************************

; A la línea de salida se conecta un altavoz que produce el sonido de una sirena que será fijado; por el diseñador. En esta solución la frecuencia es de 300 Hz, subiendo hasta 4 kHz y bajando; después, mas lentamente, a su valor inicial y repitiendo el proceso.

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

MaximoPeriodo EQU d'200' ; Corresponden a una frecuencia entre 300 Hz y MinimoPeriodo EQU d'15' ; 4 kHz tal como se demuestra posteriormente.

#DEFINE Salida PORTB,2

;**************************** Registros *********************************************************************************

CBLOCK 0x0C

ApuntadorFrecuenciaSentidoFrecuencia ; (SentidoFrecuencia)=0 (frecuencia ascendente).

; (SentidoFrecuencia)=1 (frecuencia descendente).Guarda_WGuarda_STATUS

ENDC

;**************************** Sección Código de Reset ****************************************************************

249

Page 258: Entren Adores

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto Timer0_interrupción

;*************************************** Sección de Configuración *****************************************************

ORG 0X05

COMIENZO bsf STATUS,RP0bcf Salidamovlw b'00000010' ; Prescaler de 8 asignado al TMR0.movwf OPTION_REGbcf STATUS,RP0clrf SentidoFrecuencia ; Inicializa el sentido de la variacion demovlw MaximoPeriodo ; frecuencia ascendente en la sirena.movwf ApuntadorFrecuencia ; Inicializa a la frecuencia minima.sublw d'0' ; Carga en el Timer 0 con signo negativo.movwf TMR0movlw b'10100000'movwf INTCON ; Activa interrupcion del TMR0 (TOIE).

;**************************************************** Principal *********************************************************

Principal btfss SentidoFrecuencia,0goto FrecuenciaAscendente

FrecuenciaDescendente call Retardo_20ms ; Mantiene la frecuencia durante este tiempo.

incf ApuntadorFrecuencia,F ; Aumenta el periodo, disminuye la frecuencia.

movlw MaximoPeriodo ; Ha llegado a su maximo valor de periodo?

subwf ApuntadorFrecuencia,W ; (W)=(ApuntadorFrecuencia)- MaximoPeriodo

btfsc STATUS,C ; C=0?,(W) negativo?, (ApuntadorFrecuencia)< máximo.

clrf SentidoFrecuencia ; No. La siguiente pasada entra en "FrecuenciaAscendente".

goto Fin

FrecuenciaAscendente call Retardo_10ms ; Mantiene la frecuencia durante este tiempo.

decf ApuntadorFrecuencia,F ; Disminuye el periodo, aumenta la frecuencia.

movlw MinimoPeriodo ; Ha llegado a su minimo valor de periodo?

subwf ApuntadorFrecuencia,W ; (W)=(ApuntadorFrecuencia)- MinimoPeriodo

btfss STATUS,C ; C=1?,(W) positivo?, (ApuntadorFrecuencia)>=Mínimo.

incf SentidoFrecuencia,F ; No. La siguiente pasada entra en "FrecuenciaDescendente".

Fin goto Principal

250

Page 259: Entren Adores

;********************************* Rutina de interrupción "Timer0_interrupción" *************************************

; Con un prescaler de 8 el periodo variara según el valor de ApuntadorFrecuencia entre:

; - Para (ApuntadorFrecuencia)=15, frecuencia = 4 kHz.; (efectivamente 15 x 8 = 120 us de semiperiodo que son 4 kHz aproximadamente).; - Para (ApuntadorFrecuencia)=200, frecuencia = 300 Hz.; (efectivamente 200 x 8 = 1600 us de semiperiodo que son 300 Hz aproximadamente).

Timer0_interrupción movwf Guarda_W ; Guarda el valor de W y STATUS.swapf STATUS,Wmovwf Guarda_STATUSbcf STATUS,RP0movf ApuntadorFrecuencia,Wsublw d'0' ; Carga en el Timer 0 con signo

negativo.movwf TMR0btfsc Salidagoto EstabaAlto

EstabaBajo bsf Salidagoto Fin_Timer0_interrupción

EstabaAlto bcf Salida

Fin_Timer0_interrupción swapf Guarda_STATUS,W ; Restaura el valor de W y STATUS.movwf STATUSswapf Guarda_W,Fswapf Guarda_W,Wbcf INTCON,T0IF

retfie

;******************************************** Librerías ***************************************************************

INCLUDE <RETARDOS.INC>

END

15.9.- Int_C_03.asm ( Entrenador Básico 11 )title " Encender y apagar una sirena en función de RB7 y RB6, mostrar en el modulo LCD como esta la sirena "

;************************************************** Int_C_03.asm *******************************************************

; Al actuar sobre el pulsador conectado a la línea RB7 se produce la activación de una; sirena y el modulo LCD visualiza un mensaje del tipo "Sirena ACTIVADA".; Para apagar la sirena hay que actuar sobre el pulsador conectado a la línea RB6. En la ; pantalla visualiza un mensaje del tipo "Sirena APAGADA".

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

251

Page 260: Entren Adores

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

;***************** Asignación de nombres de Registros de Funciones especiales a direcciones *****************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

MaximoPeriodoEQU d'200' ; Corresponden a una frecuencia entre 300 Hz y MinimoPeriodo EQU d'15' ; 4 kHz tal como se demuestra posteriormente.

#DEFINE Salida PORTB,2#DEFINE EntradaActivar PORTB,7#DEFINE EntradaApagarPORTB,6#DEFINE AutorizaSirena Flags,0

;**************************** Registros *********************************************************************************

CBLOCK 0x0C

FlagsApuntadorFrecuenciaSentidoFrecuencia ; (SentidoFrecuencia)=0 (frecuencia ascendente).

; (SentidoFrecuencia)=1 (frecuencia descendente).Guarda_WGuarda_STATUSGuarda_R_ContAGuarda_R_ContB

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto ServicioInterrupcion

;*************************************** Sección de Configuración *****************************************************

ORG 0X05

COMIENZO call LCD_Inicializabsf STATUS,RP0bcf Salidabsf EntradaApagarbsf EntradaActivarmovlw b'00000010' ; Prescaler de 8 asignado al TMR0.movwf OPTION_REGbcf STATUS,RP0

252

Page 261: Entren Adores

call ApagarSirena ; En principio apaga la sirena.clrf SentidoFrecuencia ; Inicializa el sentido de la variacion demovlw MaximoPeriodo ; frecuencia ascendente en la sirena.movwf ApuntadorFrecuencia ; Inicializa a la frecuencia minima.sublw d'0' ; Carga en el Timer 0 con signo negativo.movwf TMR0movlw b'10101000' ; Activa interrupcion del TMR0 (TOIE), por cambiomovwf INTCON ; lineas del Puerto B (RBIE) y la general (GIE)

; El programa principal se dedica exclusivamente a generar el sonido de la sirena con ; ayuda de la interrupción del Timer 0 en caso de que esta activada.

;**************************************************** Principal *********************************************************

Principal btfss AutorizaSirenagoto SirenaNoAutorizada ; Si no se autoriza sirena, va a modo

de bajo consumoSirenaAutorizada btfss SentidoFrecuencia,0

goto FrecuenciaAscendenteFrecuenciaDescendente call Retardo_20ms ; Mantiene la frecuencia durante

este tiempo.incf ApuntadorFrecuencia,F ; Aumenta el periodo, disminuye la

frecuencia.movlw MaximoPeriodo ; Ha llegado a su maximo valor de

periodo?subwf ApuntadorFrecuencia,W ; (W)=(ApuntadorFrecuencia)-

MaximoPeriodo.btfsc STATUS,C ; C=0?,(W) negativo?,

(ApuntadorFrecuencia)<máximo?clrf SentidoFrecuencia ; No. La siguiente pasada entra en

"FrecuenciaAscendente".goto Fin

FrecuenciaAscendente call Retardo_10ms ; Mantiene la frecuencia durante este tiempo.

decf ApuntadorFrecuencia,F ; Disminuye el período, aumenta la frecuencia.

movlw MinimoPeriodo ; Ha llegado a su minimo valor de periodo?

subwf ApuntadorFrecuencia,W ; (W)=(ApuntadorFrecuencia)- MinimoPeriodo

btfss STATUS,C ; C=1?,(W) positivo?, (ApuntadorFrecuencia)>=Mínimo.

incf SentidoFrecuencia,F ; No. La siguiente pasada entra en "FrecuenciaDescendente".

goto Fin

SirenaNoAutorizada bcf Salida ; Pone la salida en bajo.sleep ; Detiene el Timer 0 y espera en

modo bajo consumo

Fin goto Principal ; una interrupcion del pulsador.

;********************************* Rutina de interrupción "ServicioInterrupcion" **************************************

ServicioInterrupcion movwf Guarda_Wswapf STATUS,W

253

Page 262: Entren Adores

movwf Guarda_STATUS

bcf STATUS,RP0 ; Garantiza que se trabaja en el Banco 0.movf R_ContA,W ; Guarda los registros utilizados en esta movwf Guarda_R_ContA ; subrutina y también en la principal.movf R_ContB,Wmovwf Guarda_R_ContB

btfsc INTCON,RBIF ; Interrupcion por cambio en el Puerto B?call RBI_Interrupcionbtfsc INTCON,T0IF ; Interrupcion por desbordamiento del

TMR0?call Timer0_interrupción ; No. Entonces ha sido el Timer 0.

swapf Guarda_STATUS,W ; Restaura registros W y STATUS.movwf STATUSswapf Guarda_W,Fswapf Guarda_W,Wmovf Guarda_R_ContA,Wmovwf R_ContAmovf Guarda_R_ContB,Wmovwf R_ContB

bcf INTCON,RBIFbcf INTCON,T0IF

retfie

;**************************************** Subrutina "RBI_Interrupcion" ************************************************

RBI_Interrupcion call Retardo_20ms ; Espera a que se estabilicen niveles.btfsc EntradaApagar ; Esta presionado el pulsador de apagado?goto CompruebaActivar ; No, compueba el pulsador de activacion.

ApagarSirena CALL Retardo_100msbcf AutorizaSirena ; La sirena se apaga en el programa principal.call LCD_Borramovlw MensajeApagado ; Visualiza el mensaje.goto Visualiza

CompruebaActivar btfsc EntradaActivar ; Esta presionado el pulsador de activacion?.goto EsperaDejePulsar ; No hay activado pulsador alguno y sale.

ActivarSirena CALL Retardo_100msbsf AutorizaSirena ; La sirena se activa en el programa principal.call LCD_Borramovlw MensajeActivada ; Visualiza el mensaje.

Visualiza call LCD_Mensaje

EsperaDejePulsar btfss EntradaApagar ; Espera que desaparezcan las señales de entrada.goto EsperaDejePulsarbtfss EntradaActivargoto EsperaDejePulsar

return

;********************************** Subrutina "Timer0_interrupción" ***************************************************

; Con un prescaler de 8 el periodo variara según el valor de ApuntadorFrecuencia entre:

254

Page 263: Entren Adores

; - Para (ApuntadorFrecuencia)=15, frecuencia = 4 kHz.; (efectivamente 15 x 8 = 120 us de semiperiodo que son 4 kHz aproximadamente).; - Para (ApuntadorFrecuencia)=200, frecuencia = 300 Hz.; (efectivamente 200 x 8 = 1600 us de semiperiodo que son 300 Hz aproximadamente).

Timer0_interrupción movf ApuntadorFrecuencia,Wsublw d'0' ; Carga en el Timer 0 con signo negativo.movwf TMR0 btfsc Salida ; Testea el ultimo estado de la salida.goto EstabaAlto

EstabaBajo bsf Salida ; Estaba bajo y lo pasa a alto.goto Fin_Timer0_interrupción

EstabaAlto bcf Salida ; Estaba alto y lo pasa a bajo.Fin_Timer0_interrupción return

;***************************************** Subrutina "Mensajes" ********************************************************

Mensajes addwf PCL,F

MensajeApagado DT " Sirena APAGADA", 0x00MensajeActivada DT " Ahora ACTIVADA", 0x00

;******************************************** Librerías ***************************************************************

INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <RETARDOS.INC>

END

15.10.- Int_C_04.asm ( Entrenador Básico 11 )title " Control del Ciclo de Trabajo de un señal cuadrada "

;**************************************************** Int_C_04.asm *****************************************************

; Ejemplo de control del ciclo de trabajo.

; Por la línea 2 del Puerto B se genera una onda cuadrada de frecuencia constante a 100 Hz y; ciclo de trabajo variable desde 0% a 100%, es decir, el tiempo en alto varia entre 0 us (0%); y 10.000 us (100%).; El valor del ciclo de trabajo cambia mediante activación del pulsador conectado al pin; 7 del Puerto B, de la siguiente forma:

; PULSACIÓN DC (%) SEMIPERIODO ALTO SEMIPERIODO BAJO; ----------------- ---------- ---------------------------------- ----------------------------------; Inicial 0 % 0 us = 0 x 100 us 10000 us = 100 x 100 us; Primera 10 % 1000 us = 10 x 100 us 9000 us = 90 x 100 us; Segunda 20 % 2000 us = 20 x 100 us 8000 us = 80 x 100 us; Tercera 30 % 3000 us = 30 x 100 us 7000 us = 70 x 100 us; Cuarta 40 % 4000 us = 40 x 100 us 6000 us = 60 x 100 us; Quinta 50 % 5000 us = 50 x 100 us 5000 us = 50 x 100 us; Sexta 60 % 6000 us = 60 x 100 us 4000 us = 40 x 100 us; Septima 70 % 7000 us = 70 x 100 us 3000 us = 30 x 100 us; Octava 80 % 8000 us = 80 x 100 us 2000 us = 20 x 100 us; Novena 90 % 9000 us = 90 x 100 us 1000 us = 10 x 100 us; Décima 100 % 10000 us = 100 x 100 us 0 us = 0 x 100 us

255

Page 264: Entren Adores

; Al conectarlo por primera vez se genera un ciclo de trabajo de 0%, al presionar el pulsador; cambia al 10%, al actuar una segunda vez cambia al 20%, y así sucesivamente.; El modulo LCD visualiza el ciclo de trabajo vigente en cada momento.

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

;*************** Asignación de nombres de Registros de Funciones especiales a direcciones *******************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

TMR0_Carga EQU d'89' ; El semiperiodo patron va a ser de 100 us.IncrementoDC EQU d'10' ; Incremento de cada paso del ciclo de trabajo.

#DEFINE Salida PORTB,2#DEFINE Pulsador PORTB,7

;**************************** Registros *********************************************************************************

CBLOCK 0x0C

CicloTrabajo ; Ciclo de trabajo deseado.Timer0_ContadorA ; Contador auxiliar.

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto ServicioInterrupcion

;****************************************** Subrutina "Mensajes" *******************************************************

ORG 0X05

Mensajes addwf PCL,F

Mensaje_DC DT "Duty Cycle: ", 0x00Mensaje_TantoPorCiento DT "% ", 0x00

256

Page 265: Entren Adores

;*************************************** Sección de Configuración *****************************************************

COMIENZO bsf STATUS,RP0bcf Salidabsf Pulsadormovlw b'00001000' ; TMR0 sin prescaler.movwf OPTION_REGbcf STATUS,RP0call LCD_Inicializacall DC_CeroPorCiento ; Inicializa con un DC=0%, por tanto salidamovlw b'10001000' ; en bajo permanentemente.movwf INTCON ; Habilita solo interrupcion RBI.

;**************************************************** Principal ***********************************************************

Principal goto Principal

;********************************* Rutina de interrupción "ServicioInterrupcion" **************************************

ServicioInterrupcion btfsc INTCON,RBIF ; Interrupcion por cambio en el Puerto B?call Pulsador_Interrupcionbtfsc INTCON,T0IF ; Interrupcion por desbordamiento del TMR0?call Timer0_interrupciónbcf INTCON,RBIF ; Limpia flags de reconocimiento.bcf INTCON,T0IF

retfie

;*************************************** Subrutina "Pulsador_Interrupcion" ********************************************

; Subrutina de atención a la interrupción por cambio en la línea RB7 donde se ha; conectado un pulsador.; Incrementa el registro (CicloTrabajo), desde 0 (que corresponde a un DC = 0%; hasta d'100' (que corresponde a un ciclo de trabajo del 100%).

Pulsador_Interrupcion call Retardo_20msbtfsc Pulsador ; Si no es la linea del pulsador sale.goto Fin_PulsadorInterrupcionbsf INTCON,T0IE ; En principio habilita interrupciones

TMR0.movlw IncrementoDC ; Se le va a sumar al ciclo de trabajoaddwf CicloTrabajo,W ; (W)=(CicloTrabajo)+IncrementoDCmovwf CicloTrabajo ; Guarda resultado.sublw d'100' ; Si DC ha llegado al 100% la salida btfsc STATUS,Z ; pasa a alto permanentemente.goto DC_100PorCientobtfsc STATUS,C ; Si pasa de 100, lo inicializa. goto Visualiza

DC_CeroPorCiento bcf Salida ; Pone la salida siempre en bajo.clrf CicloTrabajo ; Inicializa el ciclo de trabajo a 0%.goto InhabilitaInterrupcionTMR0

DC_100PorCiento bsf Salida ; Pone la salida siempre en alto.movlw d'100' ; Esta al maximo, DC=100%.movwf CicloTrabajo

InhabilitaInterrupcionTMR0 bcf INTCON,T0IE

Visualiza call VisualizaCicloTrabajo ; Visualiza el ciclo de trabajo seleccionado.

257

Page 266: Entren Adores

EsperaDejePulsar btfss Pulsadorgoto EsperaDejePulsar

Fin_PulsadorInterrupcion movf CicloTrabajo,W ; Carga todos los contadores.movwf Timer0_ContadorAmovlw TMR0_Cargamovwf TMR0return

;************************************* Subrutina "Timer0_interrupción" ************************************************

; Mantiene la salida en alto un tiempo igual a 100us x (CicloTrabajo); y en bajo un tiempo igual a 100us x (100-CicloTrabajo).

Timer0_interrupción movlw TMR0_Cargamovwf TMR0decfsz Timer0_ContadorA,F ; Decrementa el contador.goto Fin_Timer0_interrupciónbtfsc Salida ;Testea el anterior estado de la

salida.goto EstabaAlto

EstabaBajo nopbsf Salida ; Estaba bajo y lo pasa a alto.movf CicloTrabajo,W ; Repone el contador nuevamente movwf Timer0_ContadorA ; con el tiempo en alto.nopgoto Fin_Timer0_interrupción

EstabaAlto bcf Salida ; Estaba alto y lo pasa a bajo.movf CicloTrabajo,W ; Repone el contador nuevamente sublw .100 ; con el tiempo en bajo.movwf Timer0_ContadorA

Fin_Timer0_interrupción return

;********************************* Subrutina "VisualizaCicloTrabajo" **************************************************

; Visualiza el ciclo de trabajo en el visualizador LCD. Se hace de manera tal que cuando; haya que visualizar un numero mayor de 9, las decenas siempre se visualicen aunque sean; cero. Y cuando sea menor de 99 las decenas no se visualicen si es cero.

VisualizaCicloTrabajo call Retardo_100mscall LCD_Linea1 ; Visualiza el ciclo de trabajo seleccionado.movlw Mensaje_DCcall LCD_Mensajemovf CicloTrabajo,Wcall BIN_a_BCD ; Lo pasa a BCD.movf BCD_Centenas,W ; Visualiza las centenas.btfss STATUS,Z ; Si son cero no visualiza las centenas.goto VisualizaCentenasmovf CicloTrabajo,W ; Vuelve a recuperar este valor.call BIN_a_BCD ; Lo pasa a BCD.call LCD_Byte ; Visualiza las decenas y unidades.goto VisualizaTantoPorCiento

VisualizaCentenas call LCD_Nibble ; Visualiza las centenas.movf CicloTrabajo,W ; Vuelve a recuperar este valor.call BIN_a_BCD ; Lo pasa a BCD.call LCD_ByteCompleto ; Visualiza las decenas (aunque sea cero) y

; unidades.

258

Page 267: Entren Adores

VisualizaTantoPorCiento movlw Mensaje_TantoPorCiento ; Y ahora el símbolo "%".call LCD_Mensaje

return

;******************************************** Librerías ***************************************************************

INCLUDE <LCD_MENS.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <RETARDOS.INC>INCLUDE <BIN_BCD.INC>

END

15.11.- Int_Re_01.asm ( Entrenador Básico 11 )title "Reloj digital en tiempo real sin puesta en hora "title " utilizando la interrupción del Timer 0 "

;********************************************** Int_Re_01.asm **********************************************************

; Programa para un reloj digital en tiempo real sin puesta en hora. Visualiza en un formato:; " 8:47:39" (Segunda línea).

; Las temporizaciones necesarias del reloj se logran mediante interrupciones por desbordamiento; del Timer 0 cada 50 ms. también actualiza un contador llamado MedioSegundo incrementado cada; 500 ms y que será utilizado en las intermitencias de posteriores programas.

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

;*************** Asignación de nombres de Registros de Funciones especiales a direcciones *******************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

TMR0_Carga50ms EQU d'195' ; Para conseguir la interrupcion del; Timer 0 cada 50 ms.

;**************************** Registros *********************************************************************************

CBLOCK 0x0C

Hora ; Guarda las horas.

259

Page 268: Entren Adores

Minuto ; Guarda los minutos.Segundo ; Guarda los segundos.MedioSegundo ; Se incrementa cada medio segundo.Registro50ms ; Se incrementa cada 50ms.

ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto Timer0_interrupción

;*************************************** Sección de Configuración *****************************************************

ORG 0x05

COMIENZO call LCD_Inicializabsf STATUS,RP0 ; Acceso al Banco 1.movlw b'00000111' ; Prescaler de 256 para el TMR0 y habilitamovwf OPTION_REG ; resistencias de Pull-Up del Puerto B.bcf STATUS,RP0 ; Acceso al Banco 0.clrf Hora ; Inicializa todos los datos del reloj. clrf Minutoclrf Segundoclrf MedioSegundoclrf Registro50msmovlw TMR0_Carga50ms ; Carga el TMR0.movwf TMR0movlw b'10100000' ; Activa interrupcion del TMR0 (TOIE)movwf INTCON ; y la general (GIE).

;**************************************************** Principal ***********************************************************

; La sección "Principal" es de mantenimiento. Solo espera las interrupciones.; No se puede poner en modo de bajo consumo porque la instrucción "sleep" detiene el Timer 0.

Principal goto Principal

;********************************* Rutina de interrupción "Timer0_interrupción" *************************************

Timer0_interrupción btfsc INTCON,T0IF ; Si es una interrupcion procedente delcall Reloj ; desbordamiento del Timer 0, actualiza el reloj.

; correspondiente.FinInterrupcion bcf INTCON,T0IF

retfie

;************************************************ Subrutina "Reloj" *****************************************************

; Esta subrutina actualiza los contadores Horas, Minutos, Segundos, MedioSegundo y Registro50ms.; Se ejecuta debido a la petición de interrupción del Timer 0, cada 50 ms.

; Como el PIC trabaja a una frecuencia de 4 MHz, el TMR0 evoluciona cada us y se desborda cada; 195 x 256 = 49920 µ. Sumándole el retardo de 71 us y el pequeño tiempo de los saltos iniciales

260

Page 269: Entren Adores

; y de carga del contador, resulta un total de 50000 us exactos. Es decir, el TMR0 producirá; una interrupción cada 50 ms exactos, comprobado experimentalmente con la ventana Stopwatch del; simulador del MPLAB.

Reloj call Retardo_50micros ; Retardo de 71 us paracall Retardo_20micros ; ajustar a 50 ms exactos.nop

movlw TMR0_Carga50ms ; Carga el timer 0. movwf TMR0

call IncrementaRegistro50msbtfss STATUS,C ; Ha contado 10 veces 50 ms = 1/2 segundo?goto FinReloj ; No. Pues sale sin visualizar el reloj.

IncrementaReloj call IncrementaMedioSegundobtfss STATUS,C ; Ha pasado 1 segundo?goto ActualizaReloj ; No. Pues sale visualizando el reloj.call IncrementaSegundos ; Si. Incrementa el segundero.btfss STATUS,C ; Han pasado 60 segundos?goto ActualizaReloj ; No. Pues sale visualizando el reloj.call IncrementaMinutos ; Si. Incrementa el minutero.btfss STATUS,C ; Han pasado 60 minutos?goto ActualizaReloj ; No. Pues sale visualizando el reloj.call IncrementaHoras ; Si. Incrementa las horas.

ActualizaReloj call VisualizaReloj ; Visualiza el reloj.FinReloj return

;******************************************* Subrutina "VisualizaReloj" *************************************************

; Visualiza el reloj en la segunda línea en formato: " 8:47:39" (Segunda línea).

VisualizaReloj movlw d'4' ; Se coloca para centrar la visualizacioncall LCD_PosicionLinea2 ; en la segunda linea.movf Hora,W ; Va a visualizar las horas. call BIN_a_BCD ; Lo pasa a BCD.call LCD_Byte ; Visualiza rechazando el cero de las decenas.movlw ':' ; Envia ":" para separar datos.call LCD_Caractermovf Minuto,W ; Visualiza minutos.call BIN_a_BCD ; Lo pasa a BCD.call LCD_ByteCompletomovlw ':' ; Envia ":" para separar datos.call LCD_Caractermovf Segundo,W ; Visualiza segundos.call BIN_a_BCD ; Lo pasa a BCD.call LCD_ByteCompletoreturn

;***************************************** Subrutina "IncrementaRegistro50ms" **************************************

; Incrementa el valor de la variable Registro50ms. Cuando llega a 10, lo cual supone ; medio segundo (50 ms x 10 = 500 ms), lo resetea y sale con el Carry a "1".

IncrementaRegistro50ms incf Registro50ms,Fmovlw d'10'subwf Registro50ms,W ; (W)=(Registro50ms)-10btfsc STATUS,C ; C=0?, (W) negativo?, (Registro50ms)<10?clrf Registro50ms ; Lo inicializa si ha superado su valor

máximo.return

261

Page 270: Entren Adores

;************************************* Subrutina "IncrementaMedioSegundo" *****************************************

; Incrementa el valor de la variable MedioSegundo. Su bit de menor peso se pondrá a "1" una; vez por segundo.

IncrementaMedioSegundo incf MedioSegundo,F ; Incrementa.bsf STATUS,C ; Supone que ha llegado al segundo.btfss MedioSegundo,0 ; El bit 0 se pondrá a "1" cada segundo.bcf STATUS,C

return

;************************************* Subrutina "IncrementaSegundos" **********************************************

; Incrementa el valor de la variable Segundos. Si es igual al valor máximo de 60 lo resetea; y sale con el Carry a "1".

IncrementaSegundos incf Segundo,F ; Incrementa los segundos.movlw d'60'subwf Segundo,W ; Ha superado valor máximo?. (W)=(Segundo)-60.btfsc STATUS,C ; C=0?, (W) negativo?, (Segundo)<60?clrf Segundo ; Lo inicializa si ha superado su valor maximo.

return

;***************************************** Subrutina "IncrementaMinutos" *********************************************

; Incrementa el valor de la variable Minuto. Si es igual al valor máximo de 60 lo resetea; y sale con el Carry a "1".

IncrementaMinutos incf Minuto,F ; Incrementa los minutos.movlw d'60'subwf Minuto,W ; Ha superado su valor máximo?. (W)=(Minuto)-60.btfsc STATUS,C ; C=0?, (W) negativo?, (Minuto)<60?clrf Minuto ; Lo inicializa si ha superado su valor maximo.

return

;******************************************* Subrutina "IncrementaHoras" *********************************************

; Incrementa el valor de la variable Hora. Si es igual al valor máximo de 24 lo resetea; y sale con el Carry a "1".

IncrementaHoras incf Hora,F ; Incrementa las horas.movlw .24subwf Hora,W ; Ha superado su valor máximo?. (W)=(Hora)-24.btfsc STATUS,C ; C=0?, (W) negativo?, (Hora)<24?clrf Hora ; Lo inicializa si ha superado su valor máximo.

return

;******************************************** Librerias ***************************************************************

INCLUDE <RETARDOS.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <BIN_BCD.INC>

END

262

Page 271: Entren Adores

15.12.- Int_Re_04.asm ( Entrenador Básico 11 )title " Reloj digital en tiempo real con puesta en hora. "

;***************************************************** Int_R_04.asm ****************************************************

; Programa para un reloj digital en tiempo real con puesta en hora. Visualiza los datos; en formato:

; - "Mensaje Publicitario" (Primera línea) ; - "Horas:Minutos:Segundos", (Segunda Linea)

; (por ejemplo "I.E.S. Joan Miro" (Primera línea); " 8:47:39" (Segunda Línea).

; Las temporizaciones necesarias del reloj se logran mediante el Timer 0 que; produce una interrupción cada 50 ms.

; La "PuestaEnHora" se logra mediante dos pulsadores: "MODO" e "INCREMENTAR".; Su modo de operación es:

; 1º. Pulsa MODO, las "Horas" se ponen intermitente y se ajustan mediante el; pulsador INCREMENTAR.; 2º. Pulsa MODO y pasa a ajustar los "Minutos" de forma similar.; 3º. Pulsa "MODO" y se acabo la "PuestaEnHora", pasando a visualización normal.

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

;****************** Asignación de nombres de Registros de Funciones especiales a direcciones ****************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

#DEFINE ModoPulsador PORTB,7 ; Los pulsadores se conectan a estos#DEFINE IncrementarPulsador PORTB,6 ; pines del Puerto B.#DEFINE F_AjusteHora FlagsAjuste,1 ; Flags utilizados en la puesta en hora.#DEFINE F_AjusteMinuto FlagsAjuste,0#DEFINE F_Intermitencia Intermitencia,0 ; Si es 0, apaga en intermitencia.

TMR0_Carga50ms EQU d'195' ; Para conseguir la interrupcion del; Timer 0 cada 50 ms.

;**************************** Registros *********************************************************************************

CBLOCK 0x0C

263

Page 272: Entren Adores

Hora ; Guarda las horas.Minuto ; Guarda los minutos.Segundo ; Guarda los segundos.MedioSegundo ; Incrementa cada medio segundo.Registro50ms ; Incrementa cada 50 msIntermitencia ; Para lograr la intermitencia.FlagsAjuste ; Guarda los flags para establecer los

; ajustes de hora y minuto.ENDC

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto ServicioInterrupcion

;****************************************** Subrutina "Mensajes" *******************************************************

ORG 0X05

Mensajes addwf PCL,F

MensajePublicitario DT "I.E.S. Joan Miro", 0x00

;*************************************** Sección de Configuración *****************************************************

COMIENZO call LCD_Inicializamovlw MensajePublicitariocall LCD_Mensajebsf STATUS,RP0 ; Acceso al Banco 1.movlw b'00000111' ; Prescaler de 256 para el TMR0 y habilitamovwf OPTION_REG ; resistencias de Pull-Up del Puerto B.bsf ModoPulsador ; Configurados como entrada.bsf IncrementarPulsadorbcf STATUS,RP0 ; Acceso al Banco 0.clrf FlagsAjuste ; Inicializa todos los flags de la puesta en hora.clrf Hora ; Inicializa todos los datos del reloj. clrf Minutoclrf Segundoclrf MedioSegundoclrf Registro50msmovlw TMR0_Carga50ms ; Carga el TMR0.movwf TMR0movlw b'10101000' ; Activa interrupcion del TMR0 (TOIE), por cambiomovwf INTCON ; lineas del Puerto B (RBIE) y la general (GIE).call PuestaEnHoraReset ; Puesta en hora por primera vez.

;**************************************************** Principal **********************************************************

; La sección "Principal" es mantenimiento. Solo espera las interrupciones.; No se puede poner en modo de bajo consumo porque la instrucción "sleep" detiene el Timer 0.

Principal goto Principal

264

Page 273: Entren Adores

;********************************* Rutina de interrupción "ServicioInterrupcion" **************************************

; Detecta que ha producido la interrupción y ejecuta la subrutina de atención correspondiente.

ServicioInterrupcion btfsc INTCON,T0IF ; Si es una interrupcion procedente delcall Reloj ; desbordamiento del Timer 0, actualiza el reloj.btfss INTCON,RBIF ; Si es una interrupcion RBI, lee los pulsadores.goto FinInterrupcionbtfss ModoPulsador ; Esta presionado el pulsador de "MODO"?call PuestaEnHora ; Si, pasa a poner en hora.btfss IncrementarPulsador ; Pulsado "INCREMENTAR"?.call Incrementar ; Si, pasa a incrementar el registro de tiempo

; correspondiente.FinInterrupcion bcf INTCON,RBIF

bcf INTCON,T0IF

retfie

;********************************************* Subrutina "Reloj" *********************************************************

; Esta subrutina actualiza los contadores Horas, Minutos, Segundos y Registro50ms.; Se ejecuta debido a la petición de interrupción del Timer 0 cada 50 ms.

; Como el PIC trabaja a una frecuencia de 4 MHz, el TMR0 evoluciona cada us y se desborda cada; 195 x 256 = 49920 us. Sumándole el retardo de 71 us y el pequeño tiempo de los saltos; iniciales y de carga del contador, resulta un total de 50000 us exactos. Es decir, el; TMR0 producirá una interrupción cada 50 ms exactos, comprobado experimentalmente con la; ventana Stopwatch del simulador del MPLAB.

Reloj call Retardo_50micros ; Retardo de 71 microsegundos paracall Retardo_20micros ; ajustar a 50 milisegundos exactos.nop

movlw TMR0_Carga50ms ; Carga el Timer 0.movwf TMR0call IncrementaRegistro50msbtfss STATUS,C ; Ha contado 10 veces 50 ms = 1/2 segundo?goto FinReloj ; No. Pues sale sin visualizar el reloj.

; Si esta en "ModoAjusteHora", o "ModoAjusteMinuto" conmuta el flag de intermitencia y ; salta a visualizar el reloj.

movf FlagsAjuste,Fbtfsc STATUS,Zgoto IncrementaRelojmovlw b'00000001' ; Conmuta el flag F_Intermitencia cada 500 ms.xorwf Intermitencia,Fgoto ActualizaReloj ; Visualiza el reloj y sale.

IncrementaReloj bsf F_Intermitencia ; Se mantendra siempre encendido durantecall IncrementaMedioSegundo ; el funcionamiento normal.btfss STATUS,C ; Ha pasado 1 segundo?goto ActualizaReloj ; No. Pues sale visualizando el reloj.call IncrementaSegundos ; Si. Incrementa el segundero.btfss STATUS,C ; Han pasado 60 segundos?goto ActualizaReloj ; No. Pues sale visualizando el reloj.call IncrementaMinutos ; Si. Incrementa el minutero.btfss STATUS,C ; Han pasado 60 minutos?goto ActualizaReloj ; No. Pues sale visualizando el reloj.call IncrementaHoras ; Si. Incrementa las horas.

265

Page 274: Entren Adores

ActualizaReloj call VisualizaReloj ; Visualiza el reloj.

FinReloj return

;***************************************** Subrutina "VisualizaReloj" ***************************************************

; Visualiza el reloj en la segunda línea en formato: " 8:47:39".; Cuando se ajusta una variable, esta debe aparecer en intermitencia. Para ello, utiliza; el flag F_Intermitencia que conmuta cada 500 ms en la subrutina Reloj.

VisualizaReloj movlw d'4' ; Para centrar visualizacioncall LCD_PosicionLinea2 ; en la segunda linea.btfss F_AjusteHora ; Esta en la puesta en hora?goto EnciendeHoras ; No. visualización normal.btfss F_Intermitencia ; Si. Intermitencia si procede.goto ApagaHoras ; Apaga las horas en la intermitencia.

EnciendeHoras movf Hora,W ; Va a visualizar las horas. call BIN_a_BCD ; Lo pasa a BCD.call LCD_Byte ; Visualiza rechazando cero de las decenas.goto VisualizaMinutos

ApagaHoras call LCD_DosEspaciosBlancos ; Visualiza dos espacios en blanco.

VisualizaMinutos movlw ':' ; Envia ":" para separar datos.call LCD_Caracterbtfss F_AjusteMinuto ; Esta en la puesta en hora?.goto EnciendeMinutosbtfss F_Intermitenciagoto ApagaMinutos

EnciendeMinutos movf Minuto,W ; Visualiza minutos.call BIN_a_BCD ; Lo pasa a BCD.call LCD_ByteCompletogoto VisualizaSegundos

ApagaMinutos call LCD_DosEspaciosBlancos ; Visualiza dos espacios en blanco.

VisualizaSegundos movlw ':' ; Envía ":" para separar datos.call LCD_Caractermovf Segundo,W ; Visualiza segundos.call BIN_a_BCD ; Lo pasa a BCD.call LCD_ByteCompleto

return

;****************************************** Subrutina "Incrementar" ****************************************************

; Subrutina de atención a la interrupción por cambio de la línea RB6 al cual se ha conectado; el pulsador "INCREMENTAR". Incrementa según corresponda una sola de las variables.

Incrementar call Retardo_20ms ; Espera se estabilicen niveles de tension.btfsc IncrementarPulsador ; Si es un rebote sale fuera.goto FinIncrementarbsf F_Intermitencia ; Visualiza siempre mientras incrementa.btfsc F_AjusteHoracall IncrementaHorasbtfsc F_AjusteMinutocall IncrementaMinutos

266

Page 275: Entren Adores

call Retardo_100mscall VisualizaReloj ; Visualiza mientras espera que dejecall Retardo_200ms ; de pulsar.btfss IncrementarPulsador ; Mientras permanezca pulsado,goto Incrementar ; incrementa el digito.

FinIncrementar return

;************************************** Subrutina "IncrementaRegistro50ms" *****************************************

; Incrementa el valor de la variable Registro50ms. Cuando llega a 10, lo cual supone ; medio segundo (50 ms x 10 = 500 ms), lo resetea y sale con el Carry a "1".

IncrementaRegistro50ms incf Registro50ms,Fmovlw d'10'subwf Registro50ms,W ; (W)=(Registro50ms)-10.btfsc STATUS,C ; C=0?, (W) negativo?, (Registro50ms)< 10?clrf Registro50ms ; Lo inicializa si ha superado su valor

máximo.return

;************************************** Subrutina "IncrementaMedioSegundo" ****************************************

; Incrementa el valor de la variable MedioSegundo. Su bit de menor peso se pondrá a "1" una; vez por segundo.

IncrementaMedioSegundo incf MedioSegundo,F ; Incrementa.bsf STATUS,C ; Supone que ha llegado al segundo.btfss MedioSegundo,0 ; El bit 0 se pondrá a uno cada segundo.bcf STATUS,C

return

;***************************************** Subrutina "IncrementaSegundos" ******************************************

; Incrementa el valor de la variable Segundo. Si es igual al valor máximo de 60 lo resetea; y sale con el Carry a "1".

IncrementaSegundos incf Segundo,F ; Incrementa los segundos.movlw d'60'subwf Segundo,W ; Ha superado valor máximo?. (W)=(Segundo)-60.btfsc STATUS,C ; C=0?, (W) negativo?, (Segundo)<60?clrf Segundo ; Lo inicializa si ha superado su valor maximo.

return

;******************************************* Subrutina "IncrementaMinutos" *******************************************

; Incrementa el valor de la variable Minuto. Si es igual al valor máximo de 60 lo resetea; y sale con el Carry a "1".

IncrementaMinutos incf Minuto,F ; Incrementa los minutos.movlw d'60'subwf Minuto,W ; Ha superado su valor máximo?. (W)=(Minuto)-60.btfsc STATUS,C ; C=0?, (W) negativo?, (Minuto)<60?clrf Minuto ; Lo inicializa si ha superado su valor maximo.

return

267

Page 276: Entren Adores

;******************************************** Subrutina "IncrementaHoras" ********************************************

; Incrementa el valor de la variable Hora. Si es igual al valor máximo de 24 lo resetea; y sale con el Carry a "1".

IncrementaHoras incf Hora,F ; Incrementa las horas.movlw .24subwf Hora,W ; Ha superado su valor máximo?. (W)=(Hora)-24.btfsc STATUS,C ; C=0?, (W) negativo?, (Hora)<24?clrf Hora ; Lo inicializa si ha superado su valor maximo.

return

;********************************************* Subrutina "PuestaEnHora" **********************************************

; Subrutina de atención a la interrupción producida por el pulsador "MODO" que pone en hora; el reloj. Cada vez que se pulsa, el "1" es desplazado a través del registro (FlagsAjuste),; pasando a ajustar secuencialmente: horas y minutos.

; Para comprender el funcionamiento de esta subrutina hay que saber que el registro FlagsModos; contiene 2 flags que permiten diferenciar cada uno de los ajustes de registros de tiempo.

; - "F_AjusteHora": bit 1 de "FlagsAjuste", para ajustar las horas.; - "F_AjusteMinuto": bit 0 de "FlagsAjuste", para ajustar los minutos.

; así pues el contenido del registro FlagAjuste identifica los siguientes ajustes:

; - (FlagsAjuste)=00000010. Esta ajustando el registro Hora.; - (FlagsAjuste)=00000001. Esta ajustando el registro Minuto.; - (FlagsAjuste)=00000000. Esta en visualización normal del reloj en tiempo real.

; Pueden ocurrir tres casos:

; - Que pulse "MODO" estando en modo de visualización normal que se identifica porque; (FlagsAjuste)=0. En este caso debe activar el flag F_AjusteHora, es decir carga; (FlagsAjuste)=b'00000010', ya que "F_AjusteHora" es el bit 1 del registro FlagsAjuste.; - Que pulse "MODO" estando ya en la puesta en hora, en cuyo caso debe pasar al ajuste; del siguiente registro de tiempo (minutos). Esto lo hace mediante un desplazamiento a; derechas. así, por ejemplo, si antes estaba ajustando las horas (FlagsAjuste)=b'00000010',; pasara a (FlagsAjuste)=b'00000001' identificado como ajuste de los minutos.; - Que pulse "MODO" estando en el último ajuste correspondiente a los minutos,; (FlagsAjuste)=b'00000001', pasara a (FlagsAjuste)=b'00000000', indicando que la puesta; en hora ha terminado y pasa a visualización normal del reloj en tiempo real.

PuestaEnHora call Retardo_20ms ; Espera a que se estabilicen niveles.btfsc ModoPulsador ; Si es un rebote sale fuera.goto FinPuestaEnHora

PuestaEnHoraReset ; Al pulsar "MODO" se apaga la variable debcf F_Intermitencia ; tiempo que se va a ajustar.movf FlagsAjuste,F ; Si antes estaba en funcionamiento normal, ahorabtfss STATUS,Z ; pasa a ajustar la hora.goto AjustaSiguiente ; Si no pasa a ajustar la variable de tiempo

siguiente.bsf F_AjusteHora ; Pasa a ajustar la hora.clrf Segundo ; Inicializa contador de segundos y el resto.clrf MedioSegundoclrf Registro50msgoto FinPuestaEnHora

268

Page 277: Entren Adores

AjustaSiguiente ; Desplaza un "1" a la derecha del registrobcf STATUS,C ; FlagsAjuste para ajustar secuencialmenterrf FlagsAjuste,F ; cada uno de los registros de tiempo:

; hora y minuto.

FinPuestaEnHora call VisualizaRelojbtfss ModoPulsador ; Ahora espera deje de pulsar.goto FinPuestaEnHora

return

;******************************************** Librerías ***************************************************************

INCLUDE <RETARDOS.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <BIN_BCD.INC>

END

15.13.- Int_Temp.asm ( Entrenador Básico 11 )

title " Temporizador digital de precisión "

;************************************************* INT_Temp.asm ******************************************************

; Programa de control para un temporizador digital de precisión. La programación del tiempo; de temporización se realiza mediante dos pulsadores: "AJUSTE" y "ON/INCREM". Funcionamiento:; - En estado de reposo la salida del temporizador esta apagada y el pantalla aparece el; tiempo deseado para la próxima temporización.; - Si se pulsa "ON/INCREM" comienza la temporización.; - Cuando acaba la temporización pasa otra vez a reposo.; - Si pulsa "AJUSTE" antes que haya acabado el tiempo de temporización actúa como pulsador; de paro: interrumpe la temporización, apaga la carga y pasa al estado de reposo.

; Para ajustar la temporización al tiempo deseado. ; - Pulsa "AJUSTE" y ajusta el tiempo deseado mediante el pulsador "ON/INCREM".; - Se vuelve a pulsar "AJUSTE" y pasa a modo de reposo.

; Al apagar el sistema debe conservar el tiempo de temporización deseado para la próxima vez; que se encienda.

; Programa para PIC 16F84a.; Velocidad del Reloj:1 MHz.; Reloj instrucción: 250 KHz = 4 uS.; Perro Guardián deshabilitado.; Tipo de Reloj XT.; Protección de Código: OFF.; Power Reset: ON

;************************************** Elegimos PIC ********************************************************************

LIST p=16F84A

269

Page 278: Entren Adores

;**************** Asignación de nombres de Registros de Funciones especiales a direcciones ******************

INCLUDE <P16F84A.INC> ; Este fichero contiene los nombres y direcciones de los; registros de funciones especiales.

; Este fichero esta localizado en el directorio; con el nombre MPASM.

;**************************** Igualdades ********************************************************************************

;***************************** Registros *********************************************************************************

CBLOCK 0x0C

Tiempo deseado ; El tiempo deseado de temporización.Tiempo ; Tiempo que resta de temporización.FlagsModos ; Guarda los flags con los diferentes

; modos de funcionamiento.ENDC

;**************************** Igualdades en zona EEPROM ***********************************************************

ORG 0x2100 ; Corresponde a la direccion 0 de la zona; EEPROM de datos. Aquí se va a guardar el

DE 0x00 ; tiempo de temporización deseado.

#DEFINE F_Temporizador_ON FlagsModos,2#DEFINE F_Temporizador_Ajuste FlagsModos,1#DEFINE F_Temporizador_OFF FlagsModos,0

#DEFINE SalidaTemporizador PORTB,1 ; Salida donde se conecta la carga.#DEFINE Zumbador PORTB,2 ; Salida donde se conecta el zumbador.#DEFINE AjustePulsador PORTB,7 ; Los pulsadores estan conectados a estas#DEFINE IncrementarPulsador PORTB,6 ; lineas del Puerto B.

;**************************** Sección Código de Reset ****************************************************************

ORG 0X00 ;Direccion del Vector Reset

GOTO COMIENZO ;Comienzo del Programa

;**************************** Vector de interrupción ********************************************************************

ORG 0x04

goto ServicioInterrupcion

;**************************** Subrutina de "Mensajes" *****************************************************************

ORG 0X05

Mensajes addwf PCL,F

Mensaje_ON DT " En MARCHA", 0x00

Mensaje_Ajuste DT "Tiempo deseado:", 0x00

Mensaje_OFF DT " PARADO", 0x00

270

Page 279: Entren Adores

;*************************************** Sección de Configuración *****************************************************

COMIENZO call LCD_Inicializabsf STATUS,RP0movlw b'00000111' ; Prescaler de 256 asignado al TMR0 habilitamovwf OPTION_REG ; resistencias de Pull-Up del Puerto B.bsf AjustePulsador ; Configurados como entradas.bsf IncrementarPulsadorbcf SalidaTemporizador ; Configurados como salidas.bcf Zumbadorbcf STATUS,RP0clrw ; Lee la posicion 0x00 de memoria EEPROM de call EEPROM_LeeDato ; datos donde se guarda el tiempo deseado de la movwf Tiempo deseado ; ultima vez que se ajusto.call ModoTemporizador_OFF ; Modo de funcionamiento inicial.movlw b'10001000' ; Activa interrupciones RBI.movwf INTCON

;**************************************************** Principal **********************************************************Principal goto Principal

;******************************* Rutina de interrupción "ServicioInterrupcion" ****************************************

; Detecta que ha producido la interrupción y ejecuta la subrutina de atención correspondiente.

ServicioInterrupcion btfsc INTCON,T0IFcall Temporizadorbtfss INTCON,RBIF ; Si es una interrupcion RBI lee los

pulsadores.goto FinInterrupcionbtfss AjustePulsador ; Esta presionado el pulsador de

"AJUSTE"?.call CambiarModo ; Si, pues salta a la subrutina

correspondiente.btfsc IncrementarPulsador ; Pulsado "ON/INCREM"?.goto FinInterrupcion ; No, pues salta al final y sale.

call Retardo_20ms ; Espera que se estabilice el nivel de tensión.

btfsc IncrementarPulsador ; Si es un rebote del pulsador "ON/INCREM" sale fuera.

goto FinInterrupcionbtfsc F_Temporizador_OFF ; Estaba en reposo cuando pulso

"ON/INCREM"?call ModoTemporizador_ON ; Si, pues comienza la temporizacion.btfsc F_Temporizador_Ajuste ; Estaba ajustando tiempo?call IncrementarTiempoDeseado ; Si, pues pasa a incrementar el tiempo

deseado.

FinInterrupcion bcf INTCON,RBIF ; Limpia los flags de reconocimiento.bcf INTCON,T0IFretfie

;******************** Subrutinas "CambiarModo" y todas las de MODO de funcionamiento ***********************;; Subrutina de atención a la interrupción producida al presionar el pulsador "AJUSTE" que cambia; el modo de funcionamiento.

; Hay identificados tres modos de funcionamiento que se diferencian mediante los tres flags:; A) Modo "Temporizador_OFF" o estado inicial. A el se pasa en el estado inicial cada vez

271

Page 280: Entren Adores

; que termina una temporización o cuando se aborta la temporización sin esperar a que; finalice. Reconocido por el flag F_Temporizador_OFF, bit 0 del registro FlagsModos.; una temporización o cada vez que se aborta la temporización sin esperar a que finalice.; B) Modo "Temporizador_Ajuste", donde se ajusta la temporización deseada cuando funcione; como temporizador. Reconocido por el flag F_Temporizador_Ajuste, bit 1 del FlagsModos.; C) Modo "Temporizador_ON", la salida esta activada mientras dure la temporización.; Reconocido por el flag F_Temporizacion_ON, que es el bit 2 del registro FlagsModos.

; El programa consigue que esta activado uno solo de los flags anteriores.

; El contenido del registro (FlagsModos) diferencia los siguientes modos de funcionamiento:

; - (FlagsModos)=b'00000001'. Está en el modo "Temporizador_OFF", en reposo.; - (FlagsModos)=b'00000010'. Está en el modo "Temporizador_Ajuste", ajustando tiempo deseado.; - (FlagsModos)=b'00000100'. Está en el modo "Temporizador_ON", activa la carga y temporizador.

; Al pulsar "AJUSTE" pueden darse tres casos:

; - Si estaba en modo "Temporizador_OFF", pasa a modo "Temporizador_Ajuste".; - Si estaba en modo "Temporizador_Ajuste", pasa a modo "Temporizador_OFF", pero antes salva; el tiempo de temporización deseado en la EEPROM de datos. ; - Si estaba en modo "Temporizador_ON", pasa a modo "Temporizador_OFF". (Interrumpe la; temporización).

CambiarModo call PitidoCorto ; Cada vez que pulsa origina un pitido. btfsc AjustePulsador ; Si es un rebote sale fuera.goto EsperaDejePulsarbtfsc F_Temporizador_OFF ; Esta en reposo?goto ModoTemporizador_Ajuste ; Si, pues pasa a ajustar la temporizacion.btfss F_Temporizador_Ajuste ; Esta ajustando?goto ModoTemporizador_OFF ; No, pues pasa a reposo.

; Si, pues antes de pasar a reposo salva en laclrw ; posicion 00h de memoria EEPROM de datos el

movwf EEADR ; tiempo de temporizacion deseado. Se conserva movf TiempoDeseado,W ; aunque se apague la alimentacion.call EEPROM_EscribeDato

ModoTemporizador_OFF bcf SalidaTemporizador ; Apaga la carga y resetea tiempo deseado.call Pitidomovlw b'00000001' ; Actualiza el registro FlagsModos pasando movwf FlagsModos ; al modo inicial "Temporizador_OFF".bcf INTCON,T0IE ; Prohibe las interrupciones del TMR0.movf TiempoDeseado,W ; Repone otra vez el tiempo que se desea movwf Tiempo ; para la proxima temporizacion.call LCD_Borra ; Borra la pantalla.movlw Mensaje_OFF ; En pantalla el mensaje correspondiente.goto FinCambiarModo

ModoTemporizador_Ajuste call Retardo_100msbcf SalidaTemporizador ; Apaga la cargamovlw b'00000010' ; Actualiza el registro FlagsModos pasando movwf FlagsModos ; al modo "Temporizador_Ajuste".clrf Tiempo ; Resetea el tiempo.clrf Tiempo deseadobcf INTCON,T0IE ; Prohíbe las interrupciones del TMR0.call LCD_Borramovlw Mensaje_Ajuste ; En pantalla el mensaje correspondiente.goto FinCambiarModo

272

Page 281: Entren Adores

ModoTemporizador_ON movf TiempoDeseado,W ; Si el tiempo deseado es cero pasa a modobtfsc STATUS,Z ; de trabajo "Temporizador_OFF".goto ModoTemporizador_OFFmovwf Tiempocall PitidoCortomovlw b'00000100' ; Actualiza el registro FlagsModos pasando movwf FlagsModos ; al modo "Temporizador_ON".movlw TMR0_Carga50ms ; Carga el TMR0.movwf TMR0movlw Carga_1s ; Y el registro cuyo decremento contará losmovwf Registro50ms ; segundos.bsf INTCON,T0IE ; Autoriza las interrupciones de TMR0.call LCD_Borrabsf SalidaTemporizador ; Enciende la carga.call Retardo_100msmovlw Mensaje_ON ; En pantalla el mensaje correspondiente.

FinCambiarModo call LCD_Mensajecall VisualizaTiempo

EsperaDejePulsar btfss AjustePulsador ; Espera deje de pulsar.goto EsperaDejePulsarreturn

;********************************* Subrutina "Temporizador" ***********************************************************

; Esta subrutina va decrementando el tiempo de temporización y visualizándolo en la pantalla.; Se ejecuta debido a la petición de interrupción del Timer 0 cada 50 ms exactos, comprobado; experimentalmente con la ventana "Stopwatch" del simulador del MPLAB.

CBLOCK

Registro50ms ; Guarda los incrementos cada 50 ms.

ENDC

TMR0_Carga50ms EQU d'195' ; Para conseguir la interrupcion cada 50 ms.Carga_1s EQU d'20' ; Leera cada segundo (20 x 50ms = 1000 ms).

Temporizador call Retardo_50micros ; Ajuste fino de 71 microsegundos paracall Retardo_20micros ; ajustar a 50 milisegundos exactos.nop

movlw TMR0_Carga50ms ; Carga el Timer0.movwf TMR0decfsz Registro50ms,F ; Decrementa el contador.goto FinTemporizador ; No ha pasado 1 segundo y por tanto sale.movlw Carga_1s ; Repone el contador nuevamente.movwf Registro50msbtfss F_Temporizador_ON ; Si no está en modo "Temporizador_ON" salegoto FinTemporizador ; fuera.decfsz Tiempo,Fgoto VisualizaContador ; Visualiza el tiempo restante.bcf SalidaTemporizador ; Apaga la salidacall VisualizaTiempo ; Visualiza cero segundos en la pantalla.call Pitido ; Tres pitidos indican final de la temporización.call Retardo_500mscall Pitidocall Retardo_500mscall PitidoLargo

273

Page 282: Entren Adores

call Retardo_500mscall ModoTemporizador_OFF ; Acabo la temporizacion.goto FinTemporizador

VisualizaContador call VisualizaTiempoFinTemporizador return

;**************************************** Subrutina "VisualizaTiempo" *************************************************

; Visualiza el registro Tiempo en formato "Minutos:Segundos". así por ejemplo, si; (Tiempo)=124 segundos en la segunda línea de la pantalla visualiza " 2:04", ya que 124; segundos es igual a 2 minutos mas 4 segundos.

VisualizaTiempo call Retardo_100msmovlw d'5' ; Para centrar visualizacion en lacall LCD_PosicionLinea2 ; segunda linea.movf Tiempo,W ; Convierte el tiempo deseado (y expresado solo encall MinutosSegundos ; segundos) a minutos y segundos.movf TemporizadorMinutos,W ; Visualiza los minutos.call BIN_a_BCD ; Lo pasa a BCD.call LCD_Bytemovlw ':' ; Visualiza dos puntos.call LCD_Caractermovf TemporizadorSegundos,W ; Visualiza los segundos.call BIN_a_BCD ; Lo pasa a BCD.goto LCD_ByteCompletoreturn

;**************************************** Subrutina "MinutosSegundos" ***********************************************

; Una cantidad expresada exclusivamente en segundos y contenida en el registro W es; convertida a minutos y segundos. El resultado se guarda en dos posiciones de memoria; llamadas TemporizadorMinutos y TemporizadorSegundos.

; El máximo numero a convertir será el 255 que es el máximo valor que puede adquirir el; numero binario de entrada de 8 bits. (255 segundos = 4 minutos + 15 segundos)

; El procedimiento utilizado es mediante restas de 60 tal como se explica en el siguiente; ejemplo que trata de la conversión del 124 segundos a minutos y segundos.; 124 segundos = 2 minutos + 4 segundos.

; Minutos Segundos (Segundos)<60?; ------- -------- ------------------------------------------------; 0 124 NO. Resta 60 a (Segundos) e incrementa (Minutos).; 1 64 NO. Resta 60 e (Segundos) e incrementa (Minutos).; 2 4 Si, se acabo. ;; Entrada: En el registro W el numero de segundos a convertir.; Salidas: En (TemporizadorMinutos) y (TemporizadorSegundos) el resultado.

CBLOCKTemporizadorMinutosTemporizadorSegundosENDC

;MinutosSegundos movwf TemporizadorSegundos ; Carga el numero de segundos a convertir.

clrf TemporizadorMinutos ; Carga los registros con el resultado inicial.

Resta60 movlw d'60' ; Resta 60 en cada pasada.subwf TemporizadorSegundos,W ; (W)=(TemporizadorSegundos)-60.

274

Page 283: Entren Adores

btfss STATUS,C ; (W) positivo?, (TemporizadorSegundos)>=60?.

goto FinMinutosSegundos ; No, es menor de 60. Acabo.movwf TemporizadorSegundos ; Si, por tanto, recupera lo que queda por

restar.incf TemporizadorMinutos,F ; Incrementa los minutos.goto Resta60 ; Y vuelve a dar otra pasada.

FinMinutosSegundos return

;******************************* Subrutina "IncrementarTiempoDeseado" ********************************************

; Subrutina de atención a la interrupción por cambio de la línea RB6 a la cual se ha; conectado el pulsador "INCREMENTAR".; Estando en el modo "Temporizador_Ajustar" incrementa el valor del tiempo deseado; expresado en segundos en intervalos de 5 segundos y hasta un máximo de 255 segundos.

SaltoIncremento EQU d'5'

IncrementarTiempoDeseado call PitidoCorto ; Cada vez que pulsa se oye un pitido.

movlw SaltoIncremento ; Incrementa el tiempo deseado de temporización

addwf Tiempo,F ; saltos de "SaltoIncremento" segundos.

btfsc STATUS,C ; Si pasa del valor maximo lo inicializa.

clrf Tiempocall VisualizaTiempo ; Visualiza mientras espera que deje

de pulsar.call Retardo_100msbtfss IncrementarPulsador ; Mientras permanezca pulsado,goto IncrementarTiempoDeseado ; incrementa el digito.movf Tiempo,W ; Actualiza el tiempo deseado.movwf Tiempo deseado ; Este es el tiempo deseado.return

;******************************* Subrutinas "PitidoLargo", "Pitido" y "PitidoCorto" ***********************************

PitidoLargo bsf Zumbadorcall Retardo_500ms

Pitido bsf Zumbadorcall Retardo_200ms

PitidoCorto bsf Zumbadorcall Retardo_20msbcf Zumbadorreturn

;********************************************* Librerías *****************************************************************

INCLUDE <RETARDOS.INC>INCLUDE <BIN_BCD.INC>INCLUDE <LCD_4BIT.INC>INCLUDE <LCD_MENS.INC>INCLUDE <EEPROM.INC>

END

275