Entrenadores

Share Embed Donate


Short Description

Download Entrenadores...

Description

Entrenadores de Microcontroladores PIC

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

Í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............................................... Parpadeo de un Led utilizando una librería llamada RETARDOS.INC del libro de Desarrollo de Proyectos. ....

1.5.- Ejemplo3B.asm

12 14

1.6.- Ejemplo4.asm

Simular las luces del Coche Fantástico. ...........................

15

1.7.- Ejemplo5.asm

Simular las luces del Coche Fantástico controlado 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

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

41

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

46

2.3.- Ejemplo8.asm

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. 4.2.- PWM_CAD.asm

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

53

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

59

Interrupción Externa. .....................................................

2

Í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

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

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

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

84

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

5.4.- Ejemp_13.asm

5.5.- Ejemp_14.asm

6.4.- RE1_S_RF.asm 6.5.- T_S_RF.INC

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 datos idénticos consecutivos.

El dato recibido se carga en el registro 6.7.- T_M_S_RF.INC

6.8.- R_M_S_RF.INC

DATO_SERIE_VALIDO. ...............................................

90

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

94

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

98

3

Í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

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

108

Librería que transforma un código hexadecimal en 7 segmentos. ..............................................................

110

Librería de control del teclado. ........................................

111

7.2.- Tecl_02.asm

7.4.- HEX_7SEG.INC 7.5.-TECLADO.INC

8.- Entrenador Básico 6 .................................................................................................. 8.1.- LCD_01.asm

Visualización de un mensaje en el LCD carácter a carácter. .........................................................

115 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 la utilizació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 pulsos generados del exterior. ....................................................

122

Visualizar en la pantalla del LCD los pulsos generados del exterior hasta un número máximo, se resetea y comienza de nuevo la cuenta. .....................

123

Mientras se mantenga presionado el pulsador conectado al pin RA4, incrementa un contador que se visualiza en la pantalla del LCD. ..........................

125

Mientras se mantenga presionado el pulsador conectado al pin RA4, incrementa un contador que se visualiza en la pantalla del LCD en formato decimal ,hexadecimal y binario. .......................................

127

Visualización de un mensaje fijo utilizando la librería LCD_4BIT.INC. ................................................

129

Visualización de un mensaje fijo utilizando la librería LCD_MENS.INC. .............................................

131

Visualización de varios mensajes fijo utilizando la librería LCD_MENS.INC. .............................................

132

Visualización de varios mensajes fijo utilizando la librería LCD_MENS.INC cuando se visualiza el ultimo mensaje el proceso se repite. ...............................

133

8.6.- LCD_06.asm

8.7.- LCD_07.asm

8.8.- LCD_08.asm

8.9.- Mens_01.asm 8.10.- Mens_02.asm 8.11.- Mens_03.asm 8.12.- Mens_03B.asm

4

Índice 8.13.- Mens_04.asm

Página 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 mensaje en función de un pulsador. ..............................................

144

Librería que convierte un número Binario en BCD. El resultado se guarda en tres posiciones de memorias llamadas: BCD_Centenas, BCD_Decenas y BCD_Unidades. ............................................................

145

8.19.- BIN_BCD.INC

8.20.- LCD_4BIT.INC

Librería que 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. .............. 146

8.21.- LCD_MENS.INC

Librería de subrutinas para el manejo de mensajes a visualizar en un visualizador LCD. ...............................

151

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

154

9.1.- Tecla_01.asm 9.2.- Tecla_02.asm 9.3.- Tecl_03.asm 9.4.- Tecla_04.asm

La pantalla del LCD visualiza el orden de la tecla pulsada utilizando la técnica de polling. .........................

155

La pantalla del LCD visualiza el valor hexadecimal de la tecla pulsada utilizando la técnica de polling. ........

156

La pantalla del LCD visualiza el valor hexadecimal de la tecla pulsada utilizando técnicas de interrupción. ..

157

La pantalla del LCD visualiza caracteres españoles en 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 la segunda 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 esta es 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

Cerradura Electrónica. ....................................................

169

9.8.- Tecla_09.asm

5

Í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 del microprocesador a otro C.I. PCF8476. ...........................

180

11.2.- I2C2.asm

Leer un dato del circuito integrado expansor de bus PCF8476 y transmitirlo a través del bus I2C al microprocesador. Transferir el dato del microprocesador a otro C.I. PCF8476 interrumpiendo un programa principal. ..................................................... 181

11.3.- I2C3.asm

Realizar una conversión Analógica / Digital y transmitirla 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 de bus PCF8476 y transmitirlo a través del bus I2C al microprocesador. Transferir los datos del microprocesador a otros C.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ón seleccionada por un pulsador conectado a la línea RB6 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 ANI0 del Esclavo 1(PCF8591), llevarla al Esclavo 2 (PCF8591) y visualiza la tensión en la pantalla del 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 no

confirma la transmisión. ............................................. 205

6

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 puerto serie del ordenador. Lo que se escriba por el teclado del ordenador aparecerá en la pantalla del sistema con microcontrolador. ....................................................... 209

14.2.- RTS232_2.asm

En el modulo LCD se visualizan los caracteres que se escriban en el teclado del ordenador y se transmiten a 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 la memoria de programa del microcontrolador al ordenador. Es decir, en el monitor del ordenador aparecerá el mensaje grabado en el PIC. ......................... 214

14.6.- RTS232_6.asm

Este programa envía varios mensajes grabados en la memoria 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 mensajes grabados en la memoria de programa del microcontrolador. El cambio de mensaje se ejecuta cada vez que se pulse la tecla Enter. ................................ 218

14.8.- RTS232_8.asm

Programa que visualiza en el modulo LCD el código ASCII en formato hexadecimal de la tecla pulsada y también en el monitor del ordenador en formato decimal. ............................................................................... 220

14.9.- RTS232_9.asm

SISTEMA DE MONITORIZACION: Se trata de leer el estado de las entradas conectadas a las líneas 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 del Puerto B y se envia por el puerto RS232 a un terminal para monitorizar el estado de los mismos. Se utilizara las interrupciones por cambio de nivel en una 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 desea comandar el movimiento de una estructura móvil. .............. 227

7

14.12.- RS232_RT.INC

Librería de transmisión-recepción serie asíncrona según normas RS-232. ......................................................... 230

14.13.- RS232MEN.INC

Librería de transmisión de mensajes desde el microcontrolador hacia el ordenador a través del puerto serie 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 desbordamiento del Timer 0. ........................................................................... 235

15.2.- Int_T_02.asm

Onda cuadrada de 10 kHz exactos, mediante la interrupción por desbordamiento del Timer 0. ...................... 236

15.3.- Int_T_03.asm

Led ON/OFF 500 ms utilizando la interrupción por 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 el LCD 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 frecuencia variable en función de PB7. El modulo LCD visualiza dicha 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

1.- Entrenador Básico 0

4

1.1.- Ejemplo1.asm

(Entrenador Básico 0)

Diagrama de Flujo

Leer el Puerto C y transferirlo al

Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include ; Igualdades

; Registros

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

Sección de Configuración ORG 0x05 ; Inicio de Programa COMIENZO

RP0  1 TRISC  11111111 B TRISB  00000000 B RP0  0

; Ir al Banco 1 ; Poner el Puerto C como entrada de datos. ; Poner el Puerto B como salida de datos. ; Ir al Banco 0

; Principal PORTB  PORTC

5

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 ;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 COMIENZO

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

BSF STATUS,RP0 MOVLW B'11111111' MOVWF TRISC CLRF TRISB BCF STATUS,RP0

; Poner el Puerto C como entrada de datos. ; Poner el Puerto B como salida de datos.

;**************************** Principal ************************************************************************** SEG1

MOVF PORTC,W MOVWF PORTB GOTO SEG1 END

; Leer el Puerto C y llevarlo al Acumulador. ; Transferir el dato del Acumulador al Puerto B

6

1.2.- Ejemplo2.asm

(Entrenador Básico 0)

Diagrama de Flujo

Leer el Puerto C complementarlo y transferirlo al Puerto B

Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include ; Igualdades

; Registros

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

Sección de Configuración ORG 0x05 COMIENZO

RP0  1 TRISC  11111111 B TRISB  00000000 B RP0  0

; Inicio de Programa ; Ir al Banco 1 ; Poner el Puerto C como entrada de datos. ; Poner el Puerto B como salida de datos. ; Ir al Banco 0

; Principal PORTB  PORTC

7

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 ;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 COMIENZO

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

BSF STATUS,RP0 MOVLW B'11111111' MOVWF TRISC CLRF TRISB BCF STATUS,RP0

; Poner el Puerto C como entrada de datos. ; Poner el Puerto B como salida de datos.

;**************************** Inicio ******************************************************************************* INICIO Acumulador.

COMF PORTC,W

; Complementar el Puerto C y llevarlo al

MOVWF PORTB GOTO INICIO END

; Transferir el dato del Acumulador al Puerto B

8

1.3.- Ejemplo3.asm

(Entrenador Básico 0)

Diagrama de Flujo

Parpadeo de un Led Subrutina de Tiempo Elegimos PIC List p=16f877 , f=inhx32 REG3  # DATO3 Asignación de nombres de RFS a direcciones.

#include

REG2  # DATO2

; Igualdades

REG1  # DATO1

DATO1 DATO2 DATO3

REG1  REG1 - 1

EQU 0X10 EQU 0X64 EQU 0X64

NO

; Registros REG1 REG2 REG3

EQU EQU EQU

0X22 0X23 0X24

¿ REG1 = 0 ? SI REG2  REG2 - 1

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

Sección de Configuración ORG 0x05 COMIENZO

RP0  1 TRISB  00000000 B RP0  0 PORTB  00000000 B

; Inicio de Programa ; Ir al Banco 1 ; Poner el Puerto B como salida de datos. ; Ir al Banco 0 ; Limpiar el Puerto B

¿ REG2 = 0 ?

NO

SI REG3  REG3 - 1

¿ REG3 = 0 ?

NO

SI ; Principal

RETUR

PB0  1 ; Encender el Led de PB0

SEGUNDO

PB0  0 ; Apagar el Led de PB0

SEGUNDO

9

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 ;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 COMIENZO

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

BSF STATUS,RP1 BSF STATUS,RP0 CLRF TRISB ; Configuramos el Puerto B como salidas BCF STATUS,RP0 CLRF PORTB

;**************************** Inicio **************************************************************************** SEGUIR

BSF PORTB,0 CALL SEGUNDO

10

BCF PORTB,0 CALL SEGUNDO GOTO SEGUIR ;**************************** Subrutina de perdida de tiempo de 1 Segundo ****************************** SEGUNDO SEG7 SEG6 SEG5

MOVLW DATO3 MOVWF REG3 MOVLW DATO2 MOVWF REG2 MOVLW DATO1 MOVWF REG1 DECFSZ REG1,F GOTO SEG5 DECFSZ REG2,F GOTO SEG6 DECFSZ REG3,F GOTO SEG7 RETURN END

11

1.4.- Ejemplo3A.asm

(Entrenador Básico 0)

Diagrama de Flujo

Parpadeo de un Led Utilizando una librería de Tiempo

Librería de Tiempo RETART_1S.INC

; Igualdades Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include

DATO1 DATO2 DATO3

EQU 0X10 EQU 0X64 EQU 0X64

; Registros CBOCK REG1 REG2 REG3

; Igualdades

ENDC

SEGUNDO

; Registros

REG3  # DATO3

CBLOCK 0X20 REG2  # DATO2

ENDC

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

REG1  # DATO1

REG1  REG1 - 1 NO

Sección de Configuración ORG 0x05 COMIENZO

RP0  1 TRISB  00000000 B RP0  0 PORTB  00000000 B

; Inicio de Programa ; Ir al Banco 1 ; Poner el Puerto B como salida de datos. ; Ir al Banco 0 ; Limpiar el Puerto B

; Principal PB0  1 ; Encender el Led de PB0

¿ REG1 = 0 ? SI REG2  REG2 - 1

¿ REG2 = 0 ?

NO

SI SEGUNDO

PB0  0 ; Apagar el Led de PB0

SEGUNDO

REG3  REG3 - 1

¿ REG3 = 0 ?

NO

SI RETUR

12

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

0x00

;Dirección del Vector Reset

GOTO COMIENZO

;Comienzo del Programa

;**************************** Sección de Configuración ******************************************************* ORG 0x05 COMIENZO

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

BSF STATUS,RP0 CLRF TRISB ; Configuramos el Puerto B como salidas BCF STATUS,RP0 CLRF PORTB

;**************************** Inicio ******************************************************************************* SEGUIR

BSF PORTB,0 CALL SEGUNDO BCF PORTB,0 CALL SEGUNDO GOTO SEGUIR

;********************************** Librerías ********************************************************************* INCLUDE END

1.5.- Ejemplo3B.asm

(Entrenador Básico 0) 13

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 ;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 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 COMIENZO

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

BSF STATUS,RP0 CLRF TRISB ; Configuramos el Puerto B como salidas BCF STATUS,RP0 CLRF PORTB

;**************************** Inicio ******************************************************************************* SEGUIR

BSF PORTB,0 CALL Retardo_1s BCF PORTB,0 CALL Retardo_1s GOTO SEGUIR

;**************************** Librerías *************************************************************************** INCLUDE END

1.6.- Ejemplo4.asm

(Entrenador Básico 0) 14

Diagrama de Flujo

1 Simular las luces del Coche Fantástico PORTB  DATO Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

CONTADOR  CONTADOR + 1

CY

7

DATO

0

Retardo_100ms

#include NO

¿ CONTADOR = 8?

; Igualdades

CY  0

SI CONTADOR  00000000 B ; Registros CBLOCK 0X20

CY  0

CONTADOR DATO ENDC

CY

7

DATO

0

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

Sección de Configuración ORG 0x05

PORTB  DATO

Retardo_100ms

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

CONTADOR  CONTADOR + 1

¿ CONTADOR = 7?

NO

SI CONTADOR  00000001 B

1

title " Simular las luces del Coche Fantástico " 15

;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 ;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 CONTADOR DATO ENDC ;**************************** Sección Código de Reset ******************************************************** ORG

0x00

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

;**************************** Sección de Configuración ******************************************************** ORG 0x05 COMIENZO

CLRF CONTADOR BCF STATUS,RP1 BSF STATUS,RP0 MOVLW B'00000000' MOVWF TRISB BCF STATUS,RP0

; Inicio de Programa (Una posición detrás del vector de Interrupción ; Selecciono la pagina 1 de la memoria ; Configuro el PB salidas . ; Selecciono la pagina 0 de la memoria

;*************************** Principal ************************************************************************* SEGUIR

MOVLW B'10000000' MOVWF DATO

; Encendemos el Led PB7 ; Guardamos el código en un Registro.

16

SEG1

SEG4

SEG2 SEG3

MOVF DATO,W MOVWF PORTB

;Transferimos la información del registro DATO ; al Puerto B.

INCF CONTADOR

; Incrementamos CONTADOR.

CALL Retardo_100ms

; Llamamos a la Subrutina de Retardo TIEMPO.

MOVF CONTADOR,W ; Preguntamos si CONTADOR = 8 XORLW 0X08 BTFSC STATUS,Z GOTO SEG2 BCF STATUS,C ; Si CONTADOR 8 ponemos el Cy=0 y rotamos hacia RRF DATO,F ; la Derecha el registro DATO. GOTO SEG1 ; Seguimos hacia la Derecha. CLRF CONTADOR ; Si CONTADOR = 8 ponemos el CONTADOR=0, Cy=0 y BCF STATUS,C ; rotamos hacia la Izquierda el registro DATO. RLF DATO,F MOVF DATO,W MOVWF PORTB

; Transferimos la información del registro DATO ; al Puerto B.

CALL Retardo_100ms ; Llamamos a la Subrutina de Retardo TIEMPO. INCF CONTADOR ; Preguntamos si CONTADOR = 7 MOVF CONTADOR,W XORLW 0X07 BTFSS STATUS,Z GOTO SEG3 ; Seguimos hacia la Izquierda. MOVLW 0X01 ; Ponemos el CONTADOR = 1 y volvemos hacia la izquierda. MOVWF CONTADOR GOTO SEG4 ;*************************** Subrutinas ********************************************************************** INCLUDE END

1.7.- Ejemplo5.asm

(Entrenador Básico 0) 17

Diagrama de Flujo

1

Simular las luces del Coche Fantástico controlado por PCO

PORTB  DATO

NO ¿ PC0 = 1 ?

Elegimos PIC List p=16f877 , f=inhx32

SI CONTADOR  CONTADOR + 1

Asignación de nombres de RFS a direcciones.

#include

CY

7

DATO

0

Retardo_100ms

; Igualdades NO

¿ CONTADOR = 8?

CY  0

SI

; Registros

CONTADOR  00000000 B

CBLOCK 0X20 CONTADOR DATO

CY  0

ENDC

Sección de código de Reset

CY

7

DATO

0

ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa PORTB  DATO

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

¿ PCO = 1 ?

NO

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

NO

¿ PC0 = 1? SI Retardo_100ms

CONTADOR  CONTADOR + 1

NO ¿ CONTADOR = 7? SI CONTADOR  00000001 B

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

;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 ;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 CONTADOR DATO 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 COMIENZO

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

CLRF CONTADOR BCF STATUS,RP1 BSF STATUS,RP0 MOVLW B'00000000' MOVWF TRISB BSF TRISC,0 BCF STATUS,RP0

; Selecciono la pagina 1 de la memoria ; Configuro el PB salidas . ; Selecciono la pagina 0 de la memoria

;*************************** Principal *************************************************************************** SEGUIR

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

19

SEG1 PARAR1

MOVF DATO,W MOVWF PORTB BTFSS PORTC,0 GOTO PARAR1 INCF CONTADOR

; Transferimos la información del registro DATO ; al Puerto B. ; Incrementamos CONTADOR.

CALL Retardo_100ms MOVF CONTADOR,W XORLW 0X08 BTFSC STATUS,Z GOTO SEG2

; Llamamos a la Subrutina de Retardo TIEMPO. ; Preguntamos si CONTADOR = 8

SEG4

BCF STATUS,C RRF DATO,F GOTO SEG1

SEG2 SEG3

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

PARAR2

MOVF DATO,W MOVWF PORTB BTFSS PORTC,0 GOTO PARAR2 INCF CONTADOR

; Si CONTADOR 4 ponemos el Cy=0 y rotamos hacia ; la Izquierda el registro DATO. ; Seguimos hacia la Izquierda.

; Transferimos la información del registro DATO ; al Puerto B.

CALL Retardo_100ms

; Preguntamos si CONTADOR = 7 ; Llamamos a la Subrutina de Retardo TIEMPO.

MOVF CONTADOR,W XORLW 0X07 BTFSS STATUS,Z GOTO SEG3 ; Seguimos hacia la Derecha. MOVLW 0X01 ; Ponemos el CONTADOR = 1 y volvemos hacia la izquierda. MOVWF CONTADOR GOTO SEG4 ;*************************** Librerías *************************************************************************** INCLUDE END

1.8.- Nom_disp.asm

(Entrenador Básico 0) 20

Diagrama de Flujo 1 Poner el Nombre en el Display CONTADOR  00000000 B Elegimos PIC List p=16f877 , f=inhx32

W  CONTADOR

Asignación de nombres de RFS a direcciones.

BINARIO_CARACTER

#include PORTD  W ; Igualdades

Numero_de_caracteres EQU D '5'

Retardo_500ms

; Registros CONTADOR  CONTADOR + 1

CBLOCK 0X20 CONTADOR ENDC

¿ CONTADOR =

NO

Sección de código de Reset

SI

Numero_de _caracteres

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

Sección de Configuración ORG 0x05 COMIENZO

; Inicio de Programa

RP0  1 TRISD  00000000 B RP0  0

; Ir al Banco 1 ; Poner el Puerto D como salida de datos. ; Ir al Banco 0

BINARIO_CARACTE R

PCL  PCL + W

1 RETLW B'01110011' RETLW B'01111001' RETLW B'01011110'

;Retorna con W cargado con P ;Retorna con W cargado con E ;Retorna con W cargado con d

RETLW B'01010000' RETLW B'01011100'

;Retorna con W cargado con r ;Retorna con W cargado con o

title " Poner el NOMBRE en el Display " 21

;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 ;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 COMIENZO

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

BSF STATUS,RP0 CLRF TRISD BCF STATUS,RP0

; Selecciono la pagina 1 de la memoria ; Configuro el Puerto D como salida ; Selecciono la pagina 0 de la memoria

;*************************** Principal *************************************************************************** SEG2 SEG1

CLRF CONTADOR MOVF CONTADOR,W CALL BINARIO_CARACTER MOVWF PORTD CALL Retardo_500ms INCF CONTADOR,F MOVF CONTADOR,W SUBLW Numero_de_caracteres BTFSS STATUS,Z GOTO SEG1 GOTO SEG2

22

;***************************** Subrutina de BINARIO_CARACTER ******************************************* BINARIO_CARACTER ADDWF PCL,F RETLW B'01110011' RETLW B'01111001' RETLW B'01011110' RETLW B'01010000' RETLW B'01011100'

;Suma el Contador del Programa con el contenido ; de W y lo deja en el PC. ;Retorna con W cargado con P ;Retorna con W cargado con E ;Retorna con W cargado con d ;Retorna con W cargado con r ;Retorna con W cargado con o

;***************************** Librerías *************************************************************************** INCLUDE END

1.9.- Sum_Nibl.asm

(Entrenador Básico 0) 23

Diagrama de Flujo 1 Sumar los nibles del Puerto C y llevarlos al Puerto B W  PORTC Elegimos PIC List p=16f877 , f=inhx32 W  00001111 B AND W Asignación de nombres de RFS a direcciones.

#include

Numero_bajo  W

; Igualdades W  PORTC

W  11110000 B AND W

; Registros CBLOCK 0X20 Numero_bajo Numero_alto ENDC

Numero_alto  W

Numero_alto ( 7..4 )

Sección de código de Reset

Numero_alto ( 3..0 )

ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa W  Numero_alto Sección de Configuración ORG 0x05 COMIENZO

; Inicio de Programa

RP0  1 TRISB  00000000 B TRISC  11111111 B RP0  0

; Ir al Banco 1 ; Poner el Puerto B como salida de datos. ; Poner el Puerto C como entrada de datos. ; Ir al Banco 0

W  W + Numero_bajo

PORTB  W

1

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.

24

;**************************** Elegimos PIC ********************************************************************* list p=16f877, f=inhx32 ;************* Asignación de etiquetas de Registros de Funciones especiales a direcciones ************ #include ; 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_bajo Numero_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 COMIENZO

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

BSF STATUS,RP0 CLRF TRISB MOVLW B'11111111' MOVWF TRISC BCF STATUS,RP0

; Selecciono la pagina 1 de la memoria ; Configuro el Puerto B como salida ; Selecciono la pagina 0 de la memoria

;**************************** Inicio ******************************************************************************* SEG1

COMF PORTC,W ANDLW B'00001111' MOVWF Numero_bajo COMF PORTC,W ANDLW B'11110000' MOVWF Numero_alto SWAPF Numero_alto,F MOVF Numero_alto,W ADDWF Numero_bajo,W MOVWF PORTB GOTO SEG1 END

1.10.- Dir_ind.asm

(Entrenador Básico 0) 25

Diagrama de Flujo

Direccionamiento Indirecto

Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include ; Igualdades

; Registros CBLOCK 0X20 REG1 REG2 REG3 ENDC

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

Principal ORG 0x05 COMIENZO

; Inicio de Programa FSR  # REG1 (FSR)  D’1’

FSR  FSR + 1

(FSR)  D’2’

FSR  FSR + 1

(FSR)  D’3’

FSR  FSR + 1

title "Direccionamiento FIN indirecto "

26

;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 ;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 REG1 REG2 REG3 ENDC ;**************************** Sección Código de Reset ******************************************************* ORG

0x00

;Dirección del Vector Reset

GOTO COMIENZO

;Comienzo del Programa

;**************************** Principal ************************************************************************** ORG 0x05 COMIENZO

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

MOVLW REG1 MOVWF 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

Diagrama de Flujo Trabajar con la Pagina 1 de memoria de

Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

Subrutina Prueba Pagina1 ORG 0800H

#include PORTC  PORTB

; Igualdades

; Cambio a la Página0 ; Registros

PCLATCH3  0

CBLOCK 0X20 ENDC

RETUR N

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

Sección de Configuración COMIENZO

RP0  1 TRISB  00000000 B TRISC  11111111 B RP0  0

ORG 0X05

; Ir al Banco 1 ; Poner el Puerto B como salida de datos. ; Poner el Puerto C como entrada de datos. ; Ir al Banco 0

; Cambio a la Página1 PCLATCH3  1 PCLATCH4  0

PAGINA1

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

28

;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 ;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 COMIENZO

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

BSF STATUS,RP0 MOVLW B'11111111' MOVWF TRISC CLRF TRISB BCF STATUS,RP0

;**************************** Inicio ***************************************************************************** SEG1

BSF PCLATH,3 ;Ir a la Pagina1 de memoria de Programa BCF PCLATH,4 CALL PAGINA1 GOTO SEG1

;****************************Subrutina Prueba Pagina1 ******************************************************* ORG 0800H PAGINA1

MOVF PORTC,W MOVWF PORTB ;Ir a la Pagina0 de memoria de Programa BCF PCLATH,3 RETURN END

1.12.- RETARDO_1S.INC

(Entrenador Básico 0) 29

;*********************** 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 SEG7 SEG6 SEG5

MOVLW DATO3 MOVWF REG3 MOVLW DATO2 MOVWF REG2 MOVLW DATO1 MOVWF REG1 DECFSZ REG1,F GOTO SEG5 DECFSZ REG2,F GOTO SEG6 DECFSZ REG3,F GOTO SEG7 RETURN

1.13.- RETARDOS.INC

(Entrenador Básico 0)

30

;**************************** 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 ************************************************************************************* CBLOCK R_ContA R_ContB R_ContC ENDC

; Contadores para los retardos.

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

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_BucleInterno nop ; 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

goto R1ms_BucleExterno return

; Aporta (M-1)x2 ciclos máquina. ; 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_BucleExterno movlw 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

; - Retardo_10s: ; ; - Retardo_5s: ; ; - Retardo_2s: ; ; - Retardo_1s: ; ; - Retardo_500ms: ; ; ; ; ; ;

2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 10000407 cm = 10 s. (N=100, M=100 y K=249). 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 5000207 cm = 5 s. (N= 50, M=100 y K=249). 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 2000087 cm = 2 s. (N= 20, M=100 y K=249). 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 1000047 cm = 1 s. (N= 10, M=100 y K=249). 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

2.- Entrenador Básico 1

35

2.1.- Ejemplo6.asm

(Entrenador Básico 1)

Diagrama de Flujo Encender displays dependiendo de PC0

Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include ; Igualdades

; Registros CBLOCK 0X20 ENDC

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

Sección de Configuración COMIENZO

RP0  1 TRISD  00000000 B TRISC (0)  1

ORG 0X05

; Ir al Banco 1 ; Poner el Puerto D como salida de datos. ; Poner PC0 como entrada de

Datos ADCON1  00000110 B ; Configuro las patillas de los PUERTOS A y D como señales digitales. TRISE  00000000 B RP0  0

; Poner el Puerto E como salida de datos. ; Ir al Banco 0

PORTD  11111111 B

SI ¿ PCO = 1?

; Encender Display de DECENAS PORTE  00000010 B

NO ; Encender Display de UNIDADES PORTE  00000001 B

36

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 ; 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 COMIENZO

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

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

;*************************** Principal *************************************************************************** SEGUIR SEG1 UNIDADES DECENAS

MOVLW B'11111111' MOVWF PORTD BTFSS PORTC,0 GOTO DECENAS MOVLW B'00000001' MOVWF PORTE GOTO SEG1 MOVLW B'00000010' MOVWF PORTE GOTO SEG1

37

END

2.2.- Ejemplo7.asm

(Entrenador Básico 1) 1

Diagrama de Flujo

CONTADOR  00000001 B

Contar pulsos procedentes de PC0 y llevarlos al Display de

PORTE  00000001 B Elegimos PIC List p=16f877 , f=inhx32 NO ¿ PCO = 0?

Asignación de nombres de RFS a direcciones.

#include ; Igualdades NMAYOR EQU

SI W  CONTADOR

0X0A TABLA

; Registros CONTADOR  00000000 B

CBLOCK 0X20

PORT D  W

CONTADOR CONTADOR  CONTADOR +1

ENDC SI

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

Sección de Configuración COMIENZO

RP0  1 TRISD  00000000 B TRISC (0)  1

¿ CONTADOR = NMAYOR ?

ORG 0X05H ; Ir al Banco 1 ; Poner el Puerto D como salida de datos. ; Poner PC0 como entrada de

Datos ADCON1  00000110 B ; Configuro las patillas de los PUERTOS A y D como señales digitales. 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

NO

Subrutina TABLA

PCL  PCL + W

RETLW B'00111111' 00H RETLW B'00000110' 01H RETLW B'01011011' 02H RETLW B'01001111' 03H RETLW B'01100110' 04H

;Retorna con W cargado con ;Retorna con W cargado con ;Retorna con W cargado con ;Retorna con W cargado con ;Retorna con W cargado con

1 38

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 ; 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 COMIENZO

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

BSF STATUS,RP0 CLRF TRISD MOVLW 0X06 MOVWF ADCON1

; Selecciono la pagina 1 de la memoria ; Configuro el Puerto D como salida de datos. ; Configuro el Puerto A y D como patillas digitales.

CLRF TRISE BSF PORTC,0 BCF STATUS,RP0

; Configuro el puerto E como salida de datos. ; Configuro la patilla PC0 como entrada de datos. ; Selecciono la pagina 0 de la memoria

CLRF CONTADOR MOVLW B'00111111' MOVWF PORTD

; Poner el DISPLAY de unidades a cero.

39

INCF CONTADOR MOVLW B'00000001' MOVWF PORTE ;*************************** Principal ***************************************************************************** SEGUIR

BTFSC PORTC,0 GOTO SEGUIR MOVF CONTADOR,W CALL TABLA

SEG1

INCF CONTADOR,F MOVWF PORTD MOVF CONTADOR,W XORLW NMAYOR BTFSS STATUS,Z GOTO SEG1 CLRF CONTADOR BTFSS PORTC,0 GOTO SEG1 GOTO SEGUIR

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

ADDWF PCL,F RETLW B'00111111' RETLW B'00000110' RETLW B'01011011' RETLW B'01001111' RETLW B'01100110' RETLW B'01101101' RETLW B'01111101' RETLW B'00000111' RETLW B'01111111' RETLW B'01101111'

;Suma el Contador del Programa con el contenido ;de W y lo deja en el PC. ;Retorna con W cargado con 00H ;Retorna con W cargado con 01H ;Retorna con W cargado con 02H ;Retorna con W cargado con 03H ;Retorna con W cargado con 04H ;Retorna con W cargado con 05H ;Retorna con W cargado con 06H ;Retorna con W cargado con 07H ;Retorna con W cargado con 08H ;Retorna con W cargado con 09H

END

40

2.3.- Ejemplo8.asm

(Entrenador Básico 1)

Diagrama de Flujo 1 Contar pulsos procedentes de PC0 y llevarlos al Display de Unidades y Decenas

Sección de Configuración COMIENZO

; Ir al Banco 1

ADCON1  00000110 B ; Configuro las patillas de los PUERTOS A y D como señales digitales. 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

Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include ; Igualdades NMAYOR

RP0  1

ORG 0X05H

EQU D’100’

MOSTRAR_DISPLAY

; Registros CBLOCK 0X20 CONTADOR

NO ¿ PCO = 0?

DISPLAY UNIDADES DECENAS CENTENAS

SI PULSOS  CONTADOR

DIVIDENDO DIVISOR COCIENTE RESTO

CONTADOR  CONTADOR +1

ENDC N0

¿ CONTADOR = NMAYOR ?

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

SI CONTADOR  00000000 B

1 MOSTRAR_DISPLAY

SI

NO ¿ PCO = 1?

41

Subrutina de MOSTRAR_DISPLAY

Subrutina de BIN_BCD

BIN_BCD

DIVISOR  D’100’

W  PULSOS W  UNIDADES

BCD_7SEG

PORTD  W DIVIDIR

; Habilitar display de las UNIDADES

CENTENAS  COCIENTE

PORTE  00000001 B DIVISOR  D’10’ ; Temporizar. Perder tiempo con dos NOP W  RESTO ; Deshabilitar display de las UNIDADES y DECENAS PORTE  00000000 B

DIVIDIR

DECENAS  COCIENTE W  DECENAS

BCD_7SEG

PORTD  W UNIDADES  RESTO

; Habilitar display de las DECENAS

RETUR N

PORTE  00000010 B

; Temporizar. Perder tiempo con dos NOP

Subrutina de DIVIDIR

; Deshabilitar display de las UNIDADES y DECENAS

COCIENTE  00000000 B

PORTE  00000000 B DIVIDENDO  W RETUR N

RESTO DIVIDENDO

Subrutina BCD_7SEG DIVIDENDO  DIVIDENDO - DIVISOR PCL  PCL + W

SI ¿ DIVIDENDO < 0?

RETLW B'00111111' RETLW B'00000110' RETLW B'01011011' RETLW B'01001111' RETLW B'01100110' RETLW B'01101101' RETLW B'01111101' RETLW B'00000111' RETLW B'01111111'

;Retorna con W cargado con 00H ;Retorna con W cargado con 01H ;Retorna con W cargado con 02H ;Retorna con W cargado con 03H ;Retorna con W cargado con 04H ;Retorna con W cargado con 05H ;Retorna con W cargado con 06H ;Retorna con W cargado con 07H ;Retorna con W cargado con 08H

NO COCIENTE  COCIENTE + 1

RETURN

42

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 ; 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 COMIENZO

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

BSF STATUS,RP0 MOVLW 0X06

; Selecciono la pagina 1 de la memoria

43

MOVWF ADCON1 CLRF TRISD CLRF TRISE MOVLW B'11111111' MOVWF TRISC BCF STATUS,RP0 CLRF PULSOS ;

; Configuro el Puerto D como salida ; Configuro el Puerto E como salida ; Configuro el puerto PC como entrada.

; Selecciono la pagina 0 de la memoria 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_DISPLAY BTFSC PORTC,0 GOTO SEGUIR MOVF CONTADOR,W MOVWF PULSOS INCF CONTADOR,F MOVF CONTADOR,W XORLW NMAYOR BTFSS STATUS,Z GOTO SEG1 CLRF CONTADOR

SEG1

CALL MOSTRAR_DISPLAY BTFSS PORTC,0 GOTO SEG1 GOTO SEGUIR

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

ADDWF PCL,F RETLW B'00111111' RETLW B'00000110' RETLW B'01011011' RETLW B'01001111' RETLW B'01100110' RETLW B'01101101' RETLW B'01111101' RETLW B'00000111' RETLW B'01111111' RETLW B'01101111'

;Suma el Contador del Programa con el contenido ;de W y lo deja en el PC. ;Retorna con W cargado con 00H ;Retorna con W cargado con 01H ;Retorna con W cargado con 02H ;Retorna con W cargado con 03H ;Retorna con W cargado con 04H ;Retorna con W cargado con 05H ;Retorna con W cargado con 06H ;Retorna con W cargado con 07H ;Retorna con W cargado con 08H ;Retorna con W cargado con 09H

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

CALL BIN_BCD MOVF UNIDADES,W CALL BCD_7SEG MOVWF PORTD MOVLW B'00000001' MOVWF PORTE NOP NOP MOVLW B'00000000' MOVWF PORTE

44

NOP NOP MOVF DECENAS,W CALL BCD_7SEG MOVWF PORTD MOVLW B'00000010' MOVWF PORTE NOP NOP MOVLW B'00000000' MOVWF PORTE NOP NOP RETURN ;***************************** Subrutina de Binario a BCD ******************************************************** BIN_BCD

movlw D’100’ ; Cargamos divisor con 100 movwf DIVISOR movf PULSOS,w call DIVIDIR movf COCIENTE,w movwf CENTENAS movlw D’10’ ; Cargamos divisor con 10 movwf DIVISOR movf RESTO,w call DIVIDIR movf COCIENTE,w movwf DECENAS movf RESTO,w movwf UNIDADES return

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

seg3

clrf COCIENTE movwf DIVIDENDO movf DIVIDENDO,w movwf RESTO movf DIVISOR,w subwf DIVIDENDO,f btfss STATUS,C goto seg3 incf COCIENTE goto seg2 RETURN END

45

3.- Entrenador Básico 2

46

3.1.- Ejemplo9.asm

(Entrenador Básico 2)

Diagrama de Flujo

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

1 Sección de Configuración COMIENZO

RP0  1

ORG 0X05H

; Ir al Banco 1

ADCON1  00000110 B ; Configuro las patillas de los PUERTOS A y D como señales digitales. 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.

Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

TRISC  11111111 B

#include

; Poner Puerto C como entrada de datos

CONTADOR  00000000 B ; Resetear el CONTADOR ; Igualdades NMAYOR

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

EQU D’100’

CONTADOR  CONTADOR +1 ; Registros

RP0  0

; Ir al Banco 0

CBLOCK 0X20 CONTADOR DISPLAY

NO ¿ PCO = 0?

UNIDADES DECENAS CENTENAS

SI

DIVIDENDO DIVISOR COCIENTE RESTO

PULSOS  CONTADOR

ENDC

MOSTRAR_DISPLAY

Sección de código de Reset

CONTADOR  CONTADOR +1

ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa N0

¿ CONTADOR = NMAYOR ? SI

1

CONTADOR  00000000 B

SI

NO ¿ PCO = 1?

47

Subrutina de BIN_BCD

Subrutina de MOSTRAR_DISPLAY

DIVISOR  D’100’

BIN_BCD

W  PULSOS

W  UNIDADES

DIVIDIR

BCD_7SEG

CENTENAS  COCIENTE

PORTD  W

DIVISOR  D’10’

W  DECENAS

W  RESTO

BCD_7SEG

DIVIDIR

PORTB  W

DECENAS  COCIENTE RETUR N UNIDADES  RESTO

RETUR N

Subrutina BCD_7SEG PCL  PCL + W

Subrutina de DIVIDIR RETLW B'00111111' 00H RETLW B'00000110' 01H RETLW B'01011011' 02H RETLW B'01001111' 03H RETLW B'01100110'

;Retorna con W cargado con COCIENTE  00000000 B

;Retorna con W cargado con ;Retorna con W cargado con

DIVIDENDO  W

;Retorna con W cargado con ;Retorna con W cargado con

RESTO DIVIDENDO

DIVIDENDO  DIVIDENDO - DIVISOR SI ¿ DIVIDENDO < 0? NO COCIENTE  COCIENTE + 1

RETURN

48

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

COMIENZO

ORG 05h

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

BSF STATUS,RP0 MOVLW 0X06

; Selecciono la pagina 1 de la memoria

49

MOVWF ADCON1 CLRF TRISD CLRF TRISE CLRF TRISB MOVLW B'11111111' MOVWF TRISC BCF STATUS,RP0 CLRF CONTADOR MOVLW B'00111111' MOVWF PORTD MOVWF PORTB MOVLW B'00000011' MOVWF PORTE INCF CONTADOR

; Configuro el Puerto D como salida ; Configuro el puerto PC como entrada. ; Selecciono la pagina 0 de la memoria ; Poner el Puerto D a cero. ; Poner el Puerto B a cero.

;************************************ Principal ***************************************************************** SEGUIR

SEG1

BTFSC PORTC,0 GOTO SEGUIR

; Preguntamos si hemos pulsado “PC0”

MOVF CONTADOR,W MOVWF PULSOS CALL MOSTRAR_DISPLAY ; Mostramos los datos en los Displays INCF CONTADOR,F ; Incrementamos el CONTADOR de Pulsos. MOVF CONTADOR,W XORLW NMAYOR ; Preguntamos si hemos llegado al máximo pulso a contar. BTFSS STATUS,Z GOTO SEG1 CLRF CONTADOR ; Reseteamos CONTADOR BTFSS PORTC,0 ; Preguntamos si sigue pulsado “PC0” GOTO SEG1 GOTO SEGUIR

;****************************** Subrutina de MOSTRAR_DISPLAY ****************************************** MOSTRAR_DISPLAY CALL BIN_BCD MOVF UNIDADES,w CALL BCD_7SEG MOVWF PORTD MOVF DECENAS,w CALL BCD_7SEG MOVWF PORTB RETURN ;***************************** Subrutina de Binario a BCD ******************************************************** BIN_BCD

movlw D'100' ; Cargamos divisor con 100 movwf DIVISOR movf PULSOS,w call DIVIDIR movf COCIENTE,w movwf CENTENAS movlw D'10' ; Cargamos divisor con 10 movwf DIVISOR movf RESTO,w call DIVIDIR movf COCIENTE,w movwf DECENAS

50

movf RESTO,w movwf UNIDADES RETURN ;****************************** Subrutina de Dividir ************************************************************** DIVIDIR seg2

seg3

clrf COCIENTE movwf DIVIDENDO movf DIVIDENDO,w movwf RESTO movf DIVISOR,w subwf DIVIDENDO,f btfss STATUS,C goto seg3 incf COCIENTE goto seg2 RETURN

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

ADDWF PCL,F RETLW B'00111111' RETLW B'00000110' RETLW B'01011011' RETLW B'01001111' RETLW B'01100110' RETLW B'01101101' RETLW B'01111101' RETLW B'00000111' RETLW B'01111111' RETLW B'01101111'

;Suma el Contador del Programa con el contenido de W y lo deja en el PC. ;Retorna con W cargado con 00H ;Retorna con W cargado con 01H ;Retorna con W cargado con 02H ;Retorna con W cargado con 03H ;Retorna con W cargado con 04H ;Retorna con W cargado con 05H ;Retorna con W cargado con 06H ;Retorna con W cargado con 07H ;Retorna con W cargado con 08H ;Retorna con W cargado con 09H

END

51

4.- Entrenador Básico 2A

52

4.1.- PWM_1.asm

(Entrenador Básico 2A)

Diagrama de Flujo 1 Control de un Servomotor de Posición con PWM a través del Puerto

Elegimos PIC List p=16f876 , f=inhx32

; 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

Asignación de nombres de RFS a direcciones.

#include

Retardo 20ms

; 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 Reset GOTO COMIENZO ;Comienzo del Programa

Sección de Configuración COMIENZO

RP0  1 TRISB  11111111 B TRISC (2)  0 PR2  #PERIODO RP0  0

ORG 0X05H

; Ir al Banco 1 ; Poner Puerto B como entrada de datos ;Habilitamos PC2 como salida para atacar el Servomotor 1. ; Cargamos el Periodo de la señal de PWM ; 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

53

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

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

;**************************** Sección de Configuración ******************************************************* ORG 0X05 COMIENZO

BSF STATUS,RP0 BCF STATUS,RP1 MOVLW B'11111111' MOVWF TRISB BCF TRISC,2 MOVLW PERIODO MOVWF PR2 BCF STATUS,RP0 MOVLW B'00000111' MOVWF T2CON MOVLW B'00001100' MOVWF CCP1CON

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

; Habilitamos PC2 como salida para atacar el Servomotor 1. ; Cargamos el Periodo de la señal de PWM. ;Cargamos el valor preescalar. (PWM INTERNO) ;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

;*************************** Principal ***************************************************************************** SEG1

COMF PORTB,W MOVWF CCPR1L CALL Retardo_20ms

; Nivel Alto de la señal PWM (Salida por RC2). ; Tiene que transcurrir un periodo antes de refrescar ; el nivel alto de la señal.

GOTO SEG1 ;************************** Librerias ******************************************************************************* INCLUDE END

54

4.2.- PWM_CAD.asm

(Entrenador Básico 2A)

Diagrama de Flujo 1 Sección de Configuración Control de un Servomotor de Posición con PWM a través de un Potenciómetro

COMIENZO

ORG 0X05H

RP0  1

; Ir al Banco 1

TRISB  00000000 B

; Poner Puerto B como salida de dato

;Configuración del Conversor Analogico/Digital.

Elegimos PIC List p=16f876 , f=inhx32

TRISA (5)  1 ADCON1  00000000 RP0  0 ADCON0  00100001 RP0  1

; Ir al Banco 0 ; Ir al Banco 1

;Configuración del PWM. Asignación de nombres de RFS a direcciones.

TRISC (2)  0

;Habilitamos PC2 como salida para atacar el Servomotor 1.

PR2  #PERIODO

; Cargamos el Periodo de la señal de PWM ; Ir al Banco 0

#include RP0  0 ; Igualdades PERIODO

EQU D’255’

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

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

; Registros CBLOCK 0X20 ENDC

Retardo_20ms

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

1

; Lanzamos el Conversor Analógico / Digital GO_DONE  1

; Es un BIT que está en el registro ADCON0

NO ¿ GO_DONE = 0 ? SI ; 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

55

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

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

;**************************** Sección de Configuración ***************************************************** ORG 0X05 COMIENZO

BSF STATUS,RP0 BCF STATUS,RP1

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

MOVLW B'00000000' MOVWF TRISB BSF TRISA,5 MOVLW B'00000000' MOVWF ADCON1 BCF STATUS,RP0 MOVLW B'00100001' MOVWF ADCON0

;Configuración del Conversor Analogico/Digital.

BSF STATUS,RP0

;Configuración del PWM.

56

BCF TRISC,2

;Habilitamos PC2 como salida para atacar el Servomotor 1.

MOVLW PERIODO MOVWF PR2

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

BCF STATUS,RP0 MOVLW B'00000111' MOVWF T2CON MOVLW B'00001100' MOVWF CCP1CON

;Cargamos el Valor Preescalar.(PWM INTERNO) ;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

;*************************** Principal ******************************************************************** SEG2 SEG1

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_DONE BTFSC ADCON0,GO_DONE GOTO SEG1 MOVF ADRESH,W MOVWF CCPR1L ; Nivel Alto de la señal PWM (Salida por RC2). COMF ADRESH,W MOVWF PORTB GOTO SEG2

;*************************** Librerías ******************************************************************** INCLUDE END

57

5.- Entrenador Básico 3

58

5.1.- Ejempl10.asm

( Entrenador Básico 3 ) 1

Diagrama de Flujo Sección de Configuración COMIENZO

RP0  1

ORG 0X05H

; 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

Interrupción Externa

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

Elegimos PIC List p=16f876 , f=inhx32

Asignación de nombres de RFS a direcciones.

; Resetear el registro CONTADOR

#include

CONTADOR  00000000 B

; Igualdades

; Cargar el Puntero

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

FSR  #TABLAD

W  CONTADOR

TABLA

; Registros CBLOCK 0X20

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

CONTADOR W_TEMP STATUS_TEMP PIR1_TEMP PORTB_TEMP TMR1H_TEMP TMR1L_TEMP T1CON_TEMP CONTADOR1

(FSR)  W

PORTC  W

ENDC

TIEMPO

Sección de código de Reset ; Incrementar el Puntero

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

FSR  FSR +1

Vector de Interrupción

; Incrementar CONTADOR

ORG 04H GOTO INTERRU

CONTADOR  CONTADOR +1 NO

1

SI ¿ CONTADOR = NDATOS ?

59

Rutina de Interrupción INTERRU Subrutina de TABLA NO ¿ INTF = 1? PCL  PCL + W SI RETFI E

; Salvar Registros W  W_TEMP STATUS  STATUS_TEMP PIR1_TEMP  PIR1 PORTB_TEMP  PORTB TMR1H_TEMP  TMR1H TMR1L_TEMP  TMR1L T1CON_TEMP  T1CON

RETLW B'11111110' RETLW B'11111101' RETLW B'11111011' RETLW B'11110111' RETLW B'11101111' RETLW B'11011111' RETLW B'10111111'

;Retorna con W cargado con 01H ;Retorna con W cargado con 02H ;Retorna con W cargado con 04H ;Retorna con W cargado con 08H ;Retorna con W cargado con 01H ;Retorna con W cargado con 02H ;Retorna con W cargado con 04H

; Resetear CONTADOR1 Subrutina de TIEMPO

CONTADOR1  00000000 B

; Poner un dato en el Puerto B ; Cargar cuenta Inicial PORTB  00001110 B TMR1H  #TIEMPOH TMR1L  #TIEMPOL TIEMPO ; Configurar el TIMER1 “Este proceso se debe de realizar en la Sección de Configuración

TIEMPO

T1CON  00110001 B ; Limpiar el Puerto B PORTB  00000000 B

¿ TMR1IF = 1?

NO

SI

TIEMPO

; Borrar Flag TMR1IF  0

TIEMPO

; Incrementar CONTADOR1

RETURN

CONTADOR1  CONTADOR1 +1

NO

RETFIE

¿ CONTADOR1 = NDATOS1 ? ; Recuperar Registros SI ; Borrar Flag de la INT INTF  0

T1CON  T1CON_TEMP TMR1L TMR1L_TEMP TMR1H  TMR1H_TEMP PORTB  PORTB_TEMP PIR1 PIR1_TEMP STATUS  STATUS_TEMP W  W_TEMP

60

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 ; 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 8 NDATOS1 EQU 0A TIEMPOH EQU 0XC0 TIEMPOL EQU 0X00 ;***************************** Registros ************************************************************************* CBLOCK 0X20 CONTADOR W_TEMP STATUS_TEMP PIR1_TEMP PORTB_TEMP TMR1H_TEMP TMR1L_TEMP T1CON_TEMP CONTADOR1 ENDC ;**************************** Sección Código de Reset ******************************************************** ORG

00h

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

61

;**************************** Vector de Interrupción ************************************************************ ORG 04H GOTO INTERRU ;**************************** Sección de Configuración ******************************************************** ORG 05h COMIENZO

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

BSF STATUS,RP0 ; Selecciono la pagina 1 de la memoria MOVLW 0X01 MOVWF TRISB BCF TRISE,2 CLRF TRISC BCF OPTION_REG,INTEDG BCF STATUS,RP0 ; Selecciono la pagina 0 de la memoria CLRF PORTB BSF PORTE,2 MOVLW B’10010000’ MOVWF INTCON

;*************************** Principal **************************************************************************** RESETEO

CLRF CONTADOR MOVLW TABLAD MOVWF FSR

; Encender los Led del Puerto C hacia la Izquierda.

SEGUIR

MOVF CONTADOR,W CALL TABLA MOVWF INDF MOVWF PORTC CALL TIEMPO INCF FSR INCF CONTADOR MOVF CONTADOR,W XORLW NDATOS BTFSC STATUS,Z GOTO RESETEO GOTO SEGUIR

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

ADDWF PCL,F RETLW B'11111110' RETLW B'11111101' RETLW B'11111011' RETLW B'11110111' RETLW B'11101111' RETLW B'11011111' RETLW B'10111111' RETLW B'01111111'

;Suma el Contador del Programa con el contenido ;de W y lo deja en el PC. ;Retorna con W cargado con 01H ;Retorna con W cargado con 02H ;Retorna con W cargado con 04H ;Retorna con W cargado con 08H ;Retorna con W cargado con 01H ;Retorna con W cargado con 02H ;Retorna con W cargado con 04H ;Retorna con W cargado con 08H

62

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

MOVLW TIEMPOH MOVWF TMR1H MOVLW TIEMPOL MOVWF TMR1L MOVLW B’00110001’ MOVWF T1CON

SEG1

BTFSS PIR1,TMR1IF GOTO SEG1 BCF PIR1,TMR1IF RETURN

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

BTFSS INTCON,INTF RETFIE MOVWF W_TEMP SWAPF STATUS,W MOVWF STATUS_TEMP MOVF PIR1,W MOVWF PIR1_TEMP MOVF PORTB,W MOVWF PORTB_TEMP MOVF TMR1H,W MOVWF TMR1H_TEMP MOVF TMR1L,W MOVWF TMR1L_TEMP MOVF T1CON,W MOVWF T1CON_TEMP CLRF CONTADOR1

SEGUIR1

MOVLW B’00001110’ MOVWF PORTB CALL TIEMPO CALL TIEMPO CLRF PORTB CALL TIEMPO CALL TIEMPO INCF CONTADOR1 MOVF CONTADOR1,W XORLW NDATOS1 BTFSC STATUS,Z GOTO SEGUIR2 GOTO SEGUIR1

SEGUIR2

BCF INTCON,INTF MOVF T1CON_TEMP,W MOVWF T1CON MOVF TMR1L_TEMP,W MOVWF TMR1L MOVF TMR1H_TEMP,W MOVWF TMR1H MOVF PORTB_TEMP,W MOVWF PORTB MOVF PIR1_TEMP,W MOVWF PIR1 SWAPF STATUS_TEMP,W MOVWF STATUS

63

SWAPF W_TEMP,F SWAPF W_TEMP,W RETFIE END

5.2.- Ejemp_11.asm

( Entrenador Básico 3 ) 1

Diagrama de Flujo

Sección de Configuración COMIENZO Conversión Analógica / Digital

Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include

RP0  1

ORG 0X05H

; 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

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

; Igualdades

Retardo_10micros Retardo_10micros ; Registros CBLOCK 0X20 ENDC

; Lanzamos el Conversor Analógico / Digital GO_DONE  1

; Es un BIT que está en el registro ADCON0

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

1

NO ¿ GO_DONE = 0 ? SI ; Cargamos los 8 bits más significativos que están en ADRESH en el Puerto B PORTB  ADRESH

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

64

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 ;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 COMIENZO

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

BSF STATUS,RP0 BSF TRISA,0 BCF TRISE,2 CLRF TRISB CLRF TRISC MOVLW B'00001110' MOVWF ADCON1 BCF STATUS,RP0 MOVLW B'11111111' MOVWF PORTC BSF PORTE,2 MOVLW B'00000001' MOVWF ADCON0

;Ir al Banco 1 ;Poner PORTA(0)como entrada. ;Poner PORTE(2)como salida de datos. ;Poner PORTB como salida de datos. ;Poner PORTC como salida de datos. ;Seleccionar PA0 como entrada analógica ;Los 8 BIT mas significativos se quedan en ADRESH. ;Los 2 BIT memos significativos se quedan en ADRESL. ;Ir al Banco 0 ;Apagar Leds del PUERTO C ;Elegimos PA0 y habilitamos el Conversor

;*************************** Principal ************************************************************************* SEG2

BSF ADCON0,GO_DONE

;Lanzamos el Conversor

65

SEG1

CALL Retardo_10micros CALL Retardo_10micros BTFSC ADCON0,GO_DONE GOTO SEG1 MOVF ADRESH,W MOVWF PORTB BSF STATUS,RP0 COMF ADRESL,W BCF STATUS,RP0 MOVWF PORTC GOTO SEG2

; Esperar un tiempo de adquisición de 20 uS. ;Si GO_DONE es 0 la muestra esta digitalizada. ;En ADRESH se depositan los 8 BIT mas significativos. ;En ADRESL se depositan los 2 BIT menos significativos.

;*************************** Librerías ******************************************************************** INCLUDE END

5.3.- Ejemp_12.asm

( Entrenador Básico 3 )

Diagrama de Flujo 1 Contar pulsos del exterior utilizando el TIMER0

Sección de Configuración COMIENZO

Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

#include

; Igualdades

ORG 0X05H

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

NDATOS = D'15' ; Cargar la cuenta inicial en el registro TMR0 ; Registros

TMR0  D’00’

CBLOCK 0X20 ENDC

; Cargar el registro TMR0 en el PORTB. PORTB  TMR0

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

NO

¿ TMR0 = NDATOS ? SI

1 FIN

66

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

; 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 GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

;**************************** Sección de Configuración ***************************************************** ORG 05h COMIENZO

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

BSF STATUS,RP0 CLRF TRISB

; Selecciono la pagina 1 de la memoria ; Configuro el Puerto B como salida

MOVLW B'00000110' MOVWF ADCON1 MOVLW 0x10 MOVWF TRISA MOVLW B'00111000' MOVWF OPTION_REG

;Selecciono PORTA y PORTE como entrada digitales.

CLRF TRISE BCF STATUS,RP0 CLRF PORTB BSF PORTE,2

;Selecciono RA4 como entrada de datos. ; Configuro el TIMER0 como contador de pulsos ; y la cuenta se realiza por flanco de bajada en ; la patilla RA4/T0CKI y sin preescalar. ; Selecciono PORTE como salida de datos. ; Selecciono la pagina 0 de la memoria ; Limpio Puerto B. ; Habilito los Led del PORTE

;*************************** Principal *************************************************************************** SEGUIR

MOVLW D’00’ MOVWF TMR0

; Cargar la cuenta inicial en el registro TMR0

SEGUIR1

MOVF TMR0,W MOVWF PORTB XORLW NDATOS BTFSC STATUS,Z GOTO FINAL GOTO SEGUIR1

; Cargar el registro TMR0 en el PORTB.

FINAL

; Si TMR0 = NDATOS ir a FINAL.

GOTO FINAL

67

5.4.- Ejemp_13.asm

( Entrenador Básico 3 )

Diagrama de Flujo 1 Transferir una Tabla de datos de memoria EPROM a RAM y Puerto B utilizando como subrutina de tiempo el TIMER0 y el

W  CONTADOR

TABLA Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones.

;Cargar el Acumulador donde apunta el puntero FSR (FSR)  W

#include ;Cargar el Acumulador en el PORTB.

; Igualdades

PORTB  W

TABLAD = 30H NDATOS = D’05’ TIEMPO1 = D'00' TIEMPO2 = D'20'

;Cargar el registro CONT_TI con el dato TIEMPO2

; Registros

CONT_TI  #TIEMPO2

CBLOCK 0X20 CONTADOR CONT_TI ENDC

TIEMPO

CONT_TI  CONT_TI -1

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

Sección de Configuración COMIENZO

ORG 0X05H

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

¿ CON_TI = 0?

NO

SI ; Incrementar Puntero FSR  FSR +1

; Incrementar CONTADOR CONTADOR  CONTADOR +1

¿ CONTADOR = NDATOS ? NO SI FIN

68

Subrutina de TIEMPO

Subrutina de TABLA

; Cargar el dato TIEMPO1 en el registro TMR0

PCL  PCL + W

TMR0  #TIEMPO1

NO ¿ T0IF = 1 ?

RETLW B'00000010' RETLW B'00000100' RETLW B'00001000' RETLW B'00000100' RETLW B'00000010'

;Retorna con W cargado con 02H ;Retorna con W cargado con 04H ;Retorna con W cargado con 08H ;Retorna con W cargado con 04H ;Retorna con W cargado con 02H

SI ; Borrar flag T0IF  0

RETURN

title " Transferir una Tabla de datos de memoria EPROM a RAM y Puerto B title " 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 ; 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 TIEMPO2

EQU D'00' EQU D'20'

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

69

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 COMIENZO

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

BSF STATUS,RP0 CLRF TRISB MOVLW B'00000110' MOVWF ADCON1 CLRF TRISE MOVLW B'00000111' MOVWF OPTION_REG

; Selecciono la pagina 1 de la memoria ; Configuro el Puerto B como salida ;Selecciono PORTA y PORTE como entrada digitales.

BCF STATUS,RP0 CLRF PORTB BSF PORTE,2 CLRF CONTADOR MOVLW TABLAD MOVWF FSR

; Selecciono la pagina 0 de la memoria ; Apagar los LEDS del Puerto B. ; Habilitar los Led del PORTE. ; Limpiar CONTADOR. ; Cargar el Puntero con TABLAD.

; Selecciono PORTE como salida de datos. ; Configurar el TIMER0 como Temporizador ; y con preescalar de 256.

;*************************** Principal ************************************************************************ SEGUIR

SEG2

MOVF CONTADOR,W

;Cargar el CONTADOR en el Acumulador.

CALL TABLA

;Devuelve en el Acumulador un Dato.

MOVWF INDF MOVWF PORTB

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

MOVLW TIEMPO2 MOVWF CONT_TI CALL TIEMPO DECFSZ CONT_TI,F GOTO SEG2

;Cargar en el registro CONT_TI el dato TIEMPO2.

INCF FSR INCF CONTADOR

;Incrementar el puntero FSR. ;Incrementar el CONTADOR.

MOVF CONTADOR,W XORLW NDATOS BTFSC STATUS,Z GOTO $ GOTO SEGUIR

;Si CONTADOR NDATOS ir a SEGUIR.

;Llamar a la subrutina de TIEMPO. ;Se decrementa CONT_TI si CONT_TI0 ir a SEG2.

;Parar.

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

70

TABLA

ADDWF PCL,F RETLW 01H RETLW 02H RETLW 04H RETLW 08H RETLW 04H RETLW 02H

;Suma el Contador del Programa con el contenido de W y lo deja en el PC. ;Retorna con W cargado con 01H ;Retorna con W cargado con 02H ;Retorna con W cargado con 04H ;Retorna con W cargado con 08H ;Retorna con W cargado con 04H ;Retorna con W cargado con 02H

;***************************** Subrutina de Tiempo ********************************************************** TIEMPO SEG1

MOVLW TIEMPO1 MOVWF TMR0 BTFSS INTCON,T0IF GOTO SEG1 BCF INTCON,T0IF RETURN

;Cargar el dato TIEMPO1 en el registro TMR0 ;Si el flag T0IF 1 ir a SEG1 ;Borrar flag T0IF

END

2

5.5.- Ejemp_14.asm

( Entrenador Básico 3 )

;Resetear el registro DIGITO

Diagrama de Flujo DIGITO  00000000 B

1

Detectar el número mayor ;Cargar el decontenido una tabladel de datos registro DIGITO en W.

Sección de código de Reset

W  DIGITO

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

Elegimos PIC List p=16f877 , f=inhx32 ;Cargar datos de la subrutina TABLA

Sección de Configuración

Asignación de nombres de RFS a direcciones.

COMIENZO

#include ;Subrutina que detecta el número mayor DE_MAYOR ; Igualdades ;Incrementar el registro N_DATOS = D’5’ DIGITO ; Asignamos el Número de DIGITO  DIGITO +1 datos de la tabla

ORG 0X05H

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 PORTE(2)  1

;Apagar Leds del PUERTO B ;Habilitar los Leds del Puerto B

;Decrementar el registro N_DATOS ; Registros N_DATOS  N_DATOS - 1 CBLOCK 0X20 DIGITO MAYOR ¿ N_DATOS =0? REGISTRO ENDC

2 NO Subrutina de TABLA

SI PCL  PCL + W

;Sacar el número mayor a el Puerto B 1 PORTB  MAYOR

FIN

RETLW 3FH RETLW 06H RETLW 5BH RETLW 4FH RETLW 06H

;Retorna con W cargado con 3FH ;Retorna con W cargado con 06H ;Retorna con W cargado con 5BH ;Retorna con W cargado con 4FH ;Retorna con W cargado con 66H

71

Subrutina de detectar el número mayor de una tabla DE_MAYOR

¿ REGISTRO >

SI

NO MAYOR  REGISTRO

RETURN

title " Detectar el numero mayor de una Tabla " 72

;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

; 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 MAYOR REGISTRO

; Creamos un registro llamado DIGITO en la dirección 20h ; de memoria de datos. ; Creamos un registro llamado MAYOR en la dirección 21h ; de memoria de datos. ; 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 COMIENZO

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

BSF STATUS,RP0 CLRF TRISB MOVLW B’00000110’ MOVWF ADCON1 CLRF TRISE BCF STATUS,RP0 CLRF PORTB BSF PORTE,2

; Selecciono la pagina 1 de la memoria ; Configuro el Puerto B como salida ; Selecciono PORTA y PORTE como entrada digitales ; Selecciono la pagina 0 de la memoria ; Limpiar Puerto B.

;*************************** Principal **************************************************************************** RESET

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

SEGUIR

MOVF DIGITO,W

;Cargo el contenido de DIGITO en W.

73

CALL TABLA CALL DE_MAYOR

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

INCF DIGITO,F MOVF DIGITO,W XORLW N_DATOS BTFSS STATUS,Z

;Incremento el contenido del registro ;Cargamos el contenido del Registro DIGITO a W ;Hacemos una XOR para afectar el flag Z ;Preguntamos si Z es igual a 1, si cumple salta la siguiente instrucción. ;Va a SEGUIR

GOTO SEGUIR

PARAR

MOVF MAYOR,W MOVWF PORTB GOTO PARAR

;Saca el valor Mayor Puerto B.

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

ADDWF PCL,F RETLW 3FH RETLW 06H RETLW 5BH RETLW 4FH RETLW 06H

;Suma el Contador del Programa con el contenido de W y lo deja en el PC. ;Retorna con W cargado con 3FH ;Retorna con W cargado con 06H ;Retorna con W cargado con 5BH ;Retorna con W cargado con 4FH ;Retorna con W cargado con 66H

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

RETORNO

MOVWF REGISTRO SUBWF 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,C GOTO RETORNO MOVF REGISTRO,W MOVWF MAYOR RETURN END

74

6.- Entrenador Básico 4

75

6.1.- T_S_A.asm

( Entrenador Básico 4 )

Diagrama de Flujo Transmisión Serie Asíncrona

1

Elegimos PIC List p=16f876 , f=inhx32

; Lanzar 5 veces la transmisión serie CONTADOR  NUMERO_TRANSMISIONES

Asignación de nombres de RFS a direcciones.

; Leer los datos del PORTB

#include

DATO_ANTERIOR  PORTB

; Igualdades

;Comienzo de la transmisión de los datos serie

NUMERO_TRANSMISIONES = D’5’

TXREG  PORTB

; Registros CBLOCK 0X20 ¿ Ha terminado la transmisión ?

CONTADOR DATO_ANTERIOR ENDC

NO

¿ TRMT = 1 ?

Sección de código de Reset

SI

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

; Decrementamos CONTADOR CONTADOR  CONTADOR -1

Sección de Configuración COMIENZO

RP0  1 TRISB  11111111 B de dato SPBRG  D’10’

TXSTA  00100000 B RP0  0

ORG 0X05H ¿ CONTADOR = 0?

; Ir al Banco 1 ; Poner Puerto B como entrada ; Cargar la velocidad de transmisión de datos Baud Rate = Fosc/(64(X+1)) Baud Rate = 1MHz/(64(10+1)) = 1420 BIT por segundo ; Configuración de la transmisión serie de datos (Modo Asíncrono y baja velocidad. ; Ir al Banco 0

SPEN  1

;Activamos la Puerta Serie (TX)

NO

SI

NO

Si el PORTB no cambia no se transmite ¿ PORTB = DATO_ANTERIOR ?

SI

1

76

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 ; 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 COMIENZO

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

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

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 MOVWF CONTADOR

SEG1

MOVF PORTB,W MOVWF DATO_ANTERIOR MOVWF TXREG BSF STATUS,RP0 BTFSS TXSTA,TRMT GOTO SEG2 BCF STATUS,RP0

; Leer los datos del PORTB

DECFSZ CONTADOR,F GOTO SEG1

; Decrementamos CONTADOR y si es 0 salta una ; instrucción.

SEG2

SEG3

; Lanzar 5 veces la transmisión serie.

; Comienzo de la transmisión de datos en Serie. ; Preguntamos si se ha transmitido el dato.

MOVF PORTB,W ; Si el PORTB no cambia no se transmite. SUBWF DATO_ANTERIOR,W BTFSC STATUS,Z GOTO SEG3 GOTO SEG0 END

78

6.2.- R_S_A.asm

( Entrenador Básico 4 )

Diagrama de Flujo

1

Recepción Serie Asíncrona ( 8 BIT ) Sección de Configuración COMIENZO Elegimos PIC List p=16f876 , f=inhx32

RP0  1 TRISB  00000000 B de dato BRGH  0 SPBRG  D’10’

Asignación de nombres de RFS a direcciones.

#include SYNC  0 ; Igualdades

ORG 0X05H

; Ir al Banco 1 ; Poner Puerto B como salida ;Trabajar con velocidad baja de recepción. ; Cargar la velocidad de transmisión de datos Baud Rate = Fosc/(64(X+1)) Baud Rate = 1MHz/(64(10+1)) = 1420 BIT por segundo ; Habilitamos la recepción asíncrona.

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

; Registros

; Ir al Banco 0

RCSTA  10010000 B

; Configurar y lanzar la recepción serie (Habilitar puerto serie, 8 BIT y recepción continua).

CBLOCK 0X20 DATO W_TEMP STATUS_TEMP ENDC

; Cargar el registro DATO en el PORTB PORTB  DATO

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

Vector de Interrupción

Rutina de Interrupción INTERRU

ORG 04H GOTO INTERRU

NO ¿ RCIF = 1?

1 RETFIE

SI ; Salvar Registros

; Borrar Flag de la recepción

RETFI E

W_TEMP  W STATUS_TEMP  STATUS

RCIF  0

; Recuperar Registros STATUS  STATUS_TEMP W  W_TEMP

; Cargar el dato recibido en el registro RCREG en el registro DATO DATO  RCREG

79

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 ; 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 STATUS_TEMP

;Registro de salvaguarda de la Rutina de Interr.

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

0X00

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

;**************************** Vector de Interrupción ******************************************************* ORG 0X04 GOTO INTERRU

;Vector de Interrupción.

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

COMIENZO

ORG 0X05

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

BSF STATUS,RP0 BCF STATUS,RP1 CLRF TRISB BCF TXSTA,BRGH

; Banco 1

MOVLW 0X0A MOVWF SPBRG BCF TXSTA,SYNC

; Cargar la Velocidad de Recepción de Datos.

;Trabajar con velocidad baja de recepción.

; Habilitamos la recepción asíncrona.

80

MOVLW B'11000000' MOVWF INTCON MOVLW B'00100000' MOVWF PIE1 BCF STATUS,RP0 MOVLW B'10010000' MOVWF RCSTA

;Habilitar Interrupción Serie ;Habilitar Interrupción Serie

;Configurar y lanzar la Recepción Serie

;*************************** Principal *********************************************************************** PRINCIPAL

COMF DATO,W MOVWF PORTB GOTO PRINCIPAL

;**************************** Rutina de Interrupción ****************************************************** ORG 40 INTERRU

BTFSS PIR1,RCIF RETFIE

; Detectamos si ha interrumpido la Recepción Serie.

SALVAR

MOVWF W_TEMP SWAPF STATUS,W MOVWF STATUS_TEMP

; Salvamos Registros

MOVF RCREG,W MOVWF DATO

;Cargamos el dato del registro RCREG en el registro DATO.

RECUPERAR SWAPF STATUS_TEMP,W MOVWF STATUS SWAPF W_TEMP,F SWAPF W_TEMP,W

;Recuperamos Registros.

BCF PIR1,RCIF

;Borrar flag de recepción

RETFIE

;Retorno de Interrupción.

END

81

6.3.- T1_S_RF.asm

( Entrenador Básico 4 )

Diagrama de Flujo

Transmisión Serie Asíncrona Utilizando la Librería de

1

Elegimos PIC List p=16f876 , f=inhx32

; Leer PORTB W  PORTB

Asignación de nombres de RFS a direcciones.

#include

; Guardar el PORTB en un registro DATO_ANTERIOR  PORTB

; Igualdades LANZAR_DATO_SERIE ; Registros CBLOCK 0X20 DATO_ANTERIOR NO

ENDC

Si el PORTB no cambia no se transmite

SI

¿ PORTB = DATO_ANTERIOR ?

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

Sección de Configuración COMIENZO

RP0  1 TRISB  11111111 B de dato RP0  0

ORG 0X05H

; Ir al Banco 1 ; Poner Puerto B como entrada ; Ir al Banco 0

CONFIGURACION_TRANS_SERIE

1

82

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

COMIENZO

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

BSF STATUS,RP0 MOVLW B'11111111' MOVWF TRISB BCF STATUS,RP0

; Ir al banco 1 ; Poner el Puerto B como entrada de Datos ; Ir al banco 0

CALL CONFIGURACION_TRANS_SERIE ;*************************** Principal ************************************************************************** SEG1

MOVF PORTB,W MOVWF DATO_ANTERIOR

;Leer PORTB

83

CALL LANZAR_DATO_SERIE SEG2

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

;*************************** Librerías ************************************************************************** INCLUDE END

6.4.- RE1_S_RF.asm

( Entrenador Básico 4 )

Diagrama de Flujo

1

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

Sección de Configuración COMIENZO

Elegimos PIC List p=16f876 , f=inhx32

ORG 0X05H

RP0  1

; Ir al Banco 1

TRISB  00000000 B de dato

; Poner Puerto B como salida

RP0  0

; Ir al Banco 0

Asignación de nombres de RFS a direcciones.

CONFIGURACION_RECEP_SERIE

#include

; Igualdades ; Cargar el registro DATO en el PORTB PORTB  DATO_SERIE_VALIDO ; Registros CBLOCK 0X20 W_TEMP STATUS_TEMP ENDC

Rutina de Interrupción INTERRU

Sección de código de Reset ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa

NO ¿ RCIF = 1? RETFIE SI

Vector de Interrupción ORG 04H GOTO INTERRU

1

; Salvar Registros

RETFI E

; Recuperar Registros STATUS  STATUS_TEMP W  W_TEMP

W_TEMP  W STATUS_TEMP  STATUS

El Dato se queda cargado en el registro DATO_SERIE_VALIDO RECEPCION_DATO_SERIE

84

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

; 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 STATUS_TEMP

; Registro de salvaguarda de la Rutina de Interr.

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

0X00

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

;**************************** Vector de Interrupción ******************************************************* ORG 0X04 GOTO INTERRUPCION

;Vector de Interrupción.

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

COMIENZO

ORG 0X05

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

BSF STATUS,RP0 CLRF TRISB BCF STATUS,RP0

;Configuramos el PORTB como salida de datos.

CALL CONFIGURACION_RECEP_SERIE

85

;*************************** Principal ************************************************************************ PRINCIPAL

COMF DATO_SERIE_VALIDO,W MOVWF PORTB GOTO PRINCIPAL

;**************************** Rutina de Interrupción ******************************************************* INTERRUPCION SALVAR

BTFSS PIR1,RCIF RETFIE

MOVWF W_TEMP SWAPF STATUS,W MOVWF STATUS_TEMP

; Detectamos si ha interrumpido la Recepción Serie. ; Salvamos Registros

CALL RECEPCION_DATO_SERIE ; El Dato se queda cargado en DATO_SERIE_VALIDO RECUPERAR SWAPF STATUS_TEMP,W MOVWF STATUS SWAPF W_TEMP,F SWAPF W_TEMP,W RETFIE

;Recuperamos Registros.

;Retorno de Interrupción.

;***************************** Librerias ********************************************************************** INCLUDE END

86

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 B LLAVE_ENTRADA = 01011010 B

; Registros CBLOCK DATO_TRANSMITIDO CONTADOR_TRANSMISIÓN ENDC

;Sección de Configuración CONFIGURACION_TRANS_SERIE

RPO  1

SPBRG  0X0A

; Ir al Banco 1

; 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 RP0  0 SPEN  1

; Configuración de la transmisión serie de datos (Modo Asíncrono y baja velocidad. ; Ir al Banco 0

;Activamos la Puerta Serie (TX)

RETUR N

1

87

1

LANZAR_DATO_SERIE

DATO _ TRANSMITIDO  W

; Cargar el número de transmisión CONTADOR_TRANSMISIÓN  D’10’

; Lanzar TODOCERO TXREG  #TODOCERO

NO

¿ Ha terminado la transmisión ? ¿ TRMT = 1 ?

SI ; Lanzar LLAVE_ENTRADA TXREG  #LLAVE_ENTRADA

NO ¿ CONTADOR_TRANSMISIÓN = 0? SI

NO

¿ Ha terminado la transmisión ? ¿ TRMT = 1 ? ; Decrementar el registro CONTADOR_TRANSMISION SI

CONTADOR_TRANSMISION  CONTADOR_TRANSMISIÓN - 1

; Lanzar DATO_TRANSMITIDO TXREG  #DATO_TRANSMITIDO

NO

¿ Ha terminado la transmisión ?

SI

¿ TRMT = 1 ?

RETUR N

88

; 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'

LLAVE_ENTRADA

;(Dato). Llave para iniciar un código, la tarjeta de ; transmisión de datos necesita el pulso de STOP para ; transmitir un código.

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 MOVLW B'00100000' MOVWF TXSTA

; Cargar la Velocidad de Transmisión de Datos. ; Configuración de la Transmisión Serie.

BCF STATUS,RP0 BCF STATUS,RP1

; Ir al Banco 0.

BSF RCSTA,SPEN

;Activamos la Puerta Serie (TX).

RETURN ;*************************** Lanzar Llaves y Muestra Digital *********************************************** LANZAR_DATO_SERIE

SEG1_TRANSMISION

REPETIR_TRANSMISION

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 BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato. GOTO SEG1_TRANSMISION BCF STATUS,RP0 MOVLW LLAVE_ENTRADA MOVWF TXREG

;Lanzar llave LLAVE_ENTRADA. ;Transmisión de Datos en Serie.

89

BSF STATUS,RP0 BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato. GOTO SEG2_TRANSMISION BCF STATUS,RP0 ;Lanzar DATO_TRANSMITIDO. MOVF DATO_TRANSMITIDO,W MOVWF TXREG ;Transmisión de Datos en Serie. BSF STATUS,RP0 BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato. GOTO SEG3_TRANSMISION

SEG2_TRANSMISION

SEG3_TRANSMISION

BCF STATUS,RP0 DECFSZ CONTADOR_TRANSMISION,F GOTO 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_SERIE1 DATO_SERIE2 DATO_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. ; Cargar la velocidad de Transmisión de datos

SPBRG  D’10’

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 PIE1  00100000 B

; Habilitar la Interrupción serie ; Habilitar la Interrupción serie

RP0  0 RCSTA  10010000 B

; Ir al Banco 0 ; Configurar y lanzar la recepción serie (Habilitar puerto serie, 8 BIT y recepción continua).

RETURN

1

90

1

RECEPCION_DATO_SERIE

NO

W  RCREG

¿ Ha llegado la llave de entrada ? ¿ W = LLAVE_ENTRADA ? SI ; Borramos flag de Recepción

RETURN

RCIF  0

;Borramos flag de Recepción RCIF  0

NO

¿ Ha llegado un nuevo dato ? ¿ RCIF = 1 ?

;Validamos los datos recibidos SI

DATO_SERIE_VALIDO  DATO_SERIE1

; Guardamos el dato primero SI

¿ Son iguales los datos recibidos ? ¿ DATO_SERIE1 = DATO_SERIE2 ?

DATO_SERIE1  RCREG

; Borramos flag de Recepción NO RCIF  0

NO

¿ Ha llegado la llave de entrada ? ¿ RCREG =

; Guardamos el dato segundo

SI ; Borramos flag de Recepción

DATO_SERIE2  RCREG

RCIF  0

NO

¿ Ha llegado un nuevo dato ? ¿ RCIF = 1 ?

SI

91

; 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_SERIE1 DATO_SERIE2 DATO_SERIE_VALIDO ENDC ;**************************** Sección de Configuración ********************************************************* CONFIGURACION_RECEP_SERIE

BSF STATUS,RP0 BCF STATUS,RP1

; Banco 1

BCF TXSTA,BRGH MOVLW 0X0A

;Trabajar con velocidad baja de recepción. ; Cargar la Velocidad de Recepción de Datos.

MOVWF SPBRG BCF TXSTA,SYNC MOVLW B'11000000' MOVWF INTCON

;Habilitar Interrupción Serie

MOVLW B'00100000' MOVWF PIE1

;Habilitar Interrupción Serie

BCF STATUS,RP0 BCF STATUS,RP1

; Banco 0

MOVLW B'10010000' MOVWF RCSTA

;Configurar y lanzar la Recepción Serie

RETURN

92

;****************************** Subrutina de Recepción Serie ********************************************* ;Tiene que estar dentro de la Rutina de INTERRUPCION RECEPCION_DATO_SERIE

MOVF RCREG,W XORLW LLAVE_ENTRADA BTFSS STATUS,Z GOTO SALIR _ SERIE

NO_DATO_SERIE1

BCF PIR1,RCIF BTFSS PIR1,RCIF GOTO NO_DATO_SERIE1 MOVF RCREG,W MOVWF DATO_SERIE1

NO_LLAVE_ENTRADA

BCF PIR1,RCIF BTFSS PIR1,RCIF

;Preguntamos si ha llegado la Llave "LLAVE_ENTRADA". ;Si es correcta la Llave volvemos a preguntar. ;No es correcta la Llave volvemos al PP previa recuperación de registros. ;Borramos Flag de la Recepción. ;Preguntamos si hemos recibido una nuevo DATO. ;Guardamos el Dato Primero ;Borramos Flag de la Recepción. ;Preguntamos si ha llegado la Llave "LLAVE_ENTRADA".

GOTO NO_LLAVE_ENTRADA MOVF RCREG,W ;Preguntamos si ha llegado la Llave "LLAVE_ENTRADA". XORLW LLAVE_ENTRADA BTFSS 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. NO_DATO_SERIE2

BCF PIR1,RCIF BTFSS PIR1,RCIF GOTO NO_DATO_SERIE2 MOVF RCREG,W MOVWF DATO_SERIE2 MOVF DATO_SERIE1,W

;Borramos Flag de la Recepción. ;Preguntamos si hemos recibido una nuevo DATO. ;Guardamos el Dato Segundo ;Si ambos datos son Iguales validamos el dato serie recibido.

SUBWF DATO_SERIE2,F BTFSS STATUS,Z GOTO SALIR _ SERIE VALIDAR_DATO_SERIE

MOVF DATO_SERIE1,W MOVWF DATO_SERIE_VALIDO ; El Dato se queda cargado en el Registro

DATO_SERIE_VALIDO SALIR_SERIE

BCF PIR1,RCIF RETURN END

93

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_TRANSMITIDO CONTADOR_TRANSMISIÓN LLAVE-ENTRADA ENDC

;Sección de Configuración CONFIGURACION_TRANS_SERIE

RPO  1

SPBRG  D’39’

; Ir al Banco 1

; 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 RP0  0 SPEN  1

; Configuración de la transmisión serie de datos (Modo Asíncrono y baja velocidad. ; Ir al Banco 0

;Activamos la Puerta Serie (TX)

RETUR N

1

94

1

LANZAR_DATO_SERIE

DATO _ TRANSMITIDO  W

; Cargar el número de transmisión CONTADOR_TRANSMISIÓN  D’10’

; Lanzar TODOCERO TXREG  #TODOCERO

NO

¿ Ha terminado la transmisión ? ¿ TRMT = 1 ?

SI ; Lanzar LLAVE_ENTRADA TXREG  #LLAVE_ENTRADA

NO ¿ CONTADOR_TRANSMISIÓN = 0? SI

NO

¿ Ha terminado la transmisión ? ¿ TRMT = 1 ? ; Decrementar el registro CONTADOR_TRANSMISION SI

CONTADOR_TRANSMISION  CONTADOR_TRANSMISIÓN - 1

; Lanzar DATO_TRANSMITIDO TXREG  #DATO_TRANSMITIDO

NO

¿ Ha terminado la transmisión ?

SI

¿ TRMT = 1 ?

RETUR N

95

; 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_TRANSMISION LLAVE_ENTRADA ENDC ;**************************** Sección de Configuración ************************************************* CONFIGURACION_TRANS_SERIE

BCF STATUS,RP1 BSF STATUS,RP0 MOVLW D'39' MOVWF SPBRG

MOVLW B'00100000' MOVWF TXSTA

; Ir al Banco 1.

; Cargar la Velocidad de Transmisión de Datos. ; BR = (Fosc/64(X+1)) BR = (4MHz/64(39+1)) = 1562,5 Hz ; Configuración de la Transmisión Serie.

BCF STATUS,RP0 BCF STATUS,RP1

; Ir al Banco 0.

BSF RCSTA,SPEN

;Activamos la Puerta Serie (TX).

RETURN

;*************************** Lanzar Llaves y Muestra Digital ****************************************** LANZAR_DATO_SERIE

SEG1_TRANSMISION

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 BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato. GOTO SEG1_TRANSMISION

96

REPETIR_TRANSMISION

SEG2_TRANSMISION

SEG3_TRANSMISION

BCF STATUS,RP0 ;Lanzar llave LLAVE_ENTRADA. MOVF LLAVE_ENTRADA,W MOVWF TXREG ;Transmisión de Datos en Serie. BSF STATUS,RP0 BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato. GOTO SEG2_TRANSMISION BCF STATUS,RP0 ;Lanzar DATO_TRANSMITIDO. MOVF DATO_TRANSMITIDO,W MOVWF TXREG ;Transmisión de Datos en Serie. BSF STATUS,RP0 BTFSS TXSTA,TRMT ;Preguntamos si se ha transmitido el dato. GOTO SEG3_TRANSMISION BCF STATUS,RP0 DECFSZ CONTADOR_TRANSMISION,F GOTO REPETIR_TRANSMISION RETURN

97

6.8.- R_M_S_RF.INC

( Entrenador Básico 4 )

Diagrama de Flujo

R_S_M_RF.INC

; Igualdades

; Registros CBLOCK DATO_SERIE1 DATO_SERIE2 DATO_SERIE_VALIDO LLAVE_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. ; Cargar la velocidad de Transmisión de datos

SPBRG  D’39’

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 PIE1  00100000 B

; Habilitar la Interrupción serie ; Habilitar la Interrupción serie

RP0  0 RCSTA  10010000 B

; Ir al Banco 0 ; Configurar y lanzar la recepción serie (Habilitar puerto serie, 8 BIT y recepción continua).

RETURN

1

98

1

RECEPCION_DATO_SERIE

RCIF  0

; Borramos flag de Recepción

RETURN

;Borramos flag de Recepción RCIF  0

NO

¿ Ha llegado un nuevo dato ? ¿ RCIF = 1 ?

;Validamos los datos recibidos SI

DATO_SERIE_VALIDO  DATO_SERIE1

; Guardamos el dato primero SI

¿ Son iguales los datos recibidos ? ¿ DATO_SERIE1 = DATO_SERIE2 ?

DATO_SERIE1  RCREG

; Borramos flag de Recepción NO RCIF  0

NO

¿ Ha llegado la llave de entrada ? ¿ RCREG =

; Guardamos el dato segundo

SI ; Borramos flag de Recepción

DATO_SERIE2  RCREG

RCIF  0

NO

¿ Ha llegado un nuevo dato ? ¿ RCIF = 1 ?

SI

99

; 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_SERIE1 DATO_SERIE2 DATO_SERIE_VALIDO LLAVE_ENTRADA ENDC ;**************************** Sección de Configuración ****************************************************** CONFIGURACION_RECEP_SERIE

BSF STATUS,RP0 BCF STATUS,RP1 BCF TXSTA,BRGH BSF TRISC,7 MOVLW D'39'

; Banco 1 ;Trabajar con velocidad baja de recepción. ; Cargar la Velocidad de Recepción de Datos.

MOVWF SPBRG BCF TXSTA,SYNC MOVLW B'11000000' MOVWF INTCON

;Habilitar Interrupción Serie

MOVLW B'00100000' MOVWF PIE1

;Habilitar Interrupción Serie

BCF STATUS,RP0 BCF STATUS,RP1

; Banco 0

MOVLW B'10010000' MOVWF RCSTA

;Configurar y lanzar la Recepción Serie

RETURN

100

;****************************** 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 nuevo DATO.

GOTO NO_DATO_SERIE1 MOVF RCREG,W MOVWF DATO_SERIE1 NO_LLAVE_ENTRADA

BCF PIR1,RCIF BTFSS PIR1,RCIF

;Guardamos el Dato Primero ;Borramos Flag de la Recepción. ;Preguntamos si ha llegado la Llave "LLAVE_ENTRADA".

GOTO NO_LLAVE_ENTRADA MOVF RCREG,W ;Preguntamos si ha llegado la Llave "LLAVE_ENTRADA". XORWF LLAVE_ENTRADA,W BTFSS 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. NO_DATO_SERIE2

BCF PIR1,RCIF BTFSS PIR1,RCIF GOTO NO_DATO_SERIE2 MOVF RCREG,W MOVWF DATO_SERIE2 MOVF DATO_SERIE1,W

;Borramos Flag de la Recepción. ;Preguntamos si hemos recibido una nuevo DATO. ;Guardamos el Dato Segundo ;Si ambos datos son Iguales validamos el dato serie recibido.

SUBWF DATO_SERIE2,F BTFSS STATUS,Z GOTO SALIR_SERIE VALIDAR_DATO_SERIE

SALIR_SERIE

MOVF DATO_SERIE1,W MOVWF DATO_SERIE_VALIDO

; El Dato se queda cargado en el Registro DATO_SERIE_VALIDO

BCF PIR1,RCIF RETURN

101

7.- Entrenador Básico 5

102

7.1.- Tecla0.asm

( Entrenador Básico 5 )

Diagrama de Flujo

1 Manejo del Teclado utilizando la técnica de polling

; Obtiene el valor hexadecimal de la tecla pulsada. Teclado_LeeHex

Elegimos PIC List p=16f877 , f=inhx32

Asignación de nombres de RFS a direcciones. #include

¿Se ha pulsado alguna tecla?

NO

¿Cy = 1?

; Igualdades

SI ; Registros ; Llevar el dato a el Puerto C.

CBLOCK 0x20 ENDC

Sección de código de Reset

COMIENZO

PORTC  W

; Obtiene el valor hexadecimal de la tecla pulsada.

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

Teclado_LeeHex

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

RETUR N

RP0  1 TRISC  00000000 B RP0  0

; Ir al Banco 1 ; Poner el Puerto C como salida de datos. ; Ir al Banco 0

PORTC  00000000 B

; Limpiar el PORTC

; Configura las líneas del teclado. Teclado_Inicializa

1

103

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 ;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 0x00 GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

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

COMIENZO

ORG

5

; Inicio de Programa

BCF BSF CLRF BCF CLRF CALL

STATUS,RP1 STATUS,RP0 TRISC STATUS,RP0 PORTC Teclado_Inicializa

; Ir al Banco 1 ; Poner el PORTC como salida de datos. ; Ir al Banco 0 ; Limpiar el PORTC ; Configura las líneas del teclado.

;************************************* Principal ************************************************************************** ;SEG1 SEG1

CALL Teclado_LeeOrdenTecla CALL Teclado_LeeHex BTFSS STATUS,C GOTO SEG1 MOVWF PORTC CALL Teclado_EsperaDejePulsar GOTO SEG1

; Obtiene el orden de la tecla pulsada. ; Obtiene el valor hexadecimal de la tecla pulsada. ; Preguntamos si se ha pulsado una tecla. ; Llevar el dato a el Puerto C. ; Para que no se repita el mismo carácter

;*********************************************** Librerías **************************************************************** INCLUDE INCLUDE END

104

7.2.- Tecl_01.asm

( Entrenador Básico 5 )

Diagrama de Flujo Manejo del Teclado utilizando la técnica

Rutina de Interrupción INTERRUP

de polling

Elegimos PIC List p=16f877 , f=inhx32

; Obtiene el valor hexadecimal de la tecla pulsada. Teclado_LeeHex

Asignación de nombres de RFS a direcciones. #include ; Llevar el dato a el Puerto C. PORTC  W

; Igualdades

; Registros

; Obtiene el valor hexadecimal de la tecla pulsada.

CBLOCK 0x20 ENDC

Teclado_LeeHex

; Limpia flag de la Interrupción. Sección de código de Reset

RBIF  0

ORG OOH ; Dirección del vector de Reset GOTO COMIENZO ;Comienzo del Programa RETFIE ORG O4H ; Dirección del vector de Interrupción GOTO INTERRUP

Sección de Configuración ORG 0x05 ; Inicio de Programa COMIENZO

RP0  1 TRISC  00000000 B RP0  0

; Ir al Banco 1 ; Poner el Puerto C como salida de datos. ; Ir al Banco 0

PORTC  00000000 B

; Limpiar el PORTC

; Configura las líneas del teclado. Teclado_Inicializa INTCON  10001000 B ; Habilita la interrupción RBI y la general.

; Espera en modo bajo consumo que pulse teclado. SLEEP

105

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

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

;*************************************** Vector de Interrupción ********************************************************* ORG 4 GOTO INTERRUP ;*********************************** Sección de Configuración ********************************************************* ORG 5 COMIENZO

BCF STATUS,RP1 BSF STATUS,RP0 CLRF TRISC BCF STATUS,RP0 CLRF PORTC CALL Teclado_Inicializa MOVLW B'10001000' MOVWF INTCON

; Ir al Banco 1 ; Poner el PORTC como salida de datos. ; Ir al Banco 0 ; Limpiar el Puerto C ; Configura las líneas del teclado. ; Habilita la interrupción RBI y la general.

106

;************************************* Principal ************************************************************************** PRINCIPAL

SLEEP GOTO PRINCIPAL

; Espera en modo bajo consumo que pulse teclado.

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

CALL Teclado_LeeHex MOVWF PORTC CALL Teclado_EsperaDejePulsar BCF INTCON,RBIF RETFIE

; Obtiene el valor hexadecimal de la tecla pulsada. ; Llevar el Acumulador al Puerto C. ; Para que no se repita el mismo carácter ; mientras permanece pulsado. ; Limpia flag de la Interrupción.

;*********************************************** Librerías **************************************************************** INCLUDE ; Subrutinas de control del teclado. INCLUDE END

107

7.3.- Tecl_02.asm

( Entrenador Básico 5 )

Diagrama de Flujo Manejo del Teclado utilizando la técnica

Rutina de Interrupción INTERRUP

de polling

Elegimos PIC List p=16f877 , f=inhx32

; Obtiene el valor hexadecimal de la tecla pulsada. Teclado_LeeHex

Asignación de nombres de RFS a direcciones. #include ; Llevar el dato a el Puerto C. PORTC  W

; Igualdades

; Transformar el código Hexadecimal en código de 7 segmentos.

; Registros CBLOCK 0x20 ENDC

HEX_7SEG

; Llevar el dato a el Puerto D.

Sección de código de Reset

PORTD  W

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

; Obtiene el valor hexadecimal de la tecla pulsada. ORG O4H ; Dirección del vector de Interrupción GOTO INTERRUP

Sección de Configuración ORG 0x05 ; Inicio de Programa COMIENZO

RP0  1 TRISC  00000000 B ADCON1  00000111 B TRISE  00000000 B TRISD  00000000 B RP0  0 PE0  1 PORTC  00000000 B

; Ir al Banco 1 ; Poner el Puerto C como salida de datos. ; Habilitar el PORTE como señales digitales. ; Poner el Puerto E como salida de datos. ; Poner el Puerto D como salida de datos. ; Ir al Banco 0 ; Habilitar el display de las unidades. ; Limpiar el PORTC

Teclado_LeeHex

; Limpia flag de la Interrupción. RBIF  0

RETFIE

; Configura las líneas del teclado. Teclado_Inicializa INTCON  10001000 B ; Habilita la interrupción RBI y la general.

; Espera en modo bajo consumo que pulse teclado. SLEEP

108

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 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

;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

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

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

4

GOTO INTERRUP ;*********************************** Sección de Configuración ********************************************************* ORG COMIENZO

5

BCF STATUS,RP1 BSF STATUS,RP0 CLRF TRISC MOVLW 0X07 MOVWF ADCON1 CLRF TRISE CLRF TRISD

; Ir al Banco 1 ; Poner el PORTC como salida de datos. ; Habilitar el PORTE como señales digitales. ; Poner el PORTE como salida de datos. ; Poner el PORTD como salida de datos.

109

BCF STATUS,RP0 BSF PORTE,0 CLRF PORTC CALL Teclado_Inicializa MOVLW B'10001000' MOVWF INTCON

; Ir al Banco 0 ; Habilitar el display de las unidades. ; Limpiar el Puerto C ; Configura las líneas del teclado. ; Habilita la interrupción RBI y la general.

;************************************* Principal ************************************************************************** PRINCIPAL

SLEEP GOTO PRINCIPAL

; Espera en modo bajo consumo.

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

CALL Teclado_LeeHex MOVWF PORTC CALL HEX_7SEG MOVWF PORTD CALL Teclado_EsperaDejePulsar BCF INTCON,RBIF RETFIE

; Obtiene el valor hexadecimal de la tecla pulsada. ; Llevar el Acumulador al Puerto C. ; Transformar el código Hexadecimal en código de 7 segmentos. ; Llevar el código al PORTD. ; Para que no se repita el mismo carácter ; mientras permanece pulsado. ; Limpia flag.

;*********************************************** Librerías **************************************************************** INCLUDE ; Librería de conversión de Hexadecimal a 7 Segmentos. INCLUDE ; Librería de control del teclado. INCLUDE ; Librería de Retardos. END

7.4.- HEX_7SEG.INC

( Entrenador Básico 5 )

Diagrama de Flujo Librería HEX_7SEG.INC

HEX_7SEG

RETLW 3Fh RETLW

PCL  PCL + W

; El código 7 segmentos para el "0". 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

Librería HEX_7SEG.INC ;************************************ HEX_7SEG.INC ****************************************************************** ; Transforma un código hexadecimal en 7 segmentos. ;*************************************************************************************************************************** HEX_7SEG

ADDWF

PCL,F

RETLW RETLW RETLW RETLW RETLW RETLW RETLW RETLW RETLW RETLW RETLW RETLW RETLW RETLW RETLW RETLW

3Fh 06h 5Bh 4Fh 66h 6Dh 7Dh 07h 7Fh 67h 77h 7Ch 39h 5Eh 79h 71h

7.5.-TECLADO.INC

; El código 7 segmentos para el "0". ; El código 7 segmentos para el "1". ; El código 7 segmentos para el "2". ; El código 7 segmentos para el "3". ; El código 7 segmentos para el "4". ; El código 7 segmentos para el "5". ; El código 7 segmentos para el "6". ; El código 7 segmentos para el "7". ; El código 7 segmentos para el "8". ; El código 7 segmentos para el "9". ; El código 7 segmentos para el "A". ; El código 7 segmentos para el "B". ; El código 7 segmentos para el "C". ; El código 7 segmentos para el "D". ; El código 7 segmentos para el "E". ; El código 7 segmentos para el "F".

( 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

; 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

Tecl_FinLeeHex

call btfss goto call

Teclado_LeeOrdenTecla STATUS,C Tecl_FinLeeHex Tecl_ConvierteOrdenEnHex

bsf STATUS,C return

; Tecl_ConvierteOrdenEnHex

; Lee el Orden de la tecla pulsada. ; ¿Pulsa alguna tecla?, ¿C=1? ; No, por tanto sale. ; Lo convierte en su valor real mediante tabla. ; Vuelve a posicionar el Carry, porque la ; instrucción "addwf PCL,F" lo pone a "0".

addwf PCL,F

; Según el teclado utilizado resulta:

DT DT DT DT

; Primera fila del teclado. ; Segunda fila del teclado ; Tercera fila del teclado. ; Cuarta fila del teclado.

7h,8h,9h,0Fh 4h,5h,6h,0Eh 1h,2h,3h,0Dh 0Ah,0h,0Bh,0Ch

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

; 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 movlw movwf bcf bcf call return

STATUS,RP0 ; Configura las líneas del puerto: b'11110000' ; entradas, salidas PORTB OPTION_REG,NOT_RBPU ; Habilita resistencia de Pull-Up del Puerto B. STATUS,RP0 ; Acceso al banco 0. Teclado_EsperaDejePulsar

; ; ; ; ************************************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 movf sublw btfss goto

Retardo_20ms ; Espera a que se estabilicen los niveles de tensión. PORTB,W ; Lee el Puerto B. Teclado_Comprobacion; Si es lo mismo que escribió es que ya no pulsa STATUS,Z ; tecla alguna. 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 movlw b'11111110' Tecl_ChequeaFila movwf PORTB

; Todavía no ha empezado a chequear el teclado. ; Va a chequear primera fila. ; (Ver esquema de conexión). ; Activa la fila correspondiente.

Tecl_Columna1 btfss goto

PORTB,4 Tecl_GuardaValor

; Chequea la 1ª columna buscando un cero. ; Sí, es cero y por tanto guarda su valor y sale.

113

incf

Tecl_TeclaOrden,F

Tecl_Columna2 btfss goto incf

; Va a chequear la siguiente tecla. ; Repite proceso para las siguientes

PORTB,5 Tecl_GuardaValor Tecl_TeclaOrden,F

; columnas.

Tecl_Columna3 btfss goto incf

PORTB,6 Tecl_GuardaValor Tecl_TeclaOrden,F

Tecl_Columna4 btfss goto incf

PORTB,7 Tecl_GuardaValor 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 subwf btfsc goto bsf rlf goto

Tecl_UltimaTecla Tecl_TeclaOrden,W STATUS,C Tecl_NoPulsada STATUS,C PORTB,W Tecl_ChequeaFila

; (W) = (Tecl_TeclaOrden)-Tecl_UltimaTecla. ; ¿C=0?, ¿(W) negativo?, ¿(Tecl_TeclaOrden)=10? BIN_BCD_Fin ; No, es menor de 10. Se acabó. 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 incf

BCD_Decenas BCD_Centenas,F

; Pone a cero las decenas ; e incrementa las centenas.

145

goto BIN_BCD_Fin

BCD_Resta10

swapf BCD_Decenas,W addwf BCD_Unidades,W return

; Otra pasada: Resta 10 al número a convertir. ; En el nibble alto de (W) también las decenas. ; En el nibble bajo de (W) las unidades. ; Vuelve al programa principal.

; La directiva "END" se debe poner en el programa principal no aquí.

( Entrenador Básico 6 )

8.20.- 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 ===================================================================

;*********************************************** 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 se conectan a las 4 ; líneas superiores del Puerto B del PIC, pines . ; 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_Dato LCD_GuardaDato LCD_GuardaTRISB LCD_Auxiliar1 LCD_Auxiliar2 ENDC ;***************************************************** Igualdades ******************************************************** LCD_CaracteresPorLinea

EQU

D’16’

#DEFINE LCD_PinRS #DEFINE LCD_PinRW #DEFINE LCD_PinEnable

PORTA,0 PORTA,1 PORTA,2

; Número de caracteres por línea de la pantalla.

146

#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_PinEnable bcf LCD_PinRW bcf STATUS,RP0 bcf 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_20ms movlw b'00110000' call LCD_EscribeLCD ; Escribe el dato en el LCD. call Retardo_5ms movlw b'00110000' call LCD_EscribeLCD call Retardo_200micros movlw b'00110000' call LCD_EscribeLCD movlw b'00100000' ; Interface de 4 bits. call LCD_EscribeLCD ; Ahora configura el resto de los parámetros: call call call call

LCD_2Lineas4Bits5x7 LCD_Borra LCD_CursorOFF LCD_CursorIncr

; LCD de 2 líneas y caracteres de 5x7 puntos. ; Pantalla encendida y limpia. Cursor al principio ; de la línea 1. Cursor apagado. ; 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 movwf movf andlw iorwf

b'11110000' LCD_Dato LCD_BusDatos,W b'00001111' LCD_Dato,F

bsf movf movwf movlw andwf bcf

STATUS,RP0 TRISB,W LCD_GuardaTRISB b'00001111' PORTB,F STATUS,RP0

movf

LCD_Dato,W

; Se queda con el nibble alto del dato que es el ; que hay que enviar y lo guarda. ; Lee la información actual de la parte baja ; del Puerto B, que no se debe alterar. ; Enviará la parte alta del dato de entrada ; y en la parte baja lo que había antes. ; Acceso al Banco 1. ; Guarda la configuración que tenía antes TRISB. ; Las 4 líneas inferiores del Puerto B se dejan ; como estaban y las 4 superiores como salida. ; Acceso al Banco 0. ; Recupera el dato a enviar.

147

movwf LCD_BusDatos bsf LCD_PinEnable bcf

; Envía el dato al módulo LCD. ; Permite funcionamiento del LCD mediante un pequeño

LCD_PinEnable

; pulso y termina impidiendo el funcionamiento del LCD. bsf STATUS,RP0 ; Acceso al Banco 1. Restaura el antiguo valor en movf 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' goto LCD_EnviaComando

; Cursor en modo incrementar.

LCD_Linea1

movlw b'10000000' goto LCD_EnviaComando

; Cursor al principio de la Línea 1. ; Dirección 00h de la DDRAM

LCD_Linea2

movlw b'11000000' goto LCD_EnviaComando

; Cursor al principio de la Línea 2. ; Dirección 40h de la DDRAM

LCD_PosicionLinea1

iorlw goto

b'10000000' LCD_EnviaComando

; Cursor a posición de la Línea 1, a partir de la ; dirección 00h de la DDRAM más el valor del ; registro W.

LCD_PosicionLinea2

iorlw goto

b'11000000' LCD_EnviaComando

; Cursor a posición de la Línea 2, a partir de la ; dirección 40h de la DDRAM más el valor del ; registro W.

LCD_OFF

movlw b'00001000' goto LCD_EnviaComando

; Pantalla apagada.

LCD_CursorON

movlw b'00001110' goto LCD_EnviaComando

; Pantalla encendida y cursor encendido.

LCD_CursorOFF

movlw b'00001100' goto LCD_EnviaComando

; Pantalla encendida y cursor apagado.

LCD_Borra

movlw b'00000001' goto LCD_EnviaComando

; Borra toda la pantalla, memoria DDRAM y pone el ; cursor a principio de la línea 1.

LCD_2Lineas4Bits5x7 movlw b'00101000' goto LCD_EnviaComando

; Define la pantalla de 2 líneas, con caracteres ; 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 goto

LCD_PinRS LCD_Envia

; Activa el Modo Comando, poniendo RS=0.

148

LCD_Carácter

bsf call

LCD_PinRS LCD_CodigoCGROM

LCD_Envia

movwf LCD_GuardaDato call LCD_EscribeLCD swapf LCD_GuardaDato,W

; Activa el "Modo Dato", poniendo RS=1. ; Obtiene el código para correcta visualización.

call btfss

LCD_EscribeLCD LCD_PinRS

; Guarda el dato a enviar. ; Primero envía el nibble alto. ; Ahora envía el nibble bajo. Para ello pasa el ; nibble bajo del dato a enviar a parte alta del byte. ; Se envía al visualizador LCD. ; Debe garantizar una correcta escritura

call call

Retardo_2ms Retardo_50micros

; manteniendo 2 ms en modo comando ; 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

LCD_EnheMinuscula

sublw btfss goto movlw movwf goto

; Guarda el valor del carácter y comprueba si es ; un carácter especial.

'ñ' ; ¿Es la "ñ"? STATUS,Z LCD_EnheMayuscula ; No es "ñ". b'11101110' ; Código CGROM de la "ñ". LCD_Dato LCD_FinCGROM

LCD_EnheMayuscula movf sublw btfss goto movlw movwf goto

LCD_Dato,W 'Ñ' STATUS,Z LCD_Grado b'11101110' LCD_Dato LCD_FinCGROM

; Recupera el código ASCII de entrada. ; ¿Es la "Ñ"?

LCD_Grado

movf sublw btfss goto movlw movwf

LCD_Dato,W 'º' STATUS,Z LCD_FinCGROM b'11011111' LCD_Dato

; Recupera el código ASCII de entrada. ; ¿Es el símbolo "º"?

movf

LCD_Dato,W

; En (W) el código buscado.

LCD_FinCGROM

; No es "Ñ". ; Código CGROM de la "ñ". (No hay símbolo para ; la "Ñ" mayúscula en la CGROM).

; No es "º". ; Código CGROM del símbolo "º".

return ; ************************* Subrutina "LCD_DosEspaciosBlancos" y "LCD_LineaBlanco" ************************** ; Visualiza espacios en blanco.

149

LCD_LineaEnBlanco

movlw LCD_CaracteresPorLinea goto LCD_EnviaBlancos

LCD_UnEspacioBlanco

movlw .1 goto LCD_EnviaBlancos

LCD_DosEspaciosBlancos

movlw .2 goto LCD_EnviaBlancos

LCD_TresEspaciosBlancos

movlw .3

LCD_EnviaBlancos

movwf LCD_Auxiliar1

LCD_EnviaOtroBlanco

movlw call decfsz goto

; (LCD_Auxiliar1) se utiliza como contador.

'' ; Esto es un espacio en blanco. LCD_Caracter ; Visualiza tanto espacios en blanco como LCD_Auxiliar1,F ; se haya cargado en (LCD_Auxiliar1). 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 andlw btfss goto movlw call goto

LCD_Auxiliar2 b'11110000' STATUS,Z LCD_VisualizaAlto '' LCD_Caracter LCD_VisualizaBajo

LCD_ByteCompleto

movwf LCD_Auxiliar2

; Guarda el valor de entrada.

LCD_VisualizaAlto

swapf LCD_Auxiliar2,W call LCD_Nibble

; Pone el nibble alto en la parte baja. ; Lo visualiza.

LCD_VisualizaBajo

movf call

; Repite el proceso con el nibble bajo. ; Lo visualiza.

LCD_Auxiliar2,W LCD_Nibble

; Guarda el valor de entrada. ; Analiza si el nibble alto es cero. ; Si es cero lo apaga. ; No es cero y lo visualiza. ; Visualiza un espacio en blanco.

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' movwf LCD_Auxiliar1 sublw 0x09

; Se queda con la parte baja. ; Lo guarda. ; Comprueba si hay que representarlo con

150

btfss goto movf addlw goto LCD_EnviaByteLetra LCD_FinVisualizaDigito goto ; ; ; ; ;

STATUS,C ; letra. LCD_EnviaByteLetra LCD_Auxiliar1,W '0' ; El número se pasa a carácter ASCII LCD_FinVisualizaDigito ; sumándole el ASCII del cero y lo visualiza.

movf LCD_Auxiliar1,W addlw 'A'-0x0A LCD_Caracter

; Sí, por tanto, se le suma el ASCII de la 'A'.

; 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. CBLOCK LCD_ApuntaCaracter LCD_ValorCaracter ENDC

; Indica la posición del carácter a visualizar ; respecto del comienzo de todos los mensajes, ; (posición de la etiqueta "Mensajes"). ; Código ASCII del carácter a ; 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

; ; ;

movlw Mensaje0 call LCD_Mensaje

; Carga la posición del mensaje. ; Visualiza el mensaje.

LCD_Mensaje movwf movlw subwf decf

LCD_ApuntaCaracter Mensajes LCD_ApuntaCaracter,F LCD_ApuntaCaracter,F

; Posición del primer carácter del mensaje. ; Halla la posición relativa del primer carácter ; del mensaje respecto de etiqueta "Mensajes". ; Compensa la posición que ocupa "addwf PCL,F".

LCD_VisualizaOtroCaracter movf call movwf movf btfsc goto

LCD_ApuntaCaracter,W Mensajes LCD_ValorCaracter LCD_ValorCaracter,F STATUS,Z LCD_FinMensaje

; Obtiene el código ASCII del carácter apuntado. ; Guarda el valor de carácter. ; Lo único que hace es posicionar flag Z. En caso ; que sea "0x00", que es código indicador final ; de mensaje, sale fuera.

LCD_Caracter LCD_ApuntaCaracter,F LCD_VisualizaOtroCaracter

; Visualiza el carácter ASCII leído. ; Apunta a la posición del siguiente carácter ; dentro del mensaje.

LCD_NoUltimoCaracter call incf goto 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. ; CBLOCK LCD_CursorPosicion ; Contabiliza la posición del cursor dentro de la ENDC ; pantalla LCD LCD_MensajeMovimiento movwf movlw subwf decf

LCD_ApuntaCaracter Mensajes LCD_ApuntaCaracter,F LCD_ApuntaCaracter,F

; Posición del primer carácter del mensaje. ; Halla la posición relativa del primer carácter ; del mensaje respecto de la etiqueta "Mensajes". ; Compensa la posición que ocupa "addwf PCL,F".

LCD_CursorPosicion LCD_Borra

; El cursor en la posición 0 de la línea. ; Se sitúa en la primera posición de la línea 1 y ; borra la pantalla.

LCD_CaracteresPorLinea LCD_CursorPosicion,W STATUS,Z LCD_NoEsFinalLinea

; ¿Ha llegado a final de línea?

LCD_PrimeraPosicion clrf call LCD_VisualizaCaracter movlw subwf btfss goto

152

LCD_EsFinalLinea ;

call call movlw subwf goto

Retardo_100ms Retardo_200ms LCD_CaracteresPorLinea-1 LCD_ApuntaCaracter,F LCD_PrimeraPosicion

; Lo mantiene visualizado durante este tiempo. ; Apunta a la posición del segundo carácter ; visualizado en pantalla, que será el primero en la ; siguiente visualización de línea, para producir el ; efecto de desplazamiento hacia la izquierda.

LCD_NoEsFinalLinea movf call movwf movf btfsc goto

LCD_ApuntaCaracter,W Mensajes LCD_ValorCaracter LCD_ValorCaracter,F STATUS,Z LCD_FinMovimiento

; Obtiene el ASCII del carácter apuntado. ; Guarda el valor de carácter. ; Lo único que hace es posicionar flag Z. En caso ; que sea "0x00", que es código indicador final ; de mensaje, sale fuera.

LCD_NoUltimoCaracter2 call incf

LCD_Caracter LCD_CursorPosicion,F

incf goto

LCD_ApuntaCaracter,F LCD_VisualizaCaracter

; Visualiza el carácter ASCII leído. ; Contabiliza el incremento de posición del ; cursor en la pantalla. ; Apunta a la siguiente posición por visualizar. ; 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

9.- Entrenador Básico 7

154

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

;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

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

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

clrf PORTA bsf STATUS,RP0 movlw 0x06 movwf ADCON1 bcf STATUS,RP0 call LCD_Inicializa call Teclado_Inicializa

; Reseteamos el PORTA. ; Ir al Banco 1. ; Poner el PORTA como señales digitales. ; Ir al Banco 0. ; Inicializar el LCD. ; Configura las líneas del teclado.

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

155

Principal

Fin

call btfss

Teclado_LeeOrdenTecla STATUS,C

goto

Fin

; Lee el teclado. ; Si se pulsa alguna tecla el Cy=1 y salta una instrucción. ; No, por tanto sale.

movwf GUARDA_TECLA call Teclado_EsperaDejePulsar

; Guarda el orden de la tecla pulsada. ; No sale hasta que levante el dedo.

movf call

GUARDA_TECLA,W BIN_a_BCD

; Lo pasa a BCD.

call

LCD_ByteCompleto

; Visualiza en pantalla.

goto

Principal

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



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

;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

CBLOCK 0x20 GUARDA_TECLA

; Registro que guarda el valor de la tecla pulsada.

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

0

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

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

clrf PORTA bsf STATUS,RP0 movlw 0x06 movwf ADCON1 bcf STATUS,RP0 call LCD_Inicializa call Teclado_Inicializa

; Reseteamos el PORTA. ; Ir al Banco 1. ; Poner el PORTA como señales digitales. ; Ir al Banco 0. ; Inicializar el LCD. ; 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.

Fin

movwf GUARDA_TECLA call Teclado_EsperaDejePulsar

; Guarda el valor de la tecla pulsada. ; No sale hasta que levante el dedo.

movf call

GUARDA_TECLA,W LCD_Nibble

; Visualiza el valor en pantalla.

goto

Principal

;*********************************************** Librerías **************************************************************** INCLUDE INCLUDE INCLUDE 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 del Puerto B. ; ************************************************************************************************************************** ;Programa para PIC 16F877.

157

;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

;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

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

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

4

GOTO Interrup

;Dirección del Vector de Interrupción. ;Ir a rutina de Interrupción

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

clrf PORTA bsf STATUS,RP0 movlw 0x06 movwf ADCON1 bcf STATUS,RP0 call LCD_Inicializa call Teclado_Inicializa movlw b'10001000' movwf INTCON

; Reseteamos el PORTA. ; Ir al Banco 1. ; Poner el PORTA como señales digitales. ; Ir al Banco 0. ; Inicializar el LCD. ; Configura las líneas del teclado. ; Habilita la interrupción RBI y la general.

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

movwf call movf call movf bcf retfie

GUARDA_TECLA Teclado_EsperaDejePulsar GUARDA_TECLA,W LCD_Nibble PORTB,w INTCON,RBIF

; Guarda el valor de la tecla pulsada. ; Para que no se repita el mismo carácter ; Visualiza el valor en pantalla. ; Necesario en proteus para limpiar flag. ; mientras permanece pulsado. Limpia flag.

;*********************************************** Librerías **************************************************************** INCLUDE INCLUDE INCLUDE 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

;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

GOTO COMIENZO

;Comienzo del Programa

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

4

GOTO Interrup

;Dirección del Vector de Interrupción. ;Ir a rutina de Interrupción

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

clrf PORTA bsf STATUS,RP0 movlw 0x06 movwf ADCON1 bcf STATUS,RP0 call LCD_Inicializa call Teclado_Inicializa movlw b'10001000' movwf INTCON

; Reseteamos el PORTA. ; Ir al Banco 1. ; Poner el PORTA como señales digitales. ; Ir al Banco 0. ; Inicializar el LCD. ; Configura las líneas del teclado. ; Habilita la interrupción RBI y la general.

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

sleep goto

; Espera en modo bajo consumo que pulse teclado. 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. ; ; ; ; ; Interrupcall

ORDEN DE TECLA: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

TECLADO UTILIZADO: A B C D E F G H I J K L M N O P

Teclado_LeeOrdenTecla movwf GUARDA_TECLA call Teclado_EsperaDejePulsar movf GUARDA_TECLA,W call Tecl_ConvierteOrdenEnASCII call LCD_Caracter

; Lee el Orden de la tecla pulsada ; Guarda el orden de la tecla pulsada. ; Para que no se repita el mismo carácter.

movf bcf retfie

; Necesario en proteus para limpiar flag. ; Limpia flag.

PORTB,W INTCON,RBIF

; Lo convierte en su valor ASCII mediante ; una tabla, y lo visualiza.

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

160

INCLUDE INCLUDE 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

;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

GOTO COMIENZO

;Dirección del Vector Reset ;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

bsf STATUS,RP0 movlw 0x06 movwf ADCON1 bcf STATUS,RP0 call LCD_Inicializa movlw call call movlw call call

; Ir al Banco 1. ; Poner el PORTA como señales digitales. ; Ir al Banco 0. ; Inicializar el LCD.

Mensaje presentación ; Visualiza el mensaje en movimiento. LCD_MensajeMovimiento LCD_Borra ; Borra la pantalla y se sitúa en la primera línea. MensajePulsa ; Visualiza el mensaje fijo de la primera línea. LCD_Mensaje LCD_Linea2 ; Pasa a la segunda línea.

call Teclado_Inicializa movlw b'10001000' movwf INTCON

; Configura las líneas del teclado. ; Habilita la interrupción RBI y la general.

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

sleep goto

; Espera en modo bajo consumo que pulse teclado. Principal

;************************************ Rutina de Interrupción "Interrup" ************************************************* Interrupcall

Teclado_LeeHex movwf GUARDA_TECLA call Teclado_EsperaDejePulsar

; Obtiene el valor hexadecimal de la tecla pulsada. ; Guarda el valor de la tecla pulsada. ; Para que no se repita el mismo carácter.

movf call

GUARDA_TECLA,W LCD_Nibble

; Visualiza el valor en pantalla.

movf bcf retfie

PORTB,W INTCON,RBIF

; Necesario en proteus para limpiar flag.

;******************************************* 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 INCLUDE INCLUDE INCLUDE



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

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

;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 CaracteresDosLineas

EQU EQU

d'16' d'32'

; Numero de caracteres de una línea. ; Numero de caracteres de dos líneas.

;************************************** Registros *********************************************************************** CBLOCK 0x20 GuardaTecla ContadorCaracteres

; Guarda el valor de la tecla pulsada. ; Guarda el numero de caracteres pulsados.

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

0

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

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

4

GOTO Interrup

;Dirección del Vector de Interrupción. ;Ir a rutina de Interrupción

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

clrf PORTA bsf STATUS,RP0 movlw 0x06 movwf ADCON1

; Reseteamos el PORTA. ; Ir al Banco 1. ; Poner el PORTA como señales digitales.

163

bcf call

STATUS,RP0 LCD_Inicializa

; Ir al Banco 0. ; Inicializar el LCD.

call Teclado_Inicializa movlw b'10001000' movwf INTCON

; Configura las líneas del teclado. ; Habilita la interrupción RBI y la general.

clrf

; En principio no hay caracteres escritos.

ContadorCaracteres

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

sleep goto

; Espera en modo bajo consumo que pulse teclado. Principal

;************************************ Rutina de Interrupción "Interrup" ************************************************* Interrup

call movwf call movf movlw subwf btfsc call movlw subwf btfss goto call clrf

EscribeCaracter

Teclado_LeeHex GuardaTecla Teclado_EsperaDejePulsar GuardaTecla,W CaracteresUnaLinea ContadorCaracteres,W STATUS,Z LCD_Linea2 CaracteresDosLineas ContadorCaracteres,W STATUS,Z EscribeCaracter LCD_Borra ContadorCaracteres

; Obtiene el valor de la tecla pulsada. ; Reserva el valor de la tecla pulsada. ; Para que no se repita el mismo carácter. ; Comprueba si ha llegado al numero máximo de ; caracteres de una línea. ; Se sitúa en la segunda línea. ; Comprueba si ha llegado al numero máximo de ; caracteres de dos líneas. ; No, por tanto, sigue escribiendo. ; Si, borra pantalla e inicializa el contador.

incf movf call

ContadorCaracteres,F GuardaTecla,W LCD_Nibble

; Un nuevo carácter escrito.

movf bcf

PORTB,W INTCON,RBIF

; Necesario en proteus para limpiar flag. ; Limpia flag.

; Visualiza el carácter en pantalla.

retfie ;*********************************************** Librerías **************************************************************** INCLUDE INCLUDE INCLUDE 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

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

;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

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

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

4

GOTO Interrup

;Dirección del Vector de Interrupción. ;Ir a rutina de Interrupción

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

clrf PORTA bsf STATUS,RP0 movlw 0x06 movwf ADCON1 bcf STATUS,RP0 call LCD_Inicializa

; Reseteamos el PORTA. ; Ir al Banco 1. ; Poner el PORTA como señales digitales.

call Teclado_Inicializa movlw b'10001000'

; Configura las líneas del teclado. ; Habilita la interrupción RBI y la general.

; Ir al Banco 0. ; Inicializar el LCD.

165

movwf INTCON ;************************************* Principal ************************************************************************** Principal sleep ; Espera en modo bajo consumo que pulse teclado. goto Principal ;************************************ Rutina de Interrupción "Interrup" ************************************************* Interrup

BorraPantalla limpiar_flag

call movwf call movf sublw btfss goto movf call goto call

Teclado_LeeHex GuardaValor Teclado_EsperaDejePulsar GuardaValor,W 0x09 STATUS,C BorraPantalla GuardaValor,W LCD_Nibble limpiar_flag LCD_Borra

; Obtiene el valor hexadecimal de la tecla pulsada. ; Guarda el valor leído. ; Para que no se repita el mismo carácter.

movf bcf retfie

PORTB,W INTCON,RBIF

; Necesario en proteus para limpiar flag.

; Comprueba si es mayor de 9. ; Si no es un carácter numérico salta a borrar. ; Recupera el valor leído y lo ; visualiza en la pantalla. ; Borra la pantalla.

;*********************************************** Librerías **************************************************************** INCLUDE INCLUDE INCLUDE END

( Entrenador Básico 7 )

9.8.- Tecla_08.asm

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 Dec: 10+06+15=31

(Primera Línea) (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

#include

;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 ContadorTeclasPulsadas GuardaValor Operando1 Operando2 Operando3 Resultado 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 bsf STATUS,RP0 movlw 0x06 movwf ADCON1 bcf STATUS,RP0 call LCD_Inicializa

; Reseteamos el PORTA. ; Ir al Banco 1. ; Poner el PORTA como señales digitales.

call clrf movlw movwf

; Configura las líneas del teclado. ; Resetea este contador. ; Habilita la interrupción RBI y la general.

; Ir al Banco 0. ; Inicializar el LCD.

Teclado_Inicializa ContadorTeclasPulsadas b'10001000' INTCON

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

sleep goto

; Espera en modo bajo consumo que pulse teclado. Principal

;******************************* Macro "VisualizaHex" ****************************************************************** VisualizaHex

MACRO

Operando,Caracter

movf GuardaValor,W movwf Operando call LCD_Nibble

; Recupera el valor y lo visualiza. ; Lo guarda para sumar después. ; Visualiza el valor en la pantalla

167

movlw Caracter call LCD_Caracter ; Visualiza el signo '+' o '-' según corresponda. incf ContadorTeclasPulsadas,F ENDM ;******************************* Macro "VisualizaDec" ****************************************************************** VisualizaDec

MACRO movf call call movlw call

Operando,Caracter

Operando,W BIN_a_BCD LCD_ByteCompleto Caracter LCD_Caracter

; (Operando) -> (W) ; Lo pasa a BCD. ; Visualiza en pantalla. ; A continuación signo '+' o '=' según corresponda.

ENDM ;************************************ Rutina de Interrupción "Interrup" ************************************************ Interrupcall

Teclado_LeeHex movwf GuardaValor call Teclado_EsperaDejePulsar movf ContadorTeclasPulsadas,W addwf PCL,F goto PrimeraTeclaPulsada goto SegundaTeclaPulsada goto TerceraTeclaPulsada

PrimeraTeclaPulsada

call LCD_Borra movlw MensajeHex call LCD_Mensaje VisualizaHex Operando1,'+' goto FinInterrupcion

; Obtiene el valor hexadecimal de la tecla pulsada. ; Guarda el valor leído. ; Para que no se repita el mismo carácter. ; Según el numero de tecla pulsada realiza una ; función distinta.

; Borra la pantalla anterior. ; En pantalla el mensaje "Hex:"

SegundaTeclaPulsada VisualizaHex Operando2,'+' goto FinInterrupcion TerceraTeclaPulsada

FinInterrupcion

VisualizaHex Operando3,'=' movf Operando1,W addwf Operando2,W addwf Operando3,W movwf Resultado call LCD_Byte

; Procede a la suma de los tres valores.

; Visualiza el resultado.

call LCD_Linea2 ; Ahora visualiza la segunda línea. movlw MensajeDec ; En pantalla el mensaje "Dec:" call LCD_Mensaje VisualizaDec Operando1,'+' VisualizaDec Operando2,'+' VisualizaDec Operando3,'=' VisualizaDec Resultado,' ' clrf ContadorTeclasPulsadas ; Resetea este contador. movf PORTB,W ; Necesario en proteus para limpiar flag. bcf INTCON,RBIF retfie

;************************************ Subrutina "Mensajes" ************************************************************* Mensajes

addwf PCL,F

168

MensajeHex MensajeDec

DT DT

"Hex: ", 0x0 "Dec: ", 0x0

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



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

;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

;************************************** Igualdades *********************************************************************** ; La clave puede tener cualquier tamaño y su longitud se calcula: #DEFINE LongitudClave

(FinClaveSecreta-ClaveSecreta)

#DEFINE CerraduraSalida

PORTA,3

;************************************** Registros *********************************************************************** CBLOCK 0x20 ContadorCaracteres GuardaClaveTecleada ENDC ;************************************* Sección Código de Reset ******************************************************* ORG

0

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

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

4

GOTO Interrup

;Dirección del Vector de Interrupción. ;Ir a rutina de Interrupción.

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

clrf PORTA bsf STATUS,RP0 movlw 0x06 movwf ADCON1 bcf CerraduraSalida bcf STATUS,RP0 call LCD_Inicializa call InicializaTodo call Teclado_Inicializa movlw b'10001000' movwf INTCON

; Reseteamos el PORTA. ; Ir al Banco 1. ; Poner el PORTA como señales digitales. ; Define como salida. ; Ir al Banco 0. ; Inicializar el LCD. ; Inicializa el resto de los registros. ; Configura las líneas del teclado. ; Habilita la interrupción RBI y la general.

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

sleep goto

; Espera en modo bajo consumo que pulse teclado. 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 call Teclado_EsperaDejePulsar movlw '*'

; Almacena ese digito en memoria RAM con ; con direccionamiento indirecto apuntado por FSR. ; Visualiza asterisco.

170

call incf incf movlw subwf btfss goto

LCD_Caracter FSR,F ContadorCaracteres,F LongitudClave ContadorCaracteres,W STATUS,C Fin_Interr

; Apunta a la próxima posición de RAM. ; Cuenta el numero de teclas pulsadas. ; Comprueba si ha introducido tantos caracteres ; como longitud tiene la clave secreta. ; Ha terminado de introducir caracteres? ; 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 clrf movlw movwf Comp_Claves movf movwf movf call subwf btfss goto incf incf movlw subwf btfss goto

LCD_Borra ContadorCaracteres ClaveTecleada FSR

; Borra la pantalla. ; Va a leer el primer carácter almacenado en ROM. ; Apunta a la primera posición de RAM donde se ha ; guardado la clave tecleada.

INDF,W GuardaClaveTecleada ContadorCaracteres,W LeeClaveSecreta GuardaClaveTecleada,W STATUS,Z ClaveIncorr FSR,F ContadorCaracteres,F LongitudClave ContadorCaracteres,W STATUS,C Comp_Claves

Lee la clave tecleada y guardada en RAM. ; La guarda para compararla después. ; Apunta al carácter de ROM a leer. ; En (W) el carácter de la clave secreta. ; Se comparan. ; Son iguales?, Z=1? ; No, pues la clave tecleada es incorrecta. ; Apunta a la próxima posición de RAM. ; Apunta a la próxima posición de ROM. ; Comprueba si ha comparado tantos caracteres ; como longitud tiene la clave secreta. ; Ha terminado de comparar caracteres? ; No, pues compara el siguiente carácter.

ClaveCorrecta movlw MensajeClaveCorrecta call LCD_Mensaje call movlw call bsf

LCD_Linea2 MensajeAbraPuerta LCD_Mensaje CerraduraSalida

goto

Retardo

; La clave ha sido correcta. Aparecen los mensajes ; correspondientes y permite la apertura de la ; puerta durante unos segundos.

; Activa la cerradura durante unos

segundos. ClaveIncorr

movlw MensajeClaveIncorrecta call LCD_Mensaje goto Retardo1

Retardo Retardo1

call call call

Fin_Interr

movf bcf

Retardo_2s Retardo_500ms InicializaTodo PORTB,W INTCON,RBIF

171

retfie ;*********************************** Subrutina "InicializaTodo" ******************************************************** InicializaTodo bcf clrf movlw movwf call movlw call call

CerraduraSalida ContadorCaracteres ClaveTecleada FSR LCD_Borra MensajeTeclee LCD_Mensaje LCD_Linea2

; Desactiva la cerradura. ; Inicializa este contador. ; FSR apunta a la primera dirección de la RAM ; donde se va a almacenar la clave tecleada. ; Borra la pantalla. ; Aparece el mensaje para que introduzca la clave. ; Los asteriscos se visualizan en la segunda línea.

return ;************************************ Subrutina "Mensajes" ************************************************************* Mensajes

addwf PCL,F

MensajeTeclee MensajeClaveCorrecta MensajeAbraPuerta MensajeClaveIncorrecta

DT DT DT DT

"Teclee CLAVE:", 0x00 "Clave CORRECTA", 0x00 "Abra la puerta", 0x00 "Clave INCORRECTA", 0x00

;************************************ Subrutina "LeeClaveSecreta" **************************************************** LeeClaveSecreta

addwf PCL,F

ClaveSecreta

DT DT

4h,5h,6h,1h 7h,8h

; Ejemplo de clave secreta.

FinClaveSecreta ;*********************************************** Librerías **************************************************************** INCLUDE INCLUDE INCLUDE INCLUDE



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

10.- Entrenador Básico 7-1

173

( Entrenador Básico 7-1 )

10.1.- Tecla_10.asm

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

;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

ClaveTecleada equ 0x20 CBLOCK 0x30 ContadorCaracteres GuardaClaveTecleada ContadorPAP ENDC ;************************************* Sección Código de Reset ******************************************************* ORG

0

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

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

4

GOTO Interrup

;Dirección del Vector de Interrupción. ;Ir a rutina de Interrupción.

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

clrf PORTA bsf STATUS,RP0 movlw 0x06 movwf ADCON1 clrf TRISD clrf TRISC bcf STATUS,RP0 movlw D'09' movwf PORTC clrf ContadorPAP call LCD_Inicializa call InicializaTodo call Teclado_Inicializa movlw b'10001000' movwf INTCON

; Reseteamos el PORTA. ; Ir al Banco 1. ; Poner el PORTA como señales digitales. ; Poner el PORTD como salida de datos. ; Poner el PORTC como salida de datos. ; Ir al Banco 0. ; Inicializar el motor PAP en una posición inicial. ; Inicializar el LCD. ; Inicializa el resto de los registros. ; Configura las líneas del teclado. ; Habilita la interrupción RBI y la general.

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

sleep goto

; Espera en modo bajo consumo que pulse teclado. 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 call Teclado_EsperaDejePulsar movlw '*' call LCD_Caracter incf FSR,F

; Almacena ese digito en memoria RAM con ; con direccionamiento indirecto apuntado por FSR. ; Visualiza asterisco. ; Apunta a la próxima posición de RAM.

175

incf movlw subwf btfss goto

ContadorCaracteres,F LongitudClave ContadorCaracteres,W STATUS,C Fin_Interr

; Cuenta el numero de teclas pulsadas. ; Comprueba si ha introducido tantos caracteres ; como longitud tiene la clave secreta. ; Ha terminado de introducir caracteres? ; 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 clrf movlw movwf Comp_Claves movf movwf movf call subwf btfss goto incf incf movlw subwf btfss goto

LCD_Borra ContadorCaracteres ClaveTecleada FSR

; Borra la pantalla. ; Va a leer el primer carácter almacenado en ROM. ; Apunta a la primera posición de RAM donde se ha ; guardado la clave tecleada.

INDF,W GuardaClaveTecleada ContadorCaracteres,W LeeClaveSecreta GuardaClaveTecleada,W STATUS,Z ClaveIncorr FSR,F ContadorCaracteres,F LongitudClave ContadorCaracteres,W STATUS,C Comp_Claves

; Lee la clave tecleada y guardada en RAM. ; La guarda para compararla después. ; Apunta al carácter de ROM a leer. ; En (W) el carácter de la clave secreta. ; Se comparan. ; Son iguales?, Z=1? ; No, pues la clave tecleada es incorrecta. ; Apunta a la próxima posición de RAM. ; Apunta a la próxima posición de ROM. ; Comprueba si ha comparado tantos caracteres ; como longitud tiene la clave secreta. ; Ha terminado de comparar caracteres? ; No, pues compara el siguiente carácter.

ClaveCorrecta movlw MensajeClaveCorrecta call LCD_Mensaje call LCD_Linea2 movlw MensajeEsperar call LCD_Mensaje Abrir_puerta

inc_cont_pap

esperar

; La clave ha sido correcta. Aparecen los mensajes ; correspondientes y permite la apertura de la ; puerta durante unos segundos. ; Mostrar mensaje "Espere por favor"

movf ContadorPAP,W call codigos_PAP movwf PORTC call Retardo_100ms movlw D'08' subwf ContadorPAP,W btfss STATUS,Z goto inc_cont_pap goto esperar incf ContadorPAP,F goto Abrir_puerta

; Abrir puerta

bcf bsf call movlw

; Marcar el LED de Abierto.

PORTD,1 PORTD,0 LCD_Linea1 MensajeAbraPuerta

; Mostrar mensaje "Abra la puerta"

176

call call movlw call call call

LCD_Mensaje LCD_Linea2 Tiempo1 LCD_Mensaje Retardo_2s LCD_Borra

; Mostrar mensaje "Tienes 10 Seg." ; Retardo de 10 Seg.

Cerrar_puerta bsf PORTD,1 bcf PORTD,0 decf ContadorPAP,F sigui_codigo movf ContadorPAP,W call codigos_PAP movwf PORTC call Retardo_100ms decfsz ContadorPAP,F goto sigui_codigo movf ContadorPAP,W call codigos_PAP movwf PORTC call Retardo_100ms goto ir_inicializar

; Cerrar la puerta ; Marcar el LED de Cerrado.

ClaveIncorr

movlw MensajeClaveIncorrecta call LCD_Mensaje call Retardo_500ms

; Mostrar mensaje "Clave INCORRECTA"

ir_inicializar

call InicializaTodo movlw B'11110000'

; Inicializar proceso. ; Necesario en proteus para que el teclado pueda

interrumpir. movwf PORTB Fin_Interr movf bcf

PORTB,W INTCON,RBIF

; Necesario en proteus para borrar el flag.

retfie ;*********************************** Subrutina "InicializaTodo" ******************************************************** InicializaTodo bsf bcf clrf movlw movwf call movlw call call

PORTD,1 PORTD,0 ContadorCaracteres ClaveTecleada FSR LCD_Borra MensajeTeclee LCD_Mensaje LCD_Linea2

; Marcar el LED de Cerrado. ; Inicializa este contador. ; FSR apunta a la primera direccion de la RAM ; donde se va a almacenar la clave tecleada. ; Borra la pantalla. ; Aparece el mensaje para que introduzca la clave. ; Los asteriscos se visualizan en la segunda linea.

return ;************************************ Subrutina "Mensajes" ************************************************************* Mensajes

addwf PCL,F

MensajeTeclee DT MensajeClaveCorrecta DT MensajeAbraPuerta DT MensajeEsperar DT MensajeClaveIncorrecta

"Teclee CLAVE:", 0x00 "Clave CORRECTA", 0x00 "Abra la puerta", 0x00 "Espere por favor", 0x00 DT "Clave INCORRECTA", 0x00

177

Tiempo1

DT

"Tienes 10 Seg. ", 0x00

;************************************ Subrutina "LeeClaveSecreta" **************************************************** LeeClaveSecreta ClaveSecreta

addwf PCL,F DT DT

4h,5h,6h,1h 7h,8h

; Ejemplo de clave secreta.

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 INCLUDE INCLUDE INCLUDE END

; Fin del programa.

178

11.- Entrenador Básico 8

179

( Entrenador Básico 8 )

11.1.- I2C1.asm

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

;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

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

;******************************************* Sección de Configuración ************************************************* ORG 0X05 COMIENZO

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

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

CALL Transmitir_dato_I2C

; ; ; ;

CALL Recibir_dato_I2C MOVWF GUARDAR_DATO

; Llamar a la subrutina de recepción de datos. ; Guardar dato recibido en el registro GUARDAR_DATO.

CALL ReStart_I2C

; Llamar a la subrutina de comenzar sin pasar por parada.

TRANSMITIR MOVLW ESCLAVO2 CALL Transmitir_dato_I2C

COMF GUARDAR_DATO,W

(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.

; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) ; (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.

CALL Transmitir_dato_I2C

; Complementar el contenido del registro GUARDAR_DATO ; y guardarlo en W. ; 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

; 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

;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

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

GOTO COMIENZO

;Dirección del Vector Reset ;Comienzo del Programa

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

0X04

GOTO INTERRUP

; Ir a la rutina de Interrupción.

;********************************************** Sección de Configuracion ********************************************** ORG 0X05 COMIENZO

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

CALL Config_transmisión_I2C ; Configuracion Bus_I2C BSF STATUS,RP0

; Ir al Banco 1.

BCF OPTION_REG,INTEDG BCF OPTION_REG,7 BSF INTCON,INTF BSF INTCON,INTE BSF INTCON,GIE

; Interrupción por flanco descendente. ; Activamos las resistencias PULL-UP del PORTB ; Ponemos a 1 la Bandera de Interrupción de las Patilla INT. ; Permitimos la interrupción INT. ; Activamos todas las interrupciones.

BCF STATUS,RP0

; Ir al Banco 0.

;**************************************************** Principal ********************************************************** SLEEP Goto

; Entra el microcontrolador en modo sueño. $-1

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

CALL Bit_start_I2C

; Llamar a la subrutina de Comienzo.

MOVLW ESCLAVO1 CALL Transmitir_dato_I2C

; Seleccionar esclavo de recepción. ( 0100,A2,A1,A0,1 ) ; (0100) identifica al C.I. PCF8476. ; (A2,A1,A0)=(000) por hardware. ; El ultimo BIT a 1 para poner el C.I. PCF8476 como

CALL Recibir_dato_I2C MOVWF GUARDAR_DATO

; Llamar a la subrutina de recepción de datos. ; Guardar dato recibido en el registro GUARDAR_DATO.

receptor.

181

CALL ReStart_I2C TRANSMITIR MOVLW ESCLAVO2 CALL Transmitir_dato_I2C

COMF GUARDAR_DATO,W

; Llamar a la subrutina de comenzar sin pasar por parada. ; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) ; (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.

CALL Transmitir_dato_I2C

; Complementar el contenido del registro GUARDAR_DATO ;y guardarlo en W. ; 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

; 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

;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

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 COMIENZO

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

BSF STATUS,RP0 BSF TRISA,5 MOVLW B'00000000' MOVWF ADCON1 BCF STATUS,RP0 MOVLW B'00100001' MOVWF ADCON0

; Ir al Banco 1. ; Configuracion del Conversor Analogico/Digital.

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 BTFSC ADCON0,GO_DONE GOTO SEG1

; Lanzar el Conversor Analogico/Digital.

SEG1

MOVF ADRESH,W ; Preguntamos si el dato convertido es idéntico al anterior. SUBWF GUARDAR_DATO,W BTFSC STATUS,Z GOTO SEG2 MOVF ADRESH,W ; Guardamos dato nuevo. MOVWF GUARDAR_DATO CALL Bit_start_I2C

; Llamar a la subrutina de Comienzo.

MOVLW ESCLAVO2 CALL Transmitir_dato_I2C

; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) ; (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 CALL Transmitir_dato_I2C

; Guardar el contenido del registro GUARDAR_DATO en W. ; 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 CALL Transmitir_dato_I2C

; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) ; (0100) identifica al C.I. PCF8476. ; (A2,A1,A0)=(000) por hardware.

183

; ; COMF GUARDAR_DATO,W

El ultimo BIT a 0 para poner el C.I. PCF8476 como transmisor.

CALL Transmitir_dato_I2C

; Complementar el contenido del registro GUARDAR_DATO ; y guardarlo en W. ; Llamar a la subrutina de transmisión de datos.

CALL Bit_stop_I2C

; Llamar a la subrutina de parada.

GOTO SEG2 ;************************************************** LIBRERIAS ********************************************************** INCLUDE INCLUDE END

184

12.- Entrenador Básico 8-1

186

( Entrenador Básico 8-1 )

12.1.- I2C4.asm

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

;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 ESCLAVO2 ESCLAVO3 ESCLAVO4

EQU EQU EQU EQU

B'01000001' B'01000011' B'01001000' B'01001100'

; Escribimos la dirección del Esclavo1 receptor. ; Escribimos la dirección del Esclavo2 receptor. ; Escribimos la dirección del Esclavo3 transmisor. ; 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 COMIENZO

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

CALL Config_transmisión_I2C ; Configuracion Bus_I2C BSF STATUS,RP0 BSF TRISB,0 BCF STATUS,RP0

; Ir al Banco 1 ; Poner PB0 como entrada de datos. ; Ir al Banco 0

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

187

SEG1

SEG2

BTFSC PORTB,0 GOTO SEG1

; Se pregunta si esta pulsado PB0.

CALL Bit_start_I2C

; Llamar a la subrutina de Comienzo.

MOVLW ESCLAVO1 CALL Transmitir_dato_I2C

CALL Recibir_dato_I2C MOVWF GUARDAR_DATO

; Seleccionar esclavo de recepción. ( 0100,A2,A1,A0,1 ) ; (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. ; Llamar a la subrutina de recepción de datos. ; Guardar dato recibido en el registro GUARDAR_DATO.

CALL ReStart_I2C

; Llamar a la subrutina de comenzar sin pasar por parada.

MOVLW ESCLAVO3 CALL Transmitir_dato_I2C

; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) ; (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 CALL Transmitir_dato_I2C

; Guardar el contenido del registro GUARDAR_DATO en W. ; 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 CALL Transmitir_dato_I2C

CALL Recibir_dato_I2C MOVWF GUARDAR_DATO

; Seleccionar esclavo de recepción. ( 0100,A2,A1,A0,1 ) ; (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. ; Llamar a la subrutina de recepción de datos. ; Guardar dato recibido en el registro GUARDAR_DATO.

CALL ReStart_I2C

; Llamar a la subrutina de comenzar sin pasar por parada.

MOVLW ESCLAVO4 CALL Transmitir_dato_I2C

; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) ; (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 CALL Transmitir_dato_I2C

; Guardar el contenido del registro GUARDAR_DATO en W. ; Llamar a la subrutina de transmisión de datos.

CALL Bit_stop_I2C

; Llamar a la subrutina de parada.

BTFSS PORTB,0 GOTO SEG2 GOTO SEG1

; Si sigue pulsado PB0 no retornar.

;**************************************************** LIBRERIAS ******************************************************** INCLUDE

; Libreria de control de bus I2C.

END

12.2.- I2C5.asm

( Entrenador Básico 8-1 ) 188

title " Leer datos de circuitos integrados expansores de bus PCF8476 title " 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

;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 ESCLAVO2 ESCLAVO3 ESCLAVO4

EQU EQU EQU EQU

B'01000001' B'01000011' B'01001000' B'01001100'

; Escribimos la dirección del Esclavo1 receptor. ; Escribimos la dirección del Esclavo2 receptor. ; Escribimos la dirección del Esclavo3 transmisor. ; 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 COMIENZO

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

CALL Config_transmision_I2C ; Configuracion Bus_I2C

189

BSF STATUS,RP0 BCF OPTION_REG,INTEDG BCF OPTION_REG,7 BSF INTCON,RBIF BSF INTCON,RBIE BSF INTCON,GIE BCF STATUS,RP0

; Ir al Banco 1 ; Interrupción por flanco descendente. ; Activamos las resistencias PULL-UP del PORTB ; Ponemos a 1 la Bandera de Interrupción de ; las Patilla (RB7..RB4). ; Permitimos las Interrupciones de las Patilla (RB7..RB4). ; Activamos todas las Interrupciones. ; Ir al Banco 0

;**************************************************** Principal ********************************************************** SLEEP Goto

; Poner el microcontrolador rn modo sueño. $-1

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

CALL Bit_start_I2C

; Llamar a la subrutina de Comienzo.

MOVLW ESCLAVO1 CALL Transmitir_dato_I2C

; Seleccionar esclavo de recepción. ( 0100,A2,A1,A0,1 ) ; (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 MOVWF GUARDAR_DATO

; Llamar a la subrutina de recepción de datos. ; Guardar dato recibido en el registro GUARDAR_DATO.

CALL ReStart_I2C

; Llamar a la subrutina de comenzar sin pasar por parada.

MOVLW ESCLAVO3 CALL Transmitir_dato_I2C

; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) ; (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 CALL Transmitir_dato_I2C

; Guardar el contenido del registro GUARDAR_DATO en W. ; 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 CALL Transmitir_dato_I2C

; Seleccionar esclavo de recepción. ( 0100,A2,A1,A0,1 ) ; (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 MOVWF GUARDAR_DATO

; Llamar a la subrutina de recepción de datos. ; Guardar dato recibido en el registro GUARDAR_DATO.

CALL ReStart_I2C

; Llamar a la subrutina de comenzar sin pasar por parada.

MOVLW ESCLAVO4 CALL Transmitir_dato_I2C

; Seleccionar esclavo de transmisión. ( 0100,A2,A1,A0,0 ) ; (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

;

transmisor.

MOVF GUARDAR_DATO,W CALL Transmitir_dato_I2C

; Guardar el contenido del registro GUARDAR_DATO en W. ; Llamar a la subrutina de transmisión de datos.

CALL Bit_stop_I2C

; Llamar a la subrutina de parada.

MOVF PORTB,W BCF INTCON,RBIF

; Necesario en proteus para limpiar flag. ; mientras permanece pulsado. Limpia flag.

RETFIE ;************************************************** LIBRERIAS ********************************************************* INCLUDE

; Librería de control de bus I2C.

END

191

13.- Entrenador Básico 9

192

( Entrenador Básico 9 )

13.1.- I2C6.asm

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

;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 Esclavo1_Lectura_sensor

EQU EQU

b'10011110' 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 COMIENZO

; Inicio de Programa (Una posicion detras del vector de Interrupcion

clrf PORTA bsf STATUS,RP0 movlw 0x06 movwf ADCON1 bcf STATUS,RP0

; Reseteamos el PORTA. ; Ir al Banco 1. ; Poner el PORTA como senales digitales.

call

; Inicializar el LCD.

LCD_Inicializa

193

call Config_transmision_I2C

; Configuracion Bus_I2C

call

; Llamar a la subrutina de Comienzo de I2C.

Bit_start_I2C

movlw Esclavo1_Escritura_sensor call Transmitir_dato_I2C

; Seleccionar PCF8591 Transmisor. ( 1001,A2,A1,A0,0 ) ;(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' call Transmitir_dato_I2C

; Carga la palabra de control utilizando la ; entrada AIN0 en modo simple.

call

; Llamar a la subrutina de comenzar sin pasar por parada.

ReStart_I2C

movlw Esclavo1_Lectura_sensor call Transmitir_dato_I2C

call

Recibir_dato_I2C

call

Bit_stop_I2C

call LCD_Linea1 movlw Mensaje1 call LCD_Mensaje

; Seleccionar PCF8591 Receptor. (1001,A2,A1,A0,1) ;(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. ; 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. ; Llamar a la subrutina de parada. ; Se sitúa al principio de la primera línea. ; Visualiza el Mensaje1

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

call Bit_start_I2C movlw Esclavo1_Lectura_sensor CALL Transmitir_dato_I2C

; Llamar a la subrutina de Comienzo de I2C. ; Seleccionar PCF8591 Receptor. (1001,A2,A1,A0,1) ;(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

call

Bit_stop_I2C

; Llamar a la subrutina de recepción de datos y leemos la entrada analógica. ; 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

; ; ;

- 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 call movlw call movf call movf call movlw call movf call movf call movlw call

Auxiliar LCD_Linea2 MensajeTension LCD_Mensaje Auxiliar,W BIN_a_BCD BCD_Centenas,W LCD_Nibble '.' LCD_Caracter BCD_Decenas,W LCD_Nibble BCD_Unidades,W LCD_Nibble MensajeVoltios LCD_Mensaje

; Lo guarda. ; Se sitúa al principio de la primera línea. ; Visualiza la tensión deseada. ; Recupera el dato a visualizar y lo ; pasa a BCD. ; Visualiza las centenas que corresponden a las ; unidades de voltios. ; Visualiza el punto decimal. ; Visualiza las decenas que corresponden a las ; décimas de voltios. ; Visualiza las unidades que corresponden a las ; centésimas de voltios.

return ;*********************************** Subrutina "Mensajes" ************************************************************** Mensajes

addwf PCL,F

MensajeTension MensajeVoltios Mensaje1

DT " Ve = ", 0x00 DT " V ", 0x00 DT "Señal del Sensor", 0X00

;**************************************************** LIBRERIAS ******************************************************** INCLUDE INCLUDE INCLUDE INCLUDE INCLUDE



END

13.2.- I2C7.asm

( Entrenador Básico 9 ) 195

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

; 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

#DEFINE IncrementarPulsador

b'10010010' 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

ORG 0X05

; Inicio de Programa (Una posicion detras del vector de Interrupcion)

Mensajes

addwf PCL,F

MensajeTension MensajeVoltios

DT "Tension: ", 0x00 DT " V. ", 0x00

;*************************************** Seccion de Configuracion ***************************************************** COMIENZO

clrf bsf movlw movwf

PORTA STATUS,RP0 0x06 ADCON1

; Reseteamos el PORTA. ; Ir al Banco 1. ; Poner el PORTA como senales digitales.

bcf

STATUS,RP0

call call

LCD_Inicializa Config_transmision_I2C

bsf bsf bcf

STATUS,RP0 IncrementarPulsador STATUS,RP0

; Se configura como entrada.

call call call

CargaInicialContador PCF8591_DAC Visualiza

; Realiza la carga inicial del contador. ; Lo envia al DAC para su conversion. ; Y lo visualiza en la pantalla.

movlw b'10001000' movwf INTCON

; Configuracion Bus_I2C

; Activa interrupcion por cambio en las ; lineas del Puerto B (RBIE) y la general (GIE).

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

sleep goto

; Pasa a modo de reposo. 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 btfsc IncrementarPulsador goto FinInterrupcion

IncrementarTensionDeseada

FinInterrupcion

; Espera a que se estabilicen los niveles de tension. ; Si es un rebote sale fuera.

call call

IncrementaContador PCF8591_DAC

call call btfss goto movf

Visualiza Retardo_100ms IncrementarPulsador IncrementarTensionDeseada PORTB,W

; Aumenta el valor del contador. ; Lo envia al DAC para su conversion. ; Visualiza mientras espera que deje ; de pulsar durante este tiempo. ; Mientras permanezca pulsado ; incrementara el digito.

197

bcf retfie

INTCON,RBIF

;**************************************** Subrutina "PCF8591_DAC" ************************************************** ; Escribe en el PCF8591 con el dato del registro W para su conversion a tension analagica. CBLOCK PCF8591_Dato ENDC

; Guarda el dato que tiene que enviar.

PCF8591_DAC movwf PCF8591_Dato

; Guarda el dato a enviar.

call Bit_start_I2C movlw PCF8591_DireccionEscritura CALL Transmitir_dato_I2C

; Llamar a la subrutina de Comienzo de I2C. ; Apunta al dispositivo.

movlw b'01000000' call Transmitir_dato_I2C

; Carga la palabra de control activando la ; salida analogica.

movf call

PCF8591_Dato,W Transmitir_dato_I2C

movf call call

PCF8591_Dato,W Transmitir_dato_I2C Bit_stop_I2C

; Escribe el dato dos veces para que la ; conversion sea correcta tal como se indica en el manual. ; los cronogramas del fabricante.

movf

PCF8591_Dato,W

; En (W) se recupera de nuevo el dato de entrada.

return ;************************** Subrutinas "IncrementaContador" y "CargaInicialContador" **************************** CBLOCK Contador ENDC ValorMinimo ValorMaximo SaltoIncremento

EQU EQU

d'50' d'250' EQU d'25'

; El valor minimo de tension sera 0,5 V. ; El valor maximo de tension sera 2,5 V. ; El incremento se producira en saltos de 0,25 V.

IncrementaContador

movlw addwf btfsc goto movf sublw btfsc goto movlw movwf movf return

SaltoIncremento Contador,F STATUS,C CargaInicialContador Contador,W ValorMaximo STATUS,C FinIncrementar ValorMinimo Contador Contador,W

; Incrementa el valor deseado.

CargaInicialContador FinIncrementar

; Si se desborda realiza la carga inicial. ; Ha llegado a su valor maximo ? ; (W) =Mínimo. ; No. La siguiente pasada entra en "FrecuenciaDescendente".

250

;********************************* 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 swapf movwf bcf movf sublw

Guarda_W STATUS,W Guarda_STATUS STATUS,RP0 ApuntadorFrecuencia,W d'0'

; Guarda el valor de W y STATUS.

; Carga en el Timer 0 con signo negativo.

movwf TMR0 btfsc Salida goto EstabaAlto EstabaBajo

bsf goto

Salida Fin_Timer0_interrupción

EstabaAlto

bcf

Salida

Fin_Timer0_interrupción

swapf movwf swapf swapf bcf

Guarda_STATUS,W STATUS Guarda_W,F Guarda_W,W INTCON,T0IF

; Restaura el valor de W y STATUS.

retfie ;******************************************** Librerías *************************************************************** INCLUDE 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

;************************************** Elegimos PIC ******************************************************************** LIST p=16F84A ;***************** Asignación de nombres de Registros de Funciones especiales a direcciones ***************** INCLUDE

; 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 MinimoPeriodo EQU #DEFINE #DEFINE #DEFINE #DEFINE

d'200' d'15'

; Corresponden a una frecuencia entre 300 Hz y ; 4 kHz tal como se demuestra posteriormente.

Salida PORTB,2 EntradaActivar PORTB,7 EntradaApagarPORTB,6 AutorizaSirena Flags,0

;**************************** Registros ********************************************************************************* CBLOCK 0x0C Flags ApuntadorFrecuencia SentidoFrecuencia

; (SentidoFrecuencia)=0 (frecuencia ascendente). ; (SentidoFrecuencia)=1 (frecuencia descendente).

Guarda_W Guarda_STATUS Guarda_R_ContA Guarda_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 bsf bcf bsf bsf movlw movwf bcf

LCD_Inicializa STATUS,RP0 Salida EntradaApagar EntradaActivar b'00000010' OPTION_REG STATUS,RP0

; Prescaler de 8 asignado al TMR0.

252

call clrf movlw movwf sublw movwf movlw movwf

ApagarSirena SentidoFrecuencia MaximoPeriodo ApuntadorFrecuencia d'0' TMR0 b'10101000' INTCON

; En principio apaga la sirena. ; Inicializa el sentido de la variacion de ; frecuencia ascendente en la sirena. ; Inicializa a la frecuencia minima. ; Carga en el Timer 0 con signo negativo. ; Activa interrupcion del TMR0 (TOIE), por cambio ; 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 SirenaAutorizada FrecuenciaDescendente

btfss goto

AutorizaSirena SirenaNoAutorizada

btfss goto call

SentidoFrecuencia,0 FrecuenciaAscendente Retardo_20ms

incf

ApuntadorFrecuencia,F

movlw MaximoPeriodo subwf ApuntadorFrecuencia,W

FrecuenciaAscendente

btfsc

STATUS,C

clrf

SentidoFrecuencia

goto

Fin

call

Retardo_10ms

decf

ApuntadorFrecuencia,F

movlw MinimoPeriodo subwf ApuntadorFrecuencia,W

; Si no se autoriza sirena, va a modo de bajo consumo ; Mantiene la frecuencia durante este tiempo. ; Aumenta el periodo, disminuye la frecuencia. ; Ha llegado a su maximo valor de periodo? ; (W)=(ApuntadorFrecuencia)MaximoPeriodo. ; C=0?,(W) negativo?, (ApuntadorFrecuencia)=Mínimo. ; No. La siguiente pasada entra en "FrecuenciaDescendente".

btfss

STATUS,C

incf

SentidoFrecuencia,F

goto

Fin

SirenaNoAutorizada

bcf sleep

Salida

; Pone la salida en bajo. ; 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_W swapf STATUS,W

253

movwf Guarda_STATUS bcf movf movwf movf movwf

STATUS,RP0 R_ContA,W Guarda_R_ContA R_ContB,W Guarda_R_ContB

; Garantiza que se trabaja en el Banco 0. ; Guarda los registros utilizados en esta ; subrutina y también en la principal.

btfsc call btfsc

INTCON,RBIF RBI_Interrupcion INTCON,T0IF

; Interrupcion por cambio en el Puerto B?

call

Timer0_interrupción

swapf movwf swapf swapf movf movwf movf movwf

Guarda_STATUS,W STATUS Guarda_W,F Guarda_W,W Guarda_R_ContA,W R_ContA Guarda_R_ContB,W R_ContB

bcf bcf

INTCON,RBIF INTCON,T0IF

; Interrupcion por desbordamiento del TMR0? ; No. Entonces ha sido el Timer 0. ; Restaura registros W y STATUS.

retfie ;**************************************** Subrutina "RBI_Interrupcion" ************************************************ RBI_Interrupcion

call btfsc goto

Retardo_20ms EntradaApagar CompruebaActivar

ApagarSirena

CALL bcf call movlw goto

Retardo_100ms AutorizaSirena LCD_Borra MensajeApagado Visualiza

CompruebaActivar

btfsc goto

EntradaActivar EsperaDejePulsar

ActivarSirena

CALL bsf call movlw

Retardo_100ms AutorizaSirena LCD_Borra MensajeActivada

Visualiza

call

LCD_Mensaje

EsperaDejePulsar

btfss goto btfss goto

EntradaApagar EsperaDejePulsar EntradaActivar EsperaDejePulsar

; Espera a que se estabilicen niveles. ; Esta presionado el pulsador de apagado? ; No, compueba el pulsador de activacion. ; La sirena se apaga en el programa principal. ; Visualiza el mensaje. ; Esta presionado el pulsador de activacion?. ; No hay activado pulsador alguno y sale. ; La sirena se activa en el programa principal. ; Visualiza el mensaje.

; Espera que desaparezcan las señales de entrada.

return ;********************************** Subrutina "Timer0_interrupción" *************************************************** ; Con un prescaler de 8 el periodo variara según el valor de ApuntadorFrecuencia entre:

254

; ; ; ;

- 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 sublw movwf btfsc goto

ApuntadorFrecuencia,W d'0' ; Carga en el Timer 0 con signo negativo. TMR0 Salida ; Testea el ultimo estado de la salida. EstabaAlto

EstabaBajo

bsf goto

Salida ; Estaba bajo y lo pasa a alto. Fin_Timer0_interrupción

EstabaAlto Fin_Timer0_interrupción

bcf Salida return

; Estaba alto y lo pasa a bajo.

;***************************************** Subrutina "Mensajes" ******************************************************** Mensajes

addwf PCL,F

MensajeApagado MensajeActivada

DT " Sirena APAGADA", 0x00 DT " Ahora ACTIVADA", 0x00

;******************************************** Librerías *************************************************************** INCLUDE INCLUDE INCLUDE 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 ----------------Inicial Primera Segunda Tercera Cuarta Quinta Sexta Septima Octava Novena Décima

DC (%) ---------0% 10 % 20 % 30 % 40 % 50 % 60 % 70 % 80 % 90 % 100 %

SEMIPERIODO ALTO ---------------------------------0 us = 0 x 100 us 1000 us = 10 x 100 us 2000 us = 20 x 100 us 3000 us = 30 x 100 us 4000 us = 40 x 100 us 5000 us = 50 x 100 us 6000 us = 60 x 100 us 7000 us = 70 x 100 us 8000 us = 80 x 100 us 9000 us = 90 x 100 us 10000 us = 100 x 100 us

SEMIPERIODO BAJO ---------------------------------10000 us = 100 x 100 us 9000 us = 90 x 100 us 8000 us = 80 x 100 us 7000 us = 70 x 100 us 6000 us = 60 x 100 us 5000 us = 50 x 100 us 4000 us = 40 x 100 us 3000 us = 30 x 100 us 2000 us = 20 x 100 us 1000 us = 10 x 100 us 0 us = 0 x 100 us

255

; 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

; 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 IncrementoDC

EQU EQU

d'89' d'10'

#DEFINE Salida #DEFINE Pulsador

PORTB,2 PORTB,7

; El semiperiodo patron va a ser de 100 us. ; Incremento de cada paso del ciclo de trabajo.

;**************************** Registros ********************************************************************************* CBLOCK 0x0C CicloTrabajo Timer0_ContadorA

; Ciclo de trabajo deseado. ; 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 Mensaje_TantoPorCiento

DT "Duty Cycle: ", 0x00 DT "% ", 0x00

256

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

bsf bcf bsf movlw movwf bcf call call movlw movwf

STATUS,RP0 Salida Pulsador b'00001000' OPTION_REG STATUS,RP0 LCD_Inicializa DC_CeroPorCiento b'10001000' INTCON

; TMR0 sin prescaler.

; Inicializa con un DC=0%, por tanto salida ; en bajo permanentemente. ; Habilita solo interrupcion RBI.

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

goto

Principal

;********************************* Rutina de interrupción "ServicioInterrupcion" ************************************** ServicioInterrupcion

btfsc call btfsc call bcf bcf

INTCON,RBIF ; Interrupcion por cambio en el Puerto B? Pulsador_Interrupcion INTCON,T0IF ; Interrupcion por desbordamiento del TMR0? Timer0_interrupción INTCON,RBIF ; Limpia flags de reconocimiento. 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 btfsc goto bsf

Retardo_20ms Pulsador Fin_PulsadorInterrupcion INTCON,T0IE

movlw addwf movwf sublw btfsc goto btfsc goto

IncrementoDC CicloTrabajo,W CicloTrabajo d'100' STATUS,Z DC_100PorCiento STATUS,C Visualiza

DC_CeroPorCiento

bcf clrf goto

Salida CicloTrabajo InhabilitaInterrupcionTMR0

; Pone la salida siempre en bajo. ; Inicializa el ciclo de trabajo a 0%.

DC_100PorCiento

Salida d'100' CicloTrabajo INTCON,T0IE

; Pone la salida siempre en alto. ; Esta al maximo, DC=100%.

InhabilitaInterrupcionTMR0

bsf movlw movwf bcf

Visualiza

call

VisualizaCicloTrabajo

; Visualiza el ciclo de trabajo seleccionado.

; Si no es la linea del pulsador sale. ; En principio habilita interrupciones TMR0. ; Se le va a sumar al ciclo de trabajo ; (W)=(CicloTrabajo)+IncrementoDC ; Guarda resultado. ; Si DC ha llegado al 100% la salida ; pasa a alto permanentemente. ; Si pasa de 100, lo inicializa.

257

EsperaDejePulsar

btfss goto

Pulsador EsperaDejePulsar

Fin_PulsadorInterrupcion

movf movwf movlw movwf return

CicloTrabajo,W Timer0_ContadorA TMR0_Carga TMR0

; Carga todos los contadores.

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

EstabaBajo

EstabaAlto

Fin_Timer0_interrupción

movlw movwf decfsz goto btfsc

TMR0_Carga TMR0 Timer0_ContadorA,F Fin_Timer0_interrupción Salida

goto

EstabaAlto

nop bsf movf movwf nop goto bcf movf sublw movwf return

Salida CicloTrabajo,W Timer0_ContadorA

; Decrementa el contador. ;Testea el anterior estado de la salida.

; Estaba bajo y lo pasa a alto. ; Repone el contador nuevamente ; con el tiempo en alto.

Fin_Timer0_interrupción Salida CicloTrabajo,W .100 Timer0_ContadorA

; Estaba alto y lo pasa a bajo. ; Repone el contador nuevamente ; con el tiempo en bajo.

;********************************* 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_100ms call LCD_Linea1 ; Visualiza el ciclo de trabajo seleccionado. movlw Mensaje_DC call LCD_Mensaje movf CicloTrabajo,W call 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 VisualizaCentenas movf 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 movf call call

LCD_Nibble CicloTrabajo,W BIN_a_BCD LCD_ByteCompleto

; Visualiza las centenas. ; Vuelve a recuperar este valor. ; Lo pasa a BCD. ; Visualiza las decenas (aunque sea cero) y ; unidades.

258

VisualizaTantoPorCiento

movlw Mensaje_TantoPorCiento call LCD_Mensaje

; Y ahora el símbolo "%".

return ;******************************************** Librerías *************************************************************** INCLUDE INCLUDE INCLUDE INCLUDE



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

; 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

Minuto Segundo MedioSegundo Registro50ms

; Guarda los minutos. ; Guarda los segundos. ; Se incrementa cada medio segundo. ; 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 bsf movlw movwf bcf clrf clrf clrf clrf clrf movlw movwf movlw movwf

LCD_Inicializa STATUS,RP0 b'00000111' OPTION_REG STATUS,RP0 Hora Minuto Segundo MedioSegundo Registro50ms TMR0_Carga50ms TMR0 b'10100000' INTCON

; Acceso al Banco 1. ; Prescaler de 256 para el TMR0 y habilita ; resistencias de Pull-Up del Puerto B. ; Acceso al Banco 0. ; Inicializa todos los datos del reloj.

; Carga el TMR0. ; Activa interrupcion del TMR0 (TOIE) ; 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 call

INTCON,T0IF Reloj

FinInterrupcion bcf

INTCON,T0IF retfie

; Si es una interrupcion procedente del ; desbordamiento del Timer 0, actualiza el reloj. ; correspondiente.

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

; 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 call nop movlw movwf call btfss goto

Retardo_50micros Retardo_20micros

; Retardo de 71 us para ; ajustar a 50 ms exactos.

IncrementaReloj

call btfss goto call btfss goto call btfss goto call

IncrementaMedioSegundo STATUS,C ; Ha pasado 1 segundo? ActualizaReloj ; No. Pues sale visualizando el reloj. IncrementaSegundos ; Si. Incrementa el segundero. STATUS,C ; Han pasado 60 segundos? ActualizaReloj ; No. Pues sale visualizando el reloj. IncrementaMinutos ; Si. Incrementa el minutero. STATUS,C ; Han pasado 60 minutos? ActualizaReloj ; No. Pues sale visualizando el reloj. IncrementaHoras ; Si. Incrementa las horas.

ActualizaReloj FinReloj

call VisualizaReloj return

TMR0_Carga50ms ; Carga el timer 0. TMR0 IncrementaRegistro50ms STATUS,C ; Ha contado 10 veces 50 ms = 1/2 segundo? FinReloj ; No. Pues sale sin visualizar el reloj.

; Visualiza el reloj.

;******************************************* Subrutina "VisualizaReloj" ************************************************* ; Visualiza el reloj en la segunda línea en formato: " 8:47:39" (Segunda línea). VisualizaReloj

movlw call movf call call movlw call movf call call movlw call movf call call return

d'4' LCD_PosicionLinea2 Hora,W BIN_a_BCD LCD_Byte ':' LCD_Caracter Minuto,W BIN_a_BCD LCD_ByteCompleto ':' LCD_Caracter Segundo,W BIN_a_BCD LCD_ByteCompleto

; Se coloca para centrar la visualizacion ; en la segunda linea. ; Va a visualizar las horas. ; Lo pasa a BCD. ; Visualiza rechazando el cero de las decenas. ; Envia ":" para separar datos. ; Visualiza minutos. ; Lo pasa a BCD. ; Envia ":" para separar datos. ; Visualiza segundos. ; Lo pasa a BCD.

;***************************************** 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 movlw subwf btfsc clrf

Registro50ms,F d'10' Registro50ms,W STATUS,C Registro50ms

; (W)=(Registro50ms)-10 ; C=0?, (W) negativo?, (Registro50ms)
View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF