Vous êtes sur la page 1sur 219

LA PROGRAMACION DE LOS PIC

POR BIGONOFF

PRIMERA PARTE Revisin 34

COMENZAR CON LOS PIC CON EL PIC16F84


1

1. INTRODUCCION.................................................................................................................................. 2. LOS SISTEMAS DE NUMERACION................................................................................................. 2.1 EL SISTEMA DECIMAL............................................................................................................................... 2.2 EL SISTEMA BINARIO................................................................................................................................ 2.3EL SISTEMA HEXADECIMAL....................................................................................................................... 2.4 LAS OPERACIONES................................................................................................................................... 2.5 LOS NUMEROS CON SIGNO........................................................................................................................ 2.6 LAS OPERACIONES BOOLEANAS................................................................................................................ 2.6.1 El complemento..................................................................................................................................... 2.6.2 La funcin Y o AND ................................................................................................................... 2.6.3 La funcin O u OR .................................................................................................................... 2.6.4 La funcin O EXCLUSIVA o Exclusif OR o XOR .............................................................. 2.7 UNAS PALABRAS SOBRE LAS UNIDADES.................................................................................................... 3. COMPOSICION Y FUNCIONAMIENTO DE LOS PIC................................................................ 3.1 QUE ES UN PIC ?............................................................................................................................ 3.2 LAS DIFERENTES FAMILIAS DE PIC............................................................................................ 3.3 IDENTIFICACION DE UN PIC......................................................................................................... 3.4 ORGANIZACIN DEL 16F84............................................................................................................... 3.4.1 La memoria de programa..................................................................................................................... 3.4.2 La memoria EEPROM.......................................................................................................................... 3.4.3 La memoria RAM.................................................................................................................................. 4. ORGANIZACION DE LAS INSTRUCCIONES................................................................................. 4.1 GENERALIDADES...................................................................................................................................... 4.2 LOS TIPOS DE INSTRUCCIONES.................................................................................................................. 4.2.1 Las instrucciones orientadas a octeto ............................................................................................. 4.2.2 Las instrucciones orientadas a bits ................................................................................................. 4.2.3 Les instrucciones generales.................................................................................................................. 4.2.4 Los saltos y llamada a subrutinas........................................................................................................ 4.3 PANORAMICA DE LAS INSTRUCCIONES...................................................................................................... 4.4 LOS INDICADORES DE ESTADO................................................................................................................... 4.4.1 El indicador de estado Z .................................................................................................................. 4.4.2 El indicador de estado C ................................................................................................................. 5. LOS COMIENZOS CON MPLAB....................................................................................................... 5.1 PREPARACION PARA UTILIZACION.............................................................................................................. 5.2 CREACION DE NUESTRO PRIMER PROYECTO............................................................................................... 6. ORGANIZACION DE UN FICHERO .ASM ................................................................................... 6.1 LOS COMENTARIOS..................................................................................................................................... 6.2 LAS DIRECTIVAS......................................................................................................................................... 6.3 LOS FICHEROS INCLUDE ....................................................................................................................... 6.4 LA DIRECTIVA _CONFIG.......................................................................................................................... 6.5 LAS ASIGNACIONES.................................................................................................................................... 6.6 LAS DEFINICIONES...................................................................................................................................... 6.7 LAS MACROS............................................................................................................................................... 6.8 LA ZONE DE VARIABLES............................................................................................................................. 6.9 LAS ETIQUETAS........................................................................................................................................... 6.10 LA DIRECTIVA ORG ........................................................................................................................... 6.11 LA DIRECTIVA END Y EL FIN DE UN PROGRAMA................................................................................ 7. REALIZACION DE UN PROGRAMA.................................................................................................... 7.1 CREACION DE NUESTRO PRIMER PROGRAMA................................................................................................ 7.2 EL ENSAMBLAJE DE UN PROGRAMA................................................................................................. 8. LA SIMULACION DE UN PROGRAMA................................................................................................

7 8 8 8 10 11 11 12 12 13 13 14 14 17 17 18 18 19 20 20 20 21 21 21 21 21 22 22 22 24 24 24 26 26 26 33 33 33 33 34 35 35 35 36 36 37 37 39 39 40 43

8.1 LANZAMIENTO Y PARAMETRAJE DEL SIMULADOR......................................................................................... 8.2 EXPLICACION DE LOS REGISTROS FUNDAMENTALES...................................................................................... 8.2.1 Los registros PCL y PCLATH ........................................................................................................ 8.2.2 El registro W ........................................................................................................................................ 8.2.3 El registro STATUS ............................................................................................................................. 8.3 LANZAMIENTO DE LA SIMULACION................................................................................................................ 9. EL JUEGO DE INSTRUCCIONES............................................................................................................. 9.1 LA INSTRUCCION GOTO (IR A)................................................................................................................. 9.2 LA INSTRUCCION INCF (INCREMENT FILE)............................................................................................. 9.3 LA INSTRUCCION DECF (DECREMENT FILE).......................................................................................... 9.4 LA INSTRUCCION MOVLW (MOVE LITERAL TO W)............................................................................... 9.5 LA INSTRUCCION MOVF (MOVE FILE)................................................................................................... 9.6 LA INSTRUCCION MOVWF (MOVE W TO FILE)...................................................................................... 9.7 LA INSTRUCCION ADDLW (ADD LITERAL AND W)................................................................................ 9.8 LA INSTRUCCION ADDWF (ADDW AND F)............................................................................................ 9.9 LA INSTRUCCION SUBLW (SUBTRACT W FROM LITERAL)..................................................................... 9.10 LA INSTRUCCION SUBWF (SUBTRACT W FROM F).............................................................................. 9.11 LA INSTRUCCION ANDLW (AND LITERAL WITH W)............................................................................ 9.12 LA INSTRUCCION ANDWF (ANDW WITH F)........................................................................................ 9.13 LA INSTRUCCION IORLW (INCLUSIVE OR LITERAL WITH W)............................................................... 9.14 LA INSTRUCCION IORWF (INCLUSIVE ORW WITH FILE)...................................................................... 9.15 LA INSTRUCCION XORLW (EXCLUSIVE OR LITERAL WITH W)............................................................ 9.16 LA INSTRUCCION XORWF (EXCLUSIVE ORW WITH F)........................................................................ 9.17 LA INSTRUCCION BSF (BIT SET F)......................................................................................................... 9.18 LA INSTRUCCION BCF (BIT CLEAR F).................................................................................................... 9.19 LA INSTRUCCION RLF ( ROTATE LEFT THROUGH CARRY)..................................................................... 9.20 LA INSTRUCCION RRF ( ROTATE RIGHT THROUGH CARRY)................................................................... 9.21 LA INSTRUCCION BTFSC (BIT TEST F, SKIP IF CLEAR).......................................................................... 9.22 LA INSTRUCCION BTFSS (BIT TEST F, SKIP IF SET)............................................................................... 9.23 LA INSTRUCCION DECFSZ (DECREMENT F, SKIP IF Z)......................................................................... 9.24 LA INSTRUCCION INCFSZ (INCREMENT F, SKIP IF ZERO)..................................................................... 9.25 LA INSTRUCCION SWAPF (SWAP NIBBLES IN F).................................................................................. 9.26 LA INSTRUCCION CALL (CALL SUBROUTINE)...................................................................................... 9.27 LA INSTRUCCION RETURN (RETURN FROM SUBROUTINE)................................................................. 9.28 LA INSTRUCCION RETLW (RETURN WITH LITERAL IN W)................................................................... 9.29 LA INSTRUCCION RETFIE (RETURN FROM INTERRUPT)....................................................................... 9.30 LA INSTRUCCION CLRF (CLEAR F)....................................................................................................... 9.31 LA INSTRUCCION CLRW (CLEAR W).................................................................................................... 9.32 LA INSTRUCCION CLRWDT (CLEARWATCHDOG)................................................................................ 9.33 LA INSTRUCCION COMF (COMPLEMENT F).......................................................................................... 9.34 LA INSTRUCCION SLEEP (PUESTA A DORMIR).................................................................................. 9. 35 LA INSTRUCCION NOP (NO OPERATION).............................................................................................. 9.36 LAS INSTRUCCIONES OBSOLETAS.................................................................................................................. 10. LOS MODOS DE DIRECCIONAMIENTO............................................................................................... 10.1 EL DIRECCIONAMIENTO LITERAL O INMEDIATO............................................................................................... 10.2 EL DIRECCIONAMIENTO DIRECTO..................................................................................................................... 10.3 EL DIRECCIONAMIENTO INDIRECTO.................................................................................................................. 10.3.1 Los registros FSR y INDF.......................................................................................................................... 10.4 ALGUNOS EJEMPLOS........................................................................................................................................ 11. REALIZACION DE UN PROGRAMA EMBARCADO............................................................................. 11.1 EL MATERIAL NECESARIO................................................................................................................................. 11.2MONTAJE DE LA TARJETA DE EXPERIMENTACION.............................................................................................. 11.3 CREACION DEL PROYECTO................................................................................................................................. 11.4 EDICION DEL FICHERO FUENTE.......................................................................................................................... 11.5 ELECCION DE LA CONFIGURACION..................................................................................................................... 11.6 EL REGISTRO OPTION...................................................................................................................................... 11.7 EDICION DEL PROGRAMA..................................................................................................................................

43 45 46 47 47 48 51 51 52 53 53 53 55 55 55 56 58 59 59 60 60 61 62 62 63 63 64 65 67 67 68 69 69 70 72 73 73 73 74 74 75 75 75 76 76 76 76 77 78 80 80 81 82 82 83 84 85

11.8 EL REGISTRO PORTA.................................................................................................................................... 11.8.1 uncionamiento particular de los PORTS.................................................................................................. 11.9 EL REGISTRO TRISA...................................................................................................................................... 11.10 LOS REGISTROS PORTB Y TRISB............................................................................................................. 11.11 EJEMPLO DE APLICACION............................................................................................................................ 11.12 LA RUTINA DE INICIALIZACION................................................................................................................... 11.13 LOS RESULTADOS DEN ENSAMBLADO........................................................................................................ 11.14 EL PROGRAMA PRINCIPAL........................................................................................................................... 11.15 LA BRUTINA DE TEMPORIZACION................................................................................................................ 12. LAS INTERRUPCIONES........................................................................................................................... 12.1 QUE ES UNA INTERRUPCION ?..................................................................................................................... 12.2MECANISMO GENERAL DE UNA INTERRUPCION.............................................................................................. 12.3MECANISMO DE LA INTERRUPCION SOBRE LOS PIC.................................................................................... 12.4 LAS FUENTES DE INTERRUPCION DEL 16F84................................................................................................. 12.5 LA PUESTA EN MARCHA DE LOS DISPOSITIVOS.............................................................................................. 12.6 EL REGISTRO INTCON (INTERRUPT CONTROL)......................................................................................... 12.7 SALVAGUARDIA Y RESTAURACION DEL ENTORNO......................................................................................... 12.7.1 Los registros a salvaeguardar................................................................................................................... 12.7.2 El mtodo de salvaguardia........................................................................................................................ 12.7.3 El mtodo de restauracion........................................................................................................................ 12.7.4 OPERACIONES SOBRE EL REGISTRO STATUS........................................................................................... 12.7.5Particularidad de la instruccion RETFIE ........................................................................................... 12.8 UTILIZACION DE UNA RUTINA DE INTERRUPCION......................................................................................... 12.9 ANALISIS DE LA RUTINA DE INTERRUPCION.................................................................................................. 12.10 ADAPTACION DE LA RUTINA DE INTERRUPCION.......................................................................................... 12.11 LA INICIALIZACION................................................................................................................................... 12.12 CONSTRUCCION DE UN PROGRAMA PRINCIPAL.......................................................................................... 12.13 CONSTRUCCION DE LA RUTINA DE INTERRUPCION...................................................................................... 12.14 PASO AL SIMULADOR DE UNA RUTINA DE INTERRUPCION........................................................................... 12.15 PRIMERA CORRECCION: RESET DEL FLAG................................................................................................... 12.16 PONERSE A LA ESCALA DE TIEMPO DE UN PIC........................................................................................ 12.17 EL PROBLEMA DEL ANTI REBOTE................................................................................................................. 12.18 FINALIZACION DE UN PROGRAMA............................................................................................................... 12.19 OBSERVACIONES IMPORTANTES.................................................................................................................. 12.20 CONCLUSIONES............................................................................................................................................ 13. EL TIMER 0................................................................................................................................................... 13.1 LOS DIFERENTES MODOS DE FUNCIONAMIENTO............................................................................................... 13.2 EL REGISTRO TMR0......................................................................................................................................... 13.3 LOS METODOS DE UTILIZACION DEL TIMER0................................................................................................... 13.3.1 El modo de lectura simple.......................................................................................................................... 13.3.2 El modo de vigilancia del flag................................................................................................................... 13.3.3 El modo de interrupcion............................................................................................................................. 13.3.4 Los mtodos combinados........................................................................................................................... 13.4 EL PREDIVISOR.............................................................................................................................................. 13.5 APLICACION PRCTICA DEL TIMER0.............................................................................................................. 13.5.1 Preparaciones............................................................................................................................................ 13.5.2 La inicializacion........................................................................................................................................ 13.5.3 La rutina de interrupcion.......................................................................................................................... 13.6MODIFICACION DE LOS REGISTROS EN EL SIMULADOR................................................................................... 13.7PUESTA EN PRACTICA SOBRE LA PLACA.......................................................................................................... 13.8 PRIMERA MEJORA DE LA PRECISION.............................................................................................................. 13.9 SEGUNDA MEJORA DE LA PRECISION......................................................................................................... 13.10 EL METODO DE ATRAPE ......................................................................................................................... 13.11 EL METODO HARDWARE ADAPTACION DEL RELOJ........................................................................... 13.12 EL METODO DE LUXE : EL DOBLE RELOJ................................................................................................ 13.13 EJEMPLO DE UTILIZACION DE 2 INTERRUPCIONES........................................................................................ 13.13 CONCLUSION............................................................................................................................................... 14. EL ACCESO A LA MEMORIA EEPROM .........................................................................................

87 89 90 91 91 92 95 95 96 101 101 101 103 104 105 106 108 108 109 110 112 112 113 116 118 119 120 121 122 126 127 127 128 131 132 133 133 133 133 133 134 134 134 135 137 137 139 140 141 141 141 142 142 143 144 144 145 146

14.1 TAMAO Y LOCALIZACION DE LA MEMORIA EEPROM .............................................................................. 14.2 PREPARACION DEL PROGRAMA..................................................................................................................... 14.3 INICIALIZACION DE LA ZONA EEPROM........................................................................................................... 14.4 EL REGISTRO EEDATA................................................................................................................................ 14.5 EL REGISTRO EEADR................................................................................................................................... 14.6 EL REGISTRO EECON1................................................................................................................................ 14.7 EL REGISTRO EECON2................................................................................................................................. 14.8 ACCESO EN LECTURA A LA MEMORIA EEPROM ........................................................................................ 14.9 EL ACCESO EN ESCRITURA A LA ZONA EEPROM.............................................................................................. 14.10 UTILIZACION PRCTICA DE LA MEMORIA EEPROM ................................................................................ 14.11 SECURIZACION DEL ACCESO A LA MEMORIA EEPROM ............................................................................ 14.12 CONCLUSION............................................................................................................................................... 15. EL WATCHDOG........................................................................................................................................ 15.1 EL PRINCIPIO DE FUNCIONAMIENTO.............................................................................................................. 15.2 EL PRE DIVISOR Y EL WATCHDOG................................................................................................................. 15.3 LOS ROLES DEL WATCHDOG.......................................................................................................................... 15.4 UTILIZACION CORRECTA DAL WATCHDOG.................................................................................................... 15.5 LO QUE NO HACE FALTA HACER.................................................................................................................... 15.6 MEDIDA DEL TIEMPO REAL DEL WATCHDOG................................................................................................. 15.7 SIMULACION DEL BLOQUEO DE UN PROGRAMA............................................................................................ 15.7.1 Correccion con utilizacion del watchdog................................................................................................. 15.8 ELECCION DEL VALOR DEL PRE DIVISOR........................................................................................................ 15.9 TIEMPOS TIPICO, MINIMO, Y MAXIMO........................................................................................................... 15.10 CONCLUSION................................................................................................................................................ 16. EL MODO SLEEP...................................................................................................................................... 16.1 PRINCIPIO DE FUNCIONAMIENTO................................................................................................................... 16.2 LA SALIDA DEL MODO SLEEP .................................................................................................................... 16.3 DESPERTAR CON GIE FUERA DE SERVICIO.................................................................................................... 16.4 DESPERTAR CON GIE EN SERVICIO............................................................................................................... 16.5 PUESTA A DORMIR IMPOSIBLE....................................................................................................................... 16.6 UTILIZACION DEL MODO SLEEP ............................................................................................................... REMARQUE........................................................................................................................................................... 16.7 CASOS TIPICOS DE UTILIZACION.................................................................................................................... 16.7 PARA UN CONSUMO MINIMO......................................................................................................................... 16.8 CONCLUSION................................................................................................................................................ 17. EL RESTO DEL DATASHEET.................................................................................................................. 17.1 LA ESTRUCTURA INTERNA.............................................................................................................................. 17.2 LA SECUENCIA DE DECODIFICACION............................................................................................................. 17.3 ORGANIZACION DE LA MEMORIA................................................................................................................... 17.4 LOS REGISTROS ESPECIALES......................................................................................................................... 17.5 LA ELECTRONICA DE LOS PUERTOS............................................................................................................... 17.6 EL REGISTRO DE CONFIGURACION................................................................................................................. 17.7 LOS DIFFERENTES TIPOS DE OSCILADORES.................................................................................................... 17.7.1 La precision del oscilador......................................................................................................................... 17.8 EL RESET....................................................................................................................................................... 17.9 LA PUESTA EN TENSION................................................................................................................................. 17.10 CARACTERISTICAS ELECTRICAS.................................................................................................................. 17.11 PORTABILIDAD DE LOS PROGRAMAS............................................................................................................ 17.12 LA PUESTA AL DIA DE LOS COMPONENTES................................................................................................... 17.13 CONCLUSION............................................................................................................................................... 18. TRUCOS DE PROGRAMACION............................................................................................................... 18.1 LAS COMPARACIONES..................................................................................................................................... 18.2 SUSTRAER UN VALOR DE W............................................................................................................................. 18.3 LAS MULTIPLICACIONES.................................................................................................................................. 18.4 MULTIPLICACION POR UNA CONSTANTE........................................................................................................... 18.5 DIRECCIONAMIENTO INDIRECTO APUNTANDO A 2 ZONAS DIFERENTES............................................................

146 146 148 149 149 149 150 150 151 153 155 156 157 157 157 158 159 159 159 161 162 162 163 163 164 164 164 164 165 165 165 166 166 166 167 168 168 168 168 168 169 169 169 170 171 172 173 173 173 174 175 175 176 176 179 179

18.6 LAS TABLAS EN MEMORIA DE PROGRAMA..................................................................................................... 18.7 LAS VARIABLES LOCALES............................................................................................................................. 18.7.1 Dterminction de las variables locales..................................................................................................... 18.7.2 Construccion sin variables locales.......................................................................................................... . 18.7.3 Construccion con variables locales.......................................................................................................... 18.8 DIVISION POR UNA CONSTANTE.................................................................................................................... 18.9 CONCLUSION................................................................................................................................................. 19. UTILIZACION DE LAS RUTINAS EN UN FICHERO SEPARADO.................................................. 19.1 PREGUNTAS Y PUNTO DE PARTIDA................................................................................................................. 19.2 UTILIZACION DIRECTA DE LAS RUTINAS EN EL FICHERO................................................................................ 19.3 ENCAPSULACION EN MACROS SIMPLES.......................................................................................................... 19.4 MTODO FINALIZADO..................................................................................................................................... 19.5 CONCLUSION.................................................................................................................................................. 20. LA NORMA ISO 7816................................................................................................................................... 20.1 ESPECIFICACIONES UTILES DE LA NORMA ISO 7816...................................................................................... 20.1.1 Los comandOs ISO 7816............................................................................................................................ 20.1.2 El protocolo de intercambio de informaciones.......................................................................................... 20.2 LAS CONEXIONES SERIE ASINCRONAS............................................................................................................ 20.2.1 El start-bit................................................................................................................................................... 20.2.2 Los bits de datos......................................................................................................................................... 20.2.3 El bit de paridad........................................................................................................................................ 20.2.4 El stop-bit.................................................................................................................................................. 20.2.5 Tasa de enviot........................................................................................................................................... 20.3 ADQUISICION DE LOS BITS............................................................................................................................. 20.4 CARACTERISTICAS DE LAS TARJETAS STANDARD .................................................................................... 20.5 CREACION E INICIALIZACION DEL PROYECTO................................................................................................. 20.6 LA BASE DE TIEMPOS..................................................................................................................................... 20.7 RECEPTION DE UN OCTETO............................................................................................................................ 20.8 LA EMISION DE UN CARACTER....................................................................................................................... 20.9 INITIALIZACION.............................................................................................................................................. 20.10 ENVIO DEL ATR.......................................................................................................................................... 20.11 EL ENVIO DE STATUS.................................................................................................................................... 20.12 RECEPCION DE LA CLASSE............................................................................................................................ 20.13 RECEPCION DE INS, P1, P2, Y LEN............................................................................................................ 20.14 CONTROL DE LA INSTRUCCION RECIBIDA.................................................................................................... 20.15 TRATAMIENTO DE UNA INSTRUCCION......................................................................................................... 20.16 LAS VARIABLES............................................................................................................................................ 20.17 CONCLUSION................................................................................................................................................ ANNEXE1 : PREGUNTAS FRECUENTES (F.A.Q.)..................................................................................... A1.1 ENCUENTRO QUE 8 SUB PROGRAMAS SON POCOS.......................................................................................... A1.2 NO UTILIZAO MAS QUE 8 ANIDAMIENTOS PERO MI PROGRAMA SE BLOQUEA................................................ A1.3MI PROGRAMA PARECE NO SALIR JAMAS DE LAS INTERRUPCIONES............................................................... A1.4 NO LLEGO A UTILIZAR EL SIMULADOR, LAS OPCIONES NO APARECEN........................................................... A1.5 RECIBO UN MENSAJE DE ERROR EOF ANTES DE LA INSTRUCCION END....................................................... A1.6 COMO DESENSAMBLAR UN FICHERO .HEX ?............................................................................................ A1.7 UTILIZACION DE MINUSCULAS YMAYUSCULAS............................................................................................. A1.8 LA ELECCION DE UN PROGRAMADOR............................................................................................................ A1.9 TENGO UN ERROR DE STACK .................................................................................................................... A1.10 CUALES SON LAS DIFERENCIAS ENTRE 16F84 Y 16F84A ?........................................................................ A1.11 TENGO UN ERROR 173 DESPUES DEL ENSAMBLADO..................................................................................... A1.12 EL PIC16F84 ESTA OBSOLETO, POR QUE NO UTILIZAR EL 16F628 ?........................................................ A1.13 UTILIZO UNA VERSION DE MPLAB MAS RECIENTE................................................................................. A1.14 MI PIC VIRGEN NO OSCILA.......................................................................................................................... CONTRIBUCION SOBRE UNA BASE VOLUNTARIA.............................................................................. UTILIZACION DEL PRESENTE DOCUMENTO.......................................................................................

180 184 184 184 185 185 185 186 186 186 189 190 191 192 192 193 193 194 195 195 195 195 195 196 197 197 198 199 201 203 203 205 206 206 206 207 209 209 210 210 210 210 210 210 211 211 211 212 212 213 213 214 214 215 216

1. Introduccin
Vamos a empezar un camino juntos para esta gran aventura que es la programacin de los PI !" Vo# a inten$ tar ser lo m%s concreto posi&le' pero' independientemente de todo' una cierta teor(a es indispensa&le para llegar a &uen puerto" Vo# a empezar este peque)o curso por un recordatorio so&re los sistemas de numeracin" Veo que comienza a incomodarle" Pero esto# seguro que comprender% que es de todo punto de vista imposi&le programar se$ riamente un micro controlador sin sa&er que es un &it o cmo convertir las notaciones decimales en *e+ade$ cimales" ,st- seguro que vo# a ser &reve # podremos a&ordar r%pidamente el sujeto que tanto nos interesa" .i usted es #a un /pro0 se puede saltar el primer cap(tulo # pasar directamente al siguiente" 1o dude jam%s en *acerme participe de sus sugerencias ni de *acerme sa&er los errores que se me *an esca$ pado 2333"&igono44"org5" 6eproduzca las in4ormaciones que encontrar% aqu(' traduzca el documento a otros idiomas o a otros 4ormatos" .implemente' en esos casos' respete los deseos del autor # *%game llegar una copia del tra&ajo" ,sto es para provec*o de la ma#or cantidad de gente posi&le 2&igocours7*otmail"com5" 8e llamo la atencin so&re el *ec*o de que este curso' para ser e4icaz' de&e ser le(do en su totalidad realizan$ do los ejercicios que se proponen" 8as soluciones a los ejercicios son suministradas en 4orma de 4ic*eros ejemplo ane+ados al curso" 9odo lo que le *ar% 4alta es un 16:;42<5' un cuarzo de 4 =>z' una peque)a placa de e+perimentacin' un diodo 8,?' un pulsador # el logicial MPLAB' puesto graciosamente a su disposicin por la sociedad Microchip en la direccin http://www.Microchip.com" ,n esa misma direccin encontrar% el datas*eet del 16:;4" >e pasado numerosos d(as realizando estos ejercicios" Personalmente los *e testado so&re una maqueta uno por uno" 8e pedir(a que intentase realizarlos por usted mismo antes de preguntarme por email cuestiones que *u&iesen estado #a respondidas si *u&iese *ec*o ese peque)o es4uerzo" r-ame' es en el momento de poner las cosas en practica que nos damos cuenta que 4inalmente no *a&(amos comprendido del todo alguna cosa que parec(a de todo punto de vista evidente" .iempre respondo a los correos reci&idos' pero *ace 4alta decir que me resulta un poco enervante reci&ir preguntas de gente que me dice que *a asimilado el contenido de esta o&ra en una *ora" @8e juro que me lleganA Personalmente *e utilizado la versin 6"3B de MPLAB a partir de la revisin 13C del curso" 8as revisiones precedentes utiliza&an la versin 5"2B" 8a versin 6"6B est% disponi&le en la seccin de archives so&re la pagina de Microchip" 8e pido' para seguir correctamente el curso' que utilice esta versin #' una vez aca&ado el aprendizaje' cargar la versin m%s reciente # e+perimentar por s( mismo las di4erencias" ,l PIC utilizado aqu( es el m%s simple que e+iste en esta 4amilia' no se trata de un PI de los m%s avanzados" uando realice sus propios montajes elija el modelo en 4uncin de su cuaderno de cargas" 8a calavera de la portada no es un s(m&olo ligado a este curso' es una utilidad *istrica" ?esde que propuse las primeras versiones de mi curso' no tenia alojamiento 3e&' mis cursos esta&an distri&uidos en la red 2*asta la revisin 65" ,n consecuencia' en caso de litigio' no ten(a ningDn medio de pro&ar legalmente que #o era el autor de este curso # pod(a 4%cilmente ser /ro&ado0" 1o deseando desvelar mi verdadera identidad 2no tengo necesidad de una co*orte de estudiantes llamando a mi puerta constantemente5 quise 4irmar este documen$ to de 4orma que pudiese pro&ar en todo momento que #o era el autor" .i va a mi 3e& # o&serva la 4oto de mi moto' ver% que esa calavera no es otra cosa que una parte de su care$ nado" omo esa 4oto est% en mi curso # puedo pro&ar que so# propietario de la moto' puedo pro&ar que so# el autor del curso si 4uese necesario" 7

2. Los sistemas de numeracin


2.1 El sistema decimal
,stamos *a&ituados desde la in4ancia a utilizar el sistema de numeracin decimal' *asta tal punto' que no somos conscientes de la manera en que este tra&aja # llega a ser para nosotros un automatismo" EPor qu- decimalF Porque utilizamos una numeracin con 1B ci4ras" ?iremos que es un sistema en &ase 1B" omo peque)a *istoria' utilizamos un sistema en &ase 1B porque nuestros ancestros empezaron a contar usando los diez dedos de las manos' no *ace 4alta &uscar m%s lejos" 8a posicin de las ci4ras tiene una gran importancia" 8as ci4ras menos signi4icativas se sitDan a la derec*a del nDmero # las de ma#or importancia tanto m%s cuanto m%s a la izquierda del numero est-n" ,n el numero 5B2' el 5 tiene ma#or importancia que el 2" ,n realidad' cada ci4ra' que podemos llamar digito' tiene un valor que depende de su rango" E u%l es el multiplicador a aplicar a cada digito en 4uncin de su posicin 2rango5F .im$ plemente la &ase elevada a la potencia de su rango" ,sto tiene el aire de ser complejo' pero es mu# simple de comprender" uando lo *a#a entendido' entender% cualquier sistema de numeracin" 6etomemos' por ejemplo' el numero 5B2" EGu- signi4ica el 2F .implemente que su valor equivale a 2 multipli$ cado por la &ase 21B5 elevada al rango 2posicin5 que ocupa' es decir B" Hn nDmero elevado a B siempre vale 1" ,l 2 representa' pues' 2I1" J&serve aqu( una cosa mu# importanteK el rango se cuenta de derec*a a izquierda comenzando por B" Para nuestro nDmero 5B2 en realidad su valor esK 5B2 L 2I1BB M BI1B1 M5I1B2 1tese que utilizamos el s(m&olo I para indicar multiplicacin" N recuerde que 1BB L 1' 1B1 L 1B' 1B2 L 1BB' etc"

2.2 El sistema binario


E,ntendi lo que precedeF 8o siguiente le parecer% simple" Para usted no es ningDn pro&lema contar con los dedos' pero para un ordenador no es simple" 1o sa&en' en general' m%s que *acer la distincin entre dos ni$ veles 2presencia o ausencia de tensin5" ,l sistema de numeracin decimal no se les adapta &ien" omprender% que el Dnico sistema que se les adapta es el sistema de numeracin de &ase 2 tam&i-n llamado &inario" ,ste sistema tra&aja con solo dos ci4ras' a sa&er' B # 1" omo' adem%s' los primeros ordenadores 2# los PIC5 tra&aja&an con numero de ; ci4ras &inarias' se les llam octetos 2o &#tes en ingl-s5" < la ci4ra B 1 se le llama &it 2por &inar# unit5" ,n lo que sigue' se adoptar%n las siguientes convencionesK todo numero decimal estar% escrito tal cual' o utili$ zaremos la notacin ?O+++O" 9odo numero &inario lo escri&iremos con la 4orma PO++++++++O' donde + vale B 1" <nalicemos un nDmero &inario" .ea el octeto PO1BB1B1B1O" E u%l es su valor decimalF =u# simple" <plicamos el mismo algoritmo que para el decimal" Partamos desde la derec*a *acia la izquierda # tendremosK

B10010101 = 1*2 + 0*21 + 1*22 + 0*23 + 1* 24 + 0*25 + 0*26 + 1*27

,videntemente B multiplicado por cualquier cosa es B' # 1 multiplicado por cualquier ci4ra da la ci4ra en cues$ tin" ,l c%lculo precedente quedar% comoK

B 10010101 = 1+4+16+128 = 149


omo ve es mu# 4%cil convertir cualquier nDmero de &inario a decimal" EN a la inversaF Igualmente simple" >ace 4alta conocer la ta&la de e+ponentes de 2" ,sta se aprende 4%cilmente con el uso" Podemos proceder de la 4orma siguiente 2*a# otras maneras5K E u%l es el m%s grande e+ponente de 2 contenido en 14QF 6espuestaK 7 (27 = 128) .a&emos que el &it 7 valdr% 1" Guedar% 14Q$12;L21 ,l &it 6 representa 64 que es m%s grande que 21' luego &6 valdr% B" ,l &it 5 representa 32 que es m%s grande que 21' luego &5 valdr% B" ,l &it 4 representa 16' luego &4L1 # quedar%n 21$16L5 ,l &it 3 representa ; que es m%s grande que 5' luego &3 valdr% B" ,l &it 2 representa 4' luego &2L1 # quedar%n 5$4L1 ,l &it 1 representa 2 que es m%s grande que 1' luego &1LB" ,l &it B representa 1' que es lo que nos queda' luego &BL1" ,l nDmero &inario o&tenido ser% B10010101' que es nuestro octeto de partida" 9enga en cuenta que si en$ contramos un nDmero de menos de ; ci4ras &astar% con completar con B por la izquierda *asta tener ; ci4ras" ,n e4ecto' B00011111 = B 11111 de la misma manera que 0502 = 502" Piense siempre en completar los octetos o&teniendo ; &its puesto que esto es imposi&le de *acer para la ma$ #or parte de los ensam&ladores 2veremos qu- es esto en las lecciones que seguir%n a continuacin5" J&serve que el ma#or numero que puede ser representado por un octeto es B11111111" .i *ace la conver$ sin a decimal ver% que es 255" 9odo nDmero superior a 255 necesita' para ser representado' m%s de un octe$ to" 8e do# otro m-todo simple para convertir de decimal a &inario' procediendo de manera inversa' es decir' desde la derec*a a la izquierda" ,l m-todo consiste en escri&ir el resto de ir dividiendo por 2 el nDmero en cuestin" 6etomemos nuestro numero decimal 14QK 14Q R 2 L 74 # queda 1" 74 R 2 L 37 # queda B" 37 R 2 L 1; # queda 1" 1; R 2 L Q # queda B" Q R 2 L 4 # queda 1" 4 R2 L 2 # queda B" 2 R 2 L 1 # queda B" 1 R 2 L B # queda 1" ogiendo todos los restos empezando por el Dltimo 2o empezando por el primero # rellenando de derec*a a izquierda5' o&tendremos B10010101' que es valor que *a&(amos o&tenido anteriormente" ,n general' este m-todo es m%s simple para aquellos que no tiene el *%&ito de jugar con las potencias de 2' pero el primero es m%s r%pido de *acer mentalmente si adquirimos el *%&ito"

2.3 El sistema hexadecimal


8a representacin de nDmeros &inario no es 4%cil de usar' # escri&ir una sucesin de 1 # B es una 4uente cons$ tante de errores" >ac(a 4alta una solucin m%s pr%ctica para representar nDmeros &inarios" ?ecidimos romper cada octeto en dos cuartetos # representar cada parte por una sola ci4ra" omo un cuarteto puede variar de POBBBBO a PO1111O' constatamos que le valor puede variar de B a15" ,sto da 16 com&inaciones posi&les" 8as 1B ci4ras del sistema decimal no son su4icientes para codi4icar estos valores" =ejor que inventar 6 s(m&olos nuevos se decide utilizar las 6 primeras letras del al4a&eto como ci4ras" 8gi$ camente a este sistema de numeracin en &ase 16 lo llamamos *e+adecimal" J&serve que este sistema es' simplemente' una 4orma m%s e4icaz de representar nDmeros &inarios # la con$ versin de uno a otro es instant%nea" < partir de a*ora' representaremos un numero *e+adecimal *aci-ndole comenzar por B+" Veamos si lo *a entendidoK

Tabla de conversin de diferentes (un semi octeto) Binario B0000 B0001 B0010 B0011 B0100 B0101 B0110 B0111 B1000 B1001 B1010 B1011 B1100 B1101 B1110 B1111

Hexadecimal 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xA 0xB 0xC 0xD 0xE 0xF

Decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Para representar un octeto' *acen 4alta 2 d(gitos *e+adecimales" Por ejemplo' nuestro B10010101 se repre$ senta por el *e+adecimal 0x95" .i *ace la conversin de *e+adecimal a decimal' utilizar% el mismo principio que *emos estado utilizando' # o&tendremos 0x95 = 9*161 + 5*16 = 149" Pro&emos cu%l es en *e+adecimal el nDmero m%s grande que podemos representar" 6espuestaK B+::' es decir 15*16 + 15 = 255" .i *a entendido todo esto' a*ora es capaz de convertir no importa qu- nDmero en no importa qu- &ase en otro con &ase distinta" ,ncontrar% en algunas revistas alusiones al sistema octal' que es el sistema en &ase ; # que 4ue mu# utilizado en el pasado pero casi nada actualmente"

1B

2.4 Las operaciones


?espu-s de *a&er convertido nDmeros en di4erentes 4ormatos' vamos a ver que es mu# simple realizar opera$ ciones con estos nDmeros en no importa que 4ormato" ,jemploK EGu- vale B1011 + B 1110F Procederemos de la misma manera que para una operacin en de$ cimal"

B1011
+ B1110

-------------?
.umamos las ci4ras de la derec*a # o&tenemosK 1MBL1" ,scri&imos 1" .umamos 1M1 # o&tenemos 1B 22 no e+iste en &inario5" ,scri&imos B # llevamos 1" .umamos BM1M1 2que tra(amos5 # o&tenemos 1B" ,scri&imos B # llevamos 1" .umamos 1M1M1 2que tra(amos5 # o&tenemos 11" ,scri&imos 1 # llevamos 1" Gueda lo que traemos" ,scri&imos 1" 8a respuesta ser%K B11001' es decir 25 en decimal" 8os nDmeros de partida eran B1011 es decir 11' # B1110 es decir 14" Procedemos de la misma manera pa$ ra nDmeros *e+adecimales' sa&iendo que B+: MB+1 L B+1B' es decir 15 M 1 L 16 2escri&imos B # llevamos 15"

2.5 Los nmeros con signo


,n ciertas aplicaciones es necesario utilizar nDmeros negativos" omo los procesadores no entienden el s(m&olo /$/' # como *ace 4alta limitar el tama)o a ; &its' el Dnico m-todo encontrado es incluir el signo en el numero" .e *a decidido 2# no por azar5 utilizar el &it 7 para representar el signo" ,n los nDmeros con signo' un &it 7 a 1 signi4ica nDmero negativo" .i *acemos esto' perdemos un valor posi&le" ,n e4ecto B10000000 (-0) ser% a*ora igual que B00000000 (0)" ,s m%s' por razones de 4acilidad de c%lculo' decidimos utilizar una notacin ligeramente di4erente" Para tener un nDmero negativo procederemos en 2 etapasK 1" Invertimos la totalidad del nDmero" 2" <)adimos 1" <s( o&tendremos lo que llamamos el complemento a 2" ,jemploK sea el nDmero 5' es decir B00000101" E mo escri&iremos $5F 1" Invertimos todo 2complemento a 15K B11111010 2" <)adimos 1 2complemento a 25K B11111011 Para *acer la conversin inversa' se procede de la misma manera" 1" Invertimos todo 2complemento a 15K B00000100 2" <)adimos 1 2complemento a 25K B00000101 N o&tenemos el nDmero de partida" 11

Para los nDmeros con signo tendremos a*ora los siguientes l(mitesK ,l valor m%s grande es B01111111' es decir +127" ,l valor m%s peque)o es B10000000' es decir 128"

ompro&emos que las operaciones continDan 4uncionado correctamente" 9omemos $3 M5"

B 11111101 (-3) + B 00000101 (5) ----------------------------B100000010 (2)


=e puede decir que esto no es 2" .i o&serva &ien ver% que *a# Q &its" ,l procesador no opera m%s que con ;" ,l QS &it es un &it especial que veremos m%s tarde" ,n el registro del procesador estar%n los primeros ; &its' es decir' B00000010, que representa 2" .i me *a seguido *asta a*ora estar% a punto de decirmeK cuando tenemos B11111101 E mo esto# seguro de que es $3 # no 253F 1o lo sa&remos sin conocer previamente el conte+to" .epa que los nDmeros signi4ican lo que el programador *a querido que signi4iquen" .i tra&aja con nDmeros con signo o no' o si el octeto representa otra cosa 2un tiempo' un car%cter' etc"5" 8o Dnico importante es res$ pectar el signi4icado que usted *a 4ijado a la *ora de crearlos" ,s por lo tanto su responsa&ilidad decidir la ne$ cesidad de que tipo de datos precisa"

2.6 Las operaciones booleanas


EGu- es estoF =e preguntar%" Para simpli4icarlo' diremos que se trata de operaciones que se realizan &it a &it so&re un octeto determinado" =%s que una gran teor(a so&re el alge&ra de Poole 2veo que respira mejor5' vo# a ser m%s concreto present%ndole las operaciones indispensa&les que *a# que conocer para programar los PIC u otros micro controladores"

2.6.1 El complemento
9am&i-n llamado /inversin0 o /1J90 o tam&i-n complemento a 1" < menudo se se)aliza como0A0" .u 4un$ cionamiento es mu# simple # consiste en invertir todos los &its del octeto 2B cam&ia a 1 # 1 se cam&ia a B5" ,jemploK NOT B10001111 = B01110000 omo ve' para las operaciones &ooleanas es muc*o m%s 4%cil tra&ajar directamente en &inario" 9raduzca el ejemplo sucesivamente a *e+adecimal 2podemos decir /*e+a0 como los /pro05 # despu-s a decimal e intente complementar directamente" Puenos d(as neuronas" EPara qu- sirve esta operacinF Por ejemplo' para leer un valor cu#os &its *an sido invertidos' para calcular nDmeros negativos # para otras operaciones que veremos m%s adelante"

12

2.6.2 La funcin Y o AND


8lamada tam&i-n multiplicacin &it a &it' # a menudo' anotada como /T0" onsiste en aplicar una pala&ra so&re otra pala&ra # multiplicar cada &it del mismo rango" Para realizar una operacin /N0 necesitaremos dos octetos" 8as di4erentes posi&ilidades est%n dadas en la siguiente ta&la 2se lee en *orizontal5" Primera l(neaK B <1? B L B" ,ste tipo de ta&la se llama /ta&la de verdad0 o /ta&la de Uarnaug*0' de&ido al nom&re de su inventor' Maurice Karnaugh"

Vemos que la Dnica posi&ilidad de o&tener un 1 es que los dos &its sean 1" ,sto corresponde a una multiplica$ cin directa de los &its" ,jemploK B11001100 AND B 11110000 = B11000000 EPara qu- sirve esta operacinF ,s utilizada para enmascarar 2ocultar5 los &its que no nos interesan" 9omemos el ejemplo anterior" ,l segundo octeto contiene 4 &its a 1 # 4 &its a B" J&serve el resultado o&teni$ do" 8os 4 primeros &its del primer octeto se *an mantenido como esta&an (1100) # los otros 4 *an pasado a B" Por medio de esta operacin' podemos 4orzar a B los &its que queramos sin conocer previamente qu- valor ten(an" ,sta operacin es conmutativa' es decir' o&tendremos el mismo resultado invirtiendo el orden de los octetos 2el primero por el segundo # viceversa5"

2.6.3 La funcin O u OR
< menudo anotada como /V0 permite' como su nom&re indica' posicionar un &it a 1 si el &it1 o el &it2 son 1 2o am&os a la vez5" 8a siguiente ta&la de verdad e+plica su 4uncionamiento"

13

,jemploK B10001000 OR B11000000 = B11001000 EPara qu- sirve esta instruccinF 1os permite 4orzar no importa que &it de un octeto a 1 sin conocer su esta$ do precedente" Puede ver que en el ejemplo precedente' los dos primeros &its *an sido 4orzados a 1 independientemente del nivel precedente" ,sta operacin tam&i-n es conmutativa"

. 2.6.4 La funcin O EXCLUSIVA o Exclusif OR o XOR


,sta es la Dltima operacin que vamos a a&ordar en esta puesta a nivel" .e comporta como una J6 con un de$ talle a)adido" Para o&tener un 1 *ace 4alta que el &it1 sea 1 O el &it2 sea 1 EXCLUIDO que am&os sean iguales" .i los dos &its son 1 el resultado ser% B"

Por ejemploK B10001000 XOR B11000000 = B01001000 EPara qu- sirveF .implemente para invertir no importa que &it de un octeto sin tocar el resto de ellos" ,n el ejemplo precedente puede ver que en la posicin de los dos &its a 1 del segundo octeto' en el primer octeto *an quedado invertidos # el resto permaneci sin cam&ios" on esto se termina el primer cap(tulo consagrado a los PIC" .- que *a sido /espeso0 pero' si no domina es$ to que aca&amos de e+plicar jam%s podr% realizar correctamente sus propios programas"

2.7 Unas palabras acerca de las unidades


>emos *a&lado de octetos # de &its" ,n in4orm%tica utilizamos corrientemente t-rminos como P#te # &it" ,n$ contrar% igualmente el t-rmino /pala&ra0 2Word5" Hna pala&ra es un mDltiplo de &it" ,l termino pala&ra de&e ser precisado con el tama)o de la misma" 1os podemos re4erir impl(citamente a un tama)o de pala&ra mani$ pulado por el componente 2un procesador de 16 &its manipula pala&ras de 16 &its5" uando vea este t-rmino' comprue&e de qu- se trata en 4uncin del conte+to" 8os s(m&olos m%s corrientes sonK JctetoK B 2por &#te5 PitK b 8os ingleses est%n o&ligados a utilizar /P0 ma#Dscula para los octetos con el 4in de evitar con4usiones con /&0 minDscula para los &its" 8a /traductomania0 imperante en :rancia *ace que sea el Dnico pa(s que *a adoptado el s(m&olo /o0 para octeto" Por otra parte' visto que :rancia no *a impuesto traduccin para /&it0 no *a# ries$ go de con4usiones" 14

9enga en cuenta que todo esto es mu# relativo dado que le organismo de validacin de s(m&olos 2el .I5 *a re$ usado validar una serie de s(m&olos por lo queK PK es il(cito porque #a se utiliza para de4inir el Pel" &K es il(cito porque se utiliza para el &ar" JK es il(cito por posi&le con4usin con B" oK no corresponde a nada para un angl4ono # por lo tanto no es o4icial" Prevemente' la situacin no est% clara' tendr% que *acer re4erencia a los documentos que est- le#endo pero que' en general' siguen las convenciones que le *e dado *asta a*ora" <Dn nos queda *a&lar de los mDltiplos 2Xilo' mega' etc"5 lo que se *ace r%pidamente" ,n &ase 1B' nuestra &ase de todos los d(as' se decide adoptar mDltiplo de la potencia 3" <s( por ejemploK

kilo (k) = 103 (el nico smbolo > 1 en minscula, debido a una posible confusin con Kelvin) Mega (M) = 106 Giga (G) = 109 Tera (T) = 1012
Pero tra&ajando en &ase 2' estos valores no caen justos' # 10 no representa en &ase 2mas que un valor entre otros muc*os 2le dejo a usted convertirlo a &inario5" >ace 4alta representar mDltiplos que sean particulares" .e procedi en una primera instancia' a recuperar pura # simplemente los t-rminos utilizados en &ase 1B 2Xilo' mega' etc"5 tal como recuperamos las letras para las ci4ras en el sistema *e+adecimal" .e les *a reajustado los valores utilizando los e+ponentes de 2 como mDltiplos de 1B" ?e esta 4orma *emos de4inidoK

kilo = 210 Mega = 220 Giga = 230 Tera = 240


?e esta 4orma' un Xilo octeto en in4orm%tica vale 210 octetos' es decir 1B24 octetos' mientras que un Xilogra$ mo vale 1BBB gramos" 8a situacin empeora para =ega puesto que 1 =ega octeto vale 1B4;576 octetos mientras que un =ega gramo vale 1BBBBBB gramos" 8os vendedores de material de almacenamiento masivo de datos se lo *an saltado" ,llos conservan la deno$ minacin original 2legal5 en potencias de 1B' mientras que los in4orm%ticos tra&ajan en potencias de 2" ?e tal 4orma' cuando compramos un disco duro de 1BB =& 21BB =ega octetos5 tendr% 1BB"BBB"BBB de octetos" 8os sistemas operativos 2Windo3s5 se)alan el tama)o generalmente en /=egas in4orm%ticos0 # traducen este tama)o a (100.000.0000 / 220) = 95,4Megaoctetos" 6esumiendo 1BB =ega octetos de constructor de discos duros L Q5'4 =ega octetos de in4orm%tico" ,st% claro que la situacin no pod(a perdurar" <l comienzo de los a)os 2BBB se decidi regular todo esto" ,ra claro que ser(a en &ase a inventar nuevos t-rminos' siendo el primero el t-rmino /Xi&i0 que representa el mDltiplo de &ase 2K 210"

15

8legamos a las convenciones siguientesK

Kibi (Ki) 210 1024 1,024k (retomamos la mayscula en Ki) Mbi(Mi) 220 1048576 1,048586 M Gibi (Gi) 230 1073741824 1,073741824 G Tbi (Ti) 240 1099511627776 1,099511627776 T Pebi (Pi) 250 1125899906842624 1,125899906842624 P Exbi (Ei) 260 1152921504606846976 Zebi (Zi) 270 1180591620717411303424 Yobi (Yi) 280 1208925819614629174706176
<s(' en posesin de nuevas convenciones no e+istir% ninguna duda so&re los t-rminos utilizados" ?e&er(amos encontrar en in4orm%tica los t-rminos Ui' =i' etc" 8a situacin real est% mu# lejos de ser ni parecida" 8a gran ma#or(a de los li&ros de in4orm%tica # de los logiciales continDan utilizando los Xilo para las potencias de 2' a veces incluso con la X ma#Dscula 2UP5" ?e&er% estar atento a esta situacin que tardar% &astantes a)os en re$ gularizarse" <s( pues' 210 octetos es un UiP para el mundo # es un Uio para :rancia" 230 &its son a*ora un Yi& para el mundo" .u inter-s ser% entender a su interlocutor' aunque use t-rminos incorrectos' a la vez que usted emplea los t-rminos correctos" ?e paso' no con4unda Yi&i con la 4amosa marca de WisX#' ser(a malo para sus neuronas # para sus relaciones con su je4e"

16

3. Composicin y funcionamiento de los PIC


Por 4in algo interesante" Vamos a colgarnos a*ora de un PIC' en particular del PIC16F84" 9enga por segu$ ro que todo lo que veamos del 16:;4 podr% utilizarlo directamente so&re otros 16:+++ que no son otra cosa que 16:;4 mejorados" ada dispone de las 4uncionalidades de los modelos in4eriores' aumentadas con nue$ vas 4unciones" ,n el momento de la revisin 13 de este curso' el modelo que encontrar% ser% pro&a&lemente el 16:;4<' lo cual no supondr% ningDn pro&lema para este curso" 8as di4erencias son Dnicamente de *ard3a$ re" 8o primero que de&e *acer es cargar el datas*eet del PI 16:;4' pues es el documento que vamos a utilizar en el resto de las lecciones" 8e aconsejo que lo imprima pues es algo que necesitar% constantemente cuando desarrolle sus propios programas" ,stos datas*eet son mis li&ros de ca&ecera" ,ncuentro m%s juicioso tra&ajar mediante la pr%ctica # comentar$ los en un orden Dtil' mejor que traducirlo a lo /&estia0"

3.1 Qu es un PIC?
Hn PIC no es otra cosa que un micro controlador' es decir' una unidad de tratamiento de in4ormacin de tipo micro procesador a la que se le *an a)adido peri4-ricos internos de comunicacin con el e+terior permi$ ti-ndonos realizar montajes sin necesidad de a)adir componentes e+ternos' o al menos' con un reducido nDmero de componentes e+ternos" 8a denominacin PIC est% &ajo el cop#rig*t de Microchip' por lo que otros 4a&ricantes no pueden utili$ zar ese t-rmino para sus micro controladores" Hn PIC es un micro controlador de la marca Microchip" 8os son componentes 6I. (Reduced Instructions Set Computer)' componentes con un juego de instruccio$ nes reducido" EPor qu-F .epa que contra m%s reducido es el nDmero de instrucciones' m%s 4%cil # m%s r%pido es la decodi4icacin # el componente 4unciona m%s r%pido" >a&r% adivinado que en el mercado e+isten dos 4amilias opuestas' la 6I. # la I. (Complex Instructions Set Computer)" ,n los I. disponemos de menor velocidad de tratamiento' pero las instrucciones son muc*o m%s complejas' potentes # m%s numerosas" .e trata de una eleccin estrat-gica" 9odos los PIC Mid-Range tienen un juego de 35 instrucciones' almacenan cada instruccin en una sola pa$ la&ra de programa # ejecutan cada instruccin 2salvo saltos5 en un ciclo" 9endremos grandes velocidades # las instrucciones son 4%cilmente asimila&les" 8a ejecucin en un solo ciclo es t(pica de los componentes 6I. " ,l reloj suministrado al PIC est% pre dividido por 4 a nivel de este" ,s esta &ase de tiempos la que nos da la duracin de un ciclo" .i por ejemplo utilizamos un cuarzo de 4 =>z' tendremos 1BBBBBB ciclos R segundo' o' como el PIC ejecuta pr%cticamente 1 instruccin por ciclo' e+cepto saltos' esto nos dar% una potencia del orden de 1 MIPS (1 Million dInstructions Par Seconde)" Piense que los PIC pueden alcanzar m%s de una docena de =>z segDn la 4amilia # tipo" ,s una velocidad de tratamiento m%s que *onora&le"

17

3.2 Las diferentes familias de PIC


8a 4amilia de los PIC de ; &its 2manipulan datos de ; &its en una sola operacin5 est% su&dividida en el mo$ mento de escri&ir la revisin 1 de este curso en 3 grandes 4amilias" 8a 4amilia Base-Line' que utiliza pala&ras de 12 &its para ciertas instrucciones 2veremos qu- es esto m%s ade$ lante5 (12C508) # 14 &its para otros 12F675" 8a 4amilia Mid-Range' que utiliza pala&ras de 14 &its 2de la que 4orman parte el 16:;4 # el 16:;765" 8a 4amilia High-End' que utiliza pala&ras de 16 &its # que se descri&en en la parte 5 de este curso" ?espu-s *an aparecido otras 4amilias como la Enhanced family' los PIC10F # la cosa no *ace m%s que evo$ lucionar" 1os podemos encontrar tam&i-n los PIC 16 bits' en los cuales algunos inclu#en un DSP (Digital Signal Processor)' # los de 32 &its" Por otra parte' para cada 4amilia' nuevos modelos # nuevas 4uncionalida$ des no paran de aparecer por lo que es a usted a quien le incum&e' una vez 4inalizado este aprendizaje' con$ sultar el sitio de Microchip para elegir el modelo que m%s le convenga para su aplicacin particular" 1osotros nos limitaremos en las primeras 4 partes de esta o&ra 2desde el curso parte 1 al curso parte 45 a la 4amilia Mid-Range" 8a o&ra que est% a punto de leer concierne a las &ases necesarias para utilizar el m%s simple de los PIC16F' el PIC16F84" ,l curso parte 5 le dar% las pistas para utilizar la 4amilia m%s potente de ; &its' la 4amilia High-End" uando lo comprenda todo' tendr% las &ases su4icientes para pasar a otras 4amilias' incluso a otros micros controlado$ res" 9enga en cuenta desde a*ora que el datas*eet del 16:;4 no es m%s que una peque)a parte de la documenta$ cin completa" Para tener toda la documentacin' necesitar% descargar m%s de 6BB p%ginas de documenta$ cin del sitio de Microchip' los datas*eet para la gama Mid-Range" ?e todas 4ormas' la documentacin de &ase es su4iciente para el QQ'QZ de las aplicaciones' #' adem%s' los da$ tas*eet =id$6ange est%n disponi&les en el 4ormato de un 4ic*ero por capitulo" Por mi parte tengo pr%ctica$ mente todo impreso' pero le aconsejo que lo *aga tal como lo va#a necesitando" ,sos documentos compor$ tan in4ormaciones suplementarias puntuales' so&re todo a nivel electrnico"

3.3 Identificacin de un PIC


Para identi4icar un PI ! utilizaremos simplemente su nDmero" 8as dos primeras ci4ras indican la categor(a del PIC' 16 indica PIC Mid-Range" < continuacin la letra 8K esta indica que el PIC puede 4uncionar con una e+cursin de tensin de alimenta$ cin m%s tolerante 2por ejemplo 3 V5" .eguidamente se encontrar% con una de estas posi&ilidadesK C indica que la memoria de programa es una EPROM o m%s raramente una EEPROM" CR indica una memoria de tipo ROM" F indica una memoria de tipo FLAS "

< este nivel' solo las memorias de tipo ,,P6J= o :8<.> pueden ser &orradas' por lo que no espere poder volver a programar un PIC de tipo 6" 1;

Para las versiones lea el datas*eet" ,l 16 ;4 puede ser reprogramado' se trata de una memoria eeprom" ,l 12 5B;' por ejemplo' posee una memoria de programa ,P6J= que solo se puede &orrar por e+posicin a luz ultravioleta" ,ste c*ip posee una ventana transparente para &orrar la memoria' que es una versin especial para desarrollo # no la versin que nos encontramos normalmente" Hn componente que no se puede reprogramar lo llamamos O.T.P. por One Time ProgrammingK componen$ te de programacin Dnica" 8as Dltimas ci4ras identi4ican precisamente el PIC (84)" Para aca&ar' ver% so&re el encapsulado el su4ijo /$[[0 en los cuales [[ representa la 4recuencia m%+ima de re$ loj que soporta" Por ejemplo' $B4 indicar% que puede soportar *asta 4 =>z" ?e *ec*o' parece que este dato es puramente comercial # que todos los PIC de un mismo modelo soportan tra&ajar a la velocidad m%+ima del modelo' velocidad mostrada al comienzo del datas*eet" <parentemente esta in4ormacin es inDtil" ?e to$ das 4ormas' no me *ago responsa&le de este Dltimo comentario" ,s su responsa&ilidad juzgar # o&rar en con$ secuencia" ,n un pro#ecto comercial # a 4in de evitar cualquier pro&lema' #o seguir(a las indicaciones del 4a$ &ricante" Para un pro#ecto casero o con 4ines e+perimentales' juzgue por usted mismo" Por lo tanto' un 16F84-04 es un PIC Mid-Range (16) con memoria de programa FLASH (F) por lo tanto reprograma&le del tipo 84 # capaz de aceptar una 4recuencia de reloj de 4MHz en teor(a 2pro&a&lemente 1B =>z para un 16:;4 # 2B =>z para un 16:;4<5" Hna Dltima indicacin que encontrar% es el tipo de encapsulado" Para nuestros e+perimentos utilizaremos el encapsulado de tipo PDIP' que es un encapsulado ?I8 de 1; patillas' con una distancia entre patillas de B'30" 8a versin de 4 =>z ser% m%s que su4iciente"

Microchip evoluciona sus re4erencias' *a# otras mencionadas' le corresponde a usted compro&ar a qu- co$ rresponden"
< destacar que *asta el presente' los PIC son componentes est%ticos' es decir' podremos &ajar la 4recuen$ cia del reloj *asta la parada completa sin p-rdida de datos # sin dis4uncionamientos" ,sto es por oposicin a los componentes din%micos 2como el micro procesadores de su ordenador o la 6<= de estos5' en los cuales la 4recuencia de reloj de&e estar entre l(mites &ien de4inidos" 1o prue&e nunca *acer tra&ajar un PIIIR5BB a 166 =>z' pues es un componente din%mico" Por el contrario' puede *acer tra&ajar su PI 16:;4$B4 a 1 U>z sin ningDn pro&lema incluso llegar a pararlo 2sin cortar la alimentacin5" .i va a comprar un para utilizarlo en el curso pida un PIC 16F84A-xx en encapsulado PDIP" ,sta o&ra se escri&i para un 16:;4 que actualmente est% reemplazado por el 16:;4<" >e conservado la terminolog(a en esta o&ra' las di4erencias se limitan a algunas mejoras *ard3are 2m%s rapidez entre otras5" Por lo tanto uso el t-rmino 16:;4 para indicar un 16:;4 o un 16:;4< indistintamente"

3.4 Organizacion del 16F84


8a memoria del 16:;4 est% dividida en 3 partes" ,n la p%gina 4 del datas*eet encontrar% la ta&la 1$1 que nos da una vista general de la 4amilia 16:;[" 8os nDmeros de pagina pueden variar en 4uncin de las puestas al d(a de la documentacin por parte de Microchip" Puede que tenga que &uscar un poco' o utilizar el datas*eet suministrado con el curso" Para aquellos que lo quieren entender todo' la 4igura 3$1 de la pagina ; les muestra la organizacin interna de un 16:;4"

1Q

3.4.1 La memoria de programa


8a memoria de programa est% constituida por 1 Ui pala&ras de 14 &its" ,s en esta zona donde vamos a escri&ir nuestro programa" ,sto e+plica por qu- sus 4ic*eros en P ocupan 2 Uio 2Ui&i octetos5 pues *ace 4alta 2 octe$ tos para codi4icar 14 &its" ,sto e+plica' igualmente' por qu- cuando usted lee un virgen PIC' lee 0x3FFF" ,sto es en &inario B0011111111111111' es decir' 14 &its Dtiles" =%s adelante le e+plicar- de donde vienen los 4amosos 14 &its" <dvierta que una instruccin est% codi4icada so&re una pala&ra" 1 Ui de pala&ras nos da un &uen millar de ins$ trucciones posi&les para su programa 2no est% nada mal5" uando va#a a escri&ir un programa de 1 Ui usted #a ser% m%s que autnomo en esto de la programacin de aplicaciones"

3.4.2 La memoria Eeprom


8a memoria EEPROM (Electrical Erasable Programmable Read Only Memory) est% constituida por 64 octetos que usted puede leer # escri&ir desde su programa" 8a in4ormacin all( contenida se conserva despu-s de un corte de alimentacin # es mu# Dtil para conservar par%metros semi permanentes" .u utilizacin implica el uso de procedimientos especiales que veremos m%s adelante' pues no es una 6<= sino m%s &ien una 6J= un tanto especial" ,s m%s r%pida de leer que de escri&ir" .i #a *a programado este tipo de memorias 22416 por ejemplo5 #a *a&r% constatado este e4ecto"

3.4.3 La memoria Ram


8a memoria RAM (Random Access Memory) es la que no vamos a dejar de utilizar constantemente" 9odos los datos almacenados aqu( se pierden durante un corte de la alimentacin" 8a memoria 6<= est% organizada en 2 &ancos de memoria para el 16:;4" 8a 6<= est% dividida adem%s en 2 partes" ,n cada uno de los &ancos nos vamos a encontrar /casillas0 especiales llamadas /registros especiales0 o SFR (Special Function Registers) as( como casillas de memoria /li&res0 que usted podr% utilizar a su con$ veniencia" 8os .:6 sirven para con4igurar su PI ' mientras que otros emplazamientos sirven para colocar sus varia&les 2veremos de qu- se trata m%s tarde5" ,n el caso del 16:;4 dispondr% de 64 octetos li&res" 8a organizacin de la 6<= se muestra en la ta&la 4$2 de la pagina 13" Ver% la separacin vertical de los 2 &ancos # a&ajo del todo ver% dos &ancos de 6; octetos de 6<=" ?esgraciadamente' la indicacin mapped in bank 0 le indica que acceder a esos octetos en el &anco B o en el &anco 1 es indi4erente' son lo mismo" Ver% en la parte superior el nom&re de todos los registros especiales en el PIC" Veremos todos' se lo asegu$ ro" ada registro provoca un 4uncionamiento especial del PIC o la puesta en servicio de una 4uncin particular" Ver% que ciertos registros son id-nticos en am&os &ancos 2:.6 por ejemplo5" ,sto signi4ica que acceder a ellos en el &anco B o en el &anco 1 no tiene ninguna di4erencia" ,l &anco B utiliza las direcciones desde la B+BB a la B+7: # el &anco 1 desde la B+;B a la B+::" 8as zonas grises son lugares no utilizados 2ni utiliza&les5" ,l lugar B+BB es un emplazamiento al que no se puede acceder" Para la gran ma#or(a de los registros' cada &it tiene una 4uncin especial" ,n la p%gina 14' ta&la 4$1' encon$ trar% los nom&res de los &its de estos registros"

2B

4. Organizacin de las instrucciones


4.1 Generalidades
Vamos con coraje' esto comienza a ser m%s concreto" Vamos a ec*ar un vistazo al juego de instrucciones de los PIC" .altamos directamente a la p%gina 55 del datas*eet' al cap(tulo Q" N s(' como esta o&ra no es un manual de re4erencia t-cnica sino un aprendizaje' ser% necesario ver los cap(tulos del datas*eet en desorden" ,n esa p%gina' encontrar% un peque)o recuadro en gris que *ace alusin a las antiguas instrucciones que #a no sirven" 1o nos serviremos de ellas' pues" Por el contrario' encontrar% una ta&la Q$1 que nos dice como son codi4icadas las instrucciones en los PIC" <l 4in ve a que corresponden los 14 &its de la memoria de progra$ ma"

4.2 Los tipos de instrucciones


onstatar% que e+isten 4 tipos de instrucciones que pasamos a detallar" ?e todas 4ormas' no tiene por qumemorizar cono est%n organizadas las instrucciones' se trata simplemente de comprender que es lo que pasa"

. 4.2.1 Las instrucciones orientadas a octeto


.on instrucciones que manipulan los datos en 4orma de octetos" ,st%n codi4icadas de la siguiente 4ormaK 6 !i"s #$%$ &$ ins"%'((inK lgico puesto que *a# 35 instrucciones' nos *ar%n 4alta 6 &its para codi4icar todas ellas" 1 !i" )e )es"in* 2d5K B indica que el resultado de la operacin se colocar% en el registro de tra&ajo W 2WorX5' 1 indica que el resultado se colocar% en el operando precisado por los siguientes 7 &its" + !i"s #$%$ (*)i,i($% e& *#e%$n)* 2:ile5K si d vale B 2ver arri&a5' este operando indica a la vez el dato a manipu$ lar e igualmente el entorno donde el resultado ser% almacenado" Primer pro&lema' 7 &its no nos dan acceso a la totalidad de la memoria 6<=' *e aqu( la e+plicacin de la divi$ sin de la 6<= en dos &ancos" >acen 4alta ; &its para acceder a 256 posiciones di4erentes" >ar% 4alta una solucin para recolocar el &it que nos 4alta" E>a dic*o un &it de los registrosF @PravoA Veo que lo *a entendido completamente" .e trata en realidad del &it RP0del registro STATUS" Puede se)alarme que tam&i-n *a# un RP1" ,l 16:;76' por ejemplo' dispone de 4 &ancos' este &it ser% utiliza$ do en otros PIC que veremos en la segunda parte" ?ejaremos 6P1 a B para el 16:;4' con el 4in de poder /portar0 sus programas *acia PIC superiores sin pro&lema"

4.2.2 Las instrucciones orientadas a bits


.on instrucciones que manipulan los datos en 4orma de &its" ?ic*o de otra 4orma' est%n destinadas a modi4i$ car &its precisos en registros especi4icados" ,st%n codi4icadas de la siguiente 4ormaK 4 !i"s #$%$ &$ ins"%'((in 2en el espacio dejado li&re por las instrucciones precedentes5" 3 !i"s #$%$ in)i($% e& n-.e%* )e !i" $ .$ni#'&$% 2&its B a 7 posi&les5' # de nuevoK + !i"s #$%$ in)i($% e& *#e%$n)*/

21

4.2.3 Las instrucciones generales


.on instrucciones que manipulan datos que est%n codi4icados en la misma instruccin directamente" Veremos esto m%s en detalle cuando *a&lemos del direccionamiento" .e codi4ican de la siguiente maneraK 6 &its para codi4icar la instruccin" ; &its para codi4icar el valor concernido 2valor llamado inmediato porque se encuentra inmediatamente en la instruccin" ,l valor puede valer de B a 255"

4.2.4 Los saltos y llamada a subrutinas


.on instrucciones que provocan una rotura en la secuencia de desarrollo del programa" .e codi4ican de la si$ guiente 4ormaK 3 !i"s #$%$ (*)i,i($% &$ ins"%'((in/ 11 !i"s #$%$ (*)i,i($% &$ )i%e((in )e )es"in*/ Podemos #a deducir que los saltos no dan acceso a 2 Ui de memoria de programa 22115" ,sto no supone ningDn pro&lema' el 16:;4 no dispone nada m%s que de 1 Ui de pala&ras de memoria" Para codi4icar una direccin de salto en la memoria de programa de un 16:;4' *ar% 4alta 1B &its 221B L 1B24 L 1 Ui5" 1o olvide que la reglamentacin o4icial quiere que utilicemos el t-rmino /Xilo&inario0 o /Xi&i0' a&reviado en /Ui0 para e+presar 2 a la potencia 1B" ?esgraciadamente parece que poca gente lo utiliza en la pr%ctica"

4.3 Panormica de las instrucciones.


Vo# a mostrarle cmo 4unciona la ta&la Q$2 de la pagina 56" ,sta ta&la le permite' de un simple vistazo' in4or$ marle de la 4orma en que 4unciona cada instruccin" 8a primera columna indica el ne.ni(* # los *#e%$n)*s de cada operacin" 8os nemnicos son #$&$!%$s %e0 se%v$)$s 2por lo que no podr% usarlas nada m%s que para este uso' # no para nom&rar una varia&le' por ejemplo5' que son comprendidas e interpretadas por el #%*1%$.$ )e ens$.!&$2e' llamado Ensamblador " J&serve aqu( la con4usin del lenguaje comDn para el t-rmino /ensam&lador0' que utilizamos a la vez para in$ dicar el programa que permite ensam&lar el cdigo 2programa de ensam&laje5 # el lenguaje utilizado en el editor 2lenguaje ensam&lador5" 9rate de usar los t-rminos correctos' la situacin en in4orm%tica no es a*ora simple para que le a)adamos con4usiones inDtiles" ?ecir /*e programado en ensam&lador0 no quiere decir a&solutamente nada' mismo si el personal le *a entendido" ?e&er(a decir /*e programado en lenguaje en$ sam&lador0" ,l ensam&lador es el programa que ensam&la su programa escrito en lenguaje ensam&lador" Va a encontrar en este sitio las instrucciones propiamente dic*as que va a poder codi4icar en su programa" 8a sinta+is de&e ser la siguiente para el ensam&lador MPASM 2suministrado con el entorno de desarrollo in$ tegrado MPLAB5' que utilizaremos en la pr+ima leccin"

22

9endremos' en orden' para cada l(nea de cdigoK ,tiqueta 2opcional o pudiendo encontrarse solo en una l(nea5 ,spacio2s5 o ta&ulacin2es5 1emnico 2en ma#Dsculas o minDsculas5 ,spacio2s5 o ta&ulacin2es5 Jperando o valor oma de separacin eventualmente Pit de destino W o : o eventualmente nDmero de &it de B a 7 si es necesario ,spacio2s5 o ta&ulacin2es5 2opcional5 omentario precedido de punto # coma 2opcional5

J&serve que el nemnico no puede encontrarse en la primera columna' # que todo lo que sigue a un punto # coma es ignorado por el ensam&lador 2ser% la zona de comentarios5" 8a primera columna es la zona reservada para las etiquetas 2lugares de llamada5" ?ispone de la opcin de insertar uno o m%s espacios o ta&ulaciones a cada lado de la coma" < t(tulo de ejemplo' dos l(neas validasK
Ma_ligne ; Esto es una etiqueta MOVF STATUS,W ; carga el registro STATUS en el registro de trabajo

Para terminar con nuestra ta&laK 8a segunda columna de nuestra ta&la nos da una &reve descripcin de la instruccin" 8a tercera columna nos da el nDmero de ciclos necesarios para ejecutar la instruccin" J&serve que todas las instrucciones necesitan 1 ciclo' e+cepto las instrucciones de salto que necesitan 2 2incluso las operaciones de test con salto' puesto que el resultado del test genera un saltoK instrucciones anotadas como 12255" 8a 4C columna nos da lo que llamamos el OPCODE' es decir' la pala&ra en &inario que MPASM va a gene$ rar por usted a partir del nemnico" 1o lo *ar% nunca pero sepa que podr(a programar directamente el PIC sin pasar por el ensam&lador' constru#endo directamente un 4ic*ero "*e+ con los valores o&tenidos en esta columna" ,n ese caso' de&er(a comprender # calcular los saltos" ,sto es lo que #o *ice en mis comienzos so&re un pro$ cesador 65B2 dado que no dispon(a de un ensam&lador" Podr(amos utilizar esta t-cnica para construir pro$ grama auto modi4ica&les de&ido a la severa limitacin de tama)o de memoria" ,stas t-cnicas pertenecen a la ,dad =edia de la in4orm%tica" Puede correlacionar estos valores con los de la ta&la Q$1 a titulo educativo' si no' olv(dese de esta columna"

23

8a 5C columna' por el contrario' es primordial # nos da los indicadores de estado 2.tatus :lag5 a4ectados 2mo$ di4icados5 una vez se ejecute la instruccin" Veremos estos indicadores en detalle puesto que constitu#en una llave esencial en la programacin" ?e *ec*o' estos indicadores de estado son los medios de que disponemos para tomar una decisin en un programa 2condiciones5" 8a Dltima columna nos env(a a las notas a pie de p%gina" 8a nota 1 es mu# importante' *ace alusin al m-todo de /lecturaRmodi4icacinRescritura0 propio de los puertos de entradaRsalida 2IRJ5" Volveremos a ello en el momento de tratar los PORTS" 8a nota 2 indica que una modi4icacin de un timer repone a cero el valor en su pre divisor" 8o trataremos cuando a&ordemos el timer B" 8a tercera nota indica que si nos servimos de la instruccin para modi4icar el contador del programa 2P 5' que apunta a la siguiente instruccin a ser ejecutada' *a&r% un ciclo suplementario" ,s lgico puesto que esto equivale a un salto" Veremos que esta t-cnica es pr%ctica para ir a &uscar valores en una ta&la construida en la memoria de programa"

4.4 Los indicadores de estado


,stos indicadores son indispensa&les para la programacin" ,s a&solutamente necesario *a&er comprendido su 4uncionamiento 2al menos para \ # 5" 8ea lo que sigue con muc*a atencin" 9odos los indicadores son &its del registro STATUS" Vea la ta&la en la pagina 15" <&ordaremos aqu( los 4lags Z # C" 8os otros los trataremos en el estudio del registro .9<9H. 2capi$ tulo ;"2"35

4.4.1 El indicador de estado Z


,s el indicador de \ero # 4unciona de la siguiente maneraK Si e& %es'&"$)* )e 'n$ ins"%'((in 3'e $,e("$ $ es"e !i" )$ 'n %es'&"$)* i1'$& $ 45 e& ,&$1 Z se #*si(i*n$ en 1/ Por lo tanto' no se complique la vida" ?ecir que Z61 corresponde a decir que el %es'&"$)* 6 4" 8a ta&la Q$2 en la columna 5 indica las instrucciones que modi4ican \" Por lo tanto' si realiza una suma con ADDWF # el resultado o&tenido es B' el &it \ se pondr% a 1" .i el resul$ tado es ALB 2di4erente de B5' el &it \ valdr% B" ,n los dos casos ser% modi4icado" Por el contrario' si almacena un valor con la instruccin MOVWF' el &it \ no ser% modi4icado incluso si el va$ lor almacenado es B" ,stas consideraciones son validas para el resto de los 4lags por lo que no volver- a ello"

4.4.2 El indicador de estado C


,s el indicador para Carry 2acarreo5" Si e& %es'&"$)* )e 'n$ *#e%$(in en"%$7$ )es!*%)$.ien"*5 e& !i" se #*0 si(i*n$ $ 1" .e trata' de *ec*o' del QS &it de una operacin" Por ejemploK .i sumamos

B11111110 (254) + B00000011 (3)

J&tendremos B100000001, (257)' es decir Q &its"

24

omo los registros del PIC solo tienen ; &its' o&tendremos B00000001 (1) # el &it C se posicionar% a 1 2de *ec*o el QS &it5" ,l resultado 4inal es 256 + 1 = 257" J&serve que si *a a)adido B11111110 a B00000010 *a&r(a o&tenido B00000000" ,n este caso tendr(a C = 1 # Z = 1' que signi4ica resultado nulo pero con acarreo 2por lo que resultado L 2565" <tencin' este &it sirve tam&i-n de borrow 2pr-stamo5 cuando realiza una sustraccin" ,n este caso vale B si intenta sustraer un nDmero m%s grande que le numero de partida' indicando un resultado negativo" ,n caso contrario valdr% 1 indicando un resultado positivo" 4unciona de manera inversa en el caso de sustracciones" ,studiaremos en detalle estas instrucciones" Veremos los otros &its del registro en la continuacin de esta o&ra' en el momento en que lo necesitemos"

25

5. Los comienzos con MPLAB


Vamos a arrancar la gran aventura con nuestro primer # modesto programa" ,+plicar- las instrucciones # los registros en tanto en cuanto lo va#amos necesitando" < partir de la revisin 13 del curso' tra&ajamos con MPLAB 6.x que es la versin que sali despu-s de la 5.x, utilizada en el curso *asta la revisin 12 del mismo"

5.1 Preparacin para la utilizacin


8a primera cosa a realizar es ir a &uscar la versin actual de MPLAB 6.60 en el sitio de Microchip: http://www.Microchip.com en la seccin archives " Puede utilizar una versin m%s reciente 2la ;"+5' pero ser% a su cargo el lidiar con las di4erencias" 8e aconsejo arrancar con la versin 6"6 # pasar posteriormente a una versin m%s moderna una vez terminado el aprendizaje' lo que le evitar% di4icultades a)adidas" <tencinK MPLAB-X es una versin espec(4ica de MPLAB que tiene &astantes di4erencias con las versiones cl%sicas" ,sta versin presenta la ventaja de ser compati&le con otros sistemas operativos 2J.5 so&re todo 8i$ nu+" ,n este curso' las copias de pantalla est%n realizadas so&re MPLAB 6.3 pero las di4erencias de&er(an ser m(nimas con respecto a la versin 6"6 2m%s esta&le5" .i utiliza una versin m%s reciente de # esta le pregunta qu- tipo de cdigo quiere producir' respndale siempre ABSOLUTE " ?escomprima el 4ic*ero # proceda a su instalacin" ?espu-s de la instalacin' tendr% &astantes ventanas e+$ plicativas concernientes a di4erentes Dtiles de Microchip' como el de&ugger # el simulador" omo presumo que no dispone aDn de esos Dtiles 2todav(a5' cierre todas las ventanas al 4inal de la instalacin" Personalmente' no me gusta dejar todos los datos en los su&directorios de instalacin de mis programas' en la instalacin principal" .i usted es como #o' cree un directorio en un sitio que le resulte conveniente # ll%me$ lo' por ejemplo' ?ataPI " opie all( el 4ic*ero m16F84.asm suministrado con el curso" ,s un 4ic*ero que *e creado con la 4inalidad de poder arrancar inmediatamente con un nuevo programa" 8e *e llamado m16f84.asm con una m por maqueta " .i no tiene ese 4ic*ero' es que *a cargado el curso desde un sitio inadecuado' va#a a mi 3e&K www.bigonoff.org para cargar la versin correcta # completa 2gratuitamente5" .i no desea crear un nuevo directorio' copie el 4ic*ero en el directorio de instalacinK por de4ecto c:\program files\MPLAB IDE" 8e recuerdo que guardar todos los datos en la particin que contiene todos los programas es una mu# mala idea' so&re todo en caso de &loqueo de su sistema operativo 2la restauracin &orrar(a sus datos5" Para cada nuevo programa que va#a a crear' *aga una copia de m16F84.asm" Para nuestro primer programa copieRpegue ese 4ic*ero # renom&re la copia o&tenida como Essai1.asm"

5.2 Creacin de nuestro primer proyecto


<*ora #a puede lanzar MPLAB IDE a partir del menD de arranque o del icono en su escritorio' si acept tenerlo en la instalacin" ?espu-s de unos instantes' se encontrar% con una pantalla vac(a con menD # &arra de Dtiles" .i tiene ventanas a&iertas en el escritorio de MPLAB 6' ci-rrelas todas' as( sa&r% como a&rirlas # todo el mundo arrancar% con la misma con4iguracin"

MPLAB es un logicial que est% construido en &ase a la nocin de pro#ectos" Hn pro#ecto permite memori$ zar todo el entorno de tra&ajo necesario para la construccin de un]]] pro#ecto" 8e permitir% a&rir todo el entorno de tra&ajo cuando lo seleccione"
26

MPLAB 6 dispone de un wizard 2asistente5 para la creacin de pro#ectos' lo que le permitir% crearlos autom%ticamente" ?e todas 4ormas' con el 4in de permitirle localizar las principales opciones de un pro#ecto' no me servir- de -l en este curso" .i a continuacin usted decide *acerlo' se selecciona con la a#uda del menD men project->wizard "
Va#a al menD Project # seleccione new " 8a ventana que se a&re le permite introducir el nom&re del pro#ecto # el directorio de tra&aja del mismo" Para el directorio' dispone del &otn browser que le permite apuntar al &uen directorio sin riesgo de equivocarse" ,ntre essai1 como nom&re de su nuevo pro#ecto # seleccione el directorio en el que coloc su 4ic*ero /maqueta0 # su 4ic*ero essai1.asm" >e nom&rado el 4ic*ero asm de manera id-ntica al pro#ecto' pero esto no es o&ligatorio"

Hna vez presionado el &otn ^JU_' una nueva ventana aparecer% en el rincn superior izquierdo del es$ critorio del =P8<P! I?,"

27

,n esta ventana' usted ve el nom&re del pro#ecto as( como los 4ic*eros asociados a -l" Por el momento no tiene ninguno' es normal" Vamos a comenzar a precisar los par%metros importantes de nuestro pro#ecto' empezando por el tipo de PIC que vamos a utilizar" .eleccione el menD configure->select device ' aparecer% una ventana que le propondr% la eleccin de un PIC" J&serve que' por de4ecto' le propone un de la 4amilia 1;:' la promocin de nuevos productos o&liga]] .eleccione el PIC16F84 2si elige el PIC16F84A' modi4ique todas las re4eren$ cias al en todos los 4ic*eros 4uenteK de todas 4ormas es inDtil5"

8a ventana nos muestra' con la a#uda de leds verdes # rojos' cuales son los Dtiles soportados por el PIC se$ leccionado" Hsted ver% que el simulador integrado (MPLAB SIM) 4unciona con su PIC' # as( para los otros Dtiles de desarrollo disponi&les en Microchip" Hna vez pulsado <OK> la ventana se cierra"

2;

Vamos a*ora a precisar qu- lenguaje vamos a utilizar' sa&iendo que nosotros tra&ajamos en lenguaje ensam$ &lador' pero que di4erente ensam&ladoresRcompiladores son propuestos por Microchip y por otras compaas" .eleccione el menD project -> Select langage toolsuite " ,n la ventana que se a&rir% seleccione en el menD desplega&leK Microchip MPASM toolsuite " MPASM es el ensam&lador por de4ecto de Microchip"

,n las ventanas in4eriores puede ver el nom&re del ejecuta&le utilizado por MPASM' no se preocupe" Pulse <OK> para cerrar la ventana" 1os *ace 4alta a*ora indicar a MPASM cu%l es nuestro o nuestros 4ic*ero2s5 4uente" ,so se *ace en la ven$ tana que se qued a&ierta en la esquina superior izquierda" Para a)adir un 4ic*ero 4uente es mu# simpleK cli$ quee con el &otn derec*o so&re source files ' despu-s seleccione Add " Hna vez seleccionado el 4i$ c*ero' el nom&re de este aparecer% en el %r&ol de 4ic*eros" J&serve que MPLAB apunta por de4ecto a su directorio de tra&ajo' anteriormente elegido"

2Q

<qu( es importante comprender que el 4ic*ero 4uente elegido ser% el que se ensam&le 2o compile si utiliza otro lenguaje5" ?ic*o de otra 4orma' si en ese 4ic*ero 4igura una instruccin ` include a que inclu#e otro 4ic*e$ ro' usted no de&er% seleccionarlo e+pl(citamente' ser% a)adido al pro#ecto en el momento del ensam&laje" Por el contrario' si desea ensam&lar dos 4ic*eros simult%neamente' # su primer 4ic*ero no *ace re4erencia al segundo' de&er% a)adir ese 4ic*ero al %r&ol de 4ic*eros" 9odos nuestros pro#ectos solo necesitar%n a)adir un solo 4ic*ero" .i sus pro#ectos necesitan a)adir uno o m%s 4ic*eros suplementarios' la directiva ` include a de&er% ser a)adida en el 4ic*ero 4uente con el 4in de que el ensam&lador integre de manera autom%tica esos 4ic*eros" 1o necesita nada m%s' los otros elementos del %r&ol no son necesarios para un pro#ecto en lenguaje ensam$ &lador del tipo de los que vamos a *a&lar" 1os queda un elemento importante por precisar' es el sistema de numeracin utilizado por de4ecto" .eleccio$ ne el menDK ` P%*2e(" 08 !'i&) *#"i*ns 08 #%*2e(" a" .e a&rir% una ventana" .eleccione la pesta)a ` MPASM $sse.!&e% a"

3B

omo *emos decidido tra&ajar en *e+adecimal &ajo la 4orma B+' # el &inario &ajo la 4orma POO" 9odo nDmero sin pre4ijo ser% considerado decimal" ,lija la opcin ` De(i.$& a" 1o toque las otras opciones' las utilizar% po$ si&lemente cuando llegue a ser un /pro0 # quiera adaptar ciertos par%metros" ,n su momento le resultar% m%s claro" on la 4inalidad de evitar cualquier olvido' le aconsejo poner un pre4ijo delante de cualquier nDmero que utili$ ce' esto le evitar% no pocos sinsa&ores" Htilice' por ejemplo' la siguiente sinta+isK

B+1B' >O1BO' o 1B*K para notaciones *e+adecimales" POBBB1BBBBOK para notaciones &inarias" ?O16 bK para notaciones decimales" "16K otra notacin decimal 2no olvide el `"a5"

Hn numero escrito sin pre4ijo ser% interpretado segDn el par%metro que *emos descrito anteriormente # pue$ de resultar un pro&lema si despu-s integra este 4ic*ero en otro pro#ecto o' simplemente' # le env(a ese 4ic*e$ ro a otra persona sin precisarle cual es la notacin por de4ecto" .i a pesar de todo decide utilizar un pre4ijo por de4ecto' no olvide se)alarlo en los 4ic*eros 4uente con la a#u$ da de la directiva /radi+0' como por ejemploK

radix dec ; se trabaja en decimal por defecto


,sta directiva suplanta la eleccin realizada en =P8<P #' por lo tanto' el 4ic*ero 4uncionar% correctamente sea la que sea la con4iguracin de =P8<P # de todos aquellos que va#an a ensam&lar el 4ic*ero" ,sta directiva no se puede colocar en la primera columna' ponga un espacio o una ta&ulacin antes de la directiva ` radi+ a" <*ora =P<.=! est% listo para ensam&lar el programa" Hsted me dir%K @1o *a# nada en la pantallaA ,4ectivamente =P<.=! no se preocupa de los 4ic*eros que *a# en la pantalla' solo cuentan los 4ic*eros que *a# en el %r&ol de 4ic*eros # los incluidos a partir de ellos" Puede tener todos los 4ic*eros que quiera en la pantalla' o no tener ninguno" < =P8<P! le da lo mismo" Por el contrario' todos los 4ic*eros a&iertos desde la salvaguardia del pro#ecto ser%n rea&iertos autom%ticamente en la pr+ima apertura del pro#ecto' aunque no sirvan para nada" ,sta propiedad es mu# pr%ctica para reali$ zar copiadosRpegados a partir de otro 4ic*ero o para ver que *izo otra persona mientras programamos" Vamos a mostrar nuestro 4ic*ero 4uente para ver que contiene" ,l m-todo m%s simple para *acerlo es *acer do&le clic so&re el nom&re en el %r&ol de la ventana essai1"mc3" >%galo" >e aqu( su 4ic*ero de partida a&ier$ to" Pngale el tama)o adecuado *aci-ndole ocupar la mitad izquierda de la pantalla si necesita sitio 2no nece$ sitar% la ventana de pro#ecto por lo que puede ocultarla o reducirla5" Para a&rir un 4ic*ero que no est% incluido en el %r&ol' utilice el menD ` ,i&e08*#en a o el icono de apertura en la &arra de Dtiles" .i quiere que sus pantallas tengan mejor apariencia' cam&ie las pol(ticas del editor" Para esto' seleccione ` E)i" 08 #%*#e%"ies a' despu-s la pesta)a ` "e9" a" 8uego pulse el &otn que le permitir% elegir la pol(tica de caracteresK ` C*'%ie% Ne: a de estilo ` S"$n)$%) a e imponer un tama)o ` ; a" Para los que les interese' #o tra&ajo con un monitor de 220 # mi resolucin es de 16;B+1B5B' esto le indica las proporciones" Veri4ique igualmente en la pesta)a que la longitud est% 4ijada a 4 2tama)o en =P8<P! _7"55" =odi4(quelo segDn necesidad"

31

<*ora su 4ic*ero asm est% en la pantalla" J&serven aquellos que vienen de =P8<P! 5' que la gestin de las ta&ulaciones es di4erente en =P8<P! 5 # en =P8<P! 6' lo que signi4ica que la puesta a punto de las p%ginas de un 4ic*ero escrito en =P8<P! 5 no se respetar%n en =P8<P! 6" < aquellos que dispongan de la versin precedente les interesa usar los nuevos 4ic*eros"

Para aquellos que viene de MPLAB 5' ver%n que MPLAB 6 es m%s simple de manipular' lo que ser% todav(a m%s evidente cuando utilicemos el simulador" Vamos a e+aminar este 4ic*ero m%s detenidamente"

32

6. Organizacin de un fichero .asm


Para empezar' clique en cualquier sitio del interior de ese 4ic*ero" Hsted se encuentra en el interior de un simple 4ic*ero de te+to con sinta+is coloreada" ,n la esquina in4erior izquierda ver% un nDmero de l(nea # de columna" ,s la posicin actual de su cursor" =e servir- de esa posicin para guiarle a trav-s del 4ic*e$ ro" 1o a)ada por lo tanto ninguna l(nea' por el momento' para que se conserve la correspondencia con el presente te+to" .i no es capaz de ver el numero de l(nea va#a al menD < e)i" 08 #%*#e%"ies = # marque < &ine n'.!e%s = en el su&menD < e)i"*% = .i no consigue e4ectuar modi4icaciones en su 4ic*ero # el teclado parece inactivo 2ocurrido con MPLA> ?/95 es que usted *a utilizado un car%cter e+tendido en el nom&re del 4ic*ero" <l contrario que MPLA> ?5 MPLA> 6 a*ora gestiona todos los caracteres e+tendidos para los 4ic*eros # para los dosieres"

6.1 Los comentarios


?esde la l(nea 1 a la 31 usted ve un gran cuadro" .i mira con atencin vera que el primer car%cter de cada l(nea es el s(m&olo ` c a" 9odo lo que est% a continuacin est% considerado como zona de comentarios" Hs$ ted puede poner a*( lo que usted quiera" Procure coger el *%&ito de comentar siempre sus programas" ,st- seguro de que dentro de 6 meses no se acordar% en a&soluto de que es lo que pretend(a *acer" .er% entonces cuando los comentarios le ser%n de muc*(sima utilidad si decide modi4icar el programa" N omito los casos en que' como #o' usted distri&u#e sus 4uentes o tra&aja en una empresa donde otros de&er%n releerlos" 6ellenemos el cuadro con las di4erentes re4erencias" <djunto a esta leccin el 4ic*ero < ess$i1/$s. = tal como estar% al 4inal de la misma"

6.2 Las directivas


,n la l(nea 34 encontramos una directiva destinada al MPASM para indicarle que tipo de procesador se utiliza en este programa" 8as directivas no 4orman parte del programa' no son traducidas a OPCODES' solo sirven para indicarle al ensam&lador de qu- manera tiene que tra&ajar" .on comandos destinados e+clusivamente al ensam&la$ dor" Por el contrario' las instrucciones se traducir%n en JP J?,. # ser%n cargados en el PIC" ,s imperativo *acer correctamente la distincin" 8a l(nea 36 contiene una directiva de la que #a *emos *a&lado' que le indica a =P<.= que cada vez que omitamos un pre4ijo para un nDmero' este nDmero lo tiene que considerar como representacin decimal"

6.3 Los ficheros include a


8a l(nea 35 le indica al ensam&lador' a trav-s de la directiva #include , que en este preciso punto de&e cargar el contenido del 4ic*ero P16F84.inc 2=P<.= e4ectDa un simple copiar # pegar a su copia de tra&a$ jo interno5" EGu- contiene este 4ic*eroF .implemente los valores de todas las constantes que vamos a uti$ lizar" Para ver que contiene va#a al menD file ->Open , elija all source files en el cuadro inferior y abra p16F84.inc del repertorio.

C:\Program Files\MPLAB IDE\MCHIP_Tools para MPLAB 6 y C:\Program Files\Microchip\MPASM Suite para MPLAB 7
33

Hna vez pasada la zona de comentarios' ver% unas l(neas del estiloK
FSR EQU H'04'

,sta l(nea' inclu#endo la directiva EQU signi4ica simplemente que :.6 es igual a B+B4" ?ic*o de otra manera' siempre que utilice la pala&ra :.6 en una instruccin' =P<.= reemplazar% simplemente :.6 por >OB4O 2B+B45" .iendo B4 simplemente la direccin del registro :.6 en la memoria 6<= del PI " >OB4O es otro m-todo autorizado para e+presar un nDmero en *e+adecimal' as( como *B4" <dvierta que el pre4ijo siempre est% precisado' puesto que de otra 4orma =icroc*ip no sa&r(a que sistema de numeracin por de4ecto est% usted utilizando" .i usted coge la ta&la 4$2 de la pagina 2135' constatar% que este es el caso" ,ste 4ic*ero est% destinado principalmente a evitar que usted tenga que memorizar todas las direcciones" Hn nom&re es muc*o m%s 4%cil de utilizar # de memorizar que una direccin" ierre a*ora el 4ic*ero p16:;4"inc para no ati&orrar la ventana de tra&ajo"

6.4 La directiva _CONFIG


8a l(nea siguiente comienza por __CONFIG " ,sta l(nea contiene los 4amosos @,'si!&esA' por utilizar una e+presin popular' que 4ijan el 4uncionamiento del PIC" 8os valores que est%n aqu( escritos se integraran en el 4ic*ero .hex para se)alar al programador los valores a codi4icar en las direcciones espec(4icas del PIC" Posteriormente volveremos al este tema" .epa que si un 4ic*ero .hex *a sido creado por un programador atento que *a utilizado esta directiva' usted no tendr% ninguna necesidad de de4inir estos par%metros en el momento de la programacin" ,l lo$ gicial del programador ir% normalmente a &uscar estos valores en el 4ic*ero mismo" ?esgraciadamente aDn queda un nDmero de personas que creen que esta directiva as( como los comen$ tarios # otras 4acilidades est%n reservados a los principiantes # no se utilizan normalmente" @Yran errorA 6eci&o regularmente correos de personas que estiman este procedimiento inDtil # que seguidamente in$ curren en errores" .i usted no utiliza la directiva __CONFIG estar% condenado a indicar e+pl(cita$ mente a cada utilizador de sus 4ic*eros .hex de qu- 4orma de&en con4igurar esos &its a nivel de su programador de PI " N usted mismo de&er% recordarlo cada vez que programe su 4ic*ero" 6econzcame que como m-todo es un poco /&%r&aro0" >e colocado en los 4ic*eros todos los valores posi&les de estos par%metros junto con su e+plicacin co$ rrespondiente" ,s su4iciente con reemplazar un valor con el deseado" Por ejemplo' para activar el Code Protect 2proteccin de lectura5 reemplace simplemente la l(neaK
__CONFIG _CP_OFF & _WDT_ON & _PWRTE_ON & _HS_OSC

por
__CONFIG _CP_ON & _WDT_ON & _PWRTE_ON & _HS_OSC

>%galo" 1ote que los di4erentes valores est%n unidos por el s(m&olo & (AND) e+plicado en la leccin so&re los sistemas de numeracin" :unciona pues poniendo los &its a /B0" Preste atencin a precisar todos los valores' incluso aquellos que no va#a a utilizar" 8os valores correspondientes se encuentran de nuevo en el 4ic*ero P16F84.INC . 1o *a# nada de magia' todo se e+plica re4le+ionando un poco so&re ello" 34

6.5 Las asignaciones


,n las l(neas 5; # 63 encontrar% las asignaciones personales que 4uncionan &ajo el mismo principio que el 4ic*ero .inc " EPara qu- sirveF ,s para 4acilitar el mantenimiento del programa" ,s muc*o m%s 4%cil recordar en su pro$ grama el valor MASQUE que manipular el valor B+5P" ,n el modo de tra&ajo' la 4acilidad para man$ tener una aplicacin es una de las prioridades principales de un pro#ecto por la simple razn que este mantenimiento tiene un coste" 8as asignaciones se comportan como simples sustituciones de te+to" ,n el momento de ensam&lar' cada vez que el ensam&lador se encuentra una asignacin' la reemplazara autom%ticamente por su valor" Jtra gran ventaja es que si usted cam&ia el valor de una asignacin' este cam&io ser% e4ectivo para todo el programa" Hsted no se arriesga a olvidarse de algDn valor a cam&iar por el camino" 8e aconsejo vivamente a utilizar la asignacin as( como los otros m-todos que veremos m%s adelante" 8a sinta+is es simple puesto que se trata de EQU 2igual a5" ,l s(m&olo 4unciona = de la misma manera" ,jemplo de asignacinK mivalor EQU 0x05

6.6 Las definiciones


?escendamos un poco m%s" ?escu&rimos en las l(neas de la 73 a la 75 la utilizacin de la directiva #DEFINE " 8as de4iniciones 4uncionan como las asignaciones' salvo que reservamos las asignaciones para los valores # las de4iniciones para sustituir un te+to m%s complejo" Por ejemplo' podr(amos utilizar un PJ69 seguido de un nDmero de &it' o &ien una instruccin seguida de sus par%metros" Hna de4inicin est% construida de la siguiente maneraK la directiva #DEFINE seguida del nom&re que deseamos utilizar # 4inalmente la cadena a sustituir" Por ejemploK
#DEFINE mibit PORTA,1

8a utilizacin de esta de4inicin se realiza utilizando simplemente su nom&re en el programa" Por ejem$ ploK
bsf monbit ; poner mibit a 1

.er% traducido por =P8<P! como K


bsf PORTA,1 ; poner mibit a 1

6.7 Los macros


=%s a&ajo' en las l(neas de la ;3 a la ;6 encontramos un macro"
LIREIN macro comf PORTB,0 andlw 1 endm

8a macro se compone de un nom&re escrito en la primera columna seguido de la directiva macro " ,l 4inal de la macro est% de4inido por la directiva endm 2end o4 macro5" 35

Na *a&remos deducido que la 4inalidad de una macro es reemplazar un &loque de cdigo que utilizamos a menudo" ,n nuestro ejemplo' cada vez que se encuentre la macro 8I6,I1 esta ser% reemplazada' en el momento del ensam&laje' por dos l(neasK
comf PORTB , 0 andlw 1

8a macro simpli4ica la escritura pero no reduce el tama)o del 4ic*ero "*e+ o&tenido puesto que las dos l(neas ser%n e4ectivamente escritas en el PIC" <dvi-rtase que se pueden utilizar macros m%s complejas con paso de par%metros" ,s uno de los intereses principales de las macros" 1o entraremos en estas 4uncionalidades particulares por a*ora" <dvierta as( mismo que dispone de una a#uda en el menD help->MPASM Help " ,n e4ecto la a#uda de MPLAB concierne a la utilizacin del logicial" 8as a#udas concernientes al lenguaje est%n en MPASM dado que es un lenguaje que utiliza MPLAB"

6.8 La zona des variables


9oda zona de4inida por el utilizador como declarada para varia&les comienza por la directiva CBLOCK seguida por la direccin de comienzo de la zona" Para situar las varia&les' que son emplazamientos de memoria a las cuales les *emos asignado un nom$ &re' de&emos consultar de nuevo la ta&la 4$2" Vemos que la zona de RAM de li&re utilizacin comienza en la direccin B+B " 1uestra zona de varia&les contendr% pues la directivaK
CBLOCK 0x00C ; comienzo de la zona de variables

Inmediatamente podr% utilizar 6; emplazamientos de memoria' que responder%n a la sinta+is siguienteK nom&re de la varia&le seguido del signo : 2los espacios son ignorados5 seguido del tama)o utilizado" Por ejemploK
w_temp : 1 ; Zona de 1 byte

?e&er% precisar el 4inal de la zona en curso con la a#uda de la directiva ENDCK


ENDC ; Fin de la zona

6.9 Las etiquetas


Hsted se encontrar% en el programa en la primera columna lo que llamamos etiquetas" .on nom&res que escogemos # que no son otra cosa que posiciones para MPASM' estas posiciones se podr%n utilizar di$ rectamente en el cdigo 4uente" ,l ensam&lador las sustituir% por la direccin correcta del programa en las que est-n posicionadas" ,sto nos evitar% tener que calcular constantemente cu%l es la direccin de cada punto concreto del programa" Veremos m%s adelante el principio de 4uncionamiento"

36

6.10 La directiva ORG 8a directiva ORB' seguida de la direccin' precisa en 3'C )i%e((in de la memoria del PIC ser% co$ locada la siguiente instruccin" ,+cepto por esta situacin' cada instruccin se emplazar% en la direc$ cin siguiente a la instruccin precedente" >a# dos cosas importantes a tener en cuentaK ?espu-s de un reset o de una puesta en tensin' e& PIC $%%$n($ sie.#%e )es)e &$ )i%e((in 4944" ,l comienzo de su programa se de&e situar siempre all(" 8a )i%e((in 4944 es &$ )i%e((in '"i&iD$)$ #*% &$s in"e%%'#(i*nes 2veremos el principio m%s tarde5" 1o queda' pues' muc*o espacio para colocar el programa 2entre la B+BB # la B+B35" ,mpezaremos pues por un salto *asta el lugar donde est- colocado el programa principal donde tendremos m%s espacio" Veamos cmo 4uncionaK
org 0x000 ; Direccion de arranque despues de un reset goto init ; Direccion 0 : inicializar

8a primera l(nea es nuestra directiva J6Y que indica que la l(nea siguiente se colocar% en la )i%e((in 4944" 8a segunda l(nea es una instruccin e+plicada en la p%gina 2625 que le indica al PIC que el programa de$ &e saltar a la direccin < ini" = para seguir con la ejecucin del programa" < ini" = es pues una etiqueta" ?espu-s de un reset' el PIC ejecuta la instruccin goto init que se encuentra en la direccin B+BB' se$ guido por la ejecucin de la instruccin que se encuentra en la direccin ini" m%s a&ajo en el programa 2justo de&ajo de la etiqueta init5"

6.11 La directiva END y el final de un programa ,sta directiva precisa el punto en el que aca&ar% el ensam&lado de su programa" ,s o&ligatoria en cualquier programa # su omisin generar% un error que le se)alar% que se *a llegado al 4inal del 4i$ c*ero 2,nd J4 :ile5 sin *a&er encontrado la directiva ,1?" 9odas las instrucciones que se encuentren despu-s de la directiva ,1? ser%n simplemente ignoradas" 1o se trata de una instruccin destinada a parar el 4uncionamiento del PI sino de una directiva des$ tinada a parar el 4uncionamiento de =P<.=! en este punto" ?ic*o de 4orma e+pl(citaK END no significa que el PIC se vaya a parar en este punto/ Partiendo de esto' si escri&iese un programa que terminase de la siguiente maneraK
Instruccion x Instruccion y END

37

N nos imagin%semos que Instruccin + se encuentra en la direccin B+5B 2por ejemplo5' usted se en$ contrar(a esto en la memoria 4las*K Direccion 0x50 : Direccion 0x51 : Direccion 0x52 : Direccion: 0x53: instruccion x ensamblada instruccion y ensamblada 0x3FFF (memoria flash vacia = 14 bits a 1) 0x3FFF (idem)

1inguna se)al de vuestro ,1? puesto que se trata de una directiva" ?ic*o de otra 4orma' su pic' una vez que se ejecute la instruccin #' va a ejecutar la instruccin correspondiente al cdigo *e+adeci$ mal B+3::" N esta instruccin e+iste' se trata de ` addl3 B+:: a" ?e *ec*o su pic va a ejecutar de 4orma tonta instrucciones ` addl3 B+:: a *asta llegar al 4inal de la memoria de programa" 1i tan si$ quiera cuando llegue al 4inal se parar%' simplemente incrementar% el contador de programa *asta que este des&orde # vuelva a empezar por la direccin B+BB" .u programa se volver% a ejecutar una vez m%s 2eventualmente con los registros modi4icados por la pasada precedente' puesto que no se trata de un reset5" .i usted quiere para el programa despu-s de una sola ejecucin' *ar% 4alta &loquearlo en un &ucle" .i no quiere dejar el pic en vigilanciaK
bucle goto bucle

J &ien dej%ndolo en vigilanciaK


bucle sleep goto bucle

,l &ucle es a*ora una seguridad en caso de despertar el pic de&ido a un par%sito o al des&ordamiento del 3atc*gog" Por lo tanto' no olvide nunca que ,1? no quiere decir parar" =e sa&e mal ser tan pesado en este punto' pero continDo encontrando programas enviados por in$ ternautas' e+tra)ados por un comportamiento curioso de los mismos ]" no parando nunca que cre$ (an que el pic se parar(a despu-s de la directiva ,1?"

3;

7. Realizacin de un programa
7.1 Creacin de nuestro primer programa <ntes de lanzar nuestro primer programa vamos a realizar algunas modi4icaciones al 4ic*ero essai1.asm con la 4inalidad de conservar lo que nos interesa" Primero va#a a la l(nea 1B5 2el nDmero puede ser di4erente en su 4ic*ero5 # reemplace la l(nea goto init por goto start. 1o *aga 4altas de ortogra4(a"
goto start ; Direccion 0: arrancar

?escienda a la l(nea 226' encontrar% nuestra etiqueta' que es a la que nuestro programa saltar%" Po$ rre la l(nea
clrwdt ; borrar watch dog

Veremos el signi4icado de todo esto m%s adelante" .e trata de una instruccin que #a *emos visto' la instruccin"
goto start ; bucle

8a *oja de datos 2el datas*eet5 en la pagina 62 nos ense)a que la instruccin goto viene seguida inmediatamente de un valor 2es decir de un valor en 4orma de nDmero5 codi4icado en 11 &its" 6e$ cuerde que el programa puede ser de *asta 1BBB pala&ras 2XW5 luego con 11 &its 2211L2B4;5 pode$ mos saltar a no importa qu- posicin del programa" ,l valor puede a &uen seguro ser reemplazado por una etiqueta # MPASM se encargar% de calcular por usted su correcto emplazamiento" 8a *oja de datos le indica tam&i-n que se trata de un salto in$ condicional' es decir' se realizar% siempre' sin ninguna condicin" .e indica que un salto requiere 2 ci$ clos" >agamos sitio de&ajo de la etiqueta start # a)adamos la siguiente l(nea 2atencin' jam%s en la pri$ mera columna5 K
clrf mavariable ; borrar mavariable

CLRF es una instruccin detallada en el cap(tulo dedicado a las instrucciones" Guiere decir que el emplazamiento de memoria indicado detr%s de la instruccin 2o una varia&le5 se &orrar%" ,l &it Z ser% puesto a 1 B dependiendo del resultado de la operacin' como #a *a sido e+plicado" omo el cometido de la operacin es poner la varia&le a B' el &it Z valdr% siempre 1 despu-s de esta instruccin" J&serve que el emplazamiento de memoria se puede situar desde B a 127 2B+7:5" ,s lgico" .i consulta la ta&la 4$2 ver% que la 6<= se detiene en la posicin 127 para cada uno de los 2 &ancos"

3Q

Ponga a continuacin una etiqueta 2primera columna5 a la que llamar%" ?e&ajo de esta etiqueta a)a$ da la instruccinK
boucle INCF mavariable,f

,sta instruccin tam&i-n ser% e+plicada en el cap(tulo de las instrucciones" Hsted ver% que esta ins$ truccin incrementa 2M15 el contenido de la varia&le mavariable' # que el resultado de la operacin es colocado en el emplazamiento d" Para todas las instrucciones d puede valer o &ien f ' en este caso el resultado es almacenado en la varia&le en cuestin' o &ien w en cu#o caso el resultado es almacenado en el registro de tra&ajo # la varia&le NO es .*)i,i($)$" Ver% igualmente que el &it Z del registro SFR STATUS est% a4ectado por la operacin" 8e recuerdo una vez m%sK si el resultado de la incrementacin da B entonces Z se pondr% a 1" .e pondr% a B en el resto de los casos 2en una instruccin que modi4ique Z evidentemente5" Para aca&ar' reemplace
goto start

Por
goto boucle

,l programa de&e aca&ar imperativamente por la directiva END " on esto usted de&er% tener al$ go as( comoK
start clrf mavariable ; borrar mavariable boucle incf mavariable,f ; incrementa mavariable goto boucle ; bucle END ; directive fin de programa

7.2 Ensamblado de un programa ,l ensam&lado de un pro#ecto se puede realizar de dos maneras" Pien ensam&lando Dnicamente el 4ic*ero seleccionado con <F10>' o &ien se ensam&lan todos los 4ic*eros del %r&ol pulsando <CTRL> + <F10>" ,n tanto en cuanto no tengamos nada m%s que un 4ic*ero en el %r&ol' nosotros utilizare$ mos <F10>" Vamos a intentar ensam&lar este programa para o&tener un 4ic*ero "*e+" Pulse la tecla F10 ' se a&re alguna ventana en MPLAB que intentar% ensam&lar nuestro programa" ,l ensam&lado se parar% a medio camino apareciendo una &arra roja # una nueva ventana 2output 5 se a&re' conteniendo los resultados de salida del comando" .i apareciese un error no previsto 2error 173' por ejemplo5 -c*ele un vistazo a los ane+os al 4inal del curso"

4B

EGu- *a pasadoF ,+aminemos el in4orme o&tenido" Primero vemos mensajes 23arning5" .on mensa$ jes destinados a llamar su atencin' pero que no impiden el ensam&laje del programa" 1o olvide que *a# toda una parte del programa que no sirve para nada pero que est% escrita 2de&ajo de la etiqueta start5" Hsaremos esa parte en los cap(tulos siguientes" ,l pro&lema viene' evidentemente' de las l(neas error . <ll( nos dice que el s(m&olo mavariable no *a sido de4inido por el utilizador" ,ste error se encuentra en las dos l(neas dnde *emos utiliza$ do nuestra varia&le" ,n e4ecto' nos *emos olvidado de declararla"" Para remediar este pro&lema' ce$ rramos la ventana de mensajes de error # volvemos al editor" >acemos sitio &ajo la l(nea Q7 en la zo$ na de varia&les # a)adimosK
mavariable : 1 ; declaracin de mi variable

9endremosK
CBLOCK 0x00C ; comienzo de la zona de variables w_temp :1 ; Zona de 1 byte status_temp : 1 ; zona de 1 byte mavariable : 1 ; declaracin de mi variable ENDC ; Fin de la zona

6elancemos el ensam&lado mediante la tecla <F10>. ,sta vez todo *a&r% ido &ien" ,l indicador estar% verde # despu-s de los 3arnings tendremos la 4raseK BUILD SUCCEEDED: construccin o&tenida con -+ito" <ca&amos de construir nuestro primer programa # *emos aprendido 3 de las 35 instrucciones que se pueden usar con el PIC. EGui-n dice que es complicadoF 1tese que la declaracin de la varia&le no tiene el sentido que podr(a tener por caso en lenguajes de alto nivel como C" 6ealmente esta declaracin no reserva nada' no realiza ningDn tra&ajo e+cepto el de asignar una direccin 2valor5 a la varia&le en cuestin" .a&iendo que 3 dtemp se encuentra en la direccin 6<= B+B 2puesto que P8J U est% asignado a esta direccin5 # que *emos declarado 1 octeto' statusdtemp se encuentra en la direccin B+B? # mavaria&le en la direccin B+B," >u&i-semos podido escri&ir' en vez de colocar mavaria&le en P8J UK
mavariable EQU 0x0E

o
#DEFINE mavariable 0x0E

,ntonces Epor qu- utilizar P8J UF .implemente porque as( los c%lculos son realizados autom%tica$ mente' evitando el riesgo de un mal c%lculo despu-s de una modi4icacin del programa" >a# alguna otra razn para los desarrolladores de programas o&jeto' pero se salen del %m&ito de este curso" 8es aconsejo encarecidamente utilizar siempre la directiva P8J U en vez de divertirse 2cada uno con su truco5 calculando las direcciones de todas las varia&les" <*ora' puede dejar la ventana de salida a&ierta' cerrarla o minimizarla" .algamos de nuestro progra$ ma # atendamos las demandas de salvaguardia"
41

8e aconsejo realizar la salvaguardia de 4ic*eros de 4orma regular despu-s de cada modi4icacin con la a#uda del atajo <Ctrl> + s " ,sto le evitar% disgustos por la p-rdida de in4ormacin en caso de una parada no deseada de su ordenador" Va#a a*ora al su&directorio de tra&ajo # descu&rir% 7 nuevos 4ic*eros generados por la aplicacin # del tipo essai1.xxx " J&serve so&re todo la e+istencia de su primer 4ic*ero "*e+" ,l 4ic*ero tal como de&er(a ser al 4inal de este cap(tulo' se encuentra en los 4ic*eros ejemplo suministrados' as( como todos los que iremos creando a continuacin"

42

8. La simulacin de un programa
<ca&amos de crear el cap(tulo precedente nuestro primer peque)o programa para el 16:;4" ,stric$ tamente' este programa no sirve para nada" ?e todas 4ormas' vamos a utilizarlo para e+perimentar con la simulacin en MPLAB." Hna vez visto este cap(tulo' usted ser% capaz deK rear # modi4icar un pro#ecto" ,nsam&lar su programa >acerlo rodar en el simulador para depurarlo

8.1 Lanzamiento y parametraje del simulador omencemos arrancando el essai1.asm " ,ste recuerda el nom&re del Dltimo pro#ecto que manej 2essai1.mcp5 # lo a&re autom%ticamente" .i posteriormente usted realiz ensa#os personales con otros pro#ectos' cargue nuestro pro#ecto desde el menD project->open " .e encontrar% en la ven$ tana de la Dltima leccin" 6ecuerde que si tiene algDn pro&lema' el 4ic*ero est% disponi&le en los 4ic*eros de ejemplo suminis$ trados con este curso" 6ecuerde lanzar el ensam&lado con <F10>" ,l inter-s de un simulador es el de visualizar el 4uncionamiento de un programa' luego de&emos se$ )alarle a MPLAB qu- es lo que queremos o&servar" Primero seleccionemos la puesta en servicio del simulador de MPLAB" .eleccionad el menDK Debugger -> select tool -> MPLAB Sim " ,so es todo" ?e nuevo apare$ cer%n Dtiles en la &arra de Dtiles" J&serve la aparicin de nuevas opciones en el menD debugger " .i todav(a no lo *a *ec*o' coloque la ventana del 4ic*ero 4uente al 4ondo a la izquierda" Vamos a *acer aparecer en la pantalla las in4ormaciones a vigilar" .eleccione View -> Special function registers " .e a&re una nueva ventana" <gr%ndela # colquela a la derec*a de la ventana del 4ic*ero 4uente 2o m%s all% si le 4alta sitio5" <*ora ve en esta ventana todos los registros que *a&(a descu&ierto en la ta&la 4$2 de la pagina 13" ,n el capitulo siguiente vamos a utilizarlos todos de 4orma progresiva" ,n nuestro peque)o programa utilizamos una varia&le" Vamos a *acerla aparecer" Va#a al menD View -> watch " .e a&re una nueva ventana" ?ispone de 4 posiciones para colocar 4 series de varia$ &les' es mu# pr%ctico para depurar" Para visualizar una varia&le dispone de varios m-todosK >aga un cliqueo do&le so&re la casilla situada justo de&ajo de symbol name # escri&a all( el nom&re de la varia&le" .i la varia&le no e+iste aparecer% la le#enda not found en la co$ lumna value " ,n caso contrario' es el valor actual de la varia&le lo que aparecer%" >aga un cliqueo do&le en la casilla de&ajo de la columna Add.. 2adresse5 e introduzca manualmente la direccin 2en este caso B+B, luego entre el valor ,5" .eleccione el nom&re en el 4ic*ero 4uente' cliquee una vez so&re la seleccin # arrastre la va$ ria&le *asta la ventana Watch sin soltar el &otn" Hna vez all(' suelte el &otn del ratn 2 Drag and drop 5"

Para eliminar una varia&le simplemente use la tecla <Del>"


43

,l entorno se parecer% a lo siguienteK

O!se%ve 3'e en e& $%%$n3'e MPLAB s'#*ne 3'e e& v$&*% )e &$ v$%i$!&e es 45 &* ('$& n* *('%%e ne(es$%i$.en"e en &$ %e$&i)$)5 #'es"* 3'e &$ RAM "*.$ 'n v$&*% $&e$"*%i* )es#'Cs )e 'n$ #'es"$ en "ensin/ Es"* #'e)e *($si*n$% 1%$ves s*%#%es$s #$%$ $3'e&&*s 3'e se *&vi)$n )e ini(i$&iD$% s's v$%i$!&es/ En e,e("*5 e& #%*1%$.$ #'e)e ,'n(i*n$% #e%,e("$.en"e en e& si.'&$)*% Ev$%i$!&e ini(i$&i0 D$)$ $ 4F #e%* n* $sG en &$ %e$&i)$) Ev$%i$!&e ini(i$&iD$)$ )e ,*%.$ $&e$"*%i$F/ .eleccione con el &otn derec*o del ratn so&re para indicarle el estilo de visualizacin de los valo$ res' ; &its # 4ormato *e+adecimal' aunque esto de&er(a estar elegido por de4ecto"

44

Pulse so&re <OK> para cerrar la ventana"

8.2 Explicacin de los registros fundamentales. ,stamos preparados para lanzar la simulacin" EPero de qu- servir(a esto si no comprende los cam$ &ios que se van a producir en los registros especialesF Vamos pues a comenzar e+plicando los regis$ tros de &ase necesarios para la comprensin del proceso"

45

8.2.1 Los registros PCL y PCLATH Hn procesador' en el %m&ito de este curso' es un componente que ejecuta secuencialmente una serie de instrucciones organizadas segDn un ensam&lado llamado programa" ,+iste pues en el procesador un secuenciador' es decir' un contador que permite apuntar a la pr+ima instruccin a ejecutar" ,ste contador es llamado /contador ordinal0 en los procesadores o /puntero de programa0" ,n el caso de los PIC' se llama o4icialmente PC' por Program Counter" J&serve que le P es un registro que no es accesi&le directamente por parte del utilizador" ,l principio de &ase es siempre el mismo" ,n los PI 16:' los registros solo tienen ; &its por lo que no pueden almacenar m%s de 255" >ar%n 4alta 2 registros para acceder a una direccin" ,stos PIC tie$ nen un 4uncionamiento un poco particular a este respecto" 1os encontramos primero con un registro que contiene la direccin &ase del P ' es decir' los ; &its menos signi4icativos" ,ste registro es accesi&le en lectura # escritura" .e trata del PCL (Program Counter Low)" ,+iste otro registro con 5 &its Dtiles solamente # que participa en el 4uncionamiento del secuenciador" .e llama PCLATH (Program Counter LATch High)" 9am&ien es accesi&le en lectura # escritura" ,l P completo est% codi4icado so&re 13 &its por lo que tendremos que completar el P 8 con 5 &its m%s para poder apuntar a una direccin completa de la memoria del programa" ,+isten dos casos po$ si&lesK ?espu-s de un salto' el contenido del P se carga con los 11 &its de destino contenidos en la instruccin en s( misma" 8os 2 &its que 4altan son e+tra(dos del PCLATH a trav-s de sus &its 3 # 4" ,stos &its' que de&en ser posicionados por el utilizador' son posicionados directamente en los &its 11 # 12 del P a 4in de completar la direccin de destino" omo el 16:;4 solo ges$ tiona 1 XW de memoria de programa' no tendremos necesidad de este registro en el caso de saltos" 6ecuerde que 16:;4 solo gestiona 1B &its de los 13 del P " Preste atencin a que este no ser% el caso cuando tratemos del 16:;76' por ejemplo 2ver parte 2 del curso5" ,n caso de modi4icacin del P 8 directamente por el utilizador' como para un registro ordina$ rio' P 8 se carga directamente en el P # se completa con los 5 &its del registro PCLATH" omo el 16:;4 solo gestiona 1 XW de memoria de programa' los &its &2'&3 # &4 de P 8<9> ser%n inutilizados" 8os &its B # 1 ser%n los que completen a los ; &its de P 8 para con4ormar una direccin de B1 &its"

1tese que el l(mite de P es 13 &its lo que implica que los PIC de la 4amilia de rango medio tendr%n una capacidad de programa m%+ima de ; XW 2es decir 2135" ,s importante acordarse siempre que el P apunta a la direccin siguiente' es decir' la instruccin que todav(a no est% siendo ejecutada" ,s importante comprender esto para analizar los programas que est%n siendo simulados"

46

8.2.2 El registro W ,ste registro es un registro utilizado por los para realizar toda suerte de c%lculos" 6ecuerde que el destino de un resultado 2d5 puede en general ser una direccin 6<= 245 o el registro de tra&ajo 235" ,s un registro 4undamental" ,n los 16: este registro no es accesi&le directamente" ,sto no es as( para otros PI como los PI 1;: 2parte 5 del curso5" 8.2.3 El registro STATUS ,ste es un registro donde cada &it tiene un signi4icado particular" Principalmente es utilizado para to$ do lo que tiene que ver con compro&aciones" ,s as( mismo de una importancia 4undamental" ,sta descrito en la ta&la de la pagina 15" >e aqu( los di4erentes &its que lo componen' comenzando por el &itB 2&B5' el &it m%s a la derec*a o &it menos signi4icativo" <lguna vez utilizamos el t-rmino 8.P o &it menos signi4icativo" &BK C arr#" ,ste &it es' de *ec*o' el QS &it de una operacin" Por ejemplo' si una adicin de 2 octetos da un valor _255 2B+::5 este &it se pondr% a 1" ?espu-s de una sustraccin se posicionar% si el resultado no es negativo" &1K DC ?igit arr#" ,ste &it es utilizado principalmente despu-s de un tra&ajo con nDmeros codi4ica$ dos P ?K indica un acarreo del &it 3 al 4" omo in4ormacin' un numero P ? es un numero donde cada cuarteto representa un digito decimal" 1o a&ordaremos este principio aqu(" &2K Z \ero" ,ste &it se pone a 1 si el resultado de la Dltima operacin 4ue B" 6ecuerde' de todas 4or$ mas' que estas &anderas o 4lags son posicionadas solo por las instrucciones que as( lo precisan 2Status bit affected5" &3K PD Po3er ?o3n" Indica que evento 4ue el Dltimo en causar una parada del PIC (instruccin sleep o desborde del watchdog)" ,n realidad P? tiene una &arrita encima del nom&reK activo en estado &ajo" B L &it valido" &4K TO 9ime$out" ,ste &it 2si est% a B5 indica que el arranque despu-s de una parada se de&i a un des&ordamiento del tiempo o de una puesta en sleep" ,n este caso P? *ace la distincin" &5K RP4 6egister PanX .electB" Permite indicar en qu- &anco de la 6<= se tra&aja" BL&anco B" P6K RP1 6egister PanX .elect1" Permite seleccionar los &ancos de la 6<= 2 # 3" Inutilizado en los 16:;4' de&e ser dejado en B para garantizar la compati&ilidad ascendente 2porta&ilidad del progra$ ma5" &7K IRP Indirect 6P" Permite decidir qu- &ando direccionamos en caso de direccionamiento indirecto 2que veremos m%s tarde5"

47

8.3 Lanzamiento de la simulacion

Pien' #a conocemos 4 de los registros" Vamos a poder comenzar a simular nuestro programa" ontrariamente en MPLAB 5' no necesitamos seleccionar la ventana 4uente para los comandos del simulador que est%n siempre activos independientemente de la ventana seleccionada en el interior de =P8<P" .i esto no 4uese as(' presione para ensam&lar" ?espu-s presione <F10>' la l(neaK
goto start ; Adresse 0: inicializacin

estar% a*ora indicada mediante una 4lec*a verde" 8a 4lec*a verde indica la pr+ima l(nea que va a ser ejecutada por el simulador" ?e *ec*o' lo que *emos provocado es un reset del programa" ,n vez de utilizar las teclas del teclado 2m%s pr%ctico5' podr(amos *a&er utilizado las *erramientas de la &arra de *erramientas o las opciones del menD debugger " 8a correspondencia es la siguienteK <F6> : reset <F7> : step into (avance de un paso en el programa) <F8> : step over (idem, pero se ejecuta un subprogram interior si lo hubiese).

6ecuerde que el reset provocar% el arranque en la direccin B+BB" Veri4iquemos queK 8a l(nea seleccionada contendr% la directiva ORG 0x00 que nos indica que la l(nea si$ guiente a ejecutar es la direccin B+BBK primer &uen signo" ,+aminemos P 8 # P 8<9 >' los dos a B" 8a pr+ima direccin a ejecutar ser% la B+BB" 9odo correcto"

,+aminemos la l(nea en cuestin" 1os indica que la pr+ima instruccin' despu-s de su ejecucin' ser% aquella situada en la direccin start " Pulse <F7>" .u programa estar% posicionado a*ora so&re la l(nea que sigue a la etiqueta start " .e *a e4ectuado un salto o lo que es lo mismo' una ruptura de secuencia"
start clrf mavariable ; effacer mavariable

,n este punto' la instruccin todav(a no se *a ejecutado" P 8 vale a*ora 34 52 BB11B1BB' es decir B+34 52 en decimal POBB11B1BB MPASM *a calculado -l solito en qu- lugar se sitDa la etiqueta start " .i usted *u&iese querido indic%rselo' *u&iese tenido que contar todas las l(neas precedentes para ver dnde esta&a" ,s m%s' despu-s de cada modi4icacin que realizase' *uiese tenido que recalcularlo" Por suerte MPASM lo *ace por nosotros" Pulse de nuevo^:7_ para ejecutar esta instruccinK &orrar mavaria&le" omo mavaria&le vale # B 2en el simulador5' aparentemente no *a ocurrido nada"
4;

8a nueva l(nea apuntada de&er% serK


Incf mavariable,f ; incrmenter mavariable

N P 8 a*ora valdr% B+35 ?O53O POBB11B1B1O ,s la direccin siguiente" <usencia de salto' ausencia de ruptura de secuencia" ,s simplemente la di$ reccin siguiente" <provec*emos para ec*arle una ojeada a la ventana "Ver% nuestra varia&le mavariable . .u valor es B+BB 2 >OBB5' # su direccin es B+B," Na *emos e+plicado por qu- anteriormente" Pulse a*ora <F7>" 8a varia&le mavariable vale a*ora 0x01 puesto que la operacin de incre$ mento se *a ejecutado" .upongo que a*ora #a lo *a entendido' la ejecucin de la siguiente instruc$ cin le llevar% a la l(nea que sigue a la etiqueta boucle " ?ivi-rtase a*ora pulsando ^:7_ repetidas veces # viendo cmo evoluciona la varia&le" ,n este momento se preguntar% qu- va a ocurrir cuando la varia&le llegue a tener el valor B+::" 1o va a tener que presionar la tecla 5BB veces" Podemos acelerar el proceso" Para *acer esto nada m%s 4%cil que clicar dos veces en la casilla de valor de la varia&le e introducir all( un nuevo valor' por ejemplo ff " lica en cualquier parte 4uera de la casilla para validar la entrada" Pulse ^:7_ para que la siguiente l(nea se ejecuteK
incf mavariable,f ; incrementar mavariable

.e *a&r% seleccionado la siguiente l(neaK


goto boucle ; boucle

,+aminemos que *a pasado" 8a varia&le mavariable *a pasado a valer B" 8gico puesto que B+:: M 1 L B+BB" J lo que es lo mismo B+1BB codi4icado en Q &its" .e o&tiene BB codi4icado en ; &its" ,+aminemos a*ora el registro .9<9H." EGu- apreciamos en -lF 8os &its 2'3 # 4 est%n a 1" 8os otros &its est%n a B" 8os &its 3 # 4 son activos a nivel &ajo 2B5" omo est%n a 1 quiere decir que est%n inactivos" Gueda el &it 2" Hn vistazo a la ta&la 4$3 nos indica que se trata del &it \ 2\ero5" 8gico porque el resul$ tado de la operacin *a sido B" .i a estas alturas se pregunta por qu- el &it 2 arr#5 no se *a puesto a 1' &ravo' *ace &uenas pregun$ tas" .i consulta el datas*eet en la pagina 62 ver% que para la instruccin incf el Dnico &it a4ectado es \ # e+clu#e la a4ectacin de K Status affected : Z " <l 4inal es lgico" .i utiliza la instruccin incf # o&tiene un resultado B es a&solutamente necesario que *a#a *a&ido un des&ordamiento por lo que una redundancia de la in4ormacin ser(a inDtil" <*ora vamos a navegar por los otros m-todos de ejecucin del simulador" Pulse ^:6_ para llevar el programa a reset" ,n el menD Debugger->run encontrar% todos los m-todos posi&le" Pru-&elos" Pulse ^:Q_ para lanzar r%pidamente el programa sin visualizacin" Pulse ^:5_ para pararlo"
4Q

,l menD debugger -> animate nos da una ejecucin animada" =%s lenta en ejecucin pero que nos permite seguir visualmente el desarrollo de la misma" ,l avance paso a paso se realiza a trav-s de la tecla ^:;_ # nos permite realizar lo mismo que con ^:7_ e+cepto que una su&rutina ser% ejecutada de un solo golpe' como si se tratase de una sola ins$ truccin" N otro m-todo m%s" Va#a a la l(nea
goto boucle ; boucle

Posicione el ratn al comienzo de la l(nea # presionad el &otn derec*o" <parecer% un menD" Hsted puede poner puntos de parada a lo largo del programa" 9am&i-n puede pedirle al programa que arranque *asta un punto espec(4ico 2run to cursor5 as( como otras opciones" 8a ventana trace del menD view->trace le da in4ormacin suplementaria so&re el camino del programa" ,l menD debugger le permite otras con4iguraciones" 8ea la a#uda del simulador para m%s in4ormacin concer$ niente al mismo" ,l su&$menD debugger->stimulus controler le permite posicionar puntos de pa$ rada condicionales" Hn do&le clic so&re una l(nea colocar% un punto de parada que se representar% con el s(m&olo B # que aparecer% a la derec*a de la l(nea" Hn segundo do&le clic eliminar% el punto de parada" Ponga un punto de parada en el programa" Pulse ^:6_ # despu-s ^:Q_' el programa se ejecutar% *as$ ta la l(nea roja' despu-s se parar%" >e aqu( otro m-todo practico para depurar el programa"

,+iste otro m-todo aDn m%s r%pido para depurarK la traza del programa" Guite el punto de parada' pulse ^:6_' despu-s seleccione view -> simulator trace " .e a&rir% una nueva ventana con un mensaje de no items to display " Pulse ^:Q_ # algunas 4racciones de segun$ do despu-s pulse ^:5_" ,n la ventana trace tendr% el resumen de todas las instrucciones ejecutadas por su programa des$ de el arranque *asta la parada" ,sto se revela mu# Dtil so&re todo despu-s de paradas inesperadas por ejemplo" >a# todav(a muc*as m%s opciones concernientes a la depuracin' no pudo e+plicarlas todas en el en$ cuadre de este curso" 8as ir% descu&riendo en el curso de sus e+ploraciones" 1o dude en e+perimen$ tar con todos los menDs" < d(a de *o# *a#' de todas 4ormas' menos opciones que en la versin 5 de MPLAB" ?e todas 4or$ mas pienso que es de&ido a la juventud del producto" Microchip ya *a adjuntado 4unciones que e+ist(an en la versin 5 # que no las *a&(a en la 6"BB" Para los *a&ituales de MPLAB 5 *ar% 4alta un poco de paciencia para recuperarlas todas"

5B

9. El juego de instrucciones
8as instrucciones est%n detalladas a partir de la p%gina 57 del datas*eet" Puede parecer inDtil reto$ marlas en este curso" Pero al 4inal *e optado por una e+plicacin pr%ctica de las mismas" >e escogido e+plicarlas a trav-s de peque)os ejemplos concretos m%s que simplemente traducir el dats*eet # en$ vi%roslo" Pien entendido que usted podr% e+perimentar con estas instrucciones con MPLAB # su simulador insertando estas instrucciones detr%s de la etiqueta start de su programa" Vo# a e+plicarle estas instrucciones en un orden que me 4acilite la e+plicacin' empezando por las #a descritas' con el 4in de tener en un mismo documento todas ellas" 9.1 La instruccin GOTO (ir a) ,sta instruccin e4ectDa lo que denominamos un salto incondicional' tam&i-n llamado ruptura de se$ cuencia s(ncrona incondicional" 6uptura de secuencia porque el programa no se va a desarrollar en el mismo orden que el de las instrucciones' s(ncrona porque sa&emos en qu- instante del programa se produce la ruptura e incondicional porque el salto se produce no importa qu- circunstancias" 6ecuerde que la instruccin goto contiene en si misma los 11 &its del emplazamiento de memoria al que se e4ectDa el salto" 8os 2 &its restantes son cargados con posterioridad en el P 8<9 >" .olo po$ dremos saltar al interior de una misma p%gina de 211 es decir 2B4; pala&ras" ,sto no plantea ningDn pro&lema en el caso del 16:;4 que solo dispone de 1 XW de memoria de programa' pero de&er% ser tenido en cuenta con de m%s capacidad 216:;765" Volveremos a *a&lar de ello en la parte 2 del curso" >e aqu( un resumen del 4uncionamiento de gotoK 8a direccin de salto de 11 &its se carga en P " 8os 2 &its que 4altan se cargar%n despu-s de P 8<9> 2&3 # &45K no para el 16:;4" ,l resultado da la direccin en 13 &its 21B &its para el 16:;45" 8a continuacin del programa se e4ectDa desde la nueva direccin"

6ecuerde que para el 16:;4 direccin de salto L direccin real" 1o de&e preocuparse de nada" Para el resto de casos' MPLAB os lo se)alar%" Sin"$9is goto etiqueta E2e.#&*
Start goto maslejos ; salta a la instruccio despues de etiqueta maslejos xxxxx xxx maslejos xxxxxxxx ; instruccion ejecutada despues del salto

Puede saltar *acia delante o *acia atr%s" Yoto necesita 2 ciclos de reloj' como todos los saltos"

51

9.2 La instruccin INCF (INCrement File) ,sta instruccin provoca un incremento del valor contenido en el emplazamiento especi4icado 2lla$ mado 4ile5" Sin"$9is
incf f,d

omo para todas las instrucciones' f representa File ' es decir el emplazamiento de memoria concernido por la operacin' representa el destino d " f es pues una direccin o el s(m&olo de una direccin" incf variable,f 1o con4unda en este caso la ` 4 a reemplazada por la ` varia&le a con la 4 situada despu-s de la co$ ma que constitu#e el destino" .alvo especi4icacin en contra' d valdr% siempreK 4 2la letra 45 o 1 2la ci4ra5K en este caso el resultado se almacenar% en el emplazamiento de memoria especi4icado por 4 2varia&le en nuestro caso5" W 2la letra5 o B 2la ci4ra5K en este caso el resultado de la operacin se almacena en el registro de tra&ajo # el contenido del emplazamiento de memoria nos es modi4icado" ,ste registro de tra&ajo es llamado comDnmente acumulador"

8a 4ormula ser% 245 M 1 2d5 K los par-ntesis signi4ican /el contenido de0" ,s decir' de 4orma ver&al K ,l contenido del emplazamiento especi4icado es incrementado en 1 # el resultado es almacenado en el emplazamiento especi4icado por d" ,mplazamiento que podr% ser' &ien el emplazamiento especi4ica$ do por f , o &ien el acumulador quedando en este caso 245 invariado" >i" $,e("$)* )e& %e1is"%* STATUS ,l Dnico &it a4ectado es el &it \" 6ecuerde que la Dnica 4orma de o&tener B incrementando un octeto es partiendo del valor B+:: pa$ sar a B+BB" Por lo tanto' si despu-s de un incremento' o&tenemos \L1 es que se *a des&ordado" \ valdr% 1 si 245 antes de la ejecucin val(a B+:: # no *a# otra posi&ilidad" E2e.#&*
incf mavariable , f ; ; ; ; ; ; el contenido de mavariable se incrementa en 1 el resultado se almacena en mavariable W no cambia El contenido de mavariable se carga en W W se in crementa en 1 El contenido de mavariable no cambia

incf mavariable , w

52

9.3 La instruccin DECF (DECRement File) ?ecrementa el contenido de un emplazamiento especi4icado" ,l 4uncionamiento es estrictamente igual al de la instruccin precedente e+cepto que esta vez se decrementa" Sin"$9is
decf f , d ; (f) 1 -> (d)

>i" $,e("$)* )e& %e1is"%* STATUS ,l Dnico &it a4ectado es el &it \" .i antes de ejecutar la instruccin 245 vale 1' \ valdr% 1 despues de la ejecucin 21$1LB5" E2e.#&*
decf mavariable , f ; decrementa mavariable y lo almacena en mavariable decf mavariable , w ; toma (mavariable)-1 y lo almacena en W

9.4 La instruccin MOVLW (MOVe Literal to W) ,sta instruccin carga el valor especi4icado en el acumulador" ,l valor precisado se dice literal o in$ mediato pues no depende de ningDn contenido en un emplazamiento de memoria" Sin"$9is
movlw k ; k-> w : k representa un valor desde 0x00 a 0xFF.

>i" $,e("$)* )e& %e1is"%* STATUS 1inguno 2incluso si carga un valor B" E2e.#&*
movlw 0x25 ; carga el valor 0x25 en el acumulador

9.5 La instruccin MOVF (MOVe File) arga el contenido del emplazamiento especi4icado en el destino" Sin"$9is
movf f , d ; (f) -> (d)

>i" $,e("$)* )e& %e1is"%* STATUS ,l Dnico &it a4ectado es el &it \" .i 245 vale B' \ vale 1"

53

E2e.#&* ,n esta instruccin vo# a ser m%s espec(4ico" omprender% por qu-"
movf mavariable,w ; carga el contenido de mavariable en W

HATENCIONI <qu( es imperativo *acer la distincin entre movlw k # movf f,w. ,n el primer caso es el valor el que es cargado en 3' en el segundo caso es el valor del contenido del emplazamiento el que es cargado" .i nos acordamos de la leccin precedente' mavaria&le represen$ ta&a el emplazamiento de memoria de direccin B+B, de nuestra 6<=" .upongamos que el empla$ zamiento de memoria 6<= B+B, contiene el valor B+B5 2decimos que mavaria&le contiene B+B55" .i ejecutamos la instruccinK
movlw mavariable

,l ensam&lador va a traducirla reemplazando mavaria&le por su valor" A"en(in H el contenido de una varia&le no es su valor aunque el lenguaje corriente nos permita presuponerlo" ,l ensam&lador va a realizar simplemente la siguiente sustitucin de te+toK
movlw 0x0E

?espu-s de la ejecucin de la instruccin' el registro W contendr% el valor B+B, # *a&laremos en este caso de un direccionamiento inmediato" ,l desarrollo es del tipo 4 2d5 .i por el contrario ejecutamos la instruccinK
movf mavariable , w

,l ensam&lador va a tra&ajar e4ectuando una sustitucin 2el ensam&lador siempre tra&aja de esta manera5 # o&tendremosK
movf 0x0E , w

8o que signi4icaK cargar el contenido que se encuentre en el emplazamiento B+B, en el acumulador W" >a&laremos aqu( de un direccionamiento directo" 8e recomiendo no con4undirse porque si no no comprenderemos a&solutamente nada del desarrollo de un programa" ?espu-s de esta instruccin W contendr% B+B5 que es el valor que conten(a el emplazamiento de memoria B+B," ,s decir el desa$ rrollo es del tipo 245 2d5 E2e.#&* J
movf mavariable , f

EGu- *ace esta instruccinF .i *a entendido todo lo anterior ver% que esta instruccin coloca el con$ tenido de mavaria&le en mavaria&le" ?ecir que esto no sirve para nada ser(a un poco prematuro" .i &ien el contenido de mavaria&le permanece invaria&le' el &it \ se posicionar% de acuerdo a ello" ,sto permite determinar si mavaria&le contiene B"
54

9.6 La instruccin MOVWF (MOVe W to File) Permite guardar el contenido del registro de tra&ajo W en un emplazamiento de memoria" ,s la ope$ racin inversa a mov4 4'd Sin"$9is
movwf f ; (W) -> (f)

>i" $,e("$)* )e& %e1is"%* STATUS 1inguno" E2e.#&*


movlw 0x50 ; carga 0x50 en W movwf mavariable ; mavariable contine ahora 0x50.

9.7 La instruccin ADDLW (ADD Literal and W) ,sta operacin permite a)adir un valor literal al registro W" ,stamos de nuevo en el caso de un direc$ cionamiento inmediato" Sin"$9is
addlw k ; (W) + k -> (W)

>i" $,e("$)* )e& %e1is"%* STATUS \ K si el resultado de la operacin vale B ' \ valdr% 1 K .i el resultado de la operacin es ma#or que B+:: 22555 ' valdr% 1" ? K si el resultado de la operacin comporta un trasvase del &it 3 al 4 ' ? valdr% 1 1o se preocupe muc*o por el &it ? ' solo se utilizar% para nDmeros codi4icados P ?" E2e.#&*
movlw 253 ; carga 253 en decimal en W addlw 4 ; aade 4. W contendr 1, Z valdr 0, C valdr 1(desborde) addlw 255 ; aade 255. W valdr 0, C valdr 1, Z valdr 1

9.8 La instruccin ADDWF (ADD W and F) ,l contenido del registro W se a)ade al contenido del registro :" 1o se con4unda con la instruccin precedente" .e trata a*ora de un direccionamiento directo" Sin"$9is
addwf f , d ; (w) + (f) -> (d)

55

>i" $,e("$)* )e& %e1is"%* STATUS ' ? ' et \ E2e.#&*


movlw movwf movlw addwf 12 ; carga 12 en W mavariable ; mavariable contiene ahora 12 25 ; carga 25 en W mavariable,f ;(W) + (mavariable), es decir 25+12=37 ; se carga en mavariable

9.9 La instruccin SUBLW (SUBtract W from Literal) <tencin' aqu( *a# una trampa" 8a instruccin de&er(a llamarse .HPW8" .e sustrae W del valor literal # no a la inversa" omo su nom&re indica' se trata de un direccionamiento literal o inmediato" Sin"$9is
sublw k ; k (W) -> (W)

>i" $,e("$)* )e& %e1is"%* STATUS ' ? ' et \ 4unciona de manera inversa que para la adicin" ,s comDn para la ma#or(a de los procesadores del mercado" <lgDn otro utiliza alguna vez un &it espec(4ico para la sustraccin' comDnmente llamado borrow " .i el resultado es positivo no e+istir% des&ordamientoK L1" .i *a# des&ordamiento' a B" se ver% 4orzado

,s lgico # se e+plica realizando una sustraccin de 4orma manual" ,l &it representa el QS &it puesto inicialmente a 1 de o4icio" .i e4ectuamos una sustraccin manualmente resultando ^B' se o&tendr% un valor 4inal de ; &its con el &it sustra(do" .i el resultado es _B no *a&r% cam&io en ese &it QS' lue$ go permanecer% a 1" 8a 4ormula de la sustraccin ser%K X precedido de un QS &it a 1 e contenido de W L resultado en W en 4orma ; &its con el QS &it en " E2e.#&*
movlw 0x01 ; carga 0x01 en W sublw 0x02 ; resta W de 2 ; rsultado : 2 (W) = 2-1 = 1 ; Z = 0, C = 1, luego resultado positivo

56

>agamos las operaciones manualmenteK

E mo procederF omo en una operacin en decimal" omenzaremos por los &its de la derec*aK B$1 ser% 1 # arrastro 1" ,l siguiente &it 2&15 ser% 1$2BM15 L 1$1 L B # no *a# arrastre" <s( *asta alcanzar el &it QS' que como vemos no se ver% a4ectado dando lugar a un resultado positivo 2 L15" E2e.#&* J
movlw 0x02 ; carga 0x02 en W sublw 0x02 ; resta 2 (w) = 2 2 = 0 ; Z = 1 , C = 1 : resultado 0

E2e.#&* 3
movlw 0x03 ; crga 0x03 en W sublw 0x02 ; resta 2 (W) = 2 3 = -1

Procedamos de la misma manera # o&tendremos PO11111111' con el &it a B" ,l que el &it nos indica que estamos ante un nDmero negativo' concretamente B+:: o 255 en decimal" 8a interpretacin ser% 2$3 L 255 con LB negativo $255"

sea B

57

,videntemente 1J" 6ecuerde el valor a&soluto de un nDmero negativo en &inario" ?e&eremos tomar el complemento a 2 del nDmero &inario" Por lo tantoK omplemento a 1K PO11111111 M 1 L POBBBBBBBB omplemento a 2 L complemento a 1 M 1 L POBBBBBBBB M 1 L POBBBBBBB1

8uego el resultado de la anterior operacin ser% el valor a&soluto con el signo negativo' es decir POBBBBBBB1 con signo menos L $1" Hn Dltimo detalleK para e4ectuar la resta de un numero' usted puede *acerlo mediante la suma de su complementario a 2" ,l resultado ser% estrictamente el mismo a condicin de la correcta interpretacin de los &its \ # " ,ste argucia es practica puesto que si disponemos de .HP8W para e4ectuar X e 235' utilizar el com$ plemento a 2 v(a <??8W nos permite realizar la operacin inversa 235 e X" omo =P<.= sa&e como calcular per4ectamente los complementos a 2 por s( mismo' a#ud%ndose de una constante' podemos escri&irK
sublw 8; efectuar 8 (w) addlw -8 : efectuar(w) 8

J&serve de nuevo como el nDmero de instrucciones no dice gran cosa de la potencia real de un micro si no estudiamos el conte+to de una 4orma precisa # no *acemos 4uncionar nuestro cere&ro" Por nuestra parte' no *emos ec*ado de menos en a&soluto la ausencia de una instruccin que e4ectDe 235$; puesto que en la realidad disponemos de la misma v(a la adicin de un literal" Hn &uen progra$ mador es aquel que sa&e ver m%s lejos de lo que parece evidente para e+plotar todas las posi&ilida$ des visi&les # escondidas"

9.10 La instruccin SUBWF (SUBtract W from F) ,sta instruccin resta el contenido de W del contenido de :" .eguimos en el entorno de las sustrac$ ciones' pero en este caso se trata de un direccionamiento directo" Sin"$9is
subwf f , d ; (f) (W) -> (d)

>i" $,e("$)* )e& %e1is"%* STATUS ' ? ' et \ E2e.#&*


0x20 en w pone w en (mavariable) (0x20) 0x1F en w ; (mavariable) - (w) -> (w) ; 0x20 0x1F = 0x01 ; resultado en w, C=1, Z=0 movwf autrevariable ; salva 0x01 en otra variable movlw movwf movlw subwf 0x20 ; carga mavariable ; 0x1F ; carga mavariable,w

5;

8e remito a la instruccin precedente para que sepa cmo se desarrolla la resta # la gestin de los &its # \"

9.11 La instruccin ANDLW (AND Literal with W) ,sta instruccin realiza un N lgico &it a &it entre el contenido de W # el valor literal" .e trata de un direccionamiento literal o inmediato' Sin"$9is
andlw k ; (w) AND k -> (w)

>i" $,e("$)* )e& %e1is"%* STATUS \ E2e.#&*


movlw B11001101 ; caarga w andlw B11110000 ; efectua un and(&)

6ecuerde que se e4ectDa un N lgico entre cada &it del mismo rango" ,l resultado es uno cuando los dos &its del mismo rango son 1" <l e4ectuar un <1? con el valor PO1111BBBB se enmascaran los &its de B a 3 # su&sisten los &its de 4 a 7" <provec*o para indicar que <1? es una instruccin conmutati$ va" 8e aconsejo que traduzca a &inario todas las instrucciones que conciernen a &its"

9.12 La instruccin ANDWF (AND W with F) 6ealiza un N lgico entre el contenido del registro W # el contenido de :" ,s la misma operacin que la precedente e+cepto en que es un direccionamiento directo" Vo# pues' a acelerar las e+plicaciones" Sin"$9is
andwf f , d ; (f) AND (w) -> (d)

>i" $,e("$)* )e& %e1is"%* STATUS \


5Q

E2e.#&*
movlw movwf movlw andwf peso) 0xC8 ; carga mavariable ; 0xF0 ; carga mavariable,f 0XC8 en w salva en mavariable la mascara ; (mavariable) = 0xC0 (eliminamos el cuarteto de menor

9.13 La instruccin IORLW (Inclusive OR Literal with W) 6ealiza un J6 inclusivo lgico &it a &it entre el contenido del registro W # el valor inmediato precisa$ do" 8a nocin de inclusividad de la que #a *emos *a&lado' precisa que el resultado de la operacin para un rango de &its dado valdr% 1 si uno de los dos &its vale 1' inclu#endo el caso en el que los dos valgan 1" .e trata de un direccionamiento literal o inmediato" Sin"$9is
iorlw k ; (w) OR k -> (w)

>i" $,e("$)* )e& %e1is"%* STATUS \ E2e.#&*


movlw 0xC3 ; carga 0xC3 en W iorlw 0x0F ; FUERZA los bits 0 a 3 : rsultado : (w) = 0xCF

8uego con un J6 inclusive podemos 4orzar a 1 cualquier &it 2recuerde que con <1? podemos 4orzar a B cualquier &it5" 9.14 La instruccin IORWF (Inclusive OR W with File) ,4ectDa un J6 inclusive con direccionamiento directo" Sin"$9is
iorwf f , d ; (w) OR (f) -> (d)

>i" $,e("$)* )e& %e1is"%* STATUS \

6B

9.15 La instruccin XORLW (eXclusive OR Literal with W) 6ealiza un J6 e+clusivo lgico &it a &it entre el contenido del registro W # el valor literal precisado" 8a nocin de e+clusividad precisa que el resultado de la operacin para un rango de &its dado valdr% 1 si uno de los dos &its vale 1' e+clu#endo el caso en el que los dos valgan 1" .e trata de un direcciona$ miento literal o inmediato" J&serve que si aplicamos un &it B a un &it cualquiera mediante [J6 o&tendremos como resultado el &it sin cam&io ninguno" Por el contrario' si lo aplicamos con un 1 o&tendremos el inverso del mismo" ,n e4ecto B +or 1 da 1 pero 1 +or 1 da B por e4ecto de la e+clusividad" ,sta instruccin nos permitir% invertir no importa que &it de un octeto" Sin"$9is
xorlw k ; (w) xor k -> (w)

>i" $,e("$)* )e& %e1is"%* STATUS \ E2e.#&*


movlw B11000101 ; xorlw B00001111 ; ; ; carga W xor con el valor resultado : B 11001010 se han invertido los 4 bits menos significativos

J&serve que los &its del octeto inicial *an sido invertidos por cada &it del segundo operando que val$ (an 1" on lo que #a *emos visto podemos 4orzar un &it a 1 2J65' 4orzarlo a B 2<1?5 o invertirlo 2[J65" Por lo tanto #a sa&e manipular los &its como usted quiera"

61

9.16 La instruccin XORWF (eXclusive OR W with F) ,4ectDa un J6 e+clusivo &it a &it en tre el contenido del registro W # el contenido de :" .e trata de la misma operacin que la anterior pero con direccionamiento directo" Sin"$9is
xorwf f , d ; (w) xor (f) -> (d)

>i" $,e("$)* )e& %e1is"%* STATUS \ 9.17 La instruccin BSF (Bit Set F) :uerza a 1 el &it de rango especi4icado en el contenido de :" ?ic*o de otra 4orma pone a 1 un nDmero de &it de un registro preciso" .e trata de un direccionamiento directo" Sin"$9is
bsf f , b ; (f).b = 1

,l &it nS & es posicionado a 1 en la caja de memoria 245" ,videntemente & vale entre B # 7" >i" $,e("$)* )e& %e1is"%* STATUS 1inguno" E2e.#&*
bsf STATUS , C ; pone a 1 el bit C en el registro STATUS bsf mavariable , 2 ; pone a 1 el bit 2 de (mavariable)

A"en(in H <unque usted manipule solo un &it en particular' el PI no actDa directamente so&re este Dni$ co &it" ?e *ec*o' realiza un ciclo llamado de lecturaRmodi4icacinRescritura" .i tomamos el primer ejemplo' el PI va a cargar .9<9H. 2los ; &its5' modi4icar% el &it cri&ir% .9<9H. en su emplazamiento original" # despu-s rees$

Podr(a decirme que ese es un pro&lema del PI # que a nosotros no nos concierne" ?e *ec*o s( # no" .( en cuanto al ejemplo en cuestin # no si se tratase de un puerto de salidas" 8o veremos m%s adelante" ,sta o&servacin es v%lida para todas las instrucciones de manipulacin de un &it en particular' # por lo tanto tam&i-n lo ser% para P :"

62

9.18 La instruccin BCF (Bit Clear F) :uerza a B el &it especi4icado del contenido del emplazamiento :" ?ic*o de otra 4orma' pone a B un nDmero de &it de un registro precisado" Sin"$9is
bsf f , b ; (f).b = 0

,l &it nS & es posicionado a B en la caja de memoria 245" ,videntemente & vale entre B # 7" >i" $,e("$)* )e& %e1is"%* STATUS 1inguno" E2e.#&*
bcf STATUS , C ; pone a 0 el C en el registro STATUS bcf mavariable , 2 ; pone a 0 b2 de (mavariable)

9.19 La instruccin RLF ( Rotate Left through Carry) 6otacin *acia la izquierda del registro : utilizando el carr#" .e trata de una instruccin de direcciona$ miento directo" 8as operaciones de rotacin son operaciones mu# utilizadas" 8os tienen la particularidad de tener solo una instruccin de rotacin so&re Q &its" Vamos a ver que con estas instrucciones es mu# 4%cil realizar de$ calajes" 8a pala&ra que va a su4rir la rotacin est% constituida por los ; &its de un registro especi4icado' completada por el &it 2carr#5 del registro .9<9H." 8a operacin de rotacin realiza lo siguienteK el &it es memorizado" Inmediatamente cada &it del octeto se desplaza *acia la izquierda" ,l &it 7 sale del octeto por la izquierda # se convierte en el nuevo &it " ,l nuevo &it B tomar% el valor del anciano carr# que 4ue memorizado inicialmente" .e trata pues de una ro$ tacin so&re Q &its" Sin"$9is
rlf f , d ; (f) rotacion a la izquierda con carry-> (d)

,l &it nS & es posicionado a B en la caja de memoria 245" ,videntemente & vale entre B # 7" >i" $,e("$)* )e& %e1is"%* STATUS

E2e.#&* Hn peque)o ejemplo vale m%s que un largo discurso"


bsf STATUS,C ; pone el carry a 1 movlw B00010111 ; carga el valor en w movwf mavariable ; inicializa mavariable rlf mavariable,f ; rotacion a la izquierda

63

omo ve todos los &its se *an decalado *acia la izquierda # queda so&re Q &its" E2e.#&* J

se *a realimentado al &it B" ,l resultado

bcf STATUS,C ; positionne le carry 0 movlw b00010111 ; charge la valeur dans w movwf mavariable ; initialise mavariable rlf mavariable,f ; rotation vers la gauche

.i lo entendi todo' el resultado ser% POBB1B111B con el carr# a B" EGu- ocurre si *acemos esta operacin en decimalF ojamos el nDmero 125 # rot-mosle a la izquier$ da" 1os dar% el numero 125B" >a&remos simplemente multiplicado el nDmero por su &ase 2deci$ malL&ase 1B5" ,n &inario es e+actamente igual" ojamos el numero POBBB1B111 223 en decimal5" 6ot-mosle a la izquierda # o&tendremos POBB1B111B 246 en decimal5" >emos pues e4ectuado una multiplicacin por 2 2&inario L &ase 25" Partiendo de un nDmero &inario entre B # 255' rotando tendremos un numero comprendido entre 2 # 51B 2siendo el carr# el &it ;5" 9.20 La instruccin RRF ( Rotate Right through Carry) 6otacin a la derec*a del registro : utilizando el carr#" .e trata de una instruccin de direccionamien$ to directo" 8a operacin de rotacin a la derec*a e4ectDa la siguiente operacinK el &it es memorizado" Inme$ diatamente cada &it del octeto se desplaza a la derec*a" ,l antiguo &it B sale del octeto por la dere$ c*a # pasa a ser el nuevo carr#" ,l antiguo carr# pasa a ser el nuevo &it 7" .e trata pues de una rota$ cin so&re Q &its" Sin"$9is rrf f , d ; (f) rotacion con carry -> (d) >i" $,e("$)* )e& %e1is"%* STATUS

E2e.#&* 1
bsf STATUS,C ; pone el carry a 1 movlw B00010111 ; carga el valor en w movwf mavariable ; inicializa mavariable rrf mavariable,f ; rotacin a la derecha

64

omo ve todos los &its se decalaron a la derec*a" &its" E2e.#&* J

se reintrodujo al &it 7" ,l resultado es so&re Q

bcf STATUS,C ; pone el carry a 0 movlw b00010111 ; carga el valor en w movwf mavariable ; inicializa mavariable rrf mavariable,f ; rotacin a la derecha

.i lo comprendi &ien' ver% que el resultado ser% POBBBB1B11 con el carr# a 1" .i el carr# est% a B al comienzo' simplemente se e4ectDa una rotacin a la derec*a" EGu- ocurriF .i nuestro nDmero de partida es 23 en decimal' al 4inal tenemos 11 en decimal" ,l ca$ rr# representa el &it /$10' es decir la mitad del &it B' luego " ,n e4ecto' en decimal' la ci4ra 1 despu-s de las unidades representa 1R&ase' es decir 1R1B" ,n &inario ser% f" .i miramos a*ora los Q &its veremos 11 " >emos dividido el nDmero entre 2 2&ase5" <cu-rdese de esto' le ser% mu# Dtil m%s adelante" Hn decalaje a la derec*a equivale a dividir por 2" Partiendo de un nDmero comprendido entre B # 255 o&tendremos un nDmero comprendido entre B # 127"5 2siendo el carr# el &it de rango $15 9.21 La instruccin BTFSC (Bit Test F, Skip if Clear) omprue&a el &it precisado del emplazamiento : # salta si es igual a B" .e trata del primer salto con$ dicional 2ligado a una condicin5' o ruptura de secuencia s(ncrona condicional" ,n e4ecto' no *a&r% salto si la condicin no se cumple" 8as instrucciones condicionales son la &ase de todo lo que es la toma de decisiones en un programa" J&serve que en este caso' la instruccin utilizar% 2 ciclos de reloj' si no solo utilizar(a 1" ,s m%s' *a&r% que recordar que este tipo de saltos no saltan m%s que la instruccin siguiente 2la instruccin no con$ tiene direccin de salto5" Sin"$9is
btfsc f, b ; on mira el bit b de la memoria (f). ; si es 0 salta la instruccion siguiente ; si es 1 ejecuta la instruccion siguiente Instruccion x ; se ejecuta solamente si f.b vale 1 Instruccion y ; se ejecuta solamente si f.b vale 0

65

J&serve que para pasar de la instruccin &t4sc a la instruccin # nos *ar%n 4alta 2 ciclos de reloj" ,n e4ectoK .i 4"& se cumple # saltamos +' un salto dura 2 ciclos .i 4"& no se cumple' &t4sc durar% 1 ciclo pero para llegar a # tardaremos 1 ciclo m%s en ejecu$ tar + dando un total de 2 ciclos" ,sto se cumple siempre # cuando la instruccin + no sea una instruccin de salto como en el ejemplo siguiente"

E2e.#&*
btfsc f, b ; mira el bit b de la memoria (f). ; si vale 0 salta la siguiente ; si vale 1 ejecuta la siguiente

goto plusloin ; si b vale 1 salta a plusloin Instruction y ; se ejecuta si b vale 0

plusloin : ; tratamos aqu el caso b vale 1 instruccion z

,sta 4orma de proceder se utiliza mu# a menudo cuando *a# muc*as instrucciones ejecutar en un ca$ so # en otro" ,l goto se puede' eventualmente reemplazar por un call si el desarrollo del programa requiere que se ejecute la instruccin # en todos los casos" ,sta 4orma de proceder es aplica&le a otras instrucciones de /sXip0' *a&laremos de ello m%s adelante" >i" $,e("$)* )e& %e1is"%* STATUS 1inguno E2e.#&* 1 >e aqu( un ejemplo en el que se de&e ejecutar un sola instruccin suplementaria si el &it vale 1"
btfsc STATUS,C ; mira si el bit C de STATUS vale 0 bsf mavariable,2 ; no (C=1), bit 2 de mavariable puesto a 1 xxxx ; continuacin del programa

E2e.#&* J EGu- *acer si el tratamiento del programa necesita e4ectuar m%s operacionesF omo #a *emos di$ c*o' mezclaremos saltos condicionales e incondicionales"
movlw 0x12 ; carga 12 en w subwf mavariable,f ; resta 0x12 de mavariable btfsc STATUSC ;,mira si el resultado es negativo (C=0) goto positif ; salta al tratamiento de resultado positivo xxxx ; tratamiento resultado negativo ... positif: ; aqu realizamos el tratamiento si positivo

66

9.22 L$ ins"%'((in BTFSS (Bit Test F, Skip if Set) omprue&a el &it precisado del emplazamiento de memoria : # salta si vale 1" ,l 4uncionamiento es estrictamente similar al precedente" Sin"$9is
btfss f, b ; mira el bit b de la memoria (f). ; si vale 1 salta la instruccion siguinete ; si vale 0 ejecuta la instruccion siguiente xxxx ; si el bit vale 1 no ser ejecutada (skip) xxxx ; el programa continua aqui

>i" $,e("$)* )e& %e1is"%* STATUS 1inguno" E2e.#&*


btfss STATUS,C ; mira si el bit C de STATUS vale 1 bsf mavariable,2 ; no (C=0), bit 2 de mavariable puesto a 1 xxxx ; continuacin del programa en los dos casos

9.23 La instruccin DECFSZ (DECrement F, Skip if Z) ?ecremento del contenido del emplazamiento : # salta la instruccin siguiente si el resultado 4ue B" ,sta instruccin es mu# utilizada para crear &ucles" Sin"$9is
decfsz f, d ; (f) 1 -> (d). Salto si (d) = 0

>i" $,e("$)* )e& %e1is"%* STATUS 1inguno" E2e.#&*


movlw 3 ; cargar 3 en w movwf compteur ; inicializar compteur movlw 0x5 ; cargar 5 en w boucle ; etiqueta addwfmavariable ,f ; aadir 5 a variable decfsz compteur , f ; decrementar y comprobar goto boucle ; si compteur no es 0, ir a boucle movf mavariable , w ; carga el valor obtenido en w

67

E mo *emos escrito este programaF Inicializamos el contador de &ucles Ponemos una etiqueta de comienzo de &ucle ,scri&imos las instrucciones que se *an de ejecutar varias veces 8a instruccin dec4sz permite determinar el 4inal del &ucle 8a instruccin goto permite localizar el comienzo del &ucle

ATENCION Si puso:
decfsz compteur , w ; decrementar contador y comprobar

el &ucle no aca&ar% jam%s' puesto que la varia&le contador jam%s ser% modi4icada" ,sto le permitir%' utilizando su cere&ro pro&ar una nueva utilidad de esta instruccin" TRUCO: precisando w como destino, puede comprobar si una variable vale 1 sin modificarla. J&serve que un mov44 varia&le'4 le permite compro&ar si una varia&le era nula' mientras que a*ora un dec4sz varia&le'3 le permite compro&ar si vale 1" Jtra vez compro&amos que el nDmero de ins$ trucciones no resume las capacidades de un micro utilizado" Volviendo a nuestro ejemplo' si ponemos un B en el contador de &ucles' este ser% ejecutado 256 ve$ ces" .i desea que solo sea ejecutado &ajo determinadas circunstancias de&er% a)adir una compro&a$ cin antes de la ejecucin del primer &ucle como se *ace a continuacin" E9e.#&e J
movf compteur,f ; posiciona Z btfsc STATUS , Z ; salta si Z = 0, es decir si compteur >0 goto suite ; compteur = 0, no ejecutar el bucle boucle ; etiqueta de comienzo del bucle addwf mavariable , f ; aade 5 a mavariable decfsz compteur , f ; decrement y comprueba goto boucle ; si compteur no es 0, vamos a boucle suite ; saltamos aqui si compteur = 0 movf mavariable , w ; cargamos el valor obtenido en w

9.24 La instruccin INCFSZ (INCrement F, Skip if Zero) Incrementa el contenido del emplazamiento : # salta la siguiente instruccin si el resultado 4ue B" Igual que la anterior e+cepto que incrementamos en vez de decrementar" Sin"$9is
incfsz f , d ; (f) + 1 -> (d) : saut si (d) = 0

>i" $,e("$)* )e& %e1is"%* STATUS 1inguno" TRUCOK #%e(is$n)* : (*.* )es"in*5 #'e)e (*.#%*!$% si 'n$ v$%i$!&e (*n"iene 49FF sin .*)i,i($%0 &$/
6;

9.25 La instruccin SWAPF (SWAP nibbles in F) Invierte los dos cuartetos del contenido del emplazamiento :" ,sta operacin simplemente invierte el cuarteto 2semi$octeto5 de peso d-&il con el de peso 4uerte" ,sta operacin es Dtil cuando maneja co$ di4icacin P ?" Sin"$9is
swapf f , d ; inversion de b0/b3 de (f) por b4/b7 -> (d)

>i" $,e("$)* )e& %e1is"%* STATUS 1inguno" ,sta particularidad nos resultar% mu# Dtil cuando veamos las interrupciones" E2e.#&*
movlw 0xC5 ; carga 0xC5 en w movwf mavariable ; mueve a mavariable swapf mavariable , f ; (mavariable) = 0x5C

9.26 La instruccin CALL (CALL subroutine) 8lama a una su&rutina" ,sta instruccin e4ectDa un salto incondicional a un su&$programa" .e trata de una rotura de secuencia incondicional s(ncrona con memorizacin de la direccin de retorno" EGu- es un su&programaF .e trata de una porcin de programa que puede ser llamado desde mu$ c*os sitios de un programa llamado /principal0 # que presenta la particularidad de reenviar al 4inal de su ejecucin a la instruccin siguiente a la desde la que 4ue llamado" Sin"$9is
call sousroutine ; (pc)->(pile), despues sousroutine + PCLATH -> (pc

Me($nis.* ?espu-s de la ejecucin de la instruccin' el contenido del P es guardado en una pila" Hna pila 4un$ ciona como un apilamiento de asientosK el Dltimo asiento puesto en la pila ser% el primero en poder ser recuperado" J' como #a lo *emos e+plicado' el P contiene siempre la direccin de la pr+ima instruccin a ejecutar" Hna vez el P est% guardado' su contenido se reemplaza por los 11 &its del valor de la direccin de salto 2su&rutina5' completado 2para los PI de m%s de 2 XW de memoria de programa5 por los 2 &its de peso 4uerte de P 8<9>" ,l programa saltara al emplazamiento su&rutina como si 4uese un goto" ,n el sitio de la su&rutina se van a encontrar una serie de instrucciones' el su&programa' de&iendo este' imperativamente' aca&ar en una instruccin de retorno al programa /principal0 desde el que 4ue llamada 2por ejemplo la instruccin %e"'%n5" Hna vez encontrada esta instruccin' el valor intro$ ducido en la pila ser% cargado en el P ' que mandar% el programa a la siguiente instruccin a la que *izo la llamada v(a call"

6Q

J&serve que si el su&programa llamase a otro su&programa' la direccin ser(a guardada en la pila de la misma manera" ,s por esto por lo que de&e ser una pila' para que la direccin de retorno sea siempre la Dltima que 4ue almacenada" ATENCION H Es"$ #i&$ "iene 'n "$.$7* &i.i"$)* )e 8 e.#&$D$.ien"*s/ N* e9is"e nin1'n$ ,*%.$ )e (*.#%*!$% &$ #i&$ #*% &* 3'e )e!e%L se% 's"e) .is.* 3'ien 1es"i*nes &*s s'!#%*1%$.$s )e "$& ,*%0 .$ 3'e n* #$se.*s )e 8 #*si(i*nes5 si n*5 e& #%*1%$.$ se !&*3'e$%L/ 9enga en cuenta que cuando un su&programa retorna li&era un espacio de la pila" 1o se trata' pues' de limitar el nDmero de veces que llamamos a su&programas' sino del nDmero de veces que un su&$ programa llama a otro" >i" $,e("$)* )e& %e1is"%* STATUS 1inguno"

9.27 La instruccin RETURN (RETURN from subroutine) 6etorno de su&rutina" Va siempre emparejada a una instruccin call" ,sta instruccin indica el 4inal de la porcin de programa que constitu#e una su&rutina 2.65" 6ecuerde que por cada instruccin ($&& de&er% encontrar una instruccin %e"'%n" Sin"$9is
return ; (pila) -> PC

>i" $,e("$)* )e& %e1is"%* STATUS 1inguno" E2e.#&* Imaginemos un programa que necesita una peque)a temporizacin 2como cada instruccin toma su tiempo en ser ejecutada' nos podemos arreglar para *acer perder el tiempo voluntariamente al pro$ grama con el 4in de retardar su 4uncionamiento5" ,scri&%mosloK
movlw 0xCA ; valor del compteur movwf compteur ; inicializar bucles boucle decfsz compteur,f ;dec.compteur,salto si 0 goto boucle ; bucle si no 0 xxx ; continua programa

Imaginemos que esta peque)a temporizacin sea llamada regularmente por nuestro programa prin$ cipal"

7B

Veamos qu- aspecto tendr(aK


xxx ; instruccin cualquiera xxx ; instruccin cualquiera xxx ; instruccin cualquiera xxx ; instruccin cualquiera tempo ; aqui necesitamos una temporizacion xxx ; instruccin cualquiera xxx ; instruccin cualquiera xxx ; instruccin cualquiera tempo ; aqu tambien xxx ; instruccin cualquiera xxx ; instruccin cualquiera tempo ; y tambin aqui xxx ; instruccin cualquiera

8a primera cosa que se nos viene a la ca&eza es la de copiar # pegar nuestra temporizacin" ,sto' adem%s de no ser elegante' nos o&ligar(a a' si tenemos que modi4icar el tiempo de temporizacin' realizar los cam&ios en todos los trozos que *emos copiado # pegado sin olvidarnos de ninguno de ellos" <dem%s ocupar(a muc*a memoria de programa" Igualmente podr(amos utilizar una /macro0 que' recuerde' e4ectDa una sustitucin en el momento del ensam&laje" ,s &ien cierto que a*ora' en caso de modi4icacin' solo de&emos ocuparnos de un si$ tio' pero en nuestro PIC' el cdigo ser% escrito en realidad con el consiguiente desperdicio de me$ moria de programa' so&re todo' si el cdigo es mu# e+tenso o se *acen muc*as utilizaciones del mismo" ,s para resolver esto para lo que vamos a utilizar la t-cnica de los su&programas" Primera etapa' mo$ di4icamos nuestra temporizacin para *acer de ella una su&rutinaK
tempo ; etiqueta de comienzo de subrutina movlw 0xCA ; valor de compteur movwf compteur ; inicializa el contador de bucles boucle decfsz compteur,f ; decrement y salto si 0 goto boucle ; no es 0 , salta aboucle return ; final de la subrutina

.egunda etapa' modi4icamos nuestro programa principal para que cada vez que lo necesitemos' lla$ memos al su&programa" 9endremosK
xxx ; instruccin cualquiera xxx ; instruccin cualquiera xxx ; instruccin cualquiera xxx ; instruccin cualquiera call tempo ; llamada al subprograma xxx ; instruccin cualquiera, el programa continua aqu xxx ; instruccin cualquiera xxx ; instruccin cualquiera call tempo ; llamada al subprograma xxx ; instruccin cualquiera, el programa continua aqu xxx ; instruccin cualquiera call tempo ; llamada al subprograma xxx; instruccin cualquiera, el programa continua aqu

,n este caso' la rutina de temporizacin solo est% presente una vez en la memoria de programa"

71

<Dn podemos mejorarlo m%s" .upongamos que necesitemos una temporizacin de duracin varia&le" .olo nos *ar% 4alta modi4icar la su&rutina suprimiendo el valor de inicializacin # situamos este en el programa principal antes de la llamada a la su&rutina" 8lamamos a esto una su&rutina con paso de par%metros" ,n nuestro ejemplo ser(aK
tempo ; etiqueta de comienzo de subrutina movwf compteur ; inicializa el contador de bucles boucle decfsz compteur,f ; decrement y salto si 0 goto boucle ; no es 0 , salta aboucle return ; final de la subrutina

N nuestro programa principal quedar(aK


xxx ; instruccin cualquiera xxx ; instruccin cualquiera xxx ; instruccin cualquiera xxx ; instruccin cualquiera movlw 0x25 ; carga w con 0x25 call tempo ; llamada al subprograma xxx ; instruccin cualquiera, el programa continua aqu xxx ; instruccin cualquiera xxx ; instruccin cualquiera movlw 0x50 ; carga w con 0x50 call tempo ; llamada al subprograma xxx ; instruccin cualquiera, el programa continua aqu xxx ; instruccin cualquiera movlw 0x10 ; carga w con 0x10 call tempo ; llamada al subprograma xxx; instruccin cualquiera, el programa continua aqu

N tendremos una temporizacin varia&le sin tener que escri&ir nuestra rutina de temporizacin cada vez que necesitemos un tiempo di4erente" <*ora #a sa&e que es una su&rutina" EHn juego de ni)os' noF 9.28 La instruccin RETLW (RETurn with Literal in W) 6etorno de su&rutina con el valor literal en el registro W" ,s una instruccin mu# simple" ,s equiva$ lente al return visto antes pero saliendo con un valor especi4icado en W" Sin"$9is
retlw k ; k -> (w) puis (pile)->(pc)

>i" $,e("$)* )e& %e1is"%* STATUS 1inguno" E2e.#&*


test ; etiqueta de comienzo de subrutina btfss mavariable,0 ; mira el bit 0 de mavariable retlw 0 ; si vale 0, fin fin de subprograma con (w)=0 retlw 1 ; si no, salimos con (w) = 1

72

,l programa que llam a la su&rutina conoce el resultado de la operacin por medio de la lectura del registro 3" ,l inter-s del ejemplo es mu# limitado' pero le muestra cmo proceder con esta instruc$ cin"

9.29 La instruccin RETFIE (RETurn From IntErrupt) 6etorno de interrupcin" 9rataremos en un capitulo separado qu- son las interrupciones" .er(a idiota en$ cajar todo un capitulo en la e+plicacin de una instruccin" .epa de todas 4ormas' que esta instruccin e4ectDa un retorno de una interrupcin de la misma manera que return lo *ace desde un su&programa' salvo que' dado que ret4ie relanza autom%ticamente las interrupciones' *a&r% una operacin suplemen$ taria realizada" Sin"$9is
retfie ; retour dinterruption

>i" $,e("$)* )e& %e1is"%* STATUS 1inguno" 9.30 La instruccin CLRF (CLeaR F) Porra el contenido del emplazamiento :" .implemente pone a B el valor del emplazamiento" Sin"$9is
clrf f ; (f) = 0

>i" $,e("$)* )e& %e1is"%* STATUS \ vale siempre 1 despu-s de esta instruccin" E2e.#&*
Clrf mavariable ; (mavariable) = 0

9.31 La instruccin CLRW (CLeaR W) Porra el contenido del registro W" ?ic*o de otra 4orma' pone a B el acumulador" Sin"$9is
clrw ; (w) = 0

,s una instruccin que no ser(a indispensa&le puesto que podr(amos *acer ` movl3 ' B " 8a di4erencia estri&a en que con 86W se posiciona a 1 el &it \" >i" $,e("$)* )e& %e1is"%* STATUS \ vale siempre 1 despu-s de esta instruccin"
73

9.32 La instruccin CLRWDT (CLeaR WatchDog) 6earma el perro guardi%n 23atc*dog5 de su programa" 9rataremos la puesta en marc*a de esta parte con posterioridad" .epa que este es un mecanismo mu# pr%ctico que nos permite resetear el PIC en caso de &loqueo del programa 2un par%sito por ejemplo5" ,l mecanismo es de todas 4ormas mu# simple de entenderK se trata para su programa de enviar esta ins$ truccin a intervalos regulares" .i el comando no es reci&ido en un tiempo determinado 2programa&le5' el PIC re arranca desde la direccin B+BB" ,s como el mecanismo llamado /de *om&re muerto0 utilizado por los conductores de trenes que de&en pulsar un &otn a intervalos regulares" .e detecta as( si el con$ ductor est% siempre en el de&ido estado de atencin' # por lo tanto vivo" Sin"$9is
clrwdt ; (wdt) = 0

>i" $,e("$)* )e& %e1is"%* STATUS 1inguno" 9.33 La instruccin COMF (COMplement F) ,4ectDa el complemento a 1 de un emplazamiento de memoria especi4icado" ?ic*o de 4orma m%s eviden$ teK invierte todos los &its de un emplazamiento" Sin"$9is
comf f , d ; NOT (f) -> (d)

>i" $,e("$)* )e& %e1is"%* STATUS \ E2e.#&*


movlw B11001010 ; carga el valor en W movwf mavariable ; inicializa mavariable comf mavariable,f ; invierte el valor de los bits ; (mavariable) = B00110101

J&serve que si precisa 3 como destino' posicionar% \ sin modi4icar la varia&le" TRUCOK si #%e(is$.*s : (*.* )es"in* #*)%e.*s (Me3'e$% si &$ v$%i$!&e v$&e 49FF sin .*)i,i($%&$/

74

9.34 La instruccin SLEEP (Dormir) .itDa el PIC en modo dormido" Para la ejecucin del programa # disminu#e el consumo el-ctrico" .olo se despertar% &ajo ciertas condiciones especiales que veremos m%s tarde" Sin"$9is
sleep ; Silencio, estoy durmiendo !

>i" $,e("$)* )e& %e1is"%* STATUS 9B ' P? K estos &its ser%n descritos en el estudio de los modos de reset del PI "

9. 35 La instruccin NOP (No Operation) 1inguna operacin" omo am&os de&emos estar cansados a estas alturas' le presento la operacin que no *ace nada' no posiciona nada # que no modi4ica nada" Parecer(a que no sirve para nada" ?e *ec*o se utiliza ma#oritariamente para perder tiempo" Sin"$9is
nop ; Parecer que se trabaja ya es un trabajo !

N aqu( aca&a el an%lisis de las 35 instrucciones utilizadas normalmente en los PI ! de rango medio" 8e puede parecer arduo pero practicando un poco conocer% r%pidamente todas estas instrucciones intuiti$ vamente" Para su consuelo' piense que ciertos procesadores de tecnolog(a I. disponen de varios centena$ res de instrucciones" 9.36 Las instrucciones obsoletas Guedan aDn 2 instrucciones que se utilizaron en versiones precedentes de PIC16F" 9odav(a son reco$ nocidas por el PIC16F84 pero su utilizacin est desaconsejada por Microchip. .u compati&ilidad 4utura no est% garantizada" .e trata de la instruccin JP9IJ1 que sitDa el contenido del registro W en el registro OPTIONNREB' # de la instruccin TRIS que sitDa el contenido del registro O en el registro TRISA o TRIS> dependiendo de si utilizamos TRIS PORTA o TRIS PORT>" ,stas instrucciones #a no son necesarias puesto que estos registros #a son accesi&les directamente me$ diante m-todos cl%sicos" 8e aconsejo encarecidamente el evitar utilizarlas' so pena de encontrar pro&lemas con 4uturas versiones de los PIC de Microchip" .e las *e presentado para que sea capaz de comprender un programa que eventualmente las *a#a utili$ zado"

75

10. Los modos de direccionamiento


9odas las instrucciones usan una manera particular de acceder a las in4ormaciones que manipulan" ,s a estos m-todos a los que llamaremos /modos de direccionamiento0" >emos *a&lado de di4erentes modos de direc$ cionamiento en el estudio de las instrucciones' de&er(a a estas alturas sa&er que es un direccionamiento lite$ ral o inmediato o un direccionamiento directo" Vo# a comenzar simplemente dando un ejemplo concreto de cada modo de direccionamiento" .upongamos que desea em&olsarse cierta cantidad de dinero"

10.1 El direccionamiento literal o inmediato


on el direccionamiento inmediato podremos decirK @P* .e e.!*&s* 144QA ,l valor 4orma parte de la 4rase de 4orma inmediata" >e dic*o literalmente la cantidad de dinero de la que *a&lamos" 1o tengo necesidad alguna de m%s in4ormacin para sa&er el dinero que vo# a tener en el &olsillo" E2e.#&*
movlw 0x55 ; cargar el valor 0x55 en W

10.2 El direccionamiento directo


on el direccionamiento directo podremos ir al &anco # decirK @R'ie%* e.!*&s$%.e e& (*n"eni)* )e &$ ('en"$ nS 1J34?6A <qu( la direccin donde se encuentra el dinero est% indicada directamente en la 4rase" < pesar de ello' ten$ dremos que ir a ver a la cuenta nS 123456 para sa&er cu%nto dinero vo# a em&olsarme" ,4ectivamente' vo# a o&tener el dinero que se encuentre dentro de la cuenta nS 123456 # no el montante de 123456g 2lo sentimos muc*o5" 1o nos meteremos en el &olsillo el nDmero de la cuenta sino lo que esta con$ tenga" E2e.#&*
movf 0x10 , W ; cargar el contenido del emplazamiento 0x10 en W

10.3 El direccionamiento indirecto


<*ora podemos imaginarnos que nos vamos a em&olsar el dinero que tiene un amigo mio en su cuenta" Po$ demos decirK @Mi $.i1* .e v$ $ )e(i% s' n-.e%* )e ('en"$ T T* .e v*T $ e.!*&s$% s' (*n"eni)*A

9enemos que realizar varias operaciones para tener el dinero en nuestro &olsillo"

Primero' pedir el nDmero de cuenta de nuestro amigo 2simp%tico el c*aval5" 76

=irar que *a# en la cuenta" <*ora #a si sa&emos que nos vamos a meter al &olsillo"

,s lo mismo que decir que vamos a o&tener el nDmero de cuenta de 4orma indirecta con la inestima&le a#uda de nuestro amigo" Hsted no se mete en el &olsillo ni a su amigo 2el po&re5 ni el nDmero de cuenta a pesar de que ese nDmero se lo *a suministrado su amigo" ,l camino de acceso al dinero es muc*o m%s indirecto que previamente" A.i1* ('en"$ !*&si&&*

omo resumenK Di%e((i*n$.ien"* &i"e%$&K Di%e((i*n$.ien"* )i%e("*K Di%e((i*n$.ien"* in)i%e("*K )ine%* !*&si&&* E('en"$F !*&si&&* E$.i1*E E('en"$F

!*&si&&*

.i *a entendido esto' *a entendido todo" omo es necesario un elemento de /indireccin0 2su amigo5 esto se traduce en los PI en la presencia de una serie de registros particulares" ,+amin-mosles"

10.3.1 Los registros FSR et INDF


INDF signi4ica INDirect File" E8o veF ,s el 4amoso registro de la direccin B+BB" ,n realidad este registro no e+iste verdaderamente' es simplemente una 4orma particular de acceder a FSR utilizada por los PIC por ra$ zones de 4acilidad de construccin electrnica interna" ,n ciertos micros el modo de direccionamiento indirecto est% indicado en la propia instruccin" ,n los PI 16:' el modo de direccionamiento indirecto utiliza un pseudo$registro para acceder" ?e nuevo un modo presente no listado en la lista de instrucciones e+plicitas" ,l registro :.6 en s( mismo' se encuentra en la direccin B+B4 en los 2 &ancos" 1o es necesario pues' cargar el &anco para acceder a -l" :.6 s( es un verdadero registro" ,n el ejemplo precedente' su amigo est% representado por :.6" ,l direccionamiento indirecto es un poco par$ ticular en los PIC puesto que es siempre la misma direccin donde encontraremos la direccin de destino" omo resumen' podemos decir que usted solo tiene un Dnico amigo" <4ortunadamente su Dnico amigo dispo$ ne de numerosas cuentas" E mo se desarrolla esto en la pr%cticaF Primero tenemos que escri&ir el puntero de la direccin 2el nDmero de cuenta5 en el registro :.6" < continua$ cin accederemos a este puntero de direccin mediante el registro I1?:" Podemos decir que I1?: es de *ec*o el registro :.6 utilizado para acceder a la caja de memoria" Por lo tanto' cuando queremos modi4icar la caja de memoria punteada' modi4icamos :.6" uando queremos conocer la di$ reccin de la caja de memoria accedemos igualmente a :.6" .i queremos acceder al contenido de la caja ac$ cedemos v(a I1?:" Veremos todo esto con un peque)o ejemplo m%s adelante" ATENCION ,l contenido del registro :.6 apunta a una direccin de ; &its" J' en ciertos PIC' la zona de 6<= dispone de 4 &ancos 216:;765 por lo tanto 512 posiciones" 8a direccin completa es una direccin de Q &its"

77

,sta direccin completa se o&tiene' en direccionamiento directo' a)adiendo los &its 7 # ; &ajo la 4orma de RP4 # RP1" Por contar' en el direccionamiento indirecto' la direccin se completa a)adiendo el &it ; &ajo la 4orma de I6P" 1o se con4unda" ,n el caso del 16:;42<5' la 6<= dispone de 256 posiciones por lo que puede ser codi4icada con ; &its" RP1 e IRP no se utilizan" ,s conveniente dejarlos a B" EUEMPLO
movlw 0x50 ; cargamos un valor cualquiera movwf mavariable ; y lo ponemos en mavariable movlw mavariable ; cargamos la DIRECCION de mavariable en W ;por ejemplo en las lecciones precedentes era 0x0E movwf FSR ; ponemos la direccion en FSR. ; decimos que FSR apunta a mavariable movf INDF,w ; cragamos el CONTENIDO de INDF en W.

E& (*n"eni)* )e INDF es "%$)'(i)* #*% e& PIC (*.* e& (*n"eni)* )e& e.#&$D$.ien"* )e .e.*%i$ $#'n0 "$)$ #*% FS/

10.4 Algunos ejemplos


=e vo# a repetir pero' los modos de direccionamiento de&en de ser comprendidos de 4orma imperativa" =ul$ tiplicando los ejemplos espero que todo el mundo lo entienda" Para los #a *a&ituados a diversos procesado$ res' les pido perdn por las repeticiones" onsideraremos los registros inicializados por el ejemplo precedente"
movlw mavariable

,ste es un direccionamiento inmediato o literal' por lo tanto cargamos el valor de mavaria&le que en realidad corresponde a su direccin" Por lo tanto se colocar% el valor B+B, en el acumulador 3" ,sto se puede recono$ cer por la /&0 de mov&3" <tencin' el valor de mavaria&le no es su contenido es su direccin"
movf mavariable , w

<*ora tenemos un direccionamiento directo por lo tanto iremos a la direccin mavaria&le a ver que contiene en su interior" <ll( recogeremos el contenido # lo cargaremos en 3 por lo que E:F 6 49?4 en nuestro ejemplo" Para el ensam&lador' /mavaria&le0 ser% reemplazada por /B+B,0 por lo que tendremos .*v, 494e5:
movf INDF , w

<*ora tenemos el direccionamiento indirecto" ,ste modo se reconoce inmediatamente por la utilizacin del registro I1?:" ,l ir% a ver el registro :.6' leer% la direccin que contiene' en este caso B+B," < continuacin se va a la direccin que *a le(do # lee el contenido de ese emplazamiento" Por lo tanto' 3 a*ora tendr% el conte$ nido de la direccin B+B,' es decir B+5B"
movf FSR , w

>e aqu( una trampa" ,n e4ecto se trata de un direccionamiento directo" .e colocar% en 3 el contenido del re$ gistro :.6' por lo tanto 494E ser% colocado en 235"

7;

Vo# a terminar con unas peque)as pala&ras para los especialistas en microprocesadores que lean este curso como una puesta a punto" .e *a&r% dado cuenta que no *a&lamos en a&soluto de modos de direccionamiento inde+ado 2post o pre' con o sin o44set5" ,s simplemente porque este modo de direccionamiento no e+iste en los PIC del tipo 16: 2al contrario que en otras 4amilias de PI 5"

7Q

11. Realizacin de un programa embarcado


?esignamos' generalmente' como programa o logicial em&arcado a un programa destinado a ejecutarse lo$ calmente en una carta electrnica con 4uncionalidades *ard3are especi4icas' por oposicin a un programa destinado a ejecutarse en un P generalista" Por otra parte' # vista la actual evolucin' la lgica em&arcada comienza a cu&rir mu# diversas realidades' desde las ta&let a los smartp*ones' o incluso cartas equipadas con micros so&re las que se *ace correr un sistema operativo 2J.5" .e tiende a asociar la e+presin em&arcado a la e+presin mvil' en todo caso todos estos l(mites comienzan a estar mu# di4uminados" ,n lo que a nosotros concierne' usaremos el termino em&arcado designando a una tarjeta electrnica equipada con un PIC" Vamos' pues' a comenzar con la parte divertida" Vamos a crear peque)os programas so&re una tarjeta equi$ pada con un"

11.1 El material necesario


Htilice una tarjeta de prue&as constituida por peque)os agujeros unidos por 4ilas" 8as uniones se realizan por medio de ca&les al aire" Podr% encontrar estas tarjetas en cualquier comercio de material electrnico" onec$ te el cuarzo lo m%s cerca posi&le del PI sin ca&les adicionales" Para poner en pr%ctica estas lecciones le *ar% 4alta el siguiente material 2recupera&le # poco oneroso5K 1 PIC 16:;4 16:;4< en encapsulado P?IP # de cualquier 4recuencia" 1 cuarzo de 4 =*z 2 condensadores de 27 p: 1 8,? rojo 1 resistencia de 33B J*ms 1 pulsador 1"J" 2normalmente a&ierto5 1 poco de ca&le r(gido para las cone+iones en la tarjeta de prue&as" 1 alimentacin esta&ilizada de 5 V continua"

.i no dispone de una 4uente de alimentacin de 5 V dc puede utilizar una pila de petaca de 4'5 V o construir la peque)a 4uente de alimentacin cu#o esquema se suministra m%s adelante" ,n este caso' adem%s le *ar% 4alta el siguiente materialK 1 alimentador de tensin continua de entre 9 a15 V (no es crtico)" 1 condensador de 1B a1BB F/35V. 1condensadores de 0.1 F. 1 diodo 114BB4 o equivalente que permita una corriente de 1 < 2no es cr(tico5" 1 regulador del tipo 7;B5

;B

,s un montaje que no le arruinar%" ,s m%s' podr% recuperar los componentes para pr+imas realizaciones" Ver% que los PIC pueden ser utilizados en toneladas de aplicaciones de la vida cotidiana" ?e todas 4ormas' comprenda que de&er% construirse o comprar un programador de 2gra&ador o tostadora5" Vea el ane+o <1"; para m%s detalles"

11.2 Montaje de la placa de pruebas


Inserte el zcalo" Inserte el resto de componentes en la tarjeta # proceda a las cone+iones segDn el esquema adjunto" Veri4ique todo antes de conectar la alimentacin" <ntes de insertar el PIC en el zcalo comprue&e todo una vez m%s" onecte la alimentacin # comprue&e en el zcalo la presencia de las alimentaciones necesarias para el PIC" .i todo est% correcto' desconecte la alimentacin' inserte el PIC y vuelva a conectar la alimentacin"

Es3'e.$ )e (*ne9in )e& PIC En* *&vi)e (*ne("$% MCLR $ V))F

Es3'e.$ )e &$ ,'en"e )e $&i.en"$(in si ,'ese ne(es$%i$/

;1

11.3 Creacin de un proyecto


<*ora est% usted preparado para empezar con los e+perimentos" ,4ectDe una copia de su 4ic*ero m16:;4"asm # renm&relo como 8eddclic"asm" <rranque MPLAB # res$ ponda 1J si le pregunta si quiere cargar ,ssai1" ,n MPLAB usted sa&e #a como crear un pro#ecto" ree el pro#ecto 8eddcli en su directorio de tra&ajo (project->new project)" .i tiene una ventana a&ierta llamada untitled ci-rrela pre4eri&lemente" .i tiene una versin m%s reciente de MPLAB que le pregunta acerca de qu- tipo de ejecuta&le desea' elija Absolute " 1o se olvide de a&rir el 4ic*ero Led_cli.asm " ?e nuevo' este 4ic*ero est% disponi&le como ane+o en su versin terminada"

11.4 Edicin del fichero fuente


omplete la ca&ecera siguiente como desee" 8e indico aqu( a&ajo un ejemplo" <dquiera el *%&ito de docu$ mentar siempre sus programas" 1o es un lujo' es imperativo para un mantenimiento e4icaz en el tiempo"

;************************************************************************** ; PROGRAMA DE INTERMITENCIA DE UN LED CONECTADO EN EL PORTA.2 * ; DE UN PIC 16F84. PROGRAMA DE ENTRENAMIENTO EN EL FUNCIONAMIENTO * ; DE LOS PICS. * ;************************************************************************** ; * ; NOMBRE: LED-CLI * ; Fecha: 09/02/2001 * ; Version: 1.0 * ; Circuito: Placa de pruebas * ; Autor: Bigonoff * ;************************************************************************** ; * ; Fichier requerido: P16F84.inc * ; * ;************************************************************************** ; * ; Notas: Este programa permite hacer parpadear un LED * ; sobre el port A.2 a una frecuencia de 1 Hz * ; Este programa forma parte de la leccin 6 del curso * ; * ;**************************************************************************

;2

11.5 Eleccin de la configuracin.


=%s a&ajo en el 4ic*ero encontrar% lo siguienteK
__CONFIG _CP_OFF & _WDT_ON & _PWRTE_ON & _HS_OSC ; '__CONFIG' precisa los parmetros codificados en el procesador en el momento ; de la programacin. Las definiciones estn en el fichero include. ; He aqu los valores y sus definiciones: ;_CP_ON Code protection ON : imposible releer ;_CP_OFF Code protection OFF ;_PWRTE_ON Timer reset a la conexin en servicio ;_PWRTE_OFF Timer reset fuera de servicio ;_WDT_ON Watch-dog en servicio ;_WDT_OFF Watch-dog fuera de servicio ;_LP_OSC oscilador de cuarzo de bajo consumo ;_XT_OSC oscilador de cuarzo de velocidad media externo ;_HS_OSC oscilador de cuarzo de gran velocidad ;_RC_OSC oscilador red RC

>e incluido los comentarios en el 4ic*ero de 4orma que sea r%pidamente modi4ica&le sin tener que recurrir al datas*eet" 1ote que e4ectuamos un /N lgico0 2T5 entre los di4erentes valores' los niveles activos son' pues' niveles B da$ do que un /<1?0 solo nos permite imponer valores B" ?e&er% precisar todos los valores que no utilice sin los cuales no podr(a 4orzar los 1 correspondientes" ,l primer par%metro precisa que su PIC estar% protegido o no contra la lectura una vez programado" ?eje este par%metro en PdJ:: L no protegido" ,l segundo par%metro precisa si el perro guardi%n 23atc*dog5 est% puesto en servicio o no" ,n un primer mo$ mento reemplace W?9dJ1 por W?9dJ:: para ponerlo 4uera de servicio" ?eje PW69,dJ1 para precisar que va a utilizar un m-todo de reset securizado' con un tiempo de retardo an$ tes del arranque" ,sto le protege en caso de alimentaciones un poco lentas en arrancar" ,+plicar- esto m%s tarde" <l 4inal viene el tipo de oscilador que se va a utilizar" 8a ta&la ;$1 de la pagina 4B da los valores recomendados en 4uncin de las 4recuencias utilizadas para un PIC de 1B =*z" 6etenga que el valor d>.dJ. es conveniente con 4recuencias elevadas' a partir de 4 =*z" J&serve que a esta 4recuencia el modo d>.dJ. tam&i-n 4uncionaria" ,s importante no utilizar el modo d6 dJ. si utilizamos un cuarzo" ,ste par%metro est% reservado para un 4uncionamiento con una red 6 como la di&ujada en la 4igura ;$7 de la pagina 41" E& Me(M* )e '"i&iD$% e& #$%L.e"%* RC (*n 'n %e&*2 e9"e%n* #'e)e en"%$7$% &$ )es"%'((in )e& PIC/ <unque los PIC son componentes mu# slidos en la pr%ctica' evite equivocarse a este nivel" 8a l(nea de&er(a quedar as(K
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC

;3

11.6 El registro OPTION


.i o&serva la ta&la 4$2 compro&ar% que este registro se encuentra en la direccin de memoria B+;1' es decir en el &anco 1" ,n los 4ic*eros include de MPLAB este registro est% declarado con el nom&re de OPTION_REG" ,s este nom&re el que usted de&e utilizar" Vamos a dar aqu( los detalles" ,ste registro es un registro de &its' es decir que cada &it tiene un cometido particular" 8a ta&la de la pagina 16 representa el contenido de este regis$ troK

b7 : RBPU
uando este &it est% a B 2activo a nivel &ajo5 una resistencia re4erida a M5V se conectar% so&re cada pin del PJ69P" Veremos en esta leccin el 4uncionamiento del PJ69P" .i o&serva nuestro esquema ver% que el pul$ sador conectado a 6P2 pone este pin a masa cuando se le pulsa" 1o e+iste en nuestro esquema ninguna posi&ilidad de enviar M5V" Validando esta opcin' la resistencia interna 4uerza el pin 6P2 a 1 cuando el &otn no est% pulsado" 9enga en cuenta que esta opcin v%lida las resistencias para todo el PJ69P" 1o es posi&le elegir ciertas resis$ tencias en particular" ?e *ec*o esta opcin solo e+iste para el PJ69P" >a&r% o&servado que todos los puertos no son igualesK *a# que pensar en ello en el momento de la concep$ cin de un circuito" ,n nuestro caso pondremos las resistencias en servicio con &7LB" 6ecuerde que durante el desarrollo de aplicaciones con PI . de&er(a pensar simult%neamente en el esquema # en el programa" ,s una costum&re a adquirir"

b6 : INTEDG
?a' en el caso de utilizacin de las interrupciones so&re 6PB' el sentido de desencadenamiento de la interrup$ cin" .i &6L1 la interrupcin se dispara cuando 6PB pasa de B a 1 24lanco ascendente5" .i &6LB la interrupcin se dispara cuando 6PB pasa de 1 a B 24lanco descendente5" omo no vamos a utilizar interrupciones en esta leccin' podemos dejar &6 a B"

b5 : TOCS
,ste &it determina simplemente el 4uncionamiento del temporizador B 2timerB5" 6ecuerde que el timerB se in$ crementa &ien en 4uncin del reloj interno con &5LB o &ien contando los impulsos reci&idos por el pin 6<4 en el caso de &5L1" omo este Dltimo caso necesita un circuito de generacin de impulsos e+ternos' nosotros vamos a utilizar el reloj interno por lo que &5LB"

b4 : TOSE
?a' en el caso de tener el &it 5 a 1 2impulso e+terno5 el sentido de transicin que determinar% el contaje del timerB" .i &4L1 se contar% si la se)al pasa de 5V a BV' si &4LB a la inversa" omo *emos situado &5LB' &4 estar% inutilizado para nosotros por lo que lo dejaremos a B"

b3 : PSA
,n el PIC tenemos un pre divisor" EGu- es estoF Indica el nDmero de impulso que de&eremos reci&ir para provocar un incremento del timerB" Na volveremos a ello m%s tarde" Por a*ora &asta conocer que este pre di$ visor nos puede servir para una de las dos 4unciones siguientes 2# no para las dos5" ;4

J &ien e4ectDa una pre divisin del temporizador del perro guardi%n 2&3L15 o &ien e4ectDa una pre divisin a nivel del timerB 2&3LB5" ,n nuestro caso pondremos &3L1 2veremos por qu- m%s a&ajo5"

b2, b1,b0 : PS2,PS1,PS0


,stos tres &its determinan el valor de la pre divisin vista anteriormente" >a# ; valores posi&les mostrados en la ta&lita de la pagina 16" 1tese que los valores son di4erentes para el 3atc*dog o para el timerB" ,n e4ecto' no *a# divisor por 1 para este Dltimo registro" .i no desea utilizar pre divisor de ninguna manera' el Dnico m-todo es poner &3L1 2pre divisor en el 3atc*$ dog5 # P.2' P.1 # P.B a B" ,n este caso' no *a# pre divisor so&re timerB # *a# pre divisor por 1 so&re el 3atc*$ dog' lo que corresponde a o tener pre divisor" 1osotros pondremos P2L&1L&BLB"

11.7 Edicin del programa


Vamos a utilizar el valor POBBBB1BBB en nuestro programa' es decir el valor B+B;" 9engo la costum&re de no colocar los valores 4ijos a lo largo del programa a 4in de 4acilitar el mantenimiento" oloco los valores en el comienzo del programa utilizando asignaciones o de4iniciones" 8a asignacin #a *a sido creada m%s a&ajo en el programa" >e creado una constante que llamo OPTIONVAL # que contendr% el valor a colocar m%s tarde en el registro OPTION_REG" 8e recuerdo que las cons$ tantes no ocupan espacio en el PIC' simplemente son reemplazadas por el ensam&lador en el momento del ensam&lado" .irven para 4acilitar la lectura del programa" Pusque m%s a&ajo en el programa despu-s de las asignaciones # reemplace el valor a4ectado a JP9IJ1V<8 por aquel que *emos determinado # a)ada comentarios" .uprima la asignacin I19,6=<.U dado que no vamos a utilizar interrupciones en este primer programa" ,n la zona de asignaciones se tendr% que verK
;********************************************************************* ; ASIGNACIONES * ;********************************************************************* OPTIONVAL EQU H'08 ; Valor del registro OPTION ; Resistencias pull-up ON ; Sin pre divisor

Pajemos *asta la zona de de4iniciones" Vamos a dar un nom&re a nuestro &otn # a nuestro 8,?" 8as instrucciones &c4 # &s4 que vamos a utilizar para poner o leer a 1 o a B los registros' tienen la siguiente sin$ ta+isK bsf f , n # los registros de acceso se llaman PORTA 2para el puerto <5 # PORTB 2para el puerto P5" Vamos a utilizar la directiva #DEFINE para integrar 4 # n al mismo tiempo" Vemos en el esquema que el 8,? est% conectado al &it 2 del puerto <" ,l &otn est% conectado al &it 2 del puerto P" Porraremos las de4iniciones de ejemplo # escri&iremos las nuestras' quedando de la siguiente 4or$ maK

;********************************************************************* ; DEFINE * ;********************************************************************* #DEFINE LED PORTA,2 ; Led rojo #DEFINE BOUTON PORTB,2 ; boton

;5

8,? # PJH9J1 son dos nom&res que *emos elegido li&remente' a condicin de que no se traten de algDn nom&re reservado" 1ada de utilizar .9<9H. o =JV8W" EPara qu- sirven las de4inicionesF .upongamos que decide conectar el 8,? so&re el PJ69P &it1 26P15 por ejemplo" 1o tendremos necesidad de &uscar a lo largo de todo el programa' &astar% simplemente con cam&iar la zona ?,:I1," <dem%s' cuando lea el programa el t-rmino 8,? ser% muc*o m%s e+plicito que el de PJ69<'2" 6ecuerde priorizar la legi&ilidad # manteni&ilidad de un programa e+cepto cuando tenga la necesidad de recurrir a diversas optimizaciones" ?escendemos un poco m%s # llegamos a la zona de macros" 1o tenemos verdaderamente necesidad de utili$ zarlos' pero vamos a *acerlo a t(tulo de ejemplo" Porremos la macro de ejemplo # escri&amos las nuestrasK
;********************************************************************* ; MACROS * ;********************************************************************* LEDON macro bsf LED endm LEDOFF macro bcf LED endm

8a primera columna indica los nom&res de las macros 2aqu(' 2 macros' 8,?J1 # 8,?J::5" 8a directiva macro signi4ica /comienzo de la macro0 # la directiva endm signi4ica /4in del a macro0" J&serve que las macros pue$ den estar constituidas por multitud de l(neas de cdigo" J&serve tam&i-n' que una macro puede utilizar una de4inicin 28,?5 toda vez que se trata de un simple tra$ tamiento de te+tos" 9omemos nuestro ejemploK cuando utilicemos la l(nea siguiente en nuestro programa 2atencin @ no poner el nom&re de la macro en la primera columna cuando se utilice5K
LEDON

,n el momento del ensam&lado' nuestro ensam&lador reemplazar% 8,?J1 porK


bsf LED

N reemplazar% 8,? porK


bsf PORTA , 2

<ca&amos de utilizar una 4acilidad de escritura # mantenimiento de los programas" 6ecuerde siempre que las macros son simples sustituciones de te+to" .i su macro se compone de 5B l(neas de cdigo' cada vez que utili$ ce la macro se a)adir%n al programa 5B l(neas de cdigo m%s" 8legamos a la zona de las varia&les" <)adiremos varia&les en la medida de su necesidad" Porre las 2 varia&les presentes puesto que no vamos a utilizar interrupciones"

;6

;********************************************************************* ; DECLARACION DE VARIABLES * ;********************************************************************* CBLOCK 0x00C ; comienzo de la zona de variables ENDC ; Fin de la zona

?espu-s de la directiva J6Y B+BB' dejamos la llamada a la rutina de inicializacin" 9odo programa comporta una etapa de inicializacin de varia&les # registros" oja la costum&re de separar esta inicializacin del resto del programa" omo no vamos a utilizar las interrupciones' suprima todo lo que sigue justo *asta la rutina de inicializacin' o&teniendoK

********************************************************************** ; ARRANQUE DESPUES DEL RESET * ;********************************************************************* org 0x000 ; Direccin de arranque despus de reset goto init ; Directions 0: inicializar ;********************************************************************* ; INITIALISATIONS * ;********************************************************************* init: continuacion del programa

<ntes de seguir' primero vamos a estudiar los registros que vamos a utilizarK

11.8 El registro PORTA


,ste registro es un poco particular puesto que da acceso directamente al mundo e+terior" ,s un registro que representa la imagen num-rica 2B # 15 de los pines de 6<B a 6<4' es decir' 5 pines" .i me *a seguido' es el re$ gistro que nos servir% para encender el 8,?" ,ste registro se sitDa en la direccin B5> del &anco B" ada &it del registro representa un pin' por lo que solo 5 &its son utilizados" Para escri&ir so&re un pin de salida ponemos a 1 o a B el &it correspondiente segDn el nivel de salida deseado" Por ejemploK
bsf PORTA , 1 ; enviar nivel 1 sobre RA1

Pone un nivel M5V 2MVdd para ser precisos5 en el pin 6<1" >ace 4alta para esto que el pin est- con4igurado co$ mo salida 2ver 96I.<5" Para compro&ar una entrada' podremos' por ejemplo' utilizarK
btfss PORTA,3 ; comprueba RA3 et salta si vale 1 (>2.5V)

Para los electrnicos' tienen el esquema interno de los &its de 6<B a 6<3 en la 4igura 5$1 de la pagina 21" Pueden ver que la salida puede ser puesta a nivel alto o &ajo gracias a dos transistores de salida 2en montaje pus*$pull5" uando estos pines est%n programados como entradas' son sensi&les a niveles BR5V" ,l nivel de transicin depende del modelo de PIC' pero se sitDa generalmente en la mitad de la tensin de alimenta$ cin" Hna entrada al aire es vista como nivel B" ?e todas 4ormas' ev(telo por pro&lemas de sensi&ilidad a par%$ sitos" ;7

Para el pin 6<4' ver 4igura 5$2' en salida la con4iguracin es del tipo drenador a&ierto # en entrada se compor$ ta como un trigger$.c*mitt" .i no tiene los conocimientos electrnicos necesarios' sepa simplemente que este pin en salida puede imponer un nivel B pero no un nivel 1" .i conecta aqu( un led con respecto a masa jam%s podr% encenderlo" 8os puertos disponen de un diodo de proteccin *acia el BV # *acia el 5V" ?e tal 4orma' con una simple resis$ tencia en serie podr% enviar se)ales *acia estos pines 4uera de la gama de tensin VssRVdd" <9,1 IJ1K .i env(a una tensin tal que la corriente drenada por los diodos de limitacin *acia Vdd llega a ser superior a la corriente a&sor&ida por el PI ' esta corriente va a /alimentar0 su alimentacin que se ver% solici$ tada a a&sor&erla" .i su alimentacin no est% conce&ida para regular una corriente inversa' el riesgo es que Vdd aumente de tal 4orma que provoque la destruccin del PI " Por lo tanto' no utilice este truco de cone+ionado si carece de los conocimientos en electrnica su4icientes pa$ ra prevenir las consecuencias" ?e nuevo' el pin 6<4 es una e+cepcin a la regla puesto que no dispone de diodo *acia masa" omo resumen' los pines 6<B a 6<3 pueden ser utilizados como entradas de niveles BR5V o como salidas en$ viando BV # 5 V" ,n cuanto al pin 6<4 como salida' no puede enviar 5V" 9enga en cuenta estas especi4icaciones cuando va#a a construir su montaje" Por ejemplo' si *emos situado nuestro led entre 6<4 # Vss' jam%s podremos encenderlo" < partir de la p%gina 75 del datas*eet' capitulo 11' tiene las caracter(sticas m%+imas de 4uncionamiento del PIC" Puede recordar simplemente de limitarse a un m%+imo de 2B m< por pin de salida' con un m%+imo de ;B m< por el PJ69< # 15B m< por el PJ69P" .i va a utilizar caracter(sticas mu# cercanas a estos l(mites' analice las ta&las con m%s detenimiento teniendo en cuenta los l(mites de potencia disipada # temperatura as( como las in#ecciones de tensin" 1osotros no tendremos estos pro&lemas a lo largo de nuestros ejercicios" ,l consumo de nuestro led so&re 6<2 responde a la 4ormula apro+imada siguienteK I19,1.I?<?K 25V e 9ension 8ed5 R 33B J*ms L 25V e 1'75V5R33B L Q';5 m< J&serve' # es mu# comDn en un gran nDmero de microprocesadores' que es pre4eri&le manejar una carga so$ &re el nivel B 2carga conectada entre el pin # Vdd5 que so&re el nivel 1 2carga conectada entre el pin # Vss co$ mo en nuestro montaje5" ,sto es as( de&ido a que las so&retensiones para enviar un 1 son ma#ores que al enviar un B de&ido a la tecno$ log(a utilizada" .i *emos adoptado la /mala0 4orma de *acerlo es de&ido a que' procediendo de la mejor manera' *a&r(a que invertir todo el razonamientoK enviar un B para encender # enviar un 1 para apagar" 9rat%ndose de un curso did%ctico para aprender a programar' *e tratado de ser lo m%s intuitivo en la medida de lo posi&le"

;;

11.8.1 Funcionamiento particular de los PORTS


<cu-rdese que toda operacin so&re un &it especi4ico comporta el principio leerRmodi4icarRescri&ir" ,sto es todav(a m%s evidente en las operaciones concernientes a los puertos' tal como el encendido # apagado de un led" Por ejemplo' si escri&imos &s4 PJ69<'1' el PIC proceder% de la siguiente maneraK 1" ,l PJ69< es le(do en su totalidad 2pines de entrada # salida5 2" ,l &it 1 es puesto a 1 3" 9odo el PJ69< es reescrito C*nse('en(i$s i.#*%"$n"es @<tencinA 8o que viene a continuacin es importante" ,s la e+plicacin al 4amoso pro&lema del pin 6<4 con$ 4igurado como salida # que parece cam&iar de valor por s( mismo" Pongamos por ejemplo que el pin 6<4 sea una salida # puesto a 1 por programaK
bsf PORTA,4 ; libera la linea RA4

omo es de drenador a&ierto' supongamos que la electrnica e+terna le 4uerza eventualmente a BK por ejem$ plo conectando el pin 6<4 de 2 PI di4erentes para o&tener una especie de J6 lgico" J el caso cl%sico de uti$ lizar 6<4 para pilotar el reloj de un &us IC" .i a*ora realizamos la siguiente operacinK
bsf PORTA , 1 ; poner RA1 a 1

,l PI proceder% de la siguiente maneraK 1" 8ectura del PJ69<K el PI constata que 6<4 est% a B 2aunque el programa lo puso a 15" 2" Pone el &it 1 a 1" 3" ,scri&e el PJ69< completo' 6<1L1 # 6<4LB" =oraleja' es a*ora su propio programa 2su PI 5 quien &loquea la l(nea 6<4 a B 2aunque *a#a escrito &s4 PJ6$ 9<'45" .i la l(nea es li&erada por el otro componente esta quedar% retenida por su PI sin esperanza de ser li$ &erada" ,s un mecanismo a tener mu# en cuenta" Peor si escri&e simplemente lo siguiente' admitiendo que 6P1 # 6P4 est%n como salidasK
bsf PORTB,1 ; on met RB1 1 bsf PORTB,4 ; on met RB4 1

,l resultado parece evidente' puesto que 6P1 # 6P4 son puestos a 1 los dos" ?e nuevo *a# una trampa" Imagi$ nemos que *emos puesto una carga capacitiva mu# grande en 6P1" 8a salida' constituida por la resistencia in$ terna de 6P1 # el condensador de carga' 4orman una red 6 " ,sta red tiene una cierta constante de tiempo" >ace 4alta un cierto tiempo para alcanzar VddR2 # por lo tanto ser considerado un 1" E omprende qu- va a ocurrirF

;Q

,n el instante del &s4 PJ69P'4 suceder%K 1" ,l PI lee el PJ69P pero 6P1 no *a llegado a la tensin su4iciente # aparece como un B" 2" ,l &it 4 es 4orzado a 1 3" ,l PI reescri&e PJ69P # pone 6P1 a B =oraleja' 6P1 no pasar% a 1 # se quedar% 2en este caso preciso5 a B" .i estudiamos el datas*eet a nivel de ca$ racter(sticas el-ctricas' nos damos cuenta que podemos encontrarnos con este caso aunque se respete el da$ tas*eet" Por el contrario' siempre respetando el datas*eet' el tiempo de esta&lecimiento de la se)al perma$ necer% in4erior a un tiempo de ciclo de instruccin" =oraleja' para evitar el pro&lema nos *ar% 4alta a)adir una instruccin /nop0K
Bsf ; PORTB,1 ponemos RB1 a 1 nop ; esperamos a estabilizacion de la tension bsf PORTB,4 ; ponemos RB4 a 1

8uego' e+cepto si *a calculado per4ectamente los tiempos de su&ida de las tensiones de salida en 4uncin de las cargas' de la 4recuencia del reloj # de los ciclos internos de las instruccionesK P*n1$ sie.#%e 'n$ @n*#A en"%e )*s ins"%'((i*nes s'(esiv$s )e .$ni#'&$(in )e #ines si"'$)*s s*!%e e& .is.* #'e%"*/

Por el contrario' en 6<4 /nop0 o no' nada cam&iar%' tendr% que tener en cuenta esta eventualidad # conser$ var en memoria el estado que su programa cree tener impuesto a 6<4" .o&re otros PI ' como los 1;:' este pro&lema no e+iste #a"

11.9 El registro TRISA


,ste registro est% situado en la misma direccin que PJ69< pero en el &anco 1" .u direccin completa en ; &its es B+;5" ,s un registro de 4uncionamiento mu# simple ligado al 4uncionamiento de PJ69<" ada &it posicionado como 1 con4igura el pin correspondiente como entrada" ada &it posicionado como B con4igura el pin correspondiente como salida" ?espu-s de un reset del PIC' todos los pines son con4igurados como entradas con la 4inalidad de no enviar se)ales no deseadas por los pines" 8os &its de 96I.< se pondr%n todos a 1 despu-s de cada reset" omo solo 5 pines son usados en PJ69<' solo los &its de &B a &4 son utilizados por 96I.<" E2e.#&* )e '"i&iD$(in/ 9omemos el esquema de nuestro peque)o circuitoK EGu- tenemos que *acer para encender el ledF 2P?"K no introduzca por a*ora estas instrucciones en nuestro pro#ecto"5 Primero de&eremos con4igurar 96I.< # poner el &it 2 26<25 como salida" omo el registro 96I.< se encuentra en el &anco 1' # el direccionamiento directo solo utiliza 7 &its' de&eremos poner el &it 6PB del registro .9<9H. a 1 2ver cap(tulos precedentes5"

QB

< continuacin podremos enviar un 1 por el PJ69< correspondiente a 5V so&re el pin 6<2" 8a secuencia ser(aK
bsf bcf bcf bsf . . . bcf STATUS ,RP0 ; pasamos al banco 1 TRISA , 2 ; bit 2 de TRISA a 0 = salida para RA2 STATUS , RP0 ; pasamos al banco 0 PORTA , 2 ; enviamos 5V por RA2 : el LED se enciende

PORTA , 2 ; 0V sobre RA2, el LED se apaga

J&serve que como 6<2 quedar% como salida durante todo el programa 2segDn el esquema de nuestra aplica$ cin5' colocaremos el valor de 96I.< en la rutina de inicializacin"

11.10 Los registros PORTB y TRISB


,stos registros 4uncionan e+actamente de la misma manera que PJ69< # 96I.< salvo que conciernen a los ; pines 6P" ,n este caso utilizamos todos los &its" Veamos a*ora las particularidades del PJ69P" Na *emos visto una' puesto que las entradas del PJ69P pueden ser conectadas a una resistencia re4erida a M5V de 4orma interna" 8a seleccin se realizar% por el &it 7 del registro JP9IJ1" ,l esquema interno en las 4iguras 5$3 # 5$4 de la p%gina 23 del datas*eet nos muestra que los &its &B # &4R&7 pueden ser utilizados como 4uente de interrup$ cin' el &it B puede' adem%s' puede ser utilizado de 4orma autnoma para gestionar otro tipo de interrupcin" Veremos el 4uncionamiento de las interrupciones en otro cap(tulo" ?e todas 4ormas' tenga en cuenta a partir de #a que los esquemas que conci&a en un 4uturo de&er%n tener en cuenta todas las particularidades de los PJ69s" NOTA ?espu-s de un reset se preguntar% cual es el estado de tal o cual registro" ,ncontrar% la e+plicacin en la ta&la de la pagina 14" Puede ver' que despu-s de un reset' el registro JP$ 9IJ1d6,Y ver% todos sus &its puestos a 1" ?e&er%' pues' especi4icar el &orrado del &it7 para validar las resis$ tencias de re4erencia a M5V"

11.11 Ejemplo de aplicacin


.iempre partiendo de nuestro esquema' deseamos encender el led cuando presionemos el &otn' # apagarlo cuando soltemos" >e aqu( un ejemplo de programa que necesitar(amos 2ponga atencin a que el nivel so&re 6P2 pasa a B cuando el &otn est% apretado' cone+in a masa5"
bsf STATUS , RP0; pasamos a banco 1 bcf OPTION_REG, NOT_RBPU ; Resistencia de referencia en servicio bcf TRISA , 2 ; bit 2 de TRISA a 0 = RA2 como salida ; no es necesario confirurar TRISB ya est en entrada ; por defecto edspues del reset del PIC bcf STATUS , RP0 ; pasamos al banco 0 boucle btfss PORTB bsf PORTA , btfsc PORTB bcf PORTA , goto boucle , 2 , 2 ; 2 ; mira RB2, salta si vale 1 ; RB2 vale 0, encendemos el LED 2 ; mira RB2, salta si vale 0 ; RB2 vale 1, apagamos el led volvemos a empezar

Q1

11.12 La rutina de inicializacin


,+aminemos las instrucciones a partir de la etiqueta init " 8as 2 primeras l(neas sonK
clrf PORTA ; Salidas portA a 0 clrf PORTB ; Salidas portB a 0

Preparan el 4orzado de las salidas por los puertos a B" on esto' una vez con4igurados los puertos como sali$ das' tendr%n por de4ecto el nivel BV" .i su electrnica requiere otros niveles queda a su cargo el cam&iarlos" 8a l(nea siguiente permite conectarnos al &anco 1" >asta nueva orden las instrucciones siguientes utilizar%n los registros situados en el &anco 1"
bsf STATUS,RP0 ; pasa al banco 1

,n seguida nos encontramos conK


movlw OPTIONVAL ; cargar mascara movwf OPTION_REG ; inicializar el registro OPTION

6ecuerde que JP9IJ1V<8 es una constante" .u valor est% de4inido anteriormente por nosotros a B+;B" ,ste valor ser% enviado al registro JP9IJ1 2JP9IJ1d6,Y5" 6ecuerde tam&i-n que JP9IJ1d6,Y es el nom&re de$ clarado en MPLAB para el registro JP9IJ1" .igue la peque)a rutina destinada a &orrar la 6<=" 6ecuerde que es importante sa&er que a la puesta en ten$ sin la 6<= contiene valores aleatorios" Para evitar malas sorpresas' *e integrado esta rutina en cada re arranque que asegura que la 6<= no contiene otra cosa que ceros" ,sta rutina no es estrictamente necesaria si usted inicializa los valores de las varia&les correctamente antes de utilizarlas" .e trata de una precaucin" Pero esta precaucin cuesta mu# poco' tan solo un peque)o espacio de memoria de programa EPor qu- pri$ varse de ellaF <lguien podr(a argumentar que e+iste una p-rdida de tiempo en la ejecucin del programa' pe$ ro esta p-rdida ocurre solamente en el momento del arranque' por lo que no a4ecta en a&soluto a la veloci$ dad de ejecucin del programa como tal" ,4ecto secundarioK en tanto en cuanto que 4orzamos a B todos los valores de la 6<= tenemos una per4ecta correspondencia entre el simulador # aquello que tendremos en el PI K potenciales errores m%s 4%ciles de depurar"
; -----Borrar la RAM ------

movlw 0x0c ; inicializa el puntero movwf FSR ; punter direccionamiento indirecto init1 clrf INDF ; borrado ram apuntada por FSR incf FSR,f ; punter siguiente btfss FSR,6 ; mira si llegamos al final de la zona (>=0x40) goto init1 ; no, bucle btfss FSR,4 ; mira si llegamos al final de la zona (>=0x50) gotoinit1 ; no, bucle xxxxx ; aqu se encuentra la continuacin del programa

>e aqu( un ejemplo concreto de utilizacin del direccionamiento indirecto 2o&serve la utilizacin de I1?: que caracteriza este tipo de direccionamiento5"

Q2

,n primer lugar' inicializamos el puntero apuntando a la zona a manipular 2aqu( la zona 6<= usuario5" ,sta zona comienza en la direccin B+B 2ver ta&la 4$25 # termina en la direccin B+4: inclusive" 8a zona situada en el &anco 1 no e+iste para este PIC 2imagen del &anco B5 # no necesita ser inicializada" ?espu-s encontramos la instruccin clr4 I1?: que signi4ica &orrar la posicin de memoria apuntada por :.6" Porramos' pues' la memoria situada en B+B " < continuacin incrementamos :.6 que a*ora apuntar% a B+B?" <*ora encontramos 2 compro&aciones" Para salir de esta rutina # alcanzar el punto marcado como /aqu( se encuentra la continuacin del programa0 ser% necesario evitar las 2 l(neas goto" aemos en la primera l(nea goto cuando el &it 6 de :.6 valga B' si no la saltaremos" Para saltar este /goto0 2sXip5' :.6 de&er% valer' al menos' POB1BBBBBB' o B+4B" ,n ese momento las direcciones desde B+B *asta B+3: *a&r%n sido puestas a B" 8legamos a la segunda compro&acin" ,l siguiente goto se ejecutar% solamente si el &it 4 de :.6 vale B" ,n ca$ so contrario se saltar%" 8legaremos a la l(nea /aqu( ]0 Dnicamente cuando los &its 4 # 6 de :.6 sean iguales a 1" ,s decir en POB1B1BBBB' o lo que es lo mismo B+5B" Podrimos igualmente *a&er usado un contador de &ucles # *a&ernos servido de la instruccin )e(,sD" Pero es$ to *a&r(a *ec*o necesaria la utilizacin de una varia&le" ,sta varia&le *a&r(a sido &orrada por la propia rutina con el consiguiente &loqueo del programa lo que *u&iese *ec*o necesarias precauciones adicionales" ,l m-todo presentado aqu( es el m%s simple # e4icaz" Porre las siguientes l(neas que no nos interesan para nuestro programa"
bcf TRISA,0 ; Bit PORTA.0 en sortie (exemple) bcf STATUS,RP0 ; Slectionner banque 0 movlw INTERMASK ; masque interruption movwf INTCON ; charger interrupt control

?e&eremos inicializar 6<2 como salida para poder utilizarla con el led" 8a instruccin ser% 2recuerde que es$ tamos so&re el &anco 1 aDn5K
bcf TRISA , 2

>a&(amos declarado en las de4iniciones que 8,? era un alias de PJ69<'2 para permitir cam&iar 4%cilmente el led a otro pin" EGu- pasar% si escri&imos &c4 8,? F <lgunos dir%n que /apagamos el 8,?0" ,n a&soluto" Para aquellos que #a *a#an visto el truco' 4elicitaciones" ?e *ec*o' esta instruccin ser% reemplazada ciegamente por el ensam&lador por la siguienteK
bcf PORTA , 2

,s m%s' despu-s de una nueva sustitucin del ensam&lador de&ida a la declaracin en nuestro 4ic*ero p16:;4"inc quedar%K
bcf 0x05 , 2

omo 6PB est% posicionado a 1 cuando se ejecuta esta l(nea' estaremos apuntando constantemente al &anco 1" .i miramos que *a# en la direccin B+B5 del &anco 1' es decir en la direccin B+;5' encontrar% que est% 96I$ .<' por lo que la operacin lo que *ace es poner 6<2 como salida"

Q3

am&iando simplemente la de4inicin 8,? al principio del programa podremos cam&iar todas las re4erencias a 6<2 en el programa' incluso para 96I.<" orolarioK no es de&ido a la utilizacin de hde4ine por lo que todo se resuelve como por arte de magia la seleccin del &anco correcto' *a# que mantenerse siempre atento" Ponga un peque)o comentario en la ca&ecera # tendr%K
; inicializaciones especificas ; --------------------------bcf LED ; LED en salida (banco 1)

Va#a al &anco B antes de a&andonar la inicializacin" ,s una &uena pr%ctica puesto que muc*os errores vienen de olvidos en el cam&io de &ancos" <)adaK
bcf STATUS , RP0 ; pasar al banco 0

N termine con la l(nea


goto start

Gue le env(a al programa principal" Por el momento puede parecer inDtil puesto que lo que sigue a continua$ cin es el programa principal' pero m%s adelante vamos a a)adir su&programas # los vamos a intercalar aqu(" >e aqu( a lo que de&er% parecerse su rutina de inicializacin' que de&er(a comprenderla en su totalidad" ,sto al principio tiene el aspecto de ser mu# duro pero una vez asimilado ver% que es realmente simple" ,s m%s' #a *a visto todo lo necesario para realizar un programa sin rutinas de interrupcin"

;********************************************************************* ; INICIALIZACIONES * ;********************************************************************* init clrf PORTA ; salidas portA a 0 clrf PORTB ; salidas portB a 0 clrf EEADR ; permite disminuir el consumo bsf STATUS , RP0 ; selecciona banco 1 movlw OPTIONVAL ; carga mascara movwf OPTION_REG ; inicializa registro OPTION ; Borrar RAM ; -----------movlw 0x0c ; inicializa puntero movwf FSR ; punter direccionamiento indirecto init1 clrf INDF ; borrar ram incfFSR,f ; apuntar siguiente btfss FSR,6 ; mirar si en fin zona (>=0x40) goto init1 ; no, bucle btfss FSR,4 ; mirar si en fin zona (>=0x50) goto init1 ; no, bucle ; inicializaciones especificas ; --------------------------bcf LED ; LED en sortie (banque1) bcf STATUS , RP0 ; pasar a banco 0 goto start ; saltar al programa principal

?escendamos en el programa principal # &orremos la l(neaK


clrwdt ; borrar watchdog

Q4

11.13 Los resultados del ensamblado


8ance el ensam&lado mediante la tecla ^:1B_" 6ecuerde que llamamos ensam&lado a la traduccin 2simple5 de un programa escrito en lenguaje ensam&la$ dor en un ejecuta&le" Por el contrario' llamamos compilacin a la conversin 2compleja5 de un cdigo 4uente en lenguaje de alto nivel en un ejecuta&le" ,n la ventana de resultados del ensam&lado de&er% tener algo as( comoK
Message[302] D:\DOCUME~1\LESSONS\DATAPIC\LED_CLI.ASM 101 : Register in operand not in bank 0. Ensure that bank bits are correct.

,s un mensaje de advertencia 23arning5 que le se)ala que en la l(nea 1B1 2en mi caso' en el su#o puede ser otro numero de l(nea di4erente5 *a accedido a un registro que no est% en el &anco B" Va#a en el editor a la l(nea que le *a generado el 3arning 21B1 en mi caso5" <ll( encontrar%K
movwf OPTION_REG ; inicializar registro OPTION

Hn vistazo a la ta&la 4$2 le indica que el registro JP9IJ1 est% en el &anco 1" Pero como nuestro 6PB est% a 1 en este momento' no *a# ningDn pro&lema" uando realice grandes programas ver% que va a o&tener multi$ tud de mensajes de advertencia de este tipo" .i quiere evitar tener este tipo de mensajes de &anco' a)ada la directiva
Errorlevel 302

?irectamente &ajo la l(nea hinclude de su 4ic*ero" ,l /$/ signi4ica que quitar% este mensaje de los mensajes activos' # el 3B2 es el numero de 3arning a evitar" ,ste nDmero est% indicado entre corc*etes en el mensaje enviadoK =essagei3B2j" <tencin' eliminar mensajes de 3arning signi4ica que =P<.= dejar% de vigilarlos por usted" Puede volver a poner los mensajes en activo utilizando el signo /M0 en cualquier momento de su cdi$ go en vez de el signo 0$/" Hna &uena pr%ctica consiste en veri4icar una zona de su programa con todas las alertas para despu-s desactivarlas"

11.14 El programa principal


Gueremos *acer parpadear un led a una 4recuencia de 1 >z 21 clic por segundo5" < pesar de que' *ace #a mu$ c*os a)os' decid( escri&ir la primera versin de este curso en cap(tulos separados en un 4rum' esta&a lejos de pensar que /la intermitencia de un led0 llegar(a a ser un gran cl%sico del aprendizaje de micro controladores" Prevemente' vamos a crear un programa de la 4ormaK
debut Enciendo el LED Espero sesgundo Apago el LED Espero sesgundo Vuelvo al inicio

Pien' atencin a una gran trampaK para *acer parpadear un led a 1 >z *ace 4alta temporizar 5BB ms # no 1 s" Podemos ver que utilizaremos 2 veces la temporizacin de segundo" Vamos a crear un su&programa que llamaremos tempo "

Q5

1uestro programa principal tendr% el siguiente aspectoK


start bsf LED ; encender el LED call tempo ; llamar temporizador de 0.5s bcf LED ; apagar LED call tempo ; llamar temporizador de 0.5s goto start ; boucle

J podr(amos escri&ir tam&i-n 2usando macros5K


start LEDON ; encender el LED call tempo ; llamar temporizador de 0.5s LEDOFF ; apagar LED call tempo ; llamar temporizador de 0.5s goto start ; boucle

,lija el m-todo que pre4iera" 8o importante es *a&erlos comprendido" 8e recomiendo el segundo por ser m%s limpio # m%s 4%cil de mantener aunque parezca demandar un es4uerzo de codi4icacin suplementario"

11.15 La subrutina de temporizacin


<Dn no *emos visto el timerB' ni las interrupciones" ,l o&jetivo aqu( es *acerle entender el 4uncionamiento del 16:;4" Para realizar una temporizacin' en nuestro caso' es su4iciente con *acerle perder tiempo a nues$ tro 16:;4 entre cada inversin del led" ?e&emos perder apro+imadamente B"5s" 8os segundos no son apropiados para los PIC que tra&ajan a una velocidad muc*o m%s elevada" 1osotros vamos a utilizar unidades en la escala de tiempos de los PIC" ,sta nocin de escala de tiempos es mu# importante en programacin' *ace 4alta constantemente imaginarse los eventos que ocurren como si usted 4uese el PI " ,sperar 1 segundo equivale entonces a una eternidad # ciertos sucesos que nos parecer(an indetecta&les pasan a ser percepti&les' *a&laremos m%s de esto" 1uestro PIC est% ciclado a la 4recuencia de nuestro cuarzo' es decir 4 =*z" ,l PIC ejecuta un ciclo de instruccin cada 4 ciclo de reloj principal" ,l ejecutara 1"BBB"BBB R 4 L 1 milln de ciclos de instruccin por se$ gundo" 6ecuerde que su simple PI 16:;4< puede 4uncionar per4ectamente con un cuarzo de 2B =*z" ,sta$ mos tra&ajando a una quinta parte de las posi&ilidades" ,ste curso *a sido escrito inicialmente para PI s tra&ajando a 4 =*z' esta es la razn de la eleccin de este va$ lor # as( no es necesario modi4icar todos los ejercicios" ,s inDtil *acer tra&ajar al PI mas all% de lo necesario' de *ec*o' el *acer parpadear un led a 1 >z es #a de por s( per4ectamente inDtil 2estamos en un entorno edu$ cativo # no en el de la optimizacin o 4a&ricacin a gran escala5" ,+isten otros modelos de PI de ; &its que pueden tra&ajar a velocidades muc*o m%s importantes" ,l consumo de su PI aumenta con la velocidad a la que se le *ace tra&ajar" Pensad en ello si realiza montajes alimentados con &ater(as o pilas" 8a ma#or parte de las instrucciones 2e+cepto los saltos5 se ejecutan en un ciclo' lo cual nos da una velocidad de ejecucin apro+imada a 1 milln de instrucciones por segundo" Ver%n a veces la denominacin de =IP. pa$ ra este concepto 2=illones de Instrucciones Por .egundo5" 1uestro PIC con este cuarzo tiene una potencia de tratamiento de 1 =IP."

Q6

ada ciclo de instruccin dura una millon-sima parte de segundo' escrito de otra 4orma 1 s" >e aqu(' pues' la unidad de tiempo para tra&ajar con nuestro PIC" 1uestra temporizacin *a de ser de B"5s' es decir' 5BB"BB microsegundos" ?e&eremos no *acer nada durante 5BB"BBB de ciclos de instruccin en nuestra rutina de temporizacin" Vemos' por lo tanto' que nuestro PI en esta aplicacin se va a pasar la ma#or parte de su tiempo sin *acer nadaK 1 instruccin Dtil 2encender o apagar el led5 por cada 5BB"BBB inDtiles" 8a primera idea que se nos viene a la ca&eza es la de realizar un &ucle que incremente o decremente una va$ ria&le" >ag%moslo" ,mpecemos por declarar nuestra varia&le en la zona de 6<=" <)adiendo la declaracin o&ten$ dremosK
;********************************************************************* ; DECLARACION DE VARIABLES * ;********************************************************************* CBLOCK 0x00C ; comienzo de la zona de variables cmpt1 : 1 ; contador de bucles 1 ENDC ; Fin de la zona

reemos a*ora el esqueleto de nuestra su&rutina que situaremos entre la rutina de inicializacin # el progra$ ma principal 2de *ec*o usted podr(a ponerla en cualquier sitio' se trata de un ejemplo5" 1o olvide usar co$ mentariosK

;********************************************************************* ; SUBRUTINA DE TEMPORIZACION * ;********************************************************************* ;--------------------------------------------------------------------; Esta subrutina introduce un retardo de 500.000 s. ; No recibe ni retorna ningn parametro ;--------------------------------------------------------------------tempo

; pondremos aqu el cdigo


return ; retorno de la subrutina

>agamos a*ora el &ucle"

tempo clrf cmpt1 ; borra el contador 1 boucle1 decfsz cmpt1; decrementa el contador 1 goto boucle1 ; si no 0, bucle return ; retorno de la subrutina

8anzamos el ensam&lado con ^:1B_ # o&tenemos en la ventana de resultados una l(nea suplementaria con el siguiente aspectoK
Message[305] D:\DOCUME~1\LESSONS\DATAPIC\LED_CLI.ASM 134 : Using default destination of 1 (file).

Q7

,l nDmero de l(nea puede variar en su cdigo 4uente" omo el ensam&lado se *a realizado correctamente' nuevamente se trata de una l(nea de 3arning" Posicinese en el editor en la l(nea rese)ada 2134 en mi caso5" ,star% so&re la l(neaK
decfsz cmpt1 ; decrementa el contador 1

EGu- nos dice el mensajeF .implemente que no *emos precisado el destino de la instruccin # que *a usado por de4ecto el valor 1 para file ,' luego se *a usado ,f por de4ecto" ,n e4ecto' la instruccin dec4sz es de la 4orma decfsz f , d " 1os *emos olvidado de indicar el destino de la operacin 2el ,d 5" Preste atencin' si *u&iese querido o&tener el resultado en 3' el programa ser(a errneo" orrija el cdigo cuando o&tenga advertencias de este tipo" =odi4ique el comando a)adiendo b'4OK
decfsz cmpt1 , f ; decrementa el contador 1

<*ora vamos a calcular la duracin de este tiempo"


tempo clrfcmpt1 ; 1 ciclo boucle1 decfsz cmpt1 , f ; 1 ciclo si no hay salto, 2 con salto ; no salto 255 veces y salto 1 vez goto boucle1 ; 2 ciclos multiplicado por 255 pasadas return ; 2 ciclos

Na lo *emos visto antes' un tiempo es equivalente a un nDmero de ciclos de instruccin" Podemos medir el tiempo contando el nDmero de ciclos de instruccin" ,l tiempo total ser%K 2 ciclos para la llamada 2call tempo5 1 ciclo para el reset de la varia&le 257 ciclos para los 256 decrementos 51B ciclos para los 255 gotos 2 ciclos para el retorno

,sto *ace un total de 772 ciclos que est% mu# lejos de los 5BB"BBB necesarios" Para los siguientes c%lculos' vamos a desec*ar los 2 ciclos de llamada # los 2 ciclos el return 2comparados con 5BB"BBB tienen un e4ecto irrisorio5" Vamos a alargar nuestra rutina realizando un segundo &ucle que 4orzar% al primero a realizarse 256 veces" omencemos declarando una segunda varia&le cmpt2K
cmpt1 : 1 ; contador de bucles 1 cmpt2 : 1 ; contador de bucles 2

Q;

,scri&amos los dos &ucles im&ricadosK


tempo clrf cmpt2 ; borra el contador 2 boucle2 clrf cmpt1 ; borra el contador 1 boucle1 decfsz cmpt1 , f ; decrementa contador 1 goto boucle1 ; si no 0, boucler 1 decfsz cmpt2 , f ; si 0, decrementa contador 2 goto boucle2 ; si cmpt2 no 0, volver a empezar bucle 1 return ; retorno de la subrutina

Vemos que nuestros primer &ucle est% todav(a aqu(' pero en lugar de e4ectuar un retorno cuando termina' volvemos a comenzar el &ucle en tanto en cuanto cmtp2 no sea igual a B" Vamos a ejecutar nuestro &ucle 1 256 veces" E u%l es la temporizacin o&tenidaF alcul-mosla de una 4orma apro+imadaK ?uracin del &ucle 1K 257 ciclos M 51B ciclos M 1 ciclo 2clr4 cmpt15 L 76; ciclos ,ste &ucle se va a ejecutar 256 veces luego 76; I 256 L 1;6/648 (i(&*s a los que *a# que a)adir algunos ciclos de inicializacin' etc" Pero deseamos tener 5BB"BBB ciclos" ?e&eremos utilizar entonces sete do&le &ucle 5BB"BBBR1Q6"6B;L2'54 ve$ ces" 1o sa&emos *acer medio &ucle" ,4ectuaremos 2 do&les &ucles # de&eremos arreglar el do&le &ucle de 4orma que dure 25B"BBB ciclos 25BB"BBBR25" ada instruccin que a)adamos al &ucle 1 ser% ejecutada 256I256 veces" ada instruccin a)adida al &ucle 2 ser% ejecutada 256 veces" ada instruccin a)adida al e+terior ser% ejecutada 1 vez" 9enemos' pues' posi&ili$ dades de realizar temporizaciones mu# precisas" ,sto no es necesario aqu(" ?e todas 4ormas vamos a mejorar la precisin" .i a)adimos 1 ciclo inDtil al &ucle 1 a)adiremos 256I256 L 65"536 ciclos" ?e&er(amos a)adir 25B"BBB e 1Q6"6B; L 53"3Q2 ciclos" ,so nos dar% un error de 12"BBB ciclos' es decir' 12 mil-simas de segundo 212ms5" 8a precisin ser(a m%s que su4iciente para nuestra aplicacin' pero le recuerdo que podemos a4inar m%s nuestra precisin realizando c%lculos m%s precisos" 8e recomiendo que lo *aga como ejercicio" Puede veri4icar sus re$ sultados con un cronometro 2midiendo un gran nDmero de intermitencias5" Para perder tiempo' a)adiremos una instruccin 1JP que no *ace nada 2e+cepto perder tiempo5" Gueda por realizar el tercer &ucle para ejecutar el do&le &ucle 2 veces" rearemos una tercera varia&le cmpt3 # un tercer &ucle 2recuerde que *a&r(a m-todos m%s simple' pero se trata de un ejemplo did%ctico cu#a 4ina$ lidad es entender los conceptos mostrados5"

;********************************************************************* ; DECLARACION DE VARIABLES * ;********************************************************************* CBLOCK 0x00C ; comienzo de la zona de variables cmpt1 : 1 ; contador de bucles 1 cmpt2 : 1 ; contador de bucles 2 cmpt3 : 1 ; contador de bucles 3 ENDC ; Fin de la zona de variables

QQ

>e aqu( el cdigo 4inalK

;********************************************************************* ; SUBRUTINA DE TEMPORIZACION * ;********************************************************************* ;--------------------------------------------------------------------; Esta subrutina introduce un retardo de 500.000 s. ; No recibe ni retorna ningn parametro ;--------------------------------------------------------------------tempo movlw 2 ; para 2 bucles movwf cmpt3 ; inicializa compteur3 boucle3 clrf cmpt2 ; borra compteur2 boucle2 clrf cmpt1 ; borra compteur1 boucle1 nop; pierde 1 cycle *256 *256 *2 decfsz cmpt1 , f ; decrementa compteur1 goto boucle1 ; si no 0, boucler decfsz cmpt2 , f ; si 0, decrementa compteur 2 goto boucle2 ; si cmpt2 no 0, volver a empezar bucle1 decfsz cmpt3 , f ; si 0, decrementa compteur 3 gotoboucle3 ; si cmpt3 no 0, volver a empezar boucle2 return ; retorno de la subrutina

8ance el ensam&laje con ^:1B_" .i todo se desarroll correctamente *a&r% o&tenido en el directorio de tra&a$ jo el 4ic*ero Led_cli.hex " ,nv(eselo al PIC con la a#uda del programador 2gra&ador5" oloque el PIC programado en la tarjeta con la alimentacin desconectada" onecte la alimentacin # o&serve que pasa" EL LED PARPADEA A LA FRECUENCIA DE 1 Z :elicitaciones' aca&a de realizar su primer programa em&arcado" 8a puerta se *a a&ierto a toneladas de nue$ vas aplicaciones" CONSEUO IMPORTANTE .i en este momento usted salta *asta el tec*o gritando @II Es"* ,'n(i*n$IIA no nos precipitemos corriendo a ense)%rselo a su mujer" ?udo muc*o que ella participe de su entusiasmo por /esta peque)a lucecita que *ace intermitencias0" ,l 4ic*ero de tra&ajo que tendr(amos al 4inal de esta leccin est% disponi&le en los 4ic*eros adjuntos"

1BB

12. Las interrupciones


>e aqu( un cap(tulo que puede atemorizar un poco a los 4uturos programadores" <lgunos *a&lan de esto co$ mo reservado para /4riXis0 o que se trata de secretos de magia negra destinados a *acer *uir a todo aquel desgraciado novato que intente apro+imarse" Jtros intentan re*uirlo *aciendo uso de un lenguaje de alto ni$ vel m%gico que *ar(a desaparecer el aspecto material por otra parte indispensa&le" ,l mecanismo de las interrupciones es mu# 4%cil de entender' # por lo tanto de ponerlo en pr%ctica' si lo ma$ nejamos de una 4orma limpia # estructurada"

12.1 Qu es una interrupcin?


Imagine una conversacin normalK ada interlocutor toma la pala&ra cuando es su turno" ?e repente algo e+terior ocurre que requiere un tratamiento urgente" Por ejemplo' un piano cae des$ de el tercer piso a los pies de los que est%n discutiendo" .e imaginar% que su interlocutor no va a esperar a que usted termine su 4rase para se)alarle el peli$ gro" kl le va a interrumpir su discurso para *acerle notar la situacin de peligro" 8os interlocutores retomar%n la conversacin cuando el peligro desaparezca 2siempre # cuando el piano no *u&iese aca&ado con ellos5" .i usted *a entendido lo anterior #a entiende lo que es una interrupcin" ,n e4ecto' para los programas es e+actamente el mismo principio" .u programa se desarrolla normalmente" ?e repente ocurre un evento espec(4ico e imprevisi&le" ,l programa principal se interrumpe 2interrupcin5 # va a tratar el evento antes de retomar el programa principal en el punto en el que lo *a&(a dejado" 8a interrupcin es una rotura de secuencia as(ncrona' es decir' no sincronizada con el desarrollo normal del programa" ?ic*o de otro modo' que puede ocurrir en no importa qu- momento del desarrollo del programa # de una 4orma impredeci&le" Pude ver la di4erencia con las roturas de secuencia s(ncronas provocadas por el propio programa 2goto' call ' &t4ss ]5 # que ocurren en un entorno per4ectamente previsto"

12.2 Mecanismo general de una interrupcin


Podemos decir' sin equivocarnos muc*o' que una rutina de interrupcin es un su&programa particular' dispa$ rado por la aparicin de un evento espec(4ico" ,sto puede parecer un poco ardua pero va a ver que es mu# sencillo" Veamos cmo 4uncionaK ,l programa se ejecuta normalmente" <parece el evento ,l programa arc*iva la instruccin en curso" ,l programa salta a la direccin de tratamiento de la interrupcin 2B+B45" ,l programa trata la interrupcin" ,l programa termina el tratamiento de la interrupcin # salta a la instruccin que sigue a la Dltima que 4ue ejecutada en el programa principal"

1B1

,s &ien seguro que no se disparar% una interrupcin no importa cual evento" >ace 4alta que se cumplan 2 condiciones generalesK 1" ,l evento tiene que 4igurar en la lista de eventos suscepti&les de provocar una interrupcin so&re el procesador con el que se tra&aja" 2" ,l usuario de&e *a&er autorizado la interrupcin' es decir' de&e *a&er se)alado que el evento en cuestin de&e generar una interrupcin"

Veamos el organigrama general de la ejecucin de una interrupcinK

EGu- podemos decir viendo este organigramaF ?e entrada podemos decir que el programa principal no sa&e cu%ndo va a ser interrumpido' ni tan siquiera que lo *a sido" ,s por lo tanto crucial reponer los registros en el estado en que esta&an antes de ser interrumpido" .upongamos que la instruccin +++ *a&(a puesto un :lag 2por ejemplo el &it \5" .i por desgracia la rutina de interrupcin modi4ica ese :lag' a la vuelta' el programa principal no podr% *acer uso del mismo de una 4orma correcta # continuar normalmente"

1B2

Vemos tam&i-n que la instruccin +++ termina su ejecucin antes de rami4icarse a la rutina de interrupcin" Hna instruccin empezada no se ver% interrumpida jam%s" 1otaK en ciertas 4amilias de micro controladores e+iste una direccin de interrupcin por cada tipo por lo que no tendr(a sentido en ellos la compro&acin de qu- tipo gener la interrupcin"

12.3 Mecanismo de interrupcin de los PIC


8os PI responden en general al procedimiento *asta aqu( descrito' pero tam&i-n tienen sus propias particu$ laridades" Vamos a ver los principios so&re la 4amilia de los PIC16F" Por principio' la direccin de comienzo de cualquier interrupcin es 4ija # se trata siempre de la direc$ cin B+B4" orolarioK toda interrupcin provocara el salto del programa *acia esta direccin" 9odas las 4uentes de interrupcin llegan a esta direccin" .i el programador usa varias 4uentes de interrupcin' *ar% 4al$ ta que -l mismo determine cu%l es la 4uente que est% a punto de ser tratada" 8os PI 16:! cuando se conectan a esta direccin no guardan nada e+cepto el contenido del P ' que servir% para conocer la direccin de retorno de la interrupcin" ,s pues' el usuario el encargado de salvaguardar # posteriormente recuperar la in4ormacin" ,l contenido del P se salva so&re la pila interna 2; niveles5" 8uego' si utiliza las interrupciones' solo dispone de 7 niveles de im&ricacin para sus su& programas" =enos si usted utiliza su& programas en sus interrupciones" ,l tiempo de reaccin de una interrupcin est% calculado de la siguiente 4ormaK o ,l ciclo de la instruccin actual se termina" o ,l :lag de interrupcin es le(do al comienzo del ciclo siguiente" o ,ste es arc*ivado" ,l procesador se para un ciclo para cargar la direccin B+B4 en el P " o ,l procesador se conecta a la direccin B+B4 donde le *ar% 4alta un ciclo suplementario para leer la siguiente instruccin a ejecutar"

,l tiempo muerto total estar% entre 3 # 4 ciclos" .i queremos ser precisos' la lgica interna *ace que toda inte$ rrupcin que ocurre antes del primer cuarto de la instruccin en curso ser% tenida en cuenta como si la ins$ truccin no *u&iese comenzado" ?ic*o de otra 4orma' el tiempo muerto estar% comprendido entre 3 # 3'75 ciclos" J&serve igualmente que si la interrupcin es s(ncrona con el oscilador del PI 2interrupcin interna' generalmente el timer5' no podr% aparecer en mitad de un ciclo' el tiempo muerto ser% entonces o&ligatoria$ mente de 3 ciclos" < remarcarK

Una interrupcin no puede ser interrumpida por otra interrupcin. Las interrupciones se invalidan de forma automtica mediante el borrado del bit GIE (que veremos) despus de un salto a la posicin 0x04. Las interrupciones son devueltas a servicio automticamente despus del retorno de interrupcin. La instruccin de retorno sobre un PIC16F, RETFIE se trata exactamente como de una instruccin RETURN excepto en que la primera reposiciona el bit GIE al mismo tiempo.

1B3

,sto nos lleva al siguiente organigrama para las interrupciones en el PI 16:!K

12.4 Las fuentes de interrupcin en el 16F84


,l PIC16F84 es mu# po&re a este nivel dado que solo dispone de 4 4uentes de interrupcin 24rente a las 13 por ejemplo del PIC16F8765" 8os sucesos posi&les para generar una interrupcin sonK 9=6BK ?es&ordamiento del timerB 2tmrB5" Hna vez que el contenido del tmrB pasa de B+:: a B+BB se puede generar una interrupcin" Htilizaremos esta propiedad en el cap(tulo so&re el timer B" ,,P6J=K ,sta interrupcin se puede generar una vez completada la escritura so&re una posicin de la zona de memoria ,,P6J=" 6PBRI19K .e puede generar esta interrupcin estando el pin 6PB' tam&i-n llamado I19errupt pin' con$ 4igurado como entrada # se *a modi4icado el nivel aplicado a -l"

PJ69PK ?e la misma 4orma' se puede generar una interrupcin si el nivel de uno de los pines de 6P4 a 6P7 cam&iase" 1o es posi&le limitar la interrupcin a uno de los pines en particular" 8a interrupcin ser% e4ectiva para los 4 o para ninguno" 1B4

12.5 Puesta en marcha de los dispositivos


E mo impedir o autorizar las interrupcionesF E mo detectar cu%l es el evento que dispar la interrupcinF E mo gestionarlasF Primero vamos a a&ordar el tema de una 4orma sim&lica para a#udar a su visualizacin" Imaginemos un *otel" ,l responsa&le de servicio representa nuestro programa" ,ste *otel tiene 4 cuartos 2nuestras 4 4uentes de interrupcin5' # cada cuarto est% equipado con un &otn pulsador" ada &otn sirve para llamar al responsa&le # est% conectado a una &om&illa en la recepcin del *otel" ada &om&illa tiene la posi&ilidad de *acer sonar un tim&re 2desencadenar una interrupcin5K .i el interruptor general del tim&re est% en posicin J1" N si el interruptor particular de cada &om&illa est% en J1"

>e aqu( el esquema que o&tenemosK

uando entienda &ien este peque)o esquema el-ctrico equivalente' *a&r% comprendido el principio de las in$ terrupciones" Puede ver enseguida que *a# dos 4ormas por las que el responsa&le del servicio puede enterar$ se que un cuarto pide atencinK O !ien $ "%$vCs )e &$ !*.!i&&$ * !ien $ "%$vCs )e& "i.!%e/ $ =ediante el primer m-todo' el responsa&le de&er% mirar las &om&illas regularmente para veri4icar que alguien llama" ?e&er% escrutar el ta&lero de se)alizacin" ,s el responsa&le el que decide cuando mira # por lo tanto cuando reaccionar ante una demanda"

1B5

on el tim&re' el responsa&le es interrumpido de su tra&ajo" 1o tiene necesidad de ir a mirar el panel de se)alizacin inDtilmente' pero ser% interrumpido en su tra&ajo" ,ste es el m-todo de las interrupciones" ,l responsa&le no es el que decide cuando reaccionar% a la demanda de un cliente' lo *ar% cu%ndo suene el tim&re 2si no' lo despediremos5" J&serve los siguientes puntosK ,l *u-sped no puede decidir que m-todo va a utilizar el responsa&le del servicio' es -l quien decidir% validar o no los tim&razos" ,l responsa&le puede impedir todas las posi&ilidades de que suene el tim&re de una vez a trav-s del interruptor general o decidir qu- *a&itacin puede *acerla sonar # cual no 2interruptores asociados a cada *a&itacin5" 8os interruptores de validacin no tra&ajan so&re las &om&illas" .i el responsa&le es interrumpido durante su tra&ajo por el tim&re' tiene de todas 4ormas que ir al panel de se)alizacin para ver quien le est% llamando' salvo que solo *a#a autorizado a una *a&ita$ cin" 8o que no aparece en este esquema simpli4icado' pero que *a# que tener en cuenta' es que una vez que una &om&illa se encendi' esta se quedar% encendida 2el &otn queda memorizado5" ,s el res$ ponsa&le de servicio quien la apagar% manualmente"

Pongamos todo esto en pr%ctica para el 16:;4" >a&r% deducido #a' que para el 16:;4 &otones # l%mparas se tratan de &its de registros particulares" Veamos el registro principal de gestin de interrupciones del 16:;4"

12.6 El registro INTCON (INTerrupt CONtrol)


,ste registro est% situado en la direccin B+BP de los dos &ancos" ,st% siempre accesi&le" ,st% detallado en la ta&la 4$5 de la pagina 17" ,s un registro de &its por lo que cada &it tendr% un signi4icado particular" >e aqu( el detalle de cada &itK

b7 : GIE
Blo&al Interrupt Ena&le &it" Permite validar o no todas las interrupciones a la vez" orresponde al interruptor de validacin general de nuestro esquema"

b6 : EEIE
EEprom 3rite complete Interrupt Ena&le &it" ,ste &it permite validar la interrupcin de 4in de escritura en ee$ prom 2estudiaremos m%s tarde el mecanismo de escritura en la eeprom5" .e trata de uno de los interruptores de las *a&itaciones"

b5 : T0IE
Tmr4 Interrupt Ena&le &itK Valida la interrupcin generada por el des&ordamiento del timerB"

b4 : INTE
INTerrupt pin Ena&le &itK Valida la interrupcin en el caso de variacin de nivel en 6PB" <9,1 IJ1K recuerde el &it 6 del registro JP9IJ1 el cual determina qu- sentido de variacin provocar% la interrupcin" Podr% elegir de B 1 de 1 B pero no am&os a la vez"

b3 : RBIE
R> Interrupt Ena&le &itK Valida las interrupciones en el caso de cam&io en los &its de 6P4 a 6P7"

1B6

b2 : T0IF
Tmr4 Interrupt Flag &it" ,s un :lag' es decir' una se)al" ,ste es el de des&ordamiento del timerB" 9odos los &its aca&ados en : son 4lags 2&anderas' en el sentido se se)alizacin5" orresponden a las l%mparas de nuestro es$ quema"

b1 : INTF
INTerrupt pin Flag &itK se)ala una transicin del pin 6PB en el sentido determinado por I19,?Y del registro JP9IJ1 2&65"

b0 : RBIF
R> Interrupt Flag &itK se)ala que una de las entradas de 6P4 a 6P7 *a sido modi4icada"

Observacion
6ecuerde que los 4lags no se reposicionan a B por si mismos" .i estos 4lags est%n ligados a una interrupcin au$ torizada' su programa los de&e reponer a B en el tratamiento de la interrupcin' &ajo pena de no poder jam%s salir de la misma" ,n e4ecto' cuando salga de la interrupcin' las condiciones normales ser%n reposicionadas # la interrupcin ser% inmediatamente vuelta a llamar" ?iremos que estos 4lags son remanentes"

Observacin
9enga en cuenta que el reset de 6PI: de&e estar precedido de una lectura o de una escritura del PJ69P con el 4in de registrar 2autom%ticamente5 el ultimo valor del PJ69P utilizado" ?e lo contrario' desde el momento del reset de 6PI:' ser(a inmediatamente reposicionado por el PI al reconocer una modi4icacin de lPJ69P desde el Dltimo valor almacenado en la Dltima lectura del PJ69P" 9odos los &its cu#o nom&re aca&a en , 2,na&le5 son de *ec*o conmutadores de validacin 2son los interrupto$ res de nuestro esquema sim&lico5" 8os &its cu#o nom&re termina por : 2:lags5 2son las l%mparas de nuestro esquema5" 9endremos 5 interruptores # 4 l%mparas" Pero solo tenemos ; &its" EGu- nos 4altaF .i o&serva atentamente' nos 4alta el &it ,,I:" Pero' se lo aseguro' este &it e+iste" .implemente est% en otro re$ gistro' se trata del ,, J11 que veremos en la leccin so&re el acceso a la ,,P6J=" Veamos el esquema para el PIC 16F84"

1B7

?espu-s de estas detalladas e+plicaciones' demasiado dir%n los *a&ituados a los procesadores' de&er% *a&er comprendido el 4uncionamiento de las interrupciones en el 16:;4" <nalicemos a*ora algunos detalles de la rutina de interrupcin en s( misma" Para ser concretos' vamos a mezclar teor(a # pr%ctica"

12.7 Guardado y restauracin del entorno


.i o&serva el nuevo organigrama de la rutina de interrupcin' constatar% que de&e proceder a la salvaguardia # restauracin del entorno de su programa" E,n qu- consiste estoF omo #a *emos dic*o' el programa interrumpido no sa&e qu- *a pasado" ?e&er% reponer los registros en el estado en que se encontra&an cuando ocurri la interrupcin para permitir que el programa continDe el 4un$ cionamiento despu-s de *a&er tratado la interrupcin" Peque)o ejemploK .upongamos que el programa 4ue interrumpido entre las 2 instrucciones siguientesK
movf mavariable , w ; cargar mavariable y posicionar Z -> interruption ici btfss STATUS , Z ; test Z y salto si vale 1

,s m%s que pro&a&le que la rutina de interrupcin va a utilizar una instruccin que modi4ique el &it \" ?e&er% restaurar el registro .9<9H. a la posicin en que se encontra&a antes de la interrupcin" .i no 4uese as(' el test no se realizar% so&re el valor de mavaria&le' sino so&re el valor de \ modi4icado por la rutina de interrup$ cin" ,s m%s' ser% casi cierto que el registro w va a ser modi4icado por lo que *ar% 4alta salvarlo igualmente"

12.7.1 Los registros a salvaguardar


omencemos por una generalidadK en nuestra rutina de interrupcin de&eremos salvar 9odo registro modi4icado por la rutina .i nuestro programa principal utiliza ese registro N si nuestro programa principal no espera una modi4icacin de ese registro"

?ic*o de otra 4orma' usted de&er% salvar 2# restaurar evidentemente5 todo aquello que' siendo modi4icado por la rutina de interrupcin' inducir(a un comportamiento errneo del programa principal" ,videntemente' *a# registros que' casi con toda certeza' de&er%n ser salvados atendiendo a las razones pre$ cedentes" Para empezar' el m%s simpleK el PC" .i no 4uese salvado ser(a imposi&le volver al entorno del programa princi$ pal cuando 4ue interrumpido" ?e&er% ser salvado en el entorno de la misma interrupcin" ,s imposi&le *acerlo de 4orma manual' por lo que esta salvaguardia 4orma parte del 4uncionamiento autom%tico de las interrup$ ciones" Us"e) n* se )e!e #%e*('#$% )e M$(e%&*" < continuacin' el registro STATUS" ontiene todos los 4lags condicionales" ,s pr%cticamente inconce&i&le una rutina de interrupcin que no utilice ninguna instruccin que modi4ique el .9<9H. 2o entonces la interrupcin no *ace gran cosa5"

1B;

omo el programa principal tiene todas las oportunidades del mundo de utilizar una instruccin condicional o de cam&io de &anco' la salvaguardia de STATUS es pr%cticamente o&ligatoria" ,l mismo razonamiento para el registro O" 8os registros a salvaguardar # restaurar de o4icio en sus interrupciones ser%n al QQ'QQZ de posi&ilidadesK .9<$ 9H. # W" ,n lo que se re4iere a otras salvaguardas eventuales' de&er% realizarlas en 4uncin del conte+to" Por ejemplo' si su programa principal utiliza el direccionamiento inde+ado # su rutina de interrupcin tam&i-n' ser% casi seguro necesario salvaguardar # restaurar el registro FSR" .e podr(a pensar en guardar las varia&les utilizadas en la rutina de interrupcin' pero entonces ser(a necesario un sitio para guardar 2otra varia&le5 cada varia&le' lo que no tendr(a sentido" =oraleja' si utiliza varia&les en sus rutinas de interrupcin' estas de&er%n ser varia&les reservadas para este uso # no ser utilizadas en el pro$ grama principal 2salvo si las modi4icaciones realizadas en la rutina de interrupcin son Dtiles para el programa principal5"

12.7.2 El mtodo de salvaguarda


Para guardar los registros O # STATUS se utiliza un m-todo #a considerado cl%sico" omporta comenzar #%i0 .e%* por salvar O # )es#'Cs STATUS dado que la salvaguarda de .9<9H. conlleva cargarlo primero en el re$ gistro W lo que inducir(a la perdida de W" 8a salvaguardia se resume enK
movwf w_temp ; salva W en un sitio adecuado movf STATUS,w ; transfiere STATUS a W movwf status_temp ; salva STATUS

J&serve que el datas*eet # los documentos de re4erencia' como el /mid$range re4erence manual0' indican el siguiente m-todoK
movwf w_temp ; salva W en un sitio adecuado swapf STATUS,w ; transfiere STATUS intercambiado en W movwf status_temp ; salva STATUS

,n lugar de un mov4' =icroc*ip recomienda la utilizacin de un s3ap4 2que no modi4ica ningDn &it de .9<9H.5 en la manio&ra" ,videntemente el octeto cargado est% /s3apeado0 por lo que ser% necesario otro s3ap en la reposicin" 1o *a# ningDn pro&lema en que se modi4ique .9<9H. cuando se carga en W' puesto que es W 2el antiguo contenido de .9<9H.5 el que ser% salvado" ?espu-s de consultar so&re este tema especi4ico' no *e o&tenido' por parte de =icroc*ip' la razn e+acta de esta recomendacin por su parte 2EPodr(a ser un antiguo /&ug0 concerniente a la manipulacin de .9<9H.F5" Parece incluso que este m-todo *a desaparecido de las recomendaciones o4iciales de =icroc*ip" ?e todas 4ormas' las primeras versiones de este curso *an utilizado el m-todo recomendado' por lo que lo encontrar% en los 4uentes # documentos" .epa simplemente' que puede utilizar el m-todo que m%s le apetez$ ca # no cam&iar% a&solutamente nada" ,videntemente' si utiliza un s3ap para salvar' de&er% utilizar un s3ap para restaurar' si no' el valor restaurado quedar% invertido 4rente al original" EPor qu- *acerlo simple cuando se puede *acer complicadoF

1BQ

<9,1 IJ1K esto vale e+clusivamente para el registro .9<9H." ,n lo que concierne a la restauracin de W' las o&servaciones que vienen a continuacin permanecen de aplicacin"

12.7.3 El mtodo de restauracin


Hsted me dir%K EGu- m%s *a# que decir al respectoF ,n e4ecto' parece lgico simplemente proceder a la in$ versa"
movf status_temp,w ; carga el STATUS salvaguardado movwf STATUS ; restaura STATUS movf w_temp,w ; restaura W

9odo parece simple # sin em&argo se esconde una gran trampa" ,n e4ecto' la ultima movf instruccin modi4ica el &it \ de .9<9H." N si restaura primero W' lo destruir% al recuperar .9<9H." ,sto es inacepta&le" 1ecesitaremos cam&iar el m-todo" ,l truco ser% restaurar W con una instruccin que no modi4ique ningDn &it de .9<9H." Hn vistazo a las instrucciones disponi&les nos permite ver que la instruccin swapf lleva la varia&le a W sin modi4icar ningDn &it de .9<9H." ?e todas 4ormas' esta instruccin presenta el inconveniente de invertir los 4 &its de peso 4uerte con los 4 &its de peso d-&il del octeto designado' lo que conducir(a a una restaura$ cin incorrecta" .er% necesario anular esta inversin # utilizar 2 instrucciones s3ap4 consecutivas lo que pondr% al octeto en orden correcto" 8a rutina modi4icada presenta a*ora el siguiente aspectoK
movfstatus_temp,w ; carga el STATUS salvaguardado movwf STATUS ; restaura STATUS swapf w_temp,f ; swapea el sitio guardado swapf w_temp,w ; re-swapea y lleva el resultado a W

?e esta 4orma W estar% &ien # &ellamente restaurado sin *a&er modi4icado el registro .9<9H. anteriormente restaurado" Veamos los dos m-todos que son estrictamente equivalentes" METODO INTUITIVO

Salvaguardia
movwf w_temp ; salva W en un sitio adecuado movf STATUS,w ; transfiere STATUS a W movwf status_temp ; salvaguarda STATUS

Restauracion
movf status_temp,w ; carga el STATUS salvaguardado movwf STATUS ; restaura STATUS swapf w_temp,f ; invierte el sitio de salvaguardia de W swapf w_temp,w ; re-invierte y lleva el resultado a W

11B

METODO PRECONIZADO ORIBINALMENTE

Salvaguardia
movwf w_temp ; salva W en un sitio adecuado swapf STATUS,w ; transfiere STATUS swapeado a W movwf status_temp ; salvaguarda STATUS

Restauracion
swapf movwf swapf swapf status_temp,w ; carga el STATUS salvaguardado STATUS ; restaura STATUS w_temp,f ; invierte el sitio de salvaguardia de W w_temp,w ; re-invierte y lleva el resultado a W

>e aqu( la estructura de &ase de una rutina de interrupcinK


;********************************************************************** ; ROUTINE INTERRUPTION * ;********************************************************************** ;salvaguardar registros ;--------------------ORG 0x004 ; direccion de interrupcion movwf w_temp ; salvar W swapf STATUS,w ; swap STATUS con resultado en w movwf status_temp ; salvar STATUS swapeado ; ; ; ; ; ; switch hacia las diferentes interrupciones ---------------------------------test de que interrupcion se trata tratamiento interrupcion ----------------------------tratamiento interrpcion despues de borrar su flag

;restaurar registros ;------------------swapf status_temp,w ; swap antiguo STATUS, resultado en w movwf STATUS ; restaura STATUS swapf w_temp,f ; Inversion L y H del antiguo W sin modificar Z swapf w_temp,w ; Re-inversion de L y H en W sin modificar Z retfie ; return desde interrupcion

,ste es el esqueleto de la rutina de interrupcin" E1o es complicado' verdadF .olo resta completarla puesto que el 4ic*ero m16:;4"asm contiene las rutinas de salvaguardia # restauracin 2que aca&amos de e+plicar5 # los test del tipo de interrupcin 2que vamos a detallar5" omo so# partidario de la programacin estructurada' la rutina de s3itc* nos conecta' en realidad' con su&ru$ tinas separadas" ,n e4ecto' nada nos impide el utilizar su&rutinas en una rutina de interrupcin" .olo *a# que prestar atencin al l(mite de pila disponi&le"

111

12.7.4 Operaciones sobre el registro STATUS


1o me gustar(a terminar esta parte sin prestar atencin a un punto en particular' a sa&er' instrucciones en las cuales el destino es el registro STATUS" 9oda instruccin en la que el resultado es suscepti&le de modi4icar uno o varios &its del registro .9<9H.' # en la que la meta es el registro .9<9H. en s( mismo' induce que cada &it suscepti&le de ser modi4icado por la ins$ truccin se encuentra en lectura solamente" <lgunos ejemplos para ser m%s e+plicitoK
movwf STATUS ; ningun problema, movwf no modifica ningn flag movf STATUS,w ; ningun problema, STATUS no es el destino andwf STATUS ; el bit Z se posicionar en funcin del resultado addwf STATUS ; idem para C, DC, et Z. clrf STATUS ; modifica Z, y no da el resultado esperado

.i toma por ejemplo la ultima instruccin' esperar% o&tener .9<9H.LB" Parecer(a que todo pasase como si' modi4icando el &it \ por clr4' este no estuviese a4ectado por la instruccin" <l 4inal' inmediatamente despu-s de limpiar .9<9H.' el resultado valdr% B' el &it \ se reposionar% inmediatamente # .9<9H. no valdr% jam%s B" .ea pues mu# prudente # si el destino de la instruccin es el registro .9<9H.' utilice de pre4erencia un mov34 o un s3ap4 o las instrucciones de manipulacin de &its 2&c4 # &s45"

12.7.5 Particularidad de la instruccin RETFIE


< este nivel de la e+posicin' un remarque pertinente es el siguienteK EPor qu- e+iste una instruccin 6,9:I, puesto que podr(amos utilizar una instruccin 6,9H61 precedida de una instruccin YI,F Para empezar' la misma estructura de nuestra rutina impide que una interrupcin pueda ser interrumpida por otra" .i este 4uese el casi' la salvaguardia de los registros W # .9<9H. seria destrozada por una segunda ope$ racin 2esto es posi&le en otros microprocesadores incluso en otros PIC5" ?iremos que nuestra rutina no es re$entrante" Para tener en cuenta este pro&lema' el PI 4uerza el &it YI, a B desde la misma entrada a la rutina de inte$ rrupcin" Para que una nueva interrupcin pueda tener lugar despu-s de terminada la interrupcin en curso' *ace 4alta volver a poner YI, a 1" ,sto es ejecutado autom%ticamente por 6,9:I," =e podr(a decir EN si *ici-semos de la siguiente maneraF
bsf INTCON , GIE ; reponer GIE a 1 return ; y salir de la rutina de interrupcion

N &ien' es e+actamente lo que *ace 6,9:I, e+cepto por un peque)o e importante detalle" 6,9:I, es una sola instruccin en s( misma por lo que no puede ser interrumpida por una interrupcin" ?iremos que es una ins$ truccin /atmica0 2no puede ser dividida5" ,n el caso del uso de las dos instrucciones precedentes' una vez puesto a 1 YI,' si uno de los 4lags de inte$ rrupcin est% a 1 2otra interrupcin o la misma que se reproduce otra vez5' el programa se reconectar% a la ru$ tina de interrupcin antes de *a&er ejecutado 6,9H61' es decir' antes de *a&er restaurado el P " ontinuaremos ocupando un emplazamiento en la pila" .a&iendo que la pila tiene un tama)o limitado a ; emplazamientos' tendremos muc*(simas oportunidades de &loqueo del programa por des&ordamiento de pi$ la" 112

.er(a imposi&le calcular el tama)o de pila utilizado por el programa puesto que ignoramos el nDmero de en$ tradas a la rutina de interrupcin" 9odas las condiciones para un &loqueo aleatorio estar%n cumplidas" Por lo tanto' utilice siempre la instruccin 6,9:I, para salir de una rutina de interrupcin' salvo que quiera que no se vuelvan a producir ninguna interrupcin despu-s de la primera que se ejecute 2caso particular5"

12.8 Utilizacin de una rutina de interrupcin


,4ectDe una copia de su 4ic*ero m16f84.asm. 6enm&relo myinter.asm " ree un nuevo pro#ecto MPLAB con el nom&re myinter segDn el procedimiento *a&itual" Vamos a construir un programa que invierta el encendido de un 8,? a cada presin so&re un pulsador" =odi$ 4ique su placa de e+perimentacin conectando el pulsador so&re la entrada 6PB 2lo siento' cuando dise)- el esquema pensa&a e+plicar las interrupciones con el timer5"

,sto le muestra que la electrnica # la programacin con micro controladores son mu# dependientes una de otra" uando usted constru#e un circuito #a de&e de pensar en la manera en la que va a programarlo" < la in$ versa' si #a dispone de un circuito esto le va a imponer numerosas restricciones a su programacin" Por ejem$ plo' ser(a imposi&le manejar el pulsador por medio de interrupciones si estuviese ca&leado a la entrada 6P2" 8a resistencia es interna en el PI !' se trata de una resistencia de carga a M5V 2pull$up5 que podemos activar por lgica" omo de costum&re' rellenaremos el enca&ezamiento # suprimiremos las l(neas que no vamos a utilizar en las varia&les' macro # ?,:I1," A"en(inII 1o suprima las varia&les w_temp # status_temp"

113

#include <p16F84.inc> ; Definicion de constantes

;********************************************************************** ; Este es un programa didctico destinado a mostrar * ; el funcionamiento de las rutinas de interrupcin * ;********************************************************************** ; * ; NOMBRE: Interrupcion por pulsador sobre RB0 * ; Fecha: 13/02/2001 * ; Version: 1.0 * ; Circuito: Placa de experimentacin * ; Auteur: Bigonoff * ; * ;********************************************************************** ; * ; Fichero requerido: P16F84.inc * ; * ; * ; * ;********************************************************************** ; Notas: Este programa transforma un pulsador en teleruptor. * ; Una pulsacin enciende el LED y otra lo apaga. * ;**********************************************************************

=e puede decir que e+agero al *acerle poner comentarios por todos los sitios" r-ame' los comentarios nos permitir%n *acer un mantenimiento del programa" 8e *ar% ganar muc*o m%s tiempo del que a*ora pierde en escri&irlos" .iento en ser tan insistente pero reci&o regularmente programas de otros internautas desprovistos de todo comentario" .i me los env(an' es porque no encuentran el error que contienen" ,stos internautas de&er(an mostrarse m%s modestos al estimar que /los comentarios est%n mu# &ien para los otros0" ?e todas 4ormas' en el momento que reci&o un programa desprovisto de comentarios este va directamente a la papelera" =i tiempo vale tanto o m%s que el de estos programadores /a*orradores0" =odi4ique la con4iguracin para suprimir el 4uncionamiento del 3atc*$dogK
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC

alculemos el valor a enviar al registro JP9IJ1 $ $ $ !+ $ 4 ' necesitamos la resistencia de carga a M5V para el pulsador" !6 $ 4' queremos interrupcin cuando pulsemos' nivel de 1 a B 24lanco descendente5" !?W!4 a B' ninguna necesidad en esta aplicacin

Por lo tanto pondremos la asignacin POBBBBBBBBOK

;********************************************************************* ; ASSIGNATIONS *

;********************************************************************* OPTIONVAL EQU H'00' ; valor del registrp OPTION ; Resistencias pull-up en ON ; Interrupcion flanco descendante en RB0

114

Para el registro INTCON de&eremos tenerK !+ $ 1K valida las interrupciones !6 $ 4K no interrupcin ,, !? $ 4K no interrupcin tmrB !4 $ 1K interrupcin 6PB en servicio !3 $ 4K no interrupcin 6P4R6P7 !JW!4 $ 4K &orrar los 4lags esto nos da B10010000' es decir 0x90 <signemos una constante para este valorc
INTERMASK EQU H'90' ; Mascara de interrupciones ; interrupciones sobre RB0

Inmediatamente' en la zona de los ?,:I1,' de4iniremos nuestro 8,? # nuestro pulsadorK


;********************************************************************* ; DEFINE ************************************************ ;********************** #DEFINE Bouton PORTB , 0 ; pulsador #DEFINE LED PORTA , 2 ; LED

,n la zona de macros' podemos escri&ir 2 macros que utilizaremos a menudo" .on las instrucciones para pasar del &anco B al &anco 1" 8as incluiremos en el nuevo 4ic*ero m16f84.asm renom&rado m16f84_new.asm como" <l 4inal de esta leccin' suprima el antiguo 4ic*ero # renom&re m16f84 como m16F84_new "
;********************************************************************* ; MACRO * ;********************************************************************* BANK0 macro bcf STATUS , RP0 ; passer en banque 0 endm BANK1macro bsf STATUS , RP0 ; passer en banque1 endm

Vamos a la zona de varia&les" ?e&emos conservar w_temp # status_temp' puesto que estas varia&les son utilizadas en la rutina de interrupcin para salvar los registros W # STATUS" Vamos a recuperar tam&i-n la peque)a rutina de tiempo de nuestro 4ic*ero led_cli.asm " 1ecesitaremos' pues' las varia&les utilizadas en esta rutina" 9odo lo anterior nos dar% una zona de varia&les por el momento como sigueK
;********************************************************************* ; DECLARATIONS DE VARIABLES * ;********************************************************************* CBLOCK 0x00C ; comienzo de la zona de variables w_temp :1 ; salvaguardia de W en las interrupciones status_temp : 1 ; salvaguardia de STATUS en las interrupciones cmpt1 : 1 ; contador de bucles 1 en tempo cmpt2 : 1 ; contador de bucles 2 en tempo cmpt3 : 1 ; contador de bucles 3 en tempo ENDC ; Fin de la zona

115

12.9 Anlisis de la rutina de interrupcin


Na *emos visto la primera parte que es la salvaguardia de los registros utilizados"
;********************************************************************** ; ROUTINE INTERRUPTION * ;********************************************************************** ;sauvegarder registres ;--------------------org 0x004 ; adresse d'interruption movwf w_temp ; sauver registre W swapf STATUS , w S ; swap status avec rsultat dans w movwf status_temp ; sauver status swapp

< continuacin de&eremos determinar cu%l es el origen de la interrupcin en curso" ,n el caso presente' se trata o&ligatoriamente de la interrupcin 6PBRI19' puesto que es la Dnica que tenemos autorizada" Podr(amos pasar de este test' pero no lo *aremos puesto que el o&jetivo es e+plicar los m-todos a utilizar" Vamos a des$ arrollar la totalidad de las e+plicaciones de 4orma que pueda utilizar cualquier com&inacin" ,+aminemos' pues' esta parteK
; switch hacia las diferentes interrupciones ; inversin del orden para modificar prioridades ;---------------------------------------btfsc INTCON,T0IE ; test si interrupcion timer autorizada btfss INTCON,T0IF ; SI , test si interrupcion timer en curso goto intsw1 ; NO, test siguiente call inttimer ; SI, tratar interrupcion timer goto restorereg ; y fin de la interrupcion ; SUPRIMIR ESTA LINEA PARA ; TRATAR VARIAS INTERRUPCIONES ; DE UNA SOLA VEZ

8as 2 primeras instrucciones e+aminan si tenemos algDn asunto con la interrupcin tmrB" =e podr(a decir' EPor qu- utilizar 2 l(neasF .er(a su4iciente e+aminar 9JI:" 1o es as( de simple" Imaginemos que el tmrB' que nosotros no utilizamos' se *a des&ordado" ,l &it 9JI: se *a&r% puesto a 1 # no *a&r% generado ninguna interrupcin dado que 9JI, est% a B" ?e la misma manera' si *u&i-semos aceptado las interrupciones timer # tuvi-semos una interrupcin de&ida a otras causas' tendr(a$ mos 9JI, a 1 # 9JI: a B" ?e&eremos tratar la interrupcin solo si esta est% permitida 2en servicio5 # el 4lag est% posicionadoc de esto el do&le test" ,+aminemos este do&le test # o&servemos el 4uncionamiento de btfsc # btfssK .i 9JI, vale B saltamos directamente al test siguiente por medio de la l(nea goto' si vale 1 c*equeamos 9JI:" .i este vale B' llegamos a la l(nea goto que pasar% al test siguiente" .i valiese 1' llamamos a la rutina de trata$ miento de la interrupcin tmrB" 8a Dltima l(nea nos permite saltar al 4inal de la rutina de interrupciones' por lo tanto restaurar los registros # salir" ,n el caso de tener dos 4uentes de interrupcin simult%neas' solo una ser(a tratada a la vez" .i por el con$ trario suprimimos esta Dltima l(nea' la siguiente interrupcin seria tratada al aca&ar el tratamiento de la inte$ rrupcin en curso" No *e estudiado este esqueleto para dejarle todas las variantes posi&les a disposicin # di$ rectamente utiliza&le"

116

A RESALTAR $ $ .i no se utiliza jam%s la interrupciontmrB' podemos suprimir esta parte del cdigo" .i la interrupcin tmrB est% puesta en servicio a lo largo de todo el programa' podr(amos suprimir el test de 9JI, 2estar(a permanentemente a 15" ,n el caso de 2 interrupciones simultaneas de 2 eventos distintos' la primera interrupcin tratada ser% aquella que ser% c*equeada primero" ,l orden de los test modi4ica' pues' la prioridad de las interrup$ ciones"

< continuacin' nos encontraremos el mismo procedimiento para las interrupciones del tipo 6=B 2las que nos interesan en nuestro caso5 # las del tipo 6P4R6P7" 1tese el emplazamiento previsto para a)adir el test de in$ terrupciones de escritura de la eeprom" ompletaremos m16F84.asm en este nivel estudiando los procedimientos de escritura de eeprom" 9odas es$ tas modi4icaciones se *an incluido en el 4ic*ero m16f84_new.asm "

intsw1 btfsc INTCON , INTE ; test si interrupcion RB0 autorizada btfss , INTF ; SI, test si interrupcion RB0 en curso INTCON goto intsw2 ; NO, saltar a test siguiente call intrb0 ; SI, tratar interrupcion RB0 bcf INTCON,INTF ; borrar flag interupcion RB0 goto restorereg ; fin de la interrupcion ; SUPRIMIR ESTA LINEA PARA ; TRATAR VARIAS INTERRUPCIONES ; DE UNA SOLA VEZ intsw2 btfsc INTCON,RBIE btfss INTCON,RBIF goto intsw3 ; NO, call intrb4 ; SI, bcf INTCON,RBIF ; goto restorereg ; intsw3 ; test si interrupcion RB4/7 autorizada ; SI, test si interrupcion RB4/7 en curso saltar tartar la interrupcion RB4/7 borrar el flag interupcion RB4/7 fin de la interrupcion

<qu( estar% el sitio para la interrupcin eeprom" :inalmente nos encontramos con la parte que sirve para la restauracin de los registros salvaguardados" Na *emos visto este procedimientoK
;restaurar registros ;------------------restorereg swapf status_temp , w ; swap antiguo status, resultado en w movwf STATUS ; restaurar status swapf w_temp , f ; Inversion L y H del antiguo W sin modificar Z swapf w_temp , w ; Re-inversion de L y H en W ; W restaurado sin modificar status retfie ; retorno desde interrupcion

117

12.10 Adaptacin de la rutina de interrupcin


Vamos a*ora a modi4icar esta rutina de interrupcin para adaptarla a nuestro caso" .olo tenemos una 4uente de interrupcin valida' que ser% para tratar I19R6PB" .uprimamos pues los test" 1os quedar%K
;********************************************************************** ; RUTINA INTERRUPCION * ;********************************************************************** ;salvaguarda registros ;--------------------org 0x004 ; direccin de interrupcion movwf w_temp ; salvar registro W swapf STATUS , w ; swap status con resultado en w movwf status_temp ; salvar status swapeado call intrb0 ; tartar interrupcion RB0 ;restaurar registros ;------------------swapf status_temp , w ; swap antiguo status, resultado en w movwf STATUS ; restaurar status swapf w_temp , f ; Inversion L y H del antiguo W sin modificar Z swapf w_temp , w ; Re-inversion de L y H en W ; W restaurado sin modificar status retfie ; retorno desde la interrupcion

Podr(amos' igualmente' pasar de la l(nea call intrb0 # poner directamente el tratamiento en su lugar" onservemos de todas 4ormas esta llamada puesto que no se va a tratar de un par de instrucciones ni esta$ mos cerca de des&ordar la pila" ,n caso de que necesitase optimizar la aplicacin al m%+imo' podr(a pensar en ello" ,n caso contrario' le recomiendo dar prioridad a la visi&ilidad del programa 2legi&ilidad continuo insis$ tiendo5" Va#amos a la continuacin del programa" Vamos a encontrarnos con las 3 rutinas de tratamiento de interrup$ ciones llamadas en origen por nuestra rutina de interrupcin" omo *emos suprimido 2 llamadas es inDtil conservar las su&rutinas correspondientes" 8a Dnica que necesitaremos ser%K
;********************************************************************** ; INTERRUPCION RB0/INT * ;********************************************************************** intrb0 return ; fin de la interrupcion RB0/INT ; puede ser reemplazada por ; retlw para retornar cdigo de error

1o contiene m%s que el retorno de la su&rutina correspondiente a la llamada call intrb0/ A"en(in5 en es"e nive& n* '"i&iD$%e.*s RETFIE #'es"* 3'e n* s$&i.*s )e &$ %'"in$ )e in"e%%'#(in5 sin* 3'e s$&i.*s )e 'n$ s'!%'"in$ &&$.$)$ #*% &$ %'"in$ )e in"e%%'#(in/ .i utiliz%semos RETFIE en este momento volver(amos a poner las interrupciones en servicio antes de salir # el programa se &loquear(a" 1tese que podr(amos utilizar para retornar un valor prede4inido a tratar por la rutina de interrupcin" Por ejemplo retlw 0 si quisi-semos tratar otras interrupciones # retlw 1 si quisi-semos salir" ,n ese caso' la l(nea goto restorereg 24in de interrupcin5 podr(a estar precedida de un test de 3 retornado por la su&rutina"

11;

12.11 La inicializacin
.igamos" 1os encontramos con la rutina de inicializacin que #a 4ue e+plicada en la leccin precedente" 1os contentaremos con reemplazar los cam&ios de &anco por los macros que *emos escrito' # con4igurar 6<2 co$ mo salida para el 8,?" J&tendremosK
;********************************************************************* ; INICIALIZACIONES * ;********************************************************************* init clrf PORTA ; Salidas portA a 0 clrf PORTB ; Salidas portB a 0 consommation clrf EEADR ; permite disminuir BANK1 ; pasar a banco1 movlw OPTIONVAL ; carga mascara movwf OPTION_REG ; inicializa registro option ; Effacer RAM ; ---------------movlw 0x0c ; inicializacion puntero movwf FSR ; punter direccionamiento indirecto init1 clrf INDF ; borrar ram incf FSR,f ; punter en siguiente btfss FSR , 6 ; test si fin zona esperada (>=0x40) goto init1 ; NO, bucle btfss FSR , 4 ; test si fin zona esperada (>=0x50) goto init1 ; NO, bucle ; configurar PORTS ; --------------bcf LED ; RA2 como salida (TRISA) BANK0 ; pasar a banco 0 movlw INTERMASK ; mascara de interrupcion movwf INTCON ; cargar control interrupcion goto start ; saltar a programa principal

.olo nos queda suprimir la l(neaK


clrwdt ; effacer watch dog

del programa principal dado que *emos desactivado el 3atc*dog"

ADVERTENCIA
Un$ 1%$n #$%"e )e &*s e%%*%es )e &*s #%*1%$.$s es"L en e& Me(M* )e e%%*%es en &$ se&e((in )e !$n(* Es*!%e "*)* en &*s PIC )e 4 !$n(*sF/ Le $(*nse2* (*.* (*nven(in5 en"%$% sie.#%e en 'n$ %'"in$ (*n e& !$n(* 45 T $se1'%$%se )e #$s$% $& !$n(* 4 $n"es )e s$&i%/ En ($s* )e n* M$(e%&* $sG5 in)i($%&* (&$%$.en"e en e& en($0 !eD$)* )e &$ s'!%'"in$/ 8ance el ensam&lado para compro&ar que no *a# errores" ?e&eria o&tener algo similar aK
Message[302] D:\DOCUME~1\LESSONS\DATAPIC\MYINTER.ASM 143 : Register in operand not in bank 0. Ensure that bank bits are correct. Build completed.

1o volveremos a e+plicar los 3arnings"

11Q

12.12 Construccin del programa principal


Vamos a*ora a realizar un tele ruptor" EGu- signi4ica esoF Pien' vamos a construir la siguiente 4uncinK una presin so&re el pulsador encender% el 8,?' una segunda presin lo apagar%" 8e vo# a guiar paso a paso en es$ ta realizacin' intentando mostrarle los pro&lemas pr%cticos que nos encontraremos en las realizaciones de este tipo" 8e recuerdo que es un programa did%ctico" 6ealizaremos este tele ruptor de una 4orma un poco m%s elegante en la leccin so&re el timerB" ?ado que queremos utilizar las interrupciones' la inversin en el encendido del 8,? se *ar% en la rutina de in$ terrupcin del pulsador" ,n un primer momento podemos pensar que el programa principal no de&e ocuparse de nada" A)ve%"en(i$ .'T i.#*%"$n"e En nin1-n ($s* #'e)e )e2$% 3'e s' #%*1%$.$ #%in(i#$& se )es&i(e ,'e%$ )e &$ D*n$ )e #%*1%$.$/ Si e& #%*0 1%$.$ n* )e!e M$(e% n$)$5 "en)%L5 en ('$&3'ie% .$ne%$ M$(e% 3'e se !'(&e s*!%e sG .is.*/ De es$ ,*%.$ e& #%*1%$.$ n* se #$%$%L 2$.Ls Ee9(e#"* ('$n)* en"%e en e& .*)* s&ee# 3'e ve%e.*s .Ls $)e&$n"eF/ 1uestro programa principal podr% ser de la 4ormaK
start goto start ; bucle

Pero para 4acilitar la visualizacin so&re el emulador le pedir- que a)ada algunas instrucciones 1JP inDtilesK

;********************************************************************* ; PROGRAMA PRINCIPAL * ;********************************************************************* start nop ; instruccion inutil nop ; instruccion inutil nop ; instruccion inutil nop ; instruccion inutil nop ; instruccion inutil goto start ; bucle END ; directiva fin de programa

12B

12.13 Construccin de la rutina de interrupcin


>emos programado el PIC de 4orma que una interrupcin so&re el 4lanco descendente de I19R6PB provo$ car% una interrupcin" 1o es su4iciente con ejecutar en esta rutina de interrupcin la inversin a nivel del 8,?" E>emos dic*o invertir un &itF ,sto le de&er(a llevar a pensar en la operacin lgica ^^J6 e+clusivo__" Podre$ mos escri&irK

;********************************************************************** ; INTERRUPCION RB0/INT * ;********************************************************************** ;---------------------------------------------------------------------; invierte el nivel de RA2 en cada pasada ;---------------------------------------------------------------------int rb0 movlw B'00000100' ; bit posicionado = bit a invertir BANK0 ; puesto que no sabemos en que banco estamos ; estamos en una interrupcin (el programa ; principal puede haber cambiado el banco). Aqui ; no es el caso, pero es una sabia precaucion xorwf PORTA , f ; invertir RA2 return ; fin de la interrupcion RB0/IN

J&serve que en este momento nuestro 8,? est% de4inido por la l(nea
#DEFINE LED PORTA , 2 ; LED

1os &astar% solo con cam&iar esta l(nea para situar nuestro led so&re otro pin di4erente sin tener que interve$ nir en nuestro programa" Por el contrario' esto no 4uncionar% a nivel de la inversin de la salida" 8o ideal es utilizar igualmente un de4ine para la m%scara en el comienzo del programaK
#DEFINE LED PORTA , 2 ; LED #DEFINE LED_MASK B00000100 ; Mascara de inversin del LED

N seguidamente reemplazar la l(nea


movlw B'00000100' ; bit posicionado = bit a invertir

por
movlw LED_MASK ; bit posicionado = bit a invertir

?e esta 4orma podremos e4ectivamente cam&iar el pin del 8,? sin intervenir en el programa e+cepto a nivel de los dos de4ines" 1uestra primera prue&a est% terminada" Pasamos el programa al simulador" <ntes le do# el 4lujo grama del programa que aca&amos de realizar" uando sus programas se va#an *aciendo m%s complejos' le aconsejo que recurra a los diagramas de 4lujo antes de escri&irlos' salvo que recurra al pseudocdigo 2escri&irlos en es$ pa)ol5"

121

:lujo grama 1 2versin tericamente 4uncional5K

omo puede ver' esta rutina de interrupcin no puede ser m%s simple' # se corresponde a lo que podr(amos imaginarnos desde un principio" Vamos a comenzar a pasarla por el simulador"

12.14 Pasaje al simulador de una rutina de interrupcin


1o olvide que el simulador de&e estar activado" .i no es as(' *%galo en este momento 2ver el cap(tulo so&re el de&ugger5" .eleccione la ventana ` .pecial :unctions 6egistersa si aDn no est% *ec*o" 8ancemos el ensam&lado con <F10>" Inmediatamente *aga <F6> para resetear el programa' despu-s *aga <F7>" 6epita <F7> para seguir la evolucin del programa" 1o se olvide que el programa va a e4ectuar 6; &u$ cles para &orrar la 6<=' sea paciente" <provec*e para o&servar el 4uncionamiento de :.6 en el direcciona$ miento indirecto" 9am&i-n puede presionar <F9> # seguidamente <F5> durante unos instantes" Hna vez llegado al programa principal' este se &ucla de 4orma in4inita" ,n e4ecto' es necesario un evento e+te$ rior 2pulsador5 para provocar el paso a la rutina de interrupcin" Vamos a*ora a e+plicar cmo simular un evento e+terior en el simulador" ,stas e+plicaciones var(an de una versin a otra de MPLAB" Hna vez ter$ minado el aprendizaje' le corresponde a usted adaptarlo a las di4erentes 4uncionalidades' esto no es nada complicado" Va#a al menD debugger -> stimulus " .i por azar tuviese mensajes de error concernientes al 4ic*ero' ign$ relos" .eleccione la pesta)a pin stimulus "

122

liquee so&re < $)) R*: = para o&tener un &otn de accin" .e crear% una nueva l(nea en la ventana' con un &otn titulado < Fi%e =/ liquee una vez so&re la columna < #in = justo al lado del &otn" 6ellenar las casillas < #in = # < $("i*n =" ,nsanc*e las columnas con el ratn para verlas mejor" Vamos a*ora a precisar la accin de nuestro &otn" ,n la casilla < "T#e = seleccionamos < $sTn(M = en lugar de <sTn(M%*ne =" ,n e4ecto' el evento podr% ocurrir en cualquier momento de la ejecucin del programa" 1o pulse el &otn ` 4ire a por el momento" on la a#uda del menD desplega&le de la casilla < #in = vamos a determinar que pin ser% estimulado por la accin so&re el &otn que *emos creado" omo nuestro &otn est% conectado so&re el pin R>4' selecciona$ mos este pin" .i o&serva en la casilla < $("i*n = ver% que *a accedido a un modo de 4uncionamiento del &otn" 9iene la po$ si&ilidad de elegir entre P'&se 2genera un impulso5' L*: 2pone un nivel B5' i1M 2pone un nivel 15 o T*11&e 2in$ versin del nivel a cada pulsacin5" ,legiremos la menos pr%ctica para este ejemplo' pero la m%s e+pl(cita" ,lija Low " <*ora s( est% #a con4igurado el &otn de estimulacin" ?e&er(a *a&er o&tenido una ventana como estaK

123

ree una nueva l(nea con add row # cree un segundo &otn"

,lija High en la casilla de accin" Puede poner comentarios en las casillas comments " 1o se corte" ,+aminemos el registro PORTB en la ventana de registros especiales" Ver% que todos los &its est%n a B" ,n e4ecto MPLAB' no puede conocer la electrnica que *a conectado a los pines" ,s su responsa&ilidad indi$ carle el nivel a los que est%n conectados los pines" Para aquellos que no *a#an comprendido el 4uncionamien$ to de la resistencia de re4erencia aM5V' *e aqu( una vez m%s el esquema equivalenteK

124

Vemos que cuando el pulsador no est% activado' tenemos un nivel 1 en 6PB provocado por la resistencia de re4erencia que pusimos en servicio" Presionemos el segundo &otn una vez # va#amos al editor" Presionemos<F7> para avanzar un paso # vali$ dar la modi4icacin del nivel" ,+aminemos PORTB : RB0 a*ora *a pasado a 1" 1uestro pulsador no est% pre$ sionado" Pulse <F7> algunas veces para veri4icar que no ocurre nada" Vamos a*ora a simular la pulsacin del pulsadorK Presione primero el &otn para enviar un B a 6PB" Vuelva al editor # pulse una sola vez<F7>" 8a instruccin que sigue al evento es a*ora la instruccin situada en la direccin B+B4 puesto que el paso de 1 a B de 6PB *a provocado nuestra interrupcin" <vance lentamente pulsando en la rutina de interrupcin" ,+amine el e4ecto de las di4erentes instruc$ ciones" Hna vez la l(neaK
xorwf PORTA , f ; inverser RA2

>a sido ejecutada constatar% que le 8,? se enciende 26<2 pasa a valer 1 en el registro PJ69<5" <vance lentamente *asta que la l(nea
retfie ; return from interrupt

.e seleccione # no pulse m%s <F7>" ,n este momento nos *emos encontrado el retorno de la rutina de interrupcin para volver al programa prin$ cipal" Pulse <F7> un sola vez" EGu- *a pasadoF ,n lugar de volver al programa principal volvemos a comenzar de nuevo en la rutina de inte$ rrupcin" Para provocar una interrupcin' *ace 4alta que el &it ena&le # el &it de 4lag de una de las 4uentes de interrup$ cin est- a 1" J solo *a# un &it ena&le a 1 # este es I19,"

125

,+aminemos INTF 2es el &it 1 de INTCON5" ,ste &it est% siempre a 1' es por esto la nueva interrupcin" >emos cometido un error cl%sico" 1os *emos olvidado de &orrar el 4lag al 4inal del tratamiento de la rutina de interrupcin" J&serve que ese &orrado est% integrado en la parte switch de de la rutina de interrupcin del 4ic*ero m16f84.asm" >emos &orrado esta l(nea por error al suprimir los di4erentes test" ?e *ec*o lo *e realizado de 4orma volunta$ ria siguiendo la regla de que /memorizamos mejor las cosas despu-s de un error0"

12.15 Primera correccin: reset del flag


1os *ace 4alta a)adir la l(nea siguiente en nuestra su&rutina intr&B
bcf INTCON , INTF ; borrar el flag INT/RB0

9endremos
rb0 movlw B'00000100' ; bit posicionado = bit a invertir BANK0 ; puesto que no sabemos en que banco estamos ; estamos en una interrupcin (el programa ; principal puede haber cambiado el banco). Aqui ; no es el caso, pero es una sabia precaucion xorwf PORTA , f ; invertir RA2 bcf INTCON , INTF ; borra el flag INT/RB0 return ; fin de la interrupcion RB0/IN

,nsam&lemos de 1uevo el programa con ^:1B_' despu-s ^:6_ # recomencemos todo el procedimiento que aca&amos de ver" Veri4ique que la rutina de interrupcin termina a*ora volviendo al programa principal" ,l 8,? est% a*ora encendido 26<2L15" Presione a*ora el segundo &otn para simular el soltar el pulsador" Presione ^:7_ varias veces # despu-s pul$ se el &otn <RB0 (L)> para simular una segunda pulsacin del pulsador" .iga la rutina de interrupcin # constate que esta vez el 8,? se apaga" J&tenemos en el simulador la siguiente 4uncionalidadK Hna presin so&re el pulsador enciende el 8,?" Jtra pulsacin lo apaga" <s( de continuo"

>emos o&tenido el resultado deseado" oloque el PIC en el programador # env(ele el 4ic*ero Myinter.hex " oloque el PIC so&re la placa de e+perimentacin 2modi4icada5 # pulse el pulsador varias veces" ,l 8,? no 4unciona de ninguna manera como *a&(amos previsto" 6eacciona de una 4orma aleatoria" EGu- est% pasandoF

126

12.16 Ponerse en la escala de tiempos del PIC


<cu-rdese' #a le llam- la atencin so&re este punto en concreto" onvirt%monos en PI # e+aminemos que vemos" ?e *ec*o la escala de tiempos est% relacionada con la escala de tama)os' vemos un enorme pulsador' con un contacto el-ctrico del tama)o de un rail de tren" uando accionamos el pulsador es como una enorme &arra que viene a cortocircuitar 2 contactos" ,sta &arra es el%stica" EGu- ve el PI !F Ve esa enorme &arra met%lica que cae so&re los 2 contactos desde una altura enorme" Hna vez que esta&lece el contacto re&ota unas cuantas veces antes de inmovilizarse" < cada pulsa$ cin so&re el pulsador' el PI ! ve una serie de aperturas # cierres del contacto en lugar de una sola' en nues$ tra escala de tiempos" ,l PIC es muc*o m%s r%pido que nuestro pulsador"

12.17 El problema del anti rebote


E mo remediar el pro&lemaF :%cilmente' ralentizando el 4uncionamiento de nuestro PI ' # por lo tanto' es$ perando un tiempo m%s largo que el necesario para los re&otes antes de autorizar una nueva interrupcin so$ &re 6PB" Vamos a utilizar nuestros conocimientos actuales para solucionar el pro&lema" onviene dise)ar un 4lujo gra$ ma 2#a se lo dije5 de lo que vamos a *acerK

127

E9#&i($(in ,l programa principal ejecuta sus inicializaciones de 4orma normal' despu-s c*equea si una peticin de tiem$ po *a ocurrido 2posicionado del 4lag tempo 5" .i el 4lag no est% activado' entramos en un &ucle sin 4in" .i pulsamos el pulsador' se genera una interrupcin' se invierte 6<2' la rutina posiciona el 4lag tempo a 1 e impide cualquier nueva interrupcin" ualquier otra nueva accin so&re 6PB quedar% sin e4ecto 2re&otes in$ cluidos5" J&serve que nada impide que una rutina de interrupcin se pro*(&a a s( misma" 8a rutina de interrupcin aca&a" 6etornamos al programa principal' el cual c*equea a*ora si *a# una demanda de tiempo mediante el posicionado del 4lag tempo" ,ste aca&a de ser posicionado por la rutina de interrup$ cin" ,l programa principal llama a*ora a una rutina de temporizacin 2que #a *a&(amos visto en la leccin principal5" ?espu-s de la espera de tiempo necesaria para la desaparicin de los re&otes' el 4lag tempo es reseteado 2para no entrar en un &ucle sin 4in5 # las interrupciones son nuevamente autorizadas con la 4inalidad de per$ mitir tener en cuenta una nueva pulsacin del pulsador" <qu( puede constatar que a veces es interesante pro*i&ir # permitir las interrupciones en di4erentes momen$ tos espec(4icos del programa"

12.18 Finalizacin de un programa


,n principio nos *ace 4alta una rutina de temporizacin" <&ra el 4ic*ero Led_cli.asm # e4ectDe un co$ piarRpegar de la rutina de temporizacin"
;********************************************************************* ; SUBRUTINA DE TEMPORIZACION * ;********************************************************************* ;--------------------------------------------------------------------; Esta subrutina introduce un retardo de 500.000 s. ; No recibe ni retorna ningn parametro ;-------------------------------------------------------tempo movlw 2 ; para 2 bucles movwf cmp ; inicializa comp boucle3 clrf cmpt2 ; borrar compteur2 boucle2 clrf cmpt1 ; borrar compteur1 boucle1 nop ; pierde 1 ciclo decfsz cmpt1 , f ; decrementa compteur1 goto boucle1 ; si no 0, bucle decfsz cmpt2 , f ; si 0, decrementa compteur2 goto boucle2 ; si cmpt2 no 0, recomienza bucle2 decfsz cmpt3 , f ; si 0, decrementa compteur3 goto boucle3 ; si cmpt3 no 0, recomienza boucle2 return ; retorno de la subrutina

Vamos a modi4icar ligeramente esta su&rutina" Podemos eliminar el &ucle e+terior puesto que 5BB ms es mu$ c*o m%s que el tiempo de re&otes del pulsador" Guitemos igualmente la instruccin 1JP" J&tendremosK

12;

;********************************************************************* ; SUBRUTINA DE TEMPORIZACION * ;********************************************************************* ;--------------------------------------------------------------------; Esta subrutina introduce un retardo ; No recibe ni retorna ningn parametro ;-------------------------------------------------------tempo clrf cmpt2 ; borrar compteur2 boucle2 clrf cmpt1 ; borrar compteur1 boucle1 decfsz cmpt1 , f ; decrementa compteur1 goto boucle1 ; si no 0, bucle decfsz cmpt2 , f ; si 0, decrementa compteur2 goto boucle2 ; si cmpt2 no 0, recomienza bucle2 return ; retorno de la subrutina

1o utilizaremos la varia&le cmpt3" Podemos suprimirla de la zona de varia&les" ?ado que estamos all(' necesi$ taremos un 4lag' es decir un &it" re-moslo en esta zona"

;********************************************************************* ; DECLARACION DE VARIABLES * ;********************************************************************* CBLOCK 0x00C ; comienzo de la zona de variables w_temp :1 ; salvaguarda de W en la interrupcion status_temp : 1 ; salvaguarda de STATUS en la interrupcion cmpt1 : 1 ; contador de bucles 1 en tempo cmpt2 : 1 ; contador de bucles 2 en tempo flags : 1 ; un octeto para 8 flags ; reservamos b0 para el flag tempo ; b1 : libre ; b2 : libre ; b3 : libre ; b4 : libre ; b5 : libre ; b6 : libre ; b7 : libre ENDC ; Fin de la zona #DEFINE tempoF flags, 0 ; Definicion del flag tempo

=odi4iquemos el programa principal siguiendo nuestro 4lujo grama # o&tendremosK


;********************************************************************* ; PROGRAMME PRINCIPAL ;********************************************************************* start btfss tempoF ; test si tempo flag esta puesto goto start ; No, esperamos a que este puesto call tempo ; SI, ejecutamos tempo bcf tempoF ; borramos el flag tempo bsf INTCON , INTE ; vuelve a poner interrupciones INT en servicio goto start ; bucle END ; directiva de fin de programa

12Q

1o nos queda m%s que modi4icar nuestra rutina de interrupcin en 4uncin de nuestro 4lujo grama' o&tenien$ doK

;********************************************************************** ; INTERRUPCION RB0/INT * ;********************************************************************** ;---------------------------------------------------------------------; invierte el nivel de RA2 en cada pasada ; prohbe toda nueva interrupcion ; valida el flag tempo ;---------------------------------------------------------------------intrb0 movlw B'00000100' ; bit posicionado = bit a invertir BANK0 ; puesto que no sabemos en que banco estamos ; estamos en una interrupcin (el programa ; principal puede haber cambiado el banco). Aqui ; no es el caso, pero es una sabia precaucion xorwf PORTA , f ; invertir RA2 bcf INTCON , INTF ; borrar flag INT/RB0 bcf INTCON , INTE ; impide otra interrupcion de RB0 bsf tempoF ; posiciona el flag tempo return ; fin de la interrupcion RB0/IN

,nsam&lemos nuestro programa # cam&iemos el nuevo 4ic*ero "*e+ en nuestro PIC" onectemos la alimen$ tacin" ,sto sigue sin 4uncionar" EGu- est% pasandoF 6e4le+ionemos" Hna vez que la rutina de interrupcin termina' las interrupciones son invalidadas" ,l pulsador re&ota sin cau$ sar ninguna llamada de interrupcin' pero su 4lag se posiciona a causa de los re&otes" 6ecuerde que los &its de ena&le no a4ectan a los 4lags" Por lo tanto' cuando el programa general pone de nuevo las interrupciones en servicio' se genera una nueva interrupcin nuevamente puesto que I19: esta&a posicionado durante los re$ &otes" Hsted de&e pensar en todo cuando maneje interrupciones" .i un programa 4unciona en el simulador pero no lo *ace en la vida real' piense inmediatamente en pro&lemas de tiempo" C*%*&$%i* R'e 'n #%*1%$.$ ,'n(i*ne en e& si.'&$)*% n* si1ni,i($ 3'e se$ (*%%e("*/ Pastar% con insertar una instruccin de reseteado del 4lag I19: antes de volver a permitir las interrupciones"
Bcf INTCON , INTF ; borrar flag INT

Podr(a decir que es inDtil &orrar este 4lag en la rutina de interrupcin" ,s lgico' pero m%s vale ir cogiendo &uenos *%&itos" ?ejemos pues esta instruccin" ,nsam&le el programa' rec%rguelo en el PI " <limente el montaje" ,sta vez 4unciona per4ectamente" >e aqu( un montaje mu# pr%ctico" .i reemplaza el 8,? por un rele o por un triac opto acoplado' estar% en posesin de un tele ruptor"

13B

< t(tulo de plus' *e aqu( el esquema de un tele ruptor completamente operacional con nuestro programaK

O!se%v$(i*nes s*!%e n'es"%* #%*1%$.$/ >emos utilizado una temporizacin de un valor cualquiera" ,sta temporizacin in*i&e la accin del pulsador durante unos 25B ms" Por lo tanto' podr(a accionar el pulsador unas 4 veces por segundo como m%+imo" Pero Ecu%l es la duracin real de los re&otesF ?epende del pulsador' tecnolog(a # tama)o" Para conocer el tiempo de re&ote de nuestro pulsador' decremente poco a poco el valor de la temporizacin *asta que apa$ rezcan pro&lemas de re&ote" Yeneralmente ser% del orden de algDn ms" O!se%v$(i*nes s*!%e n'es"%* #%*1%$.$/ 6ecuerde que una vez que utiliza interrupciones en su programa' no podr% sa&er el tiempo que separa a dos instrucciones consecutivas" Puede ocurrir que entre dos instrucciones consecutivas se cuele una interrupcin' des&aratando nuestro cal$ culo de tiempo" ,n consecuencia' no podr% utilizar el c%lculo de tiempo calculando el nDmero de instrucciones en una parte de cdigo en la que pueda ocurrir una interrupcin" Para toda aquella secuencia en la que el tiempo sea cr(tico # no pueda ser interrumpido' usted de&er% in*i&ir las interrupciones" Guedar% a su cargo volver a poder permitirlas" Hna vez que utilice interrupciones' su programa de&er% a4rontar sucesos que ocurrir%n de 4orma as(ncrona" Por lo tanto' no podr% c*equear jam%s todas las eventualidades posi&les" ?esgraciadamente' no podr% estar jam%s seguro por medio de la simulacin que su programa est% li&re de errores" ,sto le e+plica por qu- la gestin de procesos cr(ticos 2naves espaciales5 en tiempo real utilizan m%s de un or$ denador" ,n estos ordenadores' estando de sincronizados' la aparicin de un error so&re uno de ellos tiene poca pro&a&ilidad de que aparezca en el segundo" Para sa&er quien *a tenido el pro&lema' &asta con tener un tercero" 8a ma#or(a los lleva"

131

9enga esto en cuenta si algDn d(a est% llamado a realizar un programa del que dependa la seguridad de per$ sonas o &ienes" C*n(&'si*nes <l t-rmino de este cap(tulo' usted *a&r% aprendido los mecanismos de las interrupciones # podr% utilizarlas" Vamos a utilizar todav(a esta posi&ilidad en la leccin so&re el timer" ,spero *a&er desmiti4icado este concepto' demasiado a menudo imaginado como /el m-todo de los pro4e$ sionales0" ,n realidad' una vez m%s' nada de magia" ,s simplemente una e+plotacin' a veces compleja' de procedimientos simples # 4%ciles de entender" .implemente tenga en cuenta que a&andona el mundo seguro # previsi&le de lo s(ncrono para entrar en el mundo de lo as(ncrono' muc*o m%s di4(cil de simular de una 4orma totalmente e4iciente" 8a utilizacin de las interrupciones impone' de *ec*o' la per4ecta comprensin de los mecanismos puestos en juego' # nos o&liga a prever todas las posi&ilidades de ocurrencia de un evento e+terior" ,sto es especialmen$ te cierto para los programas con diversas 4uentes de interrupcin" 8e aconsejo encarecidamente' antes de encarar la realizacin de un programa de cierta complejidad' comen$ zar por escri&ir un algoritmo general o la utilizacin de un 4lujo grama"

132

13.El Timer 0
,n este cap(tulo vamos a *a&lar de las temporizaciones # de los conteos" ,l 16:;4 solo dispone de un tempo$ rizador de ; &its' al contrario que otros PIC de la 4amilia 2como el 16:;765" .i e+aminamos atentamente el 4uncionamiento del timerB veremos que se trata' de *ec*o' de un contador"

13.1 Los diferentes modos de funcionamiento


>emos visto que el timerB es un contador" EPero qu- es lo que cuenta este timerF Pien' tenemos dos posi&ili$ dadesK ,n primer lugar podemos contar los impulsos reci&idos so&re el pin RA4/TOKI" ?iremos en este ca$ so que estamos en modo contador" Podemos tam&i-n contar los ciclos de reloj del mismo PIC" ,n este caso' como el reloj est% 4ijo' contaremos en realidad tiempo" ,staremos en modo temporizador"

8a seleccin de uno u otro modo de 4uncionamiento se e4ectDa a trav-s del &it 5 del registro JP9IJ1K9B . llamado as( por Tmr0 Clock Source select bit 2de nuevo la ci4ra B no la letra J5" T4CS61 K 4uncionamiento en modo contador" T4CS64 K 4uncionamiento en modo timer" ,n el caso de que decidamos tra&ajar en modo contador' de&eremos tam&i-n decidir cu%l es el modo de tran$ sicin del impulso para que se e4ectDe el contaje" ,sto se *ace gracias al &it 4 del registro OPTION : T0SE por Timer0 Source Edge select bit.

13.2 El registro tmr0


,ste registro' que est% localizado en la direccin B+B1 del &anco B' contiene simplemente el valor actual del timerB" Podr% escri&ir o leer tmrB" .i por ejemplo *a con4igurado tmrB como contador' la lectura del registro tmrB le dar% el numero de eventos que *an llegado al pin 6<4R9JUI"

13.3 Los mtodos de utilizacin del timer0


E mo utilizar el timerB # cu%l es la o4erta de posi&ilidades a este nivelF >e aqu( de lo que vamos a *a&lar"

13.3.1 El modo de lectura simple


,l primer m-todo que nos viene a la ca&eza es el siguienteK leer el registro tmrB para ver que contiene" ,l va$ lor le(do es el re4lejo del nDmero de eventos ocurridos' teniendo en cuenta el *ec*o de que tmrB no puede contar m%s que *asta 255" ,n caso de so&repasar este valor el tmrB comienza desde B de nuevo" ,s su come$ tido el gestionar esta posi&ilidad" Peque)o ejemploK
clrf tmr0 ; comienzo de contaje 2 ciclos ms lejos ; (ver recuadro ms adelante) xxx ; aqu un cierto numero de instrucciones movf tmr0 , w ; cargar el valor de contaje movwf mavariable ; salvar para tratamiento posterior

133

13.3.2 El modo de vigilancia del flag


?e&emos sa&er a estas alturas' que todo des&ordamiento del timerB 2pasaje de B+:: a B+BB5 conlleva el posi$ cionamiento del 4lag 9BI: del registro I19 J1" Podemos utilizar este 4lag para determinar si *emos tenido un des&ordamiento del timerB o' en otras pala&ras' si el tiempo programado *a sido alcanzado" ,jemploK
clrf tmr0 ; ; comienzo de contaje 2 ciclos ms lejos ; (ver recuadro ms adelante) bcf INTCON , T0IF ; borrado del flag loop btfss INTCON , T0IF ; test si contador desbordado goto loop ; NO, esperar desbordamiento xxx ; proseguir : 256 eventos alcanzados

Hsted podr(a decir que no desea espec(4icamente espera 256 incrementos del tmrB" .upongamos que desea$ mos esperar 1BB incrementos" .er(a su4iciente con colocar en tmrB un valor tal que 1BB incrementos m%s tar$ de se provoque un des&orde del tmrB" ,jemploK
movlw 256-100 ; cargar 256 100 movwf tmr0 ; inicializar tmr0 bcf INTCON,T0IF ; borrado del flag loop btfss INTCON,T0IF ; test si contador desbordado goto loop ; NO, esperar desbordamiento xxx ; proseguir : 100 eventos alcanzados

,sto podr(a parecer correcto a primera vista' peroK T*)$ .*)i,i($(in )e& TMR4 (*n&&ev$ 'n$ #$%$)$ )e& (*n"$2e (*%%es#*n)ien"e $ J (i(&*s )e ins"%'((in/ .i el ejemplo precedente no utiliza pre divisor' *a&r% que tener en cuenta esta p-rdida colocando 256-98 # no 256-100 en el timer"
movlw 256-98 ; desbordamiento en 100 ciclos

13.3.3 El modo interrupcin


,videntemente es el modo principal de utilizacin del timerB" Puesto que 9BI: se *a posicionado en el registro I19 J1' cada vez que el 4lag 9BI: pasa a 1' se genera una interrupcin" ,l procedimiento a seguir #a se *a vis$ to en la leccin so&re interrupciones"

13.3.4 Los mtodos combinados


.upongamos que usted quiera' por ejemplo' medir el tiempo entre 2 impulsos so&re el pin 6PB" .upongamos que este tiempo sea tal que comporte el des&ordamiento de tmrB varias veces" Hn m-todo simple de medi$ cin de este tiempo ser(a el siguienteK on el primer impulso so&re 6PB lanzar el timerB en modo interrupcin" < cada interrupcin de tmrB incrementamos una varia&le" on la segunda interrupcin en 6PB leemos tmrB # paramos las interrupciones" ,l tiempo total ser% (256 * variable) + tmr0

>a&remos utilizado las interrupciones para los mDltiplos de 255 # la lectura directa de tmrB para las unidades" 134

13.4 El pre divisor


.upongamos a*ora que tra&ajamos con un cuarzo de 4 =>z 9enemos en este caso 24BBBBBBR45L1"BBB"BBB ci$ clos por segundo" ada ciclo de reloj durar% 1R1BBBBBB segundos' es decir' 1 s. .i decidimos utilizar el timerB en su modo de 4uncionamiento de interrupcin tendremos una interrupcin ca$ da 256 s es decir' apro+imadamente cada cuarto de milisegundo" .i deseamos realizar un 8,? intermitente parpadeando a una 4recuencia de M$ 1>z necesitaremos una tempo$ rizacin de 5BB ms' es decir' 2BBB veces ma#or" ,sto no es pr%ctico" Pero' disponemos de un pre divisor para disminuir la &ase de tiempos del timer" EGu- es estoF .implemente un divisor de eventos situado antes de la entrada de contaje del timerB" Podemos decidir' por ejemplo' tener un incremento del tmrB cada 2 eventos' o incluso cada 64" onsecuenciasK N'es"%* (*n"$)*% $v$nD$ .Ls &en"$.en"e5 &* 3'e evi"$%L in"e%%'#(i*nes in-"i&es/ N'es"%$ #%e(isin se ve &i.i"$)$ $ 'n .-&"i#&* )e& v$&*% )e #%e )ivisin/ J&serve la ta&la de la p%gina Q del datas*eet" Puede ver la ta&la de los &its P.B a P.2 del registro JP9IJ1 que determinan el valor del pre divisor"

,stos valores var(an' para el timerB' entre 2 # 256" ,l &it P.< determina si el pre divisor est% asociado al tiemrB o al 3atc*dog" >e aqu( una ta&la e+plicando todas las posi&ilidades de estos &its"

135

PSA $ PS4 K &its de con4iguracin del pre divisor" W".%4 K valor resultante del pre divisor so&re el timerB" WOD K valor resultante del pre divisor so&re el 3atc*dog" Te.#s ".%4 K numero de ciclos de instrucciones que causaran un des&ordamiento" Te.#s :$"(M)*1 K indica el tiempo t(pico disponi&le entre 2 resets del 3atc*dog" ,l valor entre par-ntesis indica el tiempo m(nimo' que es el que *a# que utilizar para *acer 4rente a todas las cir$ cunstancias"

J&serve que el tiempo de des&ordamiento depende a la vez del nDmero de ciclos contados entre dos des&or$ damientos as( como del tiempo necesario para ejecutar un ciclo de instruccin (1s a 4Mhz)" Por el contra$ rio' para el 3atc*dog' este tiempo est% 4ijado # no depende de la duracin del ciclo de instruccin' ni por lo tanto de la 4recuencia del reloj" O!se%v$(i*nes i.#*%"$n"esK .olo *a# un pre divisor' que puede ser elegido para el timer del 3atc*dog 2que veremos m%s tarde5 o para el tmrB" 1o puede a4ectar a los dos al mismo tiempo" 1o e+iste un pre divisor por 1 para el timerB" .i no quiere pre dividir el timerB de&er%' imperativa$ mente' seleccionar el pre divisor para el 3atc*dog con un valor 1" ,l valor contenido en el pre divisor no est% accesi&le" Por ejemplo' si selecciona una pre divisin por 64 # en un momento dado #a *an ocurrido 3B eventos' no tendremos ningDn medio directo de sa&er$ lo" ,l pre divisor limita pues la precisin en caso de lectura directa puesto que solo podremos o&tener como resultado un mDltiplo entero del pre divisor" 8a escritura en el registro tmrB &orra el contenido del pre divisor" 8os eventos que ocurrieron *asta la escritura se perder%n irremisi&lemente" 9oda modi4icacin de 9=6B 2&orrado' incremento' operacin]5 entra)ar% una parada del contaje del timer correspondiente' lo que nos dar% un de4ecto de 2 unidades 22 unidades de menos5 en el contaje previsto"

T%'(* 1 .i de&e' por una razn u otra' detener el timer' ser% su4iciente con pasarlo a modo de contaje e+terno con la condicin de que no tenga electrnica conectada al pin correspondiente (RA4/T0CKI)" 8e consejo' en ese caso' 4orzar un nivel &ajo en ese pin con el o&jetivo de evitar cualquier conteo de&ido a una pertur&acin de origen electromagn-tico #' evidentemente' ajustar 9B., a B 2conteo por 4lanco ascendente' de B a 15"

136

T%'(* J omo #a *emos comentado' en caso de lectura del timer los impulsos #a contados en el pre divisor' # no ac$ cesi&les' se pierden" ?e *ec*o' e+iste un truco para tener una precisin completa incluso con un pre divisor" Imaginemos que deseamos' por ejemplo' contar los impulsos reci&idos en T0CKI entre dos sucesos dados" Imaginemos que el sistema est% preparado para que en ausencia de impulso el nivel so&re el pin sea alto 2con una resistencia de carga por ejemplo5" .olo se necesitar% desactivar la electrnica de conteo 2otro pin del PI ' por ejemplo' a menos que' simplemente' no reci&a m%s ningDn evento5" Imaginemos' adem%s' para nuestro ejemplo' que #a *a reci&ido 53 eventos # que el pre divisor est% con4igurado en 16" ,n este momento se en$ cuentra en la siguiente situacinK 9mrB contiene 3 2parte entera de 53R165 ,l contador del pre divisor contiene 5 253 e 3 I 165

Hsted sa&e que *a contado entre 4; # 63 eventos' pero no sa&e el valor e+acto" ,l truco va a consistir en &as$ cular 6<4 como salida # enviarle v(a programa cam&ios de nivel alto a &ajo" ,sto va a motivar conteo de ele$ mentos que usted mismo *a&r% e4ectuado" .er% su4iciente con ir contando estos eventos # vigilando el mo$ mento en el que el timer pasa del valor 3 al 4" Hna vez que llegue al valor 4' *a&r% conta&ilizado e+actamente 64 eventos" .er% su4iciente a*ora con restar los eventos que usted mismo gener' # o&tendr% el nDmero e+acto de eventos que *a&(amos conta&ilizado realmente" Pensando un poco' podremos resolver cualquier tipo de situacin"

13.5 Aplicacin prctica del timer0


Vamos a poner en marc*a nuestro tmrB con una aplicacin pr%ctica" 6etomemos nuestro primer ejercicio' a sa&er' *acer parpadear un 8,? a una 4recuencia apro+imada de 1 >z"

13.5.1 Preparaciones
>aga un copiarRpegar de su nuevo 4ic*ero m16f84.asm # renm&relo como Led_tmr.asm " 6elance MPLAB # cree un nuevo pro#ecto titulado Led_tmr.pjt " <)ada su Led_tmr.asm " ree la ca&ecera 2vuelvo a insistir5"
;********************************************************************** ; * ; Hacer parpadear un LED a una frecuencia aproximada de 1 Hz * ; * ;********************************************************************** ; * ; NOMBRE: LED PARPADEANTE CON TIMER0 * ; Fecha: 17/02/2001 * ; Version: 1.0 * ; Circuito: Tarjeta de pruebas * ; Auteur: Bigonoff * ; * ;********************************************************************** ; * ; Fichero requerido: P16F84.inc * ; * ;********************************************************************** ; * ; Notas: Utilizacion didctica del tmr0 en modo interrupcin * ;**********************************************************************

137

?e4inamos a continuacin la con4iguracin poniendo el 3atc*dog 4uera de servicio" <*ora #a sa&e cmo *acerlo" alculemos el nDmero de des&ordamientos de tmrB necesarios" 1ecesitamos una temporizacin de 5BB ms' es decir 500.000 s o 5BB"BBB de veces un ciclo de instruccin" ,l timerB genera' sin pre divisin' una interrupcin cada 256 ciclos" Vamos' pues' a utilizar pre divisor" .i to$ mamos el ma#or valor disponi&le' 256' tendremos una interrupcin cada 256 I 256 L 65536 tiempos de ciclo o lo que es lo mismo' cada 65536 s 2a 4 =>z5" ?e&eremos pasar 5BB"BBB R 65536 L 7'63 veces por nuestra rutina de interrupcin" omo no podemos pasar un nDmero decimal de veces elegiremos 7 u ; veces en 4uncin del error que queramos aceptar en un sentido u otro" J&serve que si pasa 7 veces *a&r% contado poco tiempo # siempre ser% posi&le alargarlo" ,n caso contrario 2; veces5 *a&r% pasado demasiado tiempo # no *a&r% correccin posi&le" ,s evidente que la aceptacin de un error estar% en 4uncin de la aplicacin" .i lo que desea *acer parpadear es una guirnalda de 1avidad' el error ser% irrisorio" .i lo que desea construir es un cronometro' el error ser(a inacepta&le" omencemos ignorando el error" ?ecidimos utilizar un pre divisor por 256 con 7 pasadas por la rutina de interrupcin" ,l tiempo o&tenido ser%' en realidad' de 256 I 256 I 7 L 458752 s en lugar de los 500.000 s tericos" 6etomando nuestra ta&la el contenido del registro OPTION con el que de&eremos inicializar ser% B10000111' es decir' 0x87" 6esistencia de carga 4uera de servicio 2no la necesitamos5' 4uente del tmrB in$ terna # pre divisor de 256" Por lo tanto' pondremosK
OPTIONVAL EQU H'87' ; Valor registro option ; Resistencia pull-up OFF ; Prscaler timer a 256

< continuacin de&eremos determinar el valor a poner en el registro INTCON para o&tener las interrupciones so&re el tmrB" ,sto ser% B10100000' es decir' 0xA0"
INTERMASK EQU H'A0' ; Interrupciones sobre tmr0

< continuacin de4inimosK


;********************************************************************* ; DEFINE * ;********************************************************************* #DEFINE LED PORTA,2 ; LED

1o tocamos nuestra rutina de interrupcin principal dado que tenemos su4iciente espacio de memoria para conservar nuestros tests" ,scri&amos nuestra rutina de interrupcin del timer" Vemos inmediatamente que de&emos contar las pasadas de tmrB' por lo tanto' necesitaremos una varia&le" ?eclar-mosla en la zona B+B "
cmpt : 1 ; contador de pasadas

13;

13.5.2 La inicializacin
omo es m%s 4%cil detectar un valor igual a B que igual a 7' vamos a ir decrementando nuestra varia&le de 7 a B" Invertiremos el 8,? una vez alcanzado el valor B" ?e&eremos inicializar nuestra varia&le a 7 para una prime$ ra pasada" >aremos nuestra inicializacin antes del goto start" <provec*aremos para poner nuestro puerto 8,? en mo$ do salidas"
;********************************************************************* ; INITIALISATIONS * ;********************************************************************* init clrf PORTA ; Salidas portA a 0 clrf PORTB ; Salidas portB a 0 clrf EEADR ; permite disminuir el consumo BANK1 ; pasar a banco 1 movlw OPTIONVAL ; cargar mascara movwf OPTION_REG ; inicializar el registro OPTION ; Borrar la RAM ; -----------movlw 0x0c ; inicializacion del puntero movwf FSR ; punter de direccionamiento indirecto init1 clrf INDF ; borrar ram incf FSR,f ; punter en siguiente btfss FSR,6 ; test si fin zona esperada (>=0x40) goto init1 ; NO, bucle btfss FSR,4 ; test si fin zona esperada (>=0x50) goto init1 ; NO, bucle ; Inicializar puertos ; ------------------bcf LED ; poner LED como salida BANK0 ; pasar a banco 0 movlw INTERMASK ; mascara de interrupciones movwf INTCON ; cargar control de interrupciones ; Inicializacion de variables ; --------------------------movlw 7 ; carga 7 movwf cmpt ; inicializa contador de pasadas goto start ; salta al programa principal

13Q

13.5.3 La rutina de interrupcin


6ealicemos a*ora nuestra rutina de interrupcin" 8o primero' decrementaremos nuestro contador de pasadas" .i no es nulo no *aremos nada en esta pasada"
decfsz cmpt , f ; decrement el contador de pasadas return ; No es 0, no hacemos nada

.i el resultado es nulo de&eremos invertir el estado del 8,? # recargar con 7 el contador de pasadas"
;********************************************************************** ; INTERRUPCION TIMER 0 * ;********************************************************************** inttimer decfsz cmpt , f ; decrement el contador de pasadas return ; No es 0, no hacemos nada BANK0 ; por precaucion movlw b'00000100' ; seleccionar el bit a invertir xorwf PORTA , f ; invertir LED movlw 7 ; para 7 nuevas pasadas movwf cmpt ; cargar el contador de pasadas return ; fin de la interrupcion timer

.olo nos queda &orra la l(nea


clrwdt ; borra watch dog

?el programa principal' puesto que el 3atc*dog est% 4uera de servicio" ,nsam&le el programa" 8o pasamos al simulador" 1o olviden poner el simulador en servicio # a&rir la ventana de registros especiales" <vance paso a paso su programa *asta que llegue al programa principal" O!se%v$(i*nes ,l Dltimo registro que *a# en la ventana de registros especiales T0pre es un registro que no es accesi&le realmente' se trata del contador de nuestro pre divisor" .i los puede ver es porque MPLAB es quien cuenta las redivisiones necesarias para la simulacin" ,ste registro no aparece m%s en las versiones de MPLAB superiores a 5"+ para los PIC16F 2s( para los 1;:5" Puede que vuelva a aparecer en versiones superiores" ,s por esto por lo que se lo e+plico" ada vez que T0pre llega al valor de la pre divisin' tmrB se incrementa en 1" 1o es *asta que no des&orde que tendremos una interrupcin" ,n el programa principal' se incrementa en 2 unidades cada vez que presionamos <F7>" ,sto es nor$ mal puesto que el programa principal comporta un goto # esto ocupa 2 ciclos de instruccin"

14B

13.6 Modificacin de los registros en el simulador


omo no nos queremos pasar *oras simulando este programa' vamos a modi4icar los registros durante la si$ mulacin" ,sto es mu# 4%cil de realizar en MPLAB6' puesto que &astar% con *acer do&le clic so&re el valor a modi4icar en la ventana Special Function " Vamos a servirnos de esta posi&ilidad" Primero' suprimimos el pre divisor" Para *acerlo escri&iremos B10001000' es decir' 0x88" >acemos do&le clic en la casilla hex de la l(nea OPTION_REG " <*ora cada presin de <F7> incrementar% tmrB 2no el pre divisor5" <&ra a continuacin la visualizacin de las varia&les con view >watch" oloque la varia&le cmpt como se e+plic en cap(tulos precedentes" ontinDe presionando <F7> # constate que el des&ordamiento de tmrB provoca una interrupcin # que esta provoca el decremento de cmpt" Para no perder muc*o tiempo modi4i$ que en la ventana fentre modify el valor de cmpt # pngalo a 1" .iga con la simulacin" onstatar% que la pr+ima interrupcin provoca la modi4icacin del estado de 6<2"

13.7 Colocacin sobre la placa de pruebas


argue en el PIC el 4ic*ero "*e+ o&tenido # alimente la placa" uente los encendidos del 8,? que o&tene$ mos en 1 minuto" ?e&er% o&tener entre 65 # 66 pulsos por minuto" ,sto le muestra la precisin que *emos o&tenido" ,n realidad tendr% un encendido cada (256*256*7*2) = 917504 s . ,n un minuto' de&er% o&tenerK 60.000.000 / 917504 = 65,3 encendidos" 8a teor(a re4renda la pr%ctica" ,l 4ic*ero es suministrado con el nom&re de led_tmr1.asm "

13.8 Primera mejora de la precisin


Vamos a intentar mejorar la precisin de nuestro programa" Podemos comenzar modi4icando nuestro pre di$ visor" Pro&emos con valores sucesivos" Por 1 K da 5BB"BBB R 256 L 1Q53'125 pasadas" 1o es pr%ctico" Por 2 K da 5BB"BBB R 512 L Q76'5625 pasadas" 1o es pr%ctico" Por 4 K da 5BB"BBB R 1B24 L 4;;'2;125 pasadas" 1o es pr%ctico" Por ; K da 5BB"BBB R 2B4; L 244'14B625 pasadas" ,n este caso solo necesitamos un contador puesto que el nDmero de pasadas es in4erior a 256"

E u%l ser% la precisin o&tenidaF .i inicializamos cmpt a 244 con una pre divisin de ;' la duracin que o&ten$ dremos ser% de 256*8*244 = 499712 s es decir de 999424s por encendido" ,n un minuto tendremos 60000000/999424 = 60,034 encendidos" 9enemos una precisin netamente mejorada" Hsted #a puede mejo$ rar el programa segDn estas indicaciones" Ver% que de&e modi4icar el valor de 7 a 244 en dos sitios di4erentes" ,sto no es pr%ctico" <)adamos una asig$ nacinK
TIMEBASE EQU D244 ; base de tiempos = 244 decimal

141

.i tiene algDn pro&lema' el 4ic*ero 4uncional de este ejercicio est% disponi&le &ajo la denominacin Led_tmr.asm " Ventaja o&tenidaK Hna precisin m%s grande" InconvenienteK m%s interrupciones generadas' m%s tiempo perdido por el programa principal" ,n nuestro caso esto no es importante dado que el programa no *ace nada m%s" 1o siempre ser% as("

13.9 Segunda mejora de la precisin


Podemos mejorar aDn m%s la precisin de nuestro programa" ,n e4ecto' podemos no utilizar el pre divisor # utilizar m%s contadores para contar 1Q53'125 pasadas" <l 4inal de la pasada 1Q53 podremos a)adir un Dltimo temporizador a)adiendo un valor a tmrB" Por ejemploK ?etectamos 1Q53 pasadas con la a#uda de varios contadores" <l 4inal de la pasada 1Q53 estaremos a 1953*256 = 499968 s por lo que nos 4altaran 500.000 - 499.968 = 32 s" ?e&eremos a)adir 256-32 = 224 al tmrB pero teniendo en cuenta los 2 ciclos perdidos despu-s de cada mo$ di4icacin de 9=6B a)adiremos 256-30K

movlw 226 ; desborde en 30 + 2 ciclos addwf tmr0


9eniendo en cuenta que 32s es un tiempo mu# corto para realizar todo de&eremos optimizar al m%+imo nuestra rutina de interrupcin" .upresin de los test # su&programas' etc" ,sto es generalmente posi&le" 1o trataremos este procedimiento aqu( dado que no presenta ma#or inter-s en tanto que las interrupciones van a ocupar la ma#or(a del tiempo de la PH"

13.10 El mtodo llamado de atrape


,+iste un m-todo mu# astuto que garantiza que dado un tiempo usted tendr% el nDmero correcto de inte$ rrupciones # por lo tanto el encendido del 8,? en nuestro caso" Por el contrario' este m-todo no garantiza un tiempo constante entre dos interrupciones sucesivas" ,l truco consiste en dividir el tiempo deseado entre un numero entero de interrupciones" < continuacin te$ nemos en cuenta la parte 4raccionaria que se *a perdido" .i tomamos nuestro ejemplo en 13";' tendremos que nos *ar%n 4alta 244'] interrupciones para tener medio segundo" 9omamos 244 interrupciones" Vistos los par%metros utilizados' tendremos una interrupcin cada 256 * 8 = 2048 s" ,n realidad' para o&tener 5BB ms despu-s de 244 interrupciones' nos *ar% 4alta un tiempo de 500.000 / 244 = 2049,180327868852459016393442623 s" 1os 4alta 1,1803 s en cada interrupcin pa$ ra tener la duracin correcta" ,n vez de ir recti4icando el tiempo' vamos a ir memorizando el tiempo que perdemos e ir acumul%ndolo en varias varia&les" ontra m%s precisin queramos m%s ci4ras signi4icativas necesitaremos memorizar" 8imit-$ monos a los 4 primeros decimales" 1o vamos' evidentemente a tra&ajar con decimales' por lo que converti$ remos todo a diezmil-simas de s"

142

?espu-s de una pasada' vamos a a)adir el tiempo perdido' es decir 11;B3 en nuestro contador de tiempo perdido" Hna vez que este contador alcance o so&repase la duracin de una interrupcin' es decir 2B4;BBBB 2*ace 4alta una varia&le so&re varios octetos evidentemente5' ser% su4iciente conK 1" 9ener en cuenta un interrupcin suplementaria 2245 en lugar de 2445" 2" 6estar este tiempo atrapado 2B4;BBBB de nuestro contador de tiempo perdido" <s( tendremos un tiempo medio 2en nuestro caso5 de 2049,1803 s # por lo tanto una temporizacin media de 2049,1803 * 244 = 499999,9932 s" J&tendremos un nDmero medio de parpadeos de 60,0000008 en$ cendidos por minuto" J&serve el e+traordinario aumento de la precisin" ,l Dnico inconveniente es que entre dos conmutaciones sucesivas de nuestro 8,? podemos tener una di4erencia 2048 s de tiempo de' es decir 2 ms' lo que es a&so$ lutamente impercepti&le" Podemos tam&i-n disminuir el nDmero de c%lculos de la siguiente 4ormaK nos *acen 4alta 244,140625 inte$ rrupciones apara tener un retraso de 5BB ms" < cada inversin del 8,? 2cada 244 interrupciones5 *a&remos perdido B'14B625 de interrupcin" 1os *ar% 4alta conta&ilizar 14B625 2millon-simas5 cada 244 interrupciones' # a)adir una interrupcin' 245 en lugar de 244' cada vez que alcancemos el valor 1BBBBBB 2una interrupcin entera5" ,l m-todo es el mismo' solo cam&ia la 4orma de tener en cuenta el tiempo perdido" >e aqu( un m-todo mu# potente para o&tener tiempos medios mu# precisos" ,ncontrar% una aplicacin real de reloj &asado en este principio so&re mi pagina 3e&' pagina trucs et astuces ' a trav-s de la e+celente aplicacin de reloj en tiempo real dO,rio' que e+plica per4ectamente este m-todo # que aprovec*o para agra$ decer"

13.11 El mtodo hardware Adaptacin del reloj


.upongamos que deseamos construir un cronometro" 8a precisin es el dato m%s importante en este caso" 1os vamos a arreglar de tal 4orma que la desmultiplicacin caiga so&re mDltiplos enteros E moF .implemen$ te cam&iando el tiempo de instruccin' es decir' la 4recuencia del cuarzo del PIC" E2e.#&* omo no podemos acelerar un PIC por encima de su velocidad m%+ima 2utilizamos un PIC 4 =>z5' solo podemos enlentecerlo" Partimos de una &ase de tiempos demasiado r%pida" 9omemos nuestro caso de partidaK pre divisor a 256' contador de pasadas a 7" ?uracin con un cuarzo de 4 =>z K 256*256*7 por temporizacin' 256*256*7*2 por encendido' es decir 917504 s" 1osotros deseamos 1000000 s" Procedamos a calcular a la inversa" E u%nto de&e durar una instruccinF 1000000/(256*256*7*2) = 1,089913504 s" ,sto nos da una 4recuencia de 1/1,089913504s = 0,917504 MHz omo la 4recuencia de los ciclos internos es igual a la 4recuencia del cuarzo dividida por 4' necesitaremos un cuarzo de 0,917504 * 4 = 3,670016 MHz ,l Dnico pro&lema es sa&er si e+iste en el mercado cuarzos de esta 4recuencia a nuestra disposicin" ,n saco contrario' realizaremos los c%lculos con otros valores de pre divisor # contador" ,st- seguro que aca&ar% encontrando un cuarzo que responda a la necesidad por el mero *ec*o de que multitud de relojes de cuarzo est%n &asados en micro controlador # *an tenido el mismo pro&lema" .i en$ cuentra un cuarzo de la 4recuencia apropiada' o&tendr% un reloj con la precisin del cuarzo"

143

13.12 El mtodo de lujo el doble reloj


,l m-todo precedente presenta el pro&lema de *acer m%s lento el PIC" EGu- podemos *acer si queremos una velocidad m%+ima # una precisin m%+imaF 1ingDn pro&lema" <limente el PIC con su cuarzo # cree otro oscilador e+terno con su cuarzo especial de timing" <plicamos la se)al o&tenida so&re RA4/TOKI # con4iguraremos el timerB en modo contador" ,l tra&ajar% a la velocidad m%+ima # las interrupciones timerB estar%n generadas por una &ase de tiempos m%s adaptada a la medida de nuestros eventos"

13.13 Ejemplo de utilizacin de 2 interrupciones


,n este peque)o ejemplo vamos a utilizar 2 4uentes de interrupcin con el 4in de mostrar un ejemplo concre$ to de este tipo de utilizacin" Vamos a recrear nuestro programa de tele ruptor pero reemplazando la tempo$ rizacin por una interrupcin tmrB"

6ecuerde que nuestro programa principal no *ace nada" Podremos utilizar otras 4uncionalidades so&re esta placa sin pertur&ar el 4uncionamiento del tele ruptor" 9endremos una interrupcin para 6PB # otra para tmrB" <rri&a tiene el 4lujo grama que vamos a utilizar" ,4ectDe una copia de m16f84.asm # renm&relo como telerupt.asm " ree un nuevo pro#ecto telerupt.pjt # ed(telo con #a *icimos anteriormenteK corte del 3atc*dog' posicionado del 8,? como salida' puesta en servicio de las interrupciones RB0/INT" 144

ree su rutina de interrupcin timerB cada 26B ms' pre divisor a 256 # 4 pasadas" Prue&e a realizar el programa por s( mismo" %rguelo en el PIC # l%ncelo" J&serve que el 4lujo grama no contiene el contador de pasadas en tmrB" 8e dejo el tra&ajo de re4le+ionar so&re ello" Hna pulsacin so&re el pulsador enciende el 8,?' otra lo apaga" .i no lo *ace as(' &usque el error o s(rvase del simulador" No le *e suministrado el 4ic*ero 4uncional con los otros 4ic*eros del curso para el caso en que usted se quede &loqueado" O!se%v$(in ,s mu# importante comprender &ien que *a# que &orrar tmrB antes de &orrar el 4lag 9BI: # volver a lanzar las interrupciones tmrB" .i *ace lo contrario' se arriesga a que tmrB des&orde entre el momento del &orrado del 4lag # el momento del &orrado de tmrB" ,n este caso el 4lag volver% a ser posicionado inmediatamente despu-s de ser &orrado # su programa podr% 4allar intermitentemente" >ace 4alta no olvidarse que toda modi4icacin de 9=6B entra)a el no contaje de los 2 pr+imos incrementos previstos"

13.13 Conclusin
<*ora #a sa&e e+plotar el timerB" 8os m-todos e+plicados aqu( son una &ase de tra&ajo para cosas m%s serias" 8e aconsejo realizar todas las manipulaciones que *emos ido descri&iendo" Incluso los errores le ser%n de mu$ c*o provec*o"

145

14. El acceso a la memoria eeprom


,n este cap(tulo le vo# a *a&lar de los procedimientos para acceder a la eeprom interna del PIC" onviene no con4undirse con la escritura en una memoria eeprom e+terna del tipo 2416" Para ese tipo de eeprom &asta con seguir las directivas del datas*eet del componente" >a&laremos de ello m%s adelante en este curso en la 2C parte" .e trata de una memoria un tanto particularK no 4orma parte de la memoria de programa dado que no puede ejecutar instrucciones # sus direcciones de acceso no se parecen del todo a las de acceso a la 6<=" ontiene elementos no vol%tiles pudiendo ser programada al mismo tiempo que programamos el PI # estando accesi$ &le al programa en ejecucin"

14.1 Tamao y localizacin de la memoria eeprom


8a direccin 4(sica de la memoria eeprom comienza' para los PIC de rango medio' en la direccin 0x2100" ,sta direccin se sitDa 4uera del espacio de direccionamiento de la memoria de programa de los PIC16F 2recuerde' ; U pala&ras' direccin m%+ima B+1:::5' # 4uera del espacio de direccionamiento de la 6<= 24 &an$ cos de 256 elementos5" Podemos desde este momento deducir que nos *ar% 4alta utilizar procedimientos es$ peciales para acceder a la eeprom" J&serve que aunque estos emplazamientos no son accesi&les directamente por el programa' por el contrario s( lo son en el momento de la programacin" Podremos inicializar la eeprom en el momento de la programa$ cin del componente" ,stos es igualmente verdad para los registros especiales del PIC" Por ejemplo' la direccin B+2BB7 contiene los par%metros que escri&ir% en _CONFIG" Podr%' pues' reemplazar la directiva por una inicializacin dire$ cta de la direccin B+2BB7" ?e todas 4ormas se lo desaconsejo por un tema de porta&ilidad # evolucin r%pida de una 4amilia a otra de PIC" ,s m%s' Epor qu- *acerlo complicado si podemos *acerlo simpleF <s( mismo' la direccin 0x2006 contiene la identi4icacin del componente" ,s as( como un programador evo$ lucionado puede *acer la distincin entre un 16:;4 # un 16:;4<' puesto que la in4ormacin del constructor di4iere de uno a otro" ,l 16:;4 dispone de 64 emplazamientos de memoria eeprom disponi&les para su uso li&remente" Vamos a ver cmo utilizarlos"

14.2 Preparacin del programa


omencemos por *acer un copiarRpegar del 4ic*ero Led_tmr1.asm # renom&r-moslos como eep_test.asm " onstru#a su nuevo pro#ecto en MPLAB con el mismo nom&re # a)ada all( el programa desnudo" ,dite el enca&ezamiento del programa"

146

;************************************************************************ ; * ; Parpadeo LED a una frecuencia determinada por un emplazamiento eeprom * ; * ;************************************************************************ ; * ; NOMBRE: LED PARPADEANTE CON TIMER0 y utilizacin de la eeprom * ; Fecha: 18/02/2001 * ; Version: 1.0 * ; Circuito: Tarjeta de experimentos * ; Autor: Bigonoff * ; * ;************************************************************************ ; * ; Fichero requerido: P16F84.inc * ; * ;************************************************************************ ; * ; Notas: Demostracion de la utilizacin de datos en eeprom * ; La base de tiempos de parpadeo contenida en eeprom * ; * ;************************************************************************

<)adimos una varia&le en la zona de varia&les" ontendr% el valor a cargar en el contador"


reload : 1 ; valor a recargar en el contador

,n nuestro programa inicial' cada vez que el contador de pasadas en el timer llega&a a B' lo recarg%&amos con el valor B+B7" <*ora lo recargaremos con el valor contenido en la varia&le reload " ,l procedimiento es el siguienteK Inicializamos un emplazamiento eeprom eereload con el valor B+B7 en el momento de la progra$ macin del dispositivo" ,n el arranque' leemos eereload # ponemos su contenido en la varia&le reload " ,l contenido de reload se utilizar% para recargar cmpt una vez que llegue a B"

8a ventaja del procedimiento es que si modi4icamos la &ase de tiempos en la eeprom' esta modi4icacin no se perder% en el momento que dejemos de alimentar la eeprom" 8e do# el 4lujo grama que vamos a implementar en primera instancia"

147

Podr(a decirme que parece un poco inDtil leer la eeprom # copiar su contenido en reload" EPor qu- no utilizar directamente el valor de la eeprom en el resto del programaF 8a respuesta es simple" ,l procedimiento de lec$ tura de la eeprom es muc*o m%s complejo que una simple lectura de la 6<=" ,s necesario limitar los accesos a la eeprom al m%+imo" omencemos por modi4icar nuestra rutina de interrupcin" 8a Dnica l(nea a modi4icar es aquella que carga&a de o4icio el valor 7 en W" <*ora cargaremos el contenido de reload" 9endremosK
inttimer decfsz cmpt , f ; decrement el contador de pasadas return ; NO 0, no hace nada BANK0 ; por precaucion movlw b'00000100' ; selccion del bit a invertir xorwf PORTA , f ; invertir LED movf reload , w ; carga el valor contenido en reload movwf cmpt ; en el contador de pasadas return ; fin de la interrupcin timer

14.3 Inicializacin de la zona eeprom


Vemos en el 4lujo grama que leemos nuestra eeprom con la 4inalidad de colocar el contenido en nuestra va$ ria&le" Pero tam&i-n necesitamos inicializar esta eeprom en el momento de la programacin del PIC" ?e&e considerar que no servir(a de nada inicializar la eeprom a cada arranque del PIC' si no' Equ- inter-s tendr(a utilizar una zona de memoria que resiste cuando nos est% alimentadaF Inicializaremos esta zona directamente en el momento de la programacin del dispositivo" ,sto se e4ectDa con la a#uda de la directiva DE 2Data Eeprom5 puesta en la zona de datos eeprom' es decir en 0x2100" reemos una zona eeprom a continuacin de la zona de varia&les"
;********************************************************************* ; DECLARACIONES DE LA ZONA EEPROM * ;********************************************************************* org 0x2100 ; direccin comienzo zona eeprom DE 0x07 ; valor de recarga del contador

8ance el ensam&lado del programa" EGuerr%' sin duda' veri4icar que la eeprom contiene el valor B+B7F 1ada m%s simple' lance EEPROM memory en el menD Windows # veri4ique el valor" Hsted me dir% que el valor est% en la direccin B+BB en vez de en la direccin B+21BB" ,n e4ecto' *a# que distinguir 2 direcciones" 8a direccin 4(sica de este emplazamiento vista por el programa$ dor' que es B+21BB" ,sta direccin es Dnicamente accesi&le en modo programacin" Por el contrario' el programa acceder% a estos emplazamientos a partir de un procedimiento especial # con una direccin relativa" 8a direccin vista por el programa comienza por la direccin B+BB" 1o *a# ninguna po$ si&ilidad de equivocarse con una direccin de la 6<= ni con una direccin de instruccin dado que el acceso se *ace por procedimiento particular # no mediante un direccionamiento cl%sico"

14;

omo resumenK Para programar un emplazamiento ,eprom via dispositivo programador' utilizaremos las direcciones empezando por la B+21BB via un J6Y B+21BB" 1ingDn riesgo de con4usin con una direccin concer$ niente a la memoria de programa" Para acceder a un emplazamiento ,eprom via programa' utilizaremos direcciones comenzando por B+BB a trav-s de un procedimiento particular que vamos a descri&ir" 1ingDn riesgo de con4usin"

Pien entendido que tam&i-n podemos asignar un nom&re a estas direcciones como *acemos para las varia$ &les" Htilicemos' pues' el nom&re eereload para designar el valor de reload contenido en la eeprom en la di$ reccin B+BB" <)adamos simplemente un #define en la zona de inicializacin de la eeprom"
#DEFINE eereload 0x00 ; direccion eeprom de eereload

J &ien
eereload EQU 0x00

,n nuestro 4lujo grama' tenemos la necesidad de leer la eeprom" Hsamos 4 registros para acceder a la ee$ prom" Vamos a e+aminarlos"

14.4 El registro EEDATA


,s en este registro donde va a transitar el valor a escri&ir o leer de la eeprom" ,ste registro est% situado en la direccin B+B; del &anco B"

14.5 El registro EEADR


,n este registro' situado en la direccin B+BQ del &anco B' vamos a indicar en ; &its la direccin concernida por la operacin de lectura o escritura de la eeprom" Vemos que para esta 4amilia de PI ! no podemos so&re$ pasar 256 emplazamientos de eeprom" Para el 16:;4 la zona admisi&le va desde la B+BB a la B+3:' es decir' 64 posiciones"

14.6 El registro EECON1


,ste registro situado en la direccin B+;; del &anco 1' contiene 5 &its que indicaran el 4uncionamiento de los ciclos de lecturaRescritura de la eeprom" Veamos el contenido"

bits 7/6/5
1o usados"

bit 4 : EEIF
Por EEprom write operation Interrupt Flag bit" ,ste 4lag' est% ligado con la interrupcin ,,$ P6J=" Pasa a 1 una vez que la operacin de escritura *a terminado" .i el &it ,,I, de I19 J1 est% a 1 se generar% una interrupcin"

bit 3 : WRERR WRite ERRor" ,s un &it de error" Pasa a1 si una operacin de escritura en eeprom *a sido inte$ rrumpida' por ejemplo' por un reset"

14Q

bit 2 : WREN WRite ENable" <utorizacion de arranque del ciclo de escritura" ,s una especie de cerrojo de se$ guridad" bit 1 : WR WRite" <rranque del ciclo de escritura" .e pone a B autom%ticamente cuando la escritura *a ter$ minado" bit 0 : RD ReaD" <rranque de un ciclo de lectura" .e queda en 1 durante un ciclo' despu-s es puesto a B au$ tom%ticamente"
O!se%v$(inK en el caso de que el ciclo de escritura sea interrumpido por un des&orde del 3atc*dog o por un reset' usted puede leer el &it W6,66 que lo se)alar%" 8os registros # permane$ cen sin cam&ios # usted puede relanzar el ciclo de escritura" ,sto no 4unciona para un corte de co$ rriente" Para este caso le e+plicar- mi m-todo personal al 4inal de este cap(tulo"

14.7 El registro EECON2


1os volvemos a ver con un registro /4antasma0 puesto que este registro no e+iste 4(sicamente o' al menos' no es realmente accesi&le" .e trata de una direccin B+;Q del &ando 1 que sirve para enviarle comandos al PIC concernientes a los procedimientos para la eeprom" .olo lo podemos utilizar sirvi-ndonos de las instrucciones que vamos a ver a continuacin"

14.8 Acceso en lectura de la memoria eeprom


Para leer un dato en eeprom es su4iciente con poner la direccin a leer en el registro EEADR" < continuacin posicione el &it RD a 1" Inmediatamente podr% recuperar el valor le(do en el registro EEDATA" ,s necesario no olvidarse de los correspondientes cam&ios de &anco" omo este procedimiento es corto # siempre es el mismo' vamos a crear una macro para ello" omo la macro de&e contener la direccin de lectura' vamos a crear una macro con paso de par%metros" 1otaK el t-rmino /paso de par%metros0 es un poco a&usivo puesto que en realidad no pasamos nada a la ma$ cro" ,s m%s &ien el ensam&lador el que reemplaza' en el momento del ensam&laje' todos los t-rminos /par%$ metros0 por el valor especi4icado so&re la l(nea de ejecucin de la macro" Hna vez m%s' se trata de un editor de te+to' todo es conocido en el momento de ensam&lar 2al contrario que en una su&rutina5 pero as( nos *acemos la ilusin de que disponemos de una rutina capaz de todo a la que le podemos pasar par%metros" ,sta es la macro a a)adir" ?e&emos estar en el &anco B para llamar a esta macro # nos retorna el valor le(do en el registro W"

READEE macro adeeprom ; macro con 1 parametro (argumento) movlw adeeprom ; carga la direccion eeprom (argumento recibido) movwf EEADR ; direccion a leer en el registro EEADR bsf STATUS , RP0 ; pasa a banco 1 bsf EECON1 , RD ; lanzar la lectura EEPROM bcf STATUS , RP0 ; pasa a banco 0 movf EEDATA , w ; carga el valor leido en W endm ; fin de la macro

15B

J&serve que especi4icamos un argumento para la macro" ?e&emos designar estos argumentos despu-s de la directiva macro" >emos utilizado aqu( el argumento adeeprom para indicar la direccin de la eeprom" ada utilizacin de adeeprom en nuestra macro ser% simplemente reemplazado por el argumento /reci&ido0 en el momento de la llamada de la macro" Para utilizar esta macro de&eremos' pues' especi4icar el argumento" ,jemploK
READEE eereload ; lectura de la direccion eereload de la eeprom

J&serve que en el momento del ensam&lado' MPASM toma conocimiento del valor de eereload # reem$ plaza este valor directamente en el cuerpo de la rutina" ,n la memoria del programa' despu-s del ensam&la$ do' no ver% ninguna traza de un eventual par%metro" ,sta macro e4ectuar% entoncesK lectura de la eeprom en la direccin eereload' es decir' en la direccin B+BB" ,sta macro' as( como todas las modi4icaciones principales' ser%n a)adidas al 4ic*ero m16f84.asm" No se lo *e suministrado &ajo la denominacin m16f84_n2.asm " < partir de la siguiente leccin' reemplazar% a su 4ic*ero m16F84.asm actual" Volvamos a nuestro 4lujo grama" ?e&emos a)adir la lectura de la eeprom en la inicializacin # colocar este va$ lor le(do en reload # en cmpt" >e aqu( la rutina modi4icadaK
; inicializacion de variables ; ---------------------------READEE eereload ; leer posicion eeprom 0x00 movwf reload ; colocar en reload movwf cmpt ; inicializar contador de pasadas goto start ; saltar al programa principal

,nsam&le el programa # c%rguelo en el PIC" ,l 8,? de&er% parpadear a una 4recuencia de 1 >z" .i no 4uncio$ na' veri4ique el programa o comp%relo con el 4ic*ero eep_test1.asm suministrado con esta leccin"

14.9 El acceso en escritura a la zona eeprom


<*ora me dir% con razn que no sirve de nada leer la eeprom si no somos capaces de escri&ir en ella" 1uestro programa no presenta ninguna ventaja so&re el que ten(amos anteriormente" 8a o&servacin est% plenamen$ te justi4icada" <s( que vamos a ver el modo de escri&ir en la eeprom" omo no dudar%' este m-todo utiliza los mismos registros" ,l procedimiento a seguir consiste en colocar primero el valor en el registro EEDATA # la direccin en el re$ gistro EEADR" < continuacin se de&e enviar una secuencia especi4ica al PIC de la que no tenemos nada que comprender' viene impuesta por el constructor" O!se%v$(i*nes

Microchip recomienda que este procedimiento especi4ico no sea interrumpido por una interrup$ cin por lo que cancelaremos las interrupciones durante esta 4ase" <l 4inal del procedimiento de escritura' el dato aDn no est% escrito en la eeprom" 8o estar% apro+ima$ damente 1B ms m%s tarde 2lo que representa unos 1B"BBB ciclos de instruccin5" Por lo tanto no podr% volver a escri&ir un nuevo valor en la eeprom o leer este valor antes de *a&er veri4icado el 4in del ci$ clo de escritura precedente" ,l 4in de la escritura puede ser monitorizado por la generacin de una interrupcin 2&it ,,I, posicio$ nado5 o por la lectura del 4lag ,,I: 2si lo *a&(a posicionado a B antes de la escritura5 o por la consulta del &it W6 que estar% a 1 durante todo el ciclo de escritura"
151

Vamos a escri&ir una macro de escritura en la eeprom" ,sta vez de&eremos pasar 2 par%metros' a sa&er' el va$ lor a escri&ir 2que supondremos colocado en W5 # la direccin de la eeprom donde de&e ser escrito"

WRITEE macro addwrite ; el dato se encuentra en W


LOCAL loop ; etiqueta local movwf EEDATA ; colocar (w) en el registro movlw addwrite ; cargar la direccion de escritura vwf EEADR ; colocar en el registro moloop bcf INTCON , GIE ; impeder interrupciones btfsc INTCON , GIE ; test si GIE esta a 0 (inutil) goto loop ; NO, volver a empezar (inutil) bsf STATUS , RP0 ; pasa a banco 1 bcf EECON1 , EEIF ; borra flag de fin de escritura bsf EECON1 , WREN ; autorizar acceso escritura movlw 0x55 ; cargar 0x55 movwf EECON2 ; enviar comando movlw 0xAA ; cargar 0xAA movwf EECON2 ; enviar comando bsf EECON1 , WR ; lanzar ciclo de escritura bcf EECON1 , WREN ; colocar cerrojo proxima escritura bsf INTCON , GIE ; autorizar interrupciones bcf STATUS , RP0 ; pasar a banco 0 endm

O!se%v$(i*nes >e utilizado 3 instrucciones para poner YI, aB" ,sto era necesario a causa de un error en el 16 ;4 que e+plicar- m%s adelante' pero #a 4ue corregido en el 16:;4 2# siguientes modelos5" ,l test de veri4ica$ cin #a no es necesario" Pero esto me da la oportunidad de e+plicar el tema de etiquetas locales" ?ej-moslo pues como ejemplo # en el 4uturo usaremos solo una l(neaK bcf INTCON,GIE" 8a directiva 8J <8 precisa que el s(m&olo utilizado en esta macro no e+istir% m%s que en su interior" .in esta directiva' si solo usase una llamada a la macro en todo su programa' no *a&r(a ningDn pro$ &lema" .i usase la macro 2 veces o m%s' para cada llamada MPASM reemplazar(a W6I9,, por toda la lista de instrucciones contenidas *asta la directiva endm que contiene la etiqueta /loop0" J&tendr(a un programa real con la etiqueta /loop0 repetida en emplazamientos di4erentes" ,sto generar(a un error" 8a directiva 8J <8 in4orma a MPASM que cada llamada a la macro tra&aja con una etiqueta /loop0 di4erente por lo que no *a&r% empleo mDltiple" 8a secuencia est% impuesta por Microchip para la escritura de eeprom" 1o *a# nada que compren$ der a nivel de esas 4 l(neas' simplemente disparan secuencias *ard3are internas 2especie de instruc$ ciones5" ,l procedimiento de escritura en eeprom es relativamente largo pero adem%s requiere muc*o tiem$ po" Piense que para rellenar la zona completamente 264 octetos5 necesitar% B'6 s" ,ste tiempo var(a de un modelo a otro" Veri4(quelo en el datas*eet correspondiente" ,l nDmero de ciclos de escritura de la eeprom est% limitado" 8a vida de la eeprom es del entorno de 1B millones de ciclos" .i su programa comporta un error tal que escri&e la eeprom sin pararse' el PIC estar% 4uera de servicio en 2; *oras" Vigile su programa" 1uevamente' el nDmero de ciclos 2ga$ rantizado # t(pico5 de escritura var(a de un modelo a otro" omprue&e los datas*eets" <ntes de escri&ir en la eeprom de&e veri4icar que no *a# otro ciclo de escritura en curso" Htilice el &it W6 del registro ,, J11" .i vale B no *a# ningDn ciclo de escritura en curso" J&serve que *a# dos 4ormas de proceder para veri4icar esta condicinK o ,sperar a la 4inalizacin del ciclo de escritura en cursoK &loqueamos el programa *asta que el ciclo aca&e" o .alir inmediatamente de la rutina veri4icando siempre' antes de arrancarla' que no e+iste un ciclo de escritura en curso" ,lija el m-todo en 4uncin de la aplicacin pero' en todo caso' e4ectDe esta veri4icacin" Puede incluir la veri4i$ cacin directamente en la macro" 152

14.10 Utilizacin prctica de la memoria eeprom


<*ora vamos a modi4icar de nuevo nuestro programa para escri&ir en la eeprom" Vamos a incrementar la du$ racin del parpadeo del 8,? cada 16 parpadeos 2es decir' cada 32 pasadas por la rutina de interrupcin5 # salvaguardaremos este valor en la eeprom" 1o necesitaremos interrupciones eeprom para esto pero de&emos comprender el principio de las interrup$ ciones su4icientemente &ien para poder servirnos de ellas en caso de necesidad" Vamos a proceder a la modi4icacin de nuestra rutina de interrupcin" ?e&emos a)adir un segundo contador 2cmpt25 en la zona de 6<= por lo que declararemos esta varia&le"
cmpt2 : 1 ; contador de pasadas 2

.i' #a s- que *a# 4ormas de optimizarlo para no tener necesidad m%s que de un solo contador" 1o es el o&je$ tivo de este ejercicio" Guiero ser claro # centrado en el o&jetivo de este cap(tulo" 8a modi4icacin es mu# sim$ ple en realidad" ,l la rutina de interrupcin timer incrementaremos el contador numero 2 el cual utilizaremos en el programa principal"

Unas palabras sobre el bug del bloqueo de interrupciones en el 16C84


,n el 16 ;4' el 4in de la autorizacin de interrupciones no se toma en cuenta *asta el 4inal de la instruccin si$ guiente" ,ntre bcf INTCON, GIE # la siguiente instruccin puede llegar una interrupcin" omo retfie repone el &it YI, a 1 de 4orma autom%tica' la interrupcin se pondr% en servicio a pesar del programador" .er% necesario' pues' despu-s de poner YI, a B' compro&ar que e4ectivamente YI, est% a B" ,n caso contrario' signi4icar% que una interrupcin a ocurrido en este momento # *ar% 4alta recomenzar la operacin" < partir del 16:;4' las interrupciones se pro*(&en desde la instruccin ejecutada # antes de la instruccin si$ guiente" ,l /&ug0 #a no e+iste" .e lo e+plico para el caso en que se encuentre delante de una de las mu# nu$ merosas aplicaciones para este viejo PI que 4ue re4erencia en su d(a' evolucionado despu-s al 16:;4 # poste$ riormente al 16:;4<" ,l nuevo 4lujo grama ser%K

153

;********************************************************************** ; INTERRUPCION TIMER 0 ;********************************************************************** inttimer ; test contado de pasadas ; -------------------------dcfsz cmpt , f return ; decrementa el contador de pasadas ; NO 0, no hacemos nada

; inviertir LED ;--------------------------BANK0 ; por precaucion movlw b'00000100' ; selecciona el bit a invertir xorwf PORTA , f ; invertir LED ; recarga el contador de pasadas ; -----------------------------movf reload , w movwf cmpt ; carga el valor contenido en reload ; en el contador de pasadas

; incrementar contador de pasadas 2 ; ---------------------------------incf cmpt2 , f return ; incrementar el contador de pasadas 2 ; fin de la interrupcion

Vamos a escri&ir en la eeprom desde nuestro programa principal" EPor qu- no desde la rutina de interrup$ cinF ,s necesario' en la medida de lo posi&le' salir cuanto antes de una rutina de interrupcin" ,st%n reservadas para tratamiento urgente de la in4ormacin # no de&en ser interrumpi&les por otras interrupciones" J&serve que si su programa no comporta nada m%s que una 4uente de interrupciones' pudiera ser que no tenga ninguna importancia alargar la duracin de la interrupcin que la maneja" ?e todas 4ormas' conviene ir aprendiendo &uenos *%&itos" J&serve que la macro corta # relanza las interrupciones" ,videntemente usted no puede relanzar las interrup$ ciones desde dentro de una interrupcin" .i decidiese utilizar la macro dentro de una interrupcin' de&er(a suprimir la instruccin de puesta en servicio 2# de corte5 de YI, a nivel de la macro" ?e la misma manera' nuestra macro' relanza de o4icio las interrupciones" ,s as( mismo evidente que' si utiliza la macro en un programa sin interrupciones' de&er% as( mismo suprimir la l(nea en cuestin" Por el contrario' en el caso m%s re&uscado' en el que las interrupciones est-n *a&ilitadas # cortadas de 4orma intermitente' de&er% a)adir en la macro un test para no volver a *a&ilitar las interrupciones salvo en el caso de que *u&ie$ sen estado de que estuviesen *a&ilitadas a la *ora de entrar en la macro" 8o m%s simple es salvar el estado de YI, en un &it de la 6<= 24lag5 # reponer YI, en servicio si este 4lag estuviese posicionado" Veamos el programa principal"

154

;*************************************************************** ; PROGRAMA PRINCIPAL ;*************************************************************** start ; test si 16 inversiones de LED ; ----------------------------btfsscmpt2 , 5 goto star clrf cmpt2 ; incrementar reload ; -----------------incf reload , f incf reload , f ; incrementa reload ; incrementar 2 veces es mas visible ; test si 32 pasadas ; NO, esperar ; SI, borrar contador 2

; Test si la escritura precedente de la eeprom acabada ; ---------------------------------------------------; esto es a voluntad dado que el tiempo usado ; es suficientemente largo ; pasar a banco 1 ; test si escritura en curso ; SI, esperar ; pasar a banco 0

BANK1 wait btfsc EECON1 , WR goto wait BANK0

; escribir contenido de reload en eeprom ; -------------------------------------movf reload , w WRITEE eereload goto start END ; ; ; ; cargar reload escribir en direccion 0x00 bucle directive de fin de programa

,nsam&le el programa # c%rguelo en el PIC" onstru#a el montaje en la placa de e+perimentacin" J&serve que el 8,? parpadea a una 4recuencia de 1 >z" uando se encienda la 17C vez' la 4recuencia de parpadeo dis$ minuir% ligeramente" <s( cada 16 pasadas" ,stime la 4recuencia actual de parpadeo # corte la alimentacin del PIC" ,spere unos segundos # vuelva a conectar la alimentacin" ,l 8,? parpadear% a la 4recuencia precedente' indicativo de que el par%metro 4ue guardado en la eeprom" ,l 4ic*ero' tal como de&er(a estar al 4inal de esta leccin se encuentra disponi&le &ajo la denominacin eep_test.asm"

14.11 Securizacin del acceso a la memoria eeprom.


1uestro programa precedente adolece de un de4ecto grave" <dmitamos que cortamos la alimentacin justo durante una operacin de escritura en la eeprom" ,n este caso' los adtos presentes en la eeprom pueden es$ tar corrompidos" 9enemos di4erentes maneras de prevenir este pro&lemaK Puede prever una reserva de alimentacin 2condensador5 para el PI # noti4icarle que la tensin prin$ cipal *a sido cortada" <s(' podemos *acer que el PI no comience ninguna operacin de escritura en eeprom" 8a reserva de alimentacin de&er(a ser lo su4icientemente grande para poder aca&ar una eventual operacin de escritura en curso" 155

Puede *acer que sea el propio PI el que gestione la alimentacin' so&re todo si se trata de una ali$ mentacin salvaguardada 2&ater(as' pilas' etc"5" ,n este caso' despu-s de pulsar un &otn 2por ejem$ plo5' el PI terminar% sus operaciones en curso' # despu-s se cortar% la alimentacin a s( mismo' pilo$ tando la alimentacin a trav-s de un pin 2tal como los P se gestionan a s( mismos5" 9am&i-n puede no preocuparse por nada en el apagado #' en el encendido' veri4icar que los datos de la eeprom son v%lidos" >ar% 4alta utilizar 2 juegos de valores para asegurarse siempre de tener uno v%lido"

Vamos a *a&lar del Dltimo m-todo propuesto' los otros m-todos son' &%sicamente' una cuestin de *ard3a$ re" Veamos un procedimiento que nos permite veri4icar los datosK 1" Ponga una ca&ecera en el primer o los primeros octetos de la eeprom" Por ejemplo pondremos B+55 en el octeto B+BB" 2" Para empezar la escritura de nuevos valores empezaremos &orrando el enca&ezamiento" 3" ?espu-s escri&iremos los valores" 4" Para aca&ar' reescri&iremos el enca&ezamiento" ?espu-s de un arranque del PIC' si el enca&ezamiento est% presente' signi4icar% que los valores de la ee$ prom son validos" ,n caso contrario' el ciclo de escritura 4ue interrumpido" ,n su mano reaccionar en conse$ cuencia' por ejemplo' reescri&ir en la eeprom los valores por de4ecto" Para aumentar la seguridad del sistema en caso de in4ormacin cr(tica' pude enca&ezar con m%s octetos" Para no tener que volver a los valores por de4ecto' puede utilizar 2 juegos de datos' cada uno comenzando por su propio enca&ezamientoK as(' si la escritura en un &loque se interrumpi' usted podr% utilizar los valores del otro &loque"

14.12 Conclusin
>e aqu( una nueva etapa superada en su conocimiento del 16:;4" <*ora puede utilizar la zona eeprom de su PIC para almacenar all( su datos remanentes" .i tiene un riesgo de escritura de mDltiples datos a intervalos regulares' no olvide veri4icar que la operacin de escritura precedente *a&(a aca&ado antes de arrancar una nueva operacin" 1o dude en e+perimentar' pero no olvide veri4icar su programa para evitar escrituras inDtiles # 4recuentes en su eeprom" ?e todas 4ormas' no entre en p%nico" .i su programa est% correctamente dise)ado # escrito' no creo que se acerque a gastar el milln de ciclos de escritura garantizados"

156

15. El watchdog
,l 3atc*dog o /perro de guardia0 es un mecanismo de proteccin de su programa" .irve para vigilar si la eje$ cucin de su programa se desarrolla en el tiempo que usted le *a asignado para *acerlo"

15.1 El principio de funcionamiento


8a puesta en servicio o no del mecanismo del 3atc*dog se decide en el momento mismo de la programacin 2quemado5 del PI con la a#uda de la directiva NCONFIB" .i <NODTNOFF= est% especi4icado' el 3atc*dog es$ tar% 4uera de servicio" .i por el contrario' es <NODTNON= lo que est% escrito' el 3atc*dog se activar%" 1o es posi&le ponerlo en servicio o quitarlo durante la ejecucin del programa" ,l 4uncionamiento del 3atc*dog est% ligado a un timer espec(4ico' que no est% sincronizado con el programa o con un evento e+terior' # que no depende de la 4recuencia del reloj" 8a duracin espec(4ica de des&ordamiento de este tiempo es de 1; ms" ,ste valor *a# que tomarlo con cierta precaucin puesto que var(a en 4uncin de diversos par%metros tales como el de la tensin de alimentacin o el de la temperatura" 9am&i-n puede variar de un modelo a otro de PI " onviene consultar los datas*eet" ,l des&ordamiento m(nimo es de 7 ms # es el que usted de&er% utilizar en la pr%ctica" ,n e4ecto' =I 6J >IP le garantiza que ningDn PI tendr% un des&ordamiento antes de esos 7 ms" 1os indica que el tiempo medio de reset es de 1; ms pero no lo garantiza" ,s simplemente un tiempo que *a sido cons$ tatado" .i usted resetea el 3atc*dog cada 1B ms' esto podr% 4uncionar en algunos PI # en ortos no' o &ien podr(a 4uncionar o no dependiendo de la temperatura" ada vez que una instruccin clr3dt es enviada al PI ' el timer del 3atc*dog se pone a B' as( como el conteni$ do del pre divisor" .i por cualquier causa' esta instruccin no es reci&ida en el tiempo previsto' se produce un reset # el PI re arranca desde la direccin B+BB # el &it 9J del registro .9<9H. es puesto a B" 8e#endo este &it en el arranque' usted sa&r% si el PI viene de ser alimentado por primera vez o &ien el reset se produjo por un &loqueo del programa # accin del 3atc*dog"

15.2 El pre divisor del watchdog


>emos visto en las lecciones precedentes' que el pre divisor puede a4ectar al tmrB o al 3atc*dog a trav-s del &it PSA del registro OPTION" .i decidimos poner el pre divisor para el 3atc*dog' &it PSA 6 1' la ta&la del da$ tas*eet nos dir% los valores del pre divisor segDn el estado de los &its PS4WPSJ" ,n realidad' para el 3atc*dog' se trata de pos divisor' pero esto solo tiene relevancia para la electrnica del PI " 1o es relevante para su utilizacin" ,ste pos divisor multiplica el tiempo de des&ordamiento del timer del 3atc*dog" Por ejemplo' con un divisor de 2 tendr% un tiempo m(nimo de 2I7 ms L 14 ms" .a&iendo que el reset se producir%' t(picamente despu-s de un tiempo de 2I1; ms L 36 ms" Para este ejemplo # con un cuarzo de 4 =*z' esto le o&ligar% a enviar un clr3dt al menos una vez cada 14"BBB ciclos de instruccin" ,n la ma#or parte de los casos' el reset se e4ectuar% despu-s de 1;I3 L 36 ms' es decir' 36"BBB ciclos de instruccin"

157

15.3 Los roles del watchdog


,l 3atc*dog est% destinado a veri4icar que su programa no se *a atascado en una zona no valida 2de&ido a una pertur&acin de la alimentacin' por ejemplo5' o se *a atascado en un &ucle sin 4in 2&ug de programa$ cin5" .irve tam&i-n para despertar un PI del modo sleep' como veremos m%s tarde" J&serve que *a&lamos del modulo 3atc*dog integrado en su PI " ?e todas 4ormas' todo micro controlador 2# por lo tanto los PI 5 pueden estar dotados de un 3atc*dog e+terno 2circuito que es reseteado a intervalos re$ gulares por medio de un pin5 que puede presentar algunas ventajas particulares' tal como poder tratar direc$ tamente con la electrnica e+terna 2corte de la alimentacin general' por ejemplo5" Vo# a listar a continuacin algunas nociones ligadas al 3atc*dog tanto interno como e+ternoK 1" ,l 3atc*dog es un mecanismo interno o e+terno destinado a asegurar la seguridad de una aplicacin in situ" .e activa si no es solicitado a intervalos regulares" .e asegura que le logicial em&arcado parece continuar 4uncionando segDn una secuencia prevista" 2" ,l 3atc*dog puede servir' segDn los casos' para re arrancar una aplicacin despu-s del comienzo' pa$ ra pararla' para ponerla en un estado securizado' para se)alar un de4ecto o para cualquier otra accin que quiera el dise)ador del programa" 3" ,l 3atc*dog integrado en el PI es tri&utario de su &uen 4uncionamiento electrnico" .u rol es provo$ car un reset del PI # es responsa&ilidad del dise)ador del programa el tomar las eventuales medidas necesarias si el reset es de&ido al 3atc*dog 2parada del programa' se)alizacin' re arranque normal o limitado' etc"5" >a# &its espec(4icos previstos para sa&er a qu- se *a de&ido el re arranque del pro$ grama" 4" ,l 3atc*dog puede ser e+terno' lo que *ar% que la carta electrnica sea m%s compleja' pero tendr% la ventaja de poder incluso tratar con pro&lemas del propio PI # sus comando' dejando de ser tri&uta$ rio de la electrnica del PI " Podr% as( cortar la alimentacin del sistema' posicionar motores' etc" <unque el micro controlador est- en aver(a" 5" ,l 3atc*dog integrado es una seguridad mu# e4icaz a la vista de su simplicidad # relativamente 4ia&le para salir de situaciones no previstas que pongan el estado del PI en una posicin indeterminada" ?e&er(a ser usado de o4icio en toda aplicacin aca&ada" 6" ,l 3atc*dog puede remediar situaciones anormales &ien sean provocadas por un &ug no detectado aDn en la 4ase de /de&&uging0 o por un desarrollo anormal del programa provocado por una causa e+$ terna 2pertur&aciones' pro&lemas de alimentacin5' por un &locaje no previsto de un peri4-rico 2&lo$ caje de transmisin5 o cualquier otra situacin anormal" 7" ,l 3atc*dog no es un m-todo in4ali&le # a&soluto que nos permite salir de cualquier pro&lema que pueda acontecer" Para las aplicaciones de riesgo cr(tico letal 2ascensores' maquinas *erramienta' etc"5 de&en preverse mecanismos redundantes de seguridad v(a *ard3are 2sin /inteligencia em&arcada05" ,l tama)o del cinturn de seguridad aumenta la seguridad pero no le garantiza que saldr% indemne de cualquier accidente # no pone en cuestin la utilidad de las am&ulancias" ;" ,l 3atc*dog no est% pensado para enmascarar los errores de dise)o de los programas" Hn programa correctamente conce&ido de&e ser capaz de correr sin pro&lemas sin activar el 3atc*dog' que no de$ &er% ser puesto en marc*a *asta el 4inal del /de&&uging0" Q" 1o se de&en poner instrucciones clr3dt en el interior de las rutinas de interrupcin so pena de en$ mascarar pro&lemas del programa principal" 1B" ,n los PI ' el 3atc*dog integrado nos permite salir del modo dormido del PI a e+pensas de una cier$ ta imprecisin" 11" 8os PI 16:' al contrario que otros PI ' est%n desprovistos de una instruccin reset" Hna 4orma simple de provocar un reset so4t3are es entrar en un &ucle sin 4in desprovisto de instruccin clr3dt' que provocar% un reset del PI por des&ordamiento del 3atc*dog"

15;

15.4 Utilizacin correcta del watchdog


8a primera cosa a realizar si quiere aprovec*arse de esta proteccin integrada' es la de parametrizar la con4i$ guracin de la puesta en servicio del 3atc*dog" 8a primera cosa a tener en cuenta es queK si indica _WDT_ON para un programa que no gestiona el watchdog, este re arrancar constantemente sin parar, y no funcionar, pues no contendr ninguna instrucci n clrwdt!" ,s un error &astante 4recuente para aquellos que no dominan los &its de con4iguracin del programador" 8os &its de con4iguracin indicados en el 4ic*ero son modi4ica&les por la ma#or(a de los logiciales de los progra$ madores usados' los cuales son capaces de 4orzar un valor de con4iguracin di4erente del previsto por el usua$ rio en el programa" 9am&i-n es 4recuente que los programadores olviden incluir la directiva d J1:IY en sus programas' lo cual impide la con4iguracin autom%tica de los 4lags de con4iguracin" ,s una mu# mala pr%ctica puesto que el usuario 4inal de&er% conocer o adivinar cu%l es el estado de los 4lags que de&er% utilizar en el momento de quemar el PI " < continuacin' de&er% colocar una o varias instrucciones clr3dt en su programa de tal 4orma que al menos una instruccin clr3dt sea reci&ida antes de que pase el tiempo de des&ordamiento" 6ecuerde no tener en cuenta el tiempo de 1; ms sino el m%s des4avora&le de 7 ms" 9omando este como tiempo m%s des4avora&le se asegura que el programa tra&ajar% en todas las condiciones"

15.5 Qu es lo que NO es necesario hacer?


<cu-rdese que una interrupcin interrumpe el programa # lo manda a la direccin B+B4" Hna vez aca&ada la interrupcin' el programa es devuelto a la zona donde se encontra&a incluso si esta se *allase 4uera de la zona de tra&ajo" ?e&ido a esto' si usted coloca una instruccin clr3dt en una rutina de interrupcin' esta instruccin puede ser ejecutada aunque su programa se *a#a detenido" ,sto es lo contrario de lo que andamos persiguiendo" Por lo tantoK "ams use una instrucci n clrwdt en una rutina de interrupci n!# Hsted puede decirmeK de acuerdo' pero Esi una rutina de interrupcin se demora demasiado tiempoF =i res$ puesta ser%K usted se olvid de un consejo que le di' las rutinas de interrupcin de&en durar lo menos posi&le"

15.6 Medida del tiempo real del watchdog


,l valor de 7 ms es el valor m(nimo" ,l valor de 1; ms es el valor generalmente constatado" Pero Ecu%l es el va$ lor real del 3atc*dog de nuestro PI F Vamos a intentar responder a esta pregunta" <tencin' esta medida ser% meramente indicativa' no se 4ie de ella en la pr%ctica' este valor puede variar con las condiciones de alimentacin' temperatura' etc" ?e todas 4ormas siempre es interesante sa&er si la teor(a casa con la pr%ctica" >aga un copiarRpegar del 4ic*ero <&e)N(&i/ $s.=" 6enom&re el 4ic*ero como <:)"/$s.= # cree un nuevo pro$ #ecto" Por el momento' no toque la con4iguracin" =odi4ique los valores del registro JP9IJ1"
OPTIONVAL EQU B'10001111' ; Valor del registro OPTION ; Resitencia pull-up OFF ; Preescaler Wdt = 128

15Q

.uprima la varia&le cmpt3 # modi4ique la rutina tempo para quitar el &ucle e+terior"

;********************************************************************* ; SUBRUTINA DE TEMPORIZACION * ;********************************************************************* ;--------------------------------------------------------------------; Esta subrutina introduce un retardo de 500.000 s. ; No recibe ni retorna ningn parametro ;--------------------------------------------------------------------tempo clrf cmpt2 ; borra compteur2 boucle2 clrf cmpt1 ; borra compteur1 boucle1 nop; pierde 1 cycle *256 *256 *2 decfsz cmpt1 , f ; decrementa compteur1 goto boucle1 ; si no 0, boucler decfsz cmpt2 , f ; si 0, decrementa compteur 2 goto boucle2 ; si cmpt2 no 0, volver a empezar bucle1 return ; retorno de la subrutina

<)adimos la l(nea
Clrwdt ; Borrar el watchdog

lusto despu-s de la etiqueta init para estar &ien seguros de poner el 3atc*dog a B 2realmente inDtil5" Para aca&ar' modi4icamos el programa principal para que se encienda el 8,? despu-s de 25B ms"

; ********************************************************** ; PROGRAMA PRINCIPAL ; **********************************************************

start call tempo bsf LED goto start loop goto loop end ; esperamos 250 ms ; encender LED ; bucle

,nsam&le el programa' c%rguelo en el PI # mntelo en la placa de e+perimentacin" EGu- pasaF ?espu-s de apro+imadamente m de segundo el 8,? se enciende' eso es todo" 1o ocurre nada m%s" ,s lo que *a&(amos previsto" =odi4iquemos a*ora la l(nea d J1:IY para poner en servicio el 3atc*dog"
_CONFIG _CP_OFF & WDT_ON & _PWRTE_ON & _HS_OSC

,nsam&le de 1uevo el programa # c%rguelo en el PI " <limente el montaje" 16B

EGu- pasa a*oraF ,l 8,? parpadea" J&servar% que el tiempo que separa dos encendidos 2o dos apagados5 es de apro+imadamente 2 segundos" E9#&i($(in .i *a seguido todo lo anterior posi&lemente #a lo *a#a comprendido" 1uestro 3atc*dog no *a sido puesto a B despu-s del arranque del PI " Por lo tanto' una vez el tiempo /duracin de &ase I pre divisor0 se provoca un des&ordamiento del 3atc*dog que provoca un reset del PI que apaga el led # comienza el programa de nue$ vo en un &ucle sin 4in" Para conocer la &ase de tiempo en nuestras condiciones actuales del PI 2temperatura' alimentacin' etc"5 de&eremos dividir el tiempo entre dos encendidos 2o apagados5 por el pre divisor' es decir 12;" Personalmente #o *e cronometrado 2'2 segundos" =i 3atc*dog tra&aja con un tiempo de &ase de 22BB ms R 12; L 17'2 ms" Gue est% en el entorno de los 1; ms t(picos #a anunciados" .i #o *u&iese utilizado el valor de 1; ms en mi programacin' el PI se *a&r(a plantado" Vuelvo a insistir en la utilizacin del peor valor' es decir 7 ms"

15.7 Simulacion del bloqueo de un programa


>aga un copiarRpegar del 4ic*ero <&e)N(&i/ $s.=" 6enom&re el 4ic*ero como <se('%/$s.= # cree un nuevo pro#ecto" am&ie la l(nea de con4iguracin"
OPTIONVAL EQU H0F ; Valor del registro OPTION ; Resitencia pull-up ON ; Preescaler 128

N el de4ine dado que *emos modi4icado la placa de e+perimentacin"


#DEFINE BOUTON PORTB,0 ; Pulsador

=odi4ique el programa principal"


; ********************************************************** ; PROGRAMA PRINCIPAL ; ********************************************************** start bsf LED call tempo bcf LED call tempo btfsc BOUTON goto start plante goto plante ; el programa no est pensado ; para que llegue aqu ; producir un bloqueo ; ; ; ; ; ; encender LED esperamos 0,5 s apagar LED (LEDOFF) esperamos 0,5 s test pulsador bucle

end

?e esta manera' una pulsacin enviar% al programa a una zona que *emos creado # que simula un &loqueo del programa &ajo la 4orma de un &ucle sin 4in"

161

Podr(a decirme que no se trata de un &loqueo' es nuestro pulsador quien env(a el programa a la direccin in$ correcta" Por supuesto' pero es mu# di4(cil &loquear un PI &ajo demanda" Pastar% con imaginar que el pulsa$ dor no e+iste # que se trata de una pertur&acin el-ctrica e+terior que env(a nuestro programa a una zona donde no de&er(a llegar nunca" ompile el programa' c%rguelo en el PI # alimente el montaje" ,l 8,? parpadea" =antenga pulsado el pulsador un instante' el 8,? deja de parpadear" ,l programa se encuentra en un &ucle sin 4in que simula una plantada de nuestro PI "

15.7.1 Correccin utilizando el watchdog


=odi4iquemos nuestro programa" 8o primero activemos el 3atc*dog por medio de la con4iguracin' como #a *emos visto" Vamos a arreglarnos a continuacin para poner el 3atc*dog a B a intervalos regulares" >e aqu( nuestro programa principal modi4icado"
; ********************************************************** ; PROGRAMA PRINCIPAL ; ********************************************************** start bsf LED clrwdt call tempo bcf LED clrwdt call tempo btfsc BOUTON goto start plante goto plante ; el programa no est pensado ; para que llegue aqu ; producir un bloqueo ; ; ; ; ; ; ; ; encender LED borrar watchdog esperamos 0,5 s apagar LED (LEDOFF) borrar watchdog esperamos 0,5 s test pulsador bucle

end

>a&(amos programado nuestro 3atc*dog con un pre divisor de 12;' lo que nos permite enviar un comando clr3dt cada 7I12; ms' es decir cada ;Q6 ms" omo nuestra llamada a tempo demora 5BB ms' de&eremos enviar un clr3dt al comienzo o al 4inal de la lla$ mada a tempo para no so&repasar los ;Q6 ms" 9am&i-n podr(amos *a&er enviado un solo clr3dt incluido en la rutina tempo" ompile el programa' c%rguelo en el PI # alimente el montaje" ,l 8,? parpadea" Pulse el pulsador un instante" ,l 8,? deja de parpadear por un momento' despu-s comienza a operar con normalidad otra vez" ,l 3atc*dog *a recuperado el plante de su programa

15.8 Eleccin del pre divisor del watchdog


,n general' *a# que intentar calcular el pre divisor de 4orma que no tengamos que utilizar muc*os clr3dt" Pero tam&i-n *a# que tener en cuenta el tiempo de reaccin o&tenido al aumentar el pre divisor" .i una recu$ peracin de &loqueo de 2 segundos es 4acti&le o necesitamos recuperar &loqueos de 1; ms va a condicionar el valor del pre divisor" 9odo es una cuestin de compromiso" 162

1o siempre tendr% opcin de elegir" .i su pre divisor #a est% ocupado por el tmrB' por ejemplo' no le quedar% m%s remedio que enviar un clr3dt cada 7 ms" ,s una mu# mala idea' en ese caso' decidir tra&ajar sin 3atc*$ dog" E onducir(a usted una moto sin cascoF ,n el caso citado' de&er(a insertar un clr3dt en la rutina de temporizacin cada 7 ms' puesto que dura m%s que esto" 6ecuerde no utilizar esto en una rutina de interrupcin' pues estas son contrarias al esp(ritu del 3atc*dog 2salvo en *onrosas e+cepciones5" .in em&argo puede utilizar clr3dt en cualquier otra rutina sin pro&lemas"

15.9 Tiempos tpico, mnimo y mximo.


>emos visto aparecer di4erentes nociones de tiempo relacionadas con el 3atc*dog" =e parece importante precisar entre los di4erentes valores" 6ecapitulemosK Tiempo t$pico %&' ms( K es el tiempo que toma el 3atc*dog' en general' para provocar el reset del programa en caso de &loqueo" ,s el tiempo de reaccin normal 2o t(pico5 del 3atc*dog" Tiempo m$nimo %) ms( K es el tiempo m%+imo entre dos instrucciones clr3dt para evitar un &loqueo en cualquier circunstancia" Tiempo m*imo %++ ms( K es el tiempo de reaccin del 3atc*dog en el caso m%s des4avora&le en 4un$ cin del componente # de las condiciones de utilizacin" =I 6J >IP le garantiza que el reset se pro$ ducir% en tiempo m%+imo de 33 ms"

15.10 Conclusin
<*ora est% en disposicin de crear programas resistentes a &loqueos cl%sicos por poco que utilice el 3atc*dog de 4orma juiciosa" ,n general' es pre4eri&le *acer el es4uerzo de utilizarlo' puesto que el tra&ajo e+tra es des$ precia&le en comparacin con la seguridad de 4uncionamiento o&tenida" ,T-N./ON0 e& :$"(M)*1 '"i&iD$)* (*.* #%*"e((in en ($s* )e 'n$ #%*1%$.$(in (*%%e("$ T )e 'n (i%('i"* !ien (*n(e!i)* n* )e!e%L en"%$% 2$.Ls en ,'n(i*n$.ien"*/ Se "%$"$5 en 1ene%$&5 )e 3'e es"$ #%*"e((in s*0 &* en"%$%L en ,'n(i*n$.ien"* en ($s*s .'T es#*%L)i(*s E#$%Lsi"*s vi*&en"*s5 "*%.en"$s5 e"(/F/ N* )e!e se%0 vi% #$%$ en.$s($%$% e%%*%es )e #%*1%$.$(in * )e (*n(e#(in e&e("%ni($/ T*)* )e!e%G$ #*)e% ,'n(i*n$% sin &$ $T')$ )e& :$"(M)*1/ 8e aconsejo realizar los programas de la siguiente maneraK 1" ,scri&a el programa colocando las instrucciones clr3dt como tenga previsto pero sin activar el 3atc*$ dog" 2" Gueme el PI # t-ngalo en 4uncionamiento el tiempo su4iciente como para poder estar seguro de no tener errores" 3" Hna vez el programa es 4ia&le' active el 3atc*dog reprogramando el PI " ?e esta 4orma estar% seguro que el 3atc*dog no va a servir para enmascarar pro&lemas de programacin de su parte 2relanzando el PI despu-s de un &loqueo en un &ucle sin 4in' por ejemplo5"

163

16. El modo sleep


Vamos a estudiar en esta leccin un modo de 4uncionamiento mu# particular de los PI que les permite po$ nerse a dormir con la 4inalidad de reducir su consumo"

16.1 El principio de funcionamiento


,l modo `sleepa o `po3er$do3na es un modo particular de estado del PI que usted puede activar con la ins$ truccin sleep" Hna vez en este modo' el PI se lleva a la posicin dormido # deja de ejecutar el programa" ?esde la recepcin de esta instruccin' la secuencia de *ec*os es la siguienteK 1" 2" 3" 4" ,l 3atc*dog es puesto a B e+actamente como si se tratase de una instruccin clr3dt" ,l &it 9J del registro .9<9H. es puesto a 1" ,l &it P? del registro .9<9H. es puesto a B" ,l oscilador se para # el PI no ejecuta ninguna instruccin"

Hna vez en este estado' el PI est% parado" ,l consumo se ve reducido al m(nimo" .i tmrB esta sincronizado con el reloj interno' se ver% incapacitado para contar" Por el contrario' conviene recordar que el timer del 3atc*dog posee su propia circuiter(a # reloj' por lo que seguir% contando normalmente como si nada *u&iese pasado

16.2 La salida del modo sleep.


,l paso a modo sleep no tendr(a ningDn inter-s si no pudi-semos salir de -l" ,l 16:;4 solo reacciona cuando est% en este modo a los siguientes eventos' que llevaran al PI al estado normal de tra&ajoK <plicacin de un nivel B so&re el pin = 86" ,sto provocar% un reset del PI " ,l PI provocar% un reset cl%sico a la direccin B+BB" ,l usuario podr% c*equear los &its 9J # P? para veri4icar que ocurri 2reset' 3atc*dog o puesta en alimentacin5" <lcance del tiempo del 3atc*dog" <dvierta que para que este evento sea capaz de despertar el PI ' el 3atc*dog de&er% estar en servicio con los &its de con4iguracin" ,n este caso en particular' el 3atc*$ dog no provoca un reset del PI ' se contentar% simplemente con despertarlo" 8a instruccioBn siguien$ te se ejecutar% despu-s de despertar" <paricin de una interrupcin 6PBRI19' 6P o ,,P6J="

,n este Dltimo caso' para que estas interrupciones puedan despertar el PI ' *ace 4alta que los &its de puesta en servicio de la interrupcin asociada *a#a sido posicionado" Por el contrario' el &it YI, no *ace 4alta que est- puesto en servicio 2pero puede estarlo5 para generar el despertar del PI " Puede' por ejemplo' decidir despertar el PI al 4inalizar un ciclo de escritura de la eeprom" Para *acerlo' de$ &er% poner a 1 el &it ,,I, de I19 J1' lanzar el ciclo de escritura # seguir con la instruccin sleep" Hna vez que el ciclo de escritura termine' el PI despertar% # podr% seguir con el programa" ,s imposi&le despertar el PI con una interrupcin timer puesto que en este modo el timer est% parado # no puede generar una interrupcin" 9ampoco puede contar los eventos e+teriores puesto que estos se sincroni$ zan con el reloj interno # este est% parado"

16.3 Despertar con GIE fuera de servicio


.i el PI se despierta por una interrupcin en tanto que el &it YI, de I19 J1 est% a B' el programa seguir% simplemente con la siguiente instruccin a sleep"

164

16.4 Despertar con GIE en servicio


,n el caso en que YI, est- a 1' un despertar de&ido a una interrupcin motivar% la siguiente secuencia de *ec*osK 1" 8a instruccin que sigue a sleep es ejecutada" 2" .e produce un salto a la direccin B+B4 como una interrupcin ordinaria" .i no quiere ejecutar la instruccin que sigue a sleep &astar% que ponga en su lugar una instruccin 1JP"

16.5 Puesta en dormido imposible


.i el &it YI, est% puesto a B' # el &it de puesta en servicio # el 4lag de una interrupcin est%n am&os a 1 en el momento de aparecer una instruccin sleep 2por ejemplo I19,LI19:L15 la instruccin sleep es simplemente ignorada" ,sto es lgico puesto que las condiciones para despertar #a est%n en el momento de mandarlo a dormir" ,s su tra&ajo ponerlos eventualmente a B" ,l &it P? le permitir% sa&er si su instruccin sleep *a sido ejecutada 2P?LB5" .i el &it YI, est% posicionado a 1 el caso anterior no podr% ocurrir' dado que la interrupcin a*ora se gene$ rar%' interrupcin que provocar% el &orrado del 4lag asociado' e+cepto si usted *a puesto la instruccin sleep en el interior de la rutina de interrupcin" J&serve igualmente' que en el caso de que la instruccin sleep no *a#a sido ejecutada' su 3atc*dog no se pondr% a B" .i de&e *acerlo en este momento # no est% seguro de la ejecucin de la instruccin sleep' a)ada un clr3dt antes de esta instruccin"

16.6 Utilizacin de la instruccin sleep


Vamos a *acer un peque)o ejercicio de poner a dormir el PI " >aga un copiarRpegar del 4ic*ero <.16F84/$s.= # renm&relo como <s&ee#/$s.=" ree un nuevo pro#ecto" Ponga el pre divisor del 3atc*dog a 32" ,sto nos dar% un tiempo de des&ordamiento t(pico de 1; ms I 32 L 576 ms"
OPTIONVAL EQU H8D ; Valor del registro OPTION ; Preescaler Wdt = 32

?e4ina el 8,? so&re el pin 6<2"


#DEFINE LED PORTA,2 ; LED

Ponga el 8,? como salida en la rutina de inicializacin"


Bcf LED ; LED como salida

165

,scri&amos el programa principal"


; ********************************************************** ; PROGRAMA PRINCIPAL ; ********************************************************** start bsf LED sleep bcf LED sleep goto start end ; ; ; ; ; encender LED modo dormido apagar LED modo dormido bucle

,l 4uncionamiento es mu# simple" ?espu-s de encender el 8,? el PI es puesto a dormir" Hna vez alcanzado el tiempo del 3atc*dog el PI se despierta # sigue tra&ajando" >e aqu( un programa de parpadeo de un 8,? con un consumo m(nimo" ,s m%s' esta es otra 4orma simple de medir el tiempo real de su 3atc*dog" N*"$ ,l despertar del PI no es instant%neo" .i usted utiliza un cuarzo' el PI esperar% 1B24 ciclos de reloj antes de seguir con el programa" >a# que tenerlo en cuenta" ,ste tiempo muerto es necesario para que el oscilador de cuarzo adquiera cierta esta&ilidad" .e consciente de que el despertar del PI necesitar% de este tiempo"

16.7 Caso tpico de aplicacin


,ste modo de 4uncionamiento es principalmente utilizado en los casos en los que el consumo de energ(a es cr(tico 2uso de &ater(as5" ,n este caso pondremos el PI en modo sleep en todo momento que podamos" Jtro caso t(pico es en el que el PI no tiene nada que *acer e+cepto esperar que ocurra un evento e+terior" ,n este caso' mejor que utilizar un &ucle sin 4in en espera de la interrupcin' podremos poner a dormir el PI a la espera de que el *ec*o ocurra"

16.7.1 Para un consumo mnimo


,l modo sleep asegura una puesta a dormir del PI " .u rol principal es limitar el consumo de energ(a" Para *acer esto no &astar% con pasar el PI a modo sleep' *ar% 4alta poner a dormir tam&i-n toda la peri4eria" ,l paso a modo sleep no modi4ica el estado de los pines con4igurados como salida" <9,1 IJ1K el paso a modo sleep no modi4ica la con4iguracin ni estado de los pines de salida" .i tiene consu$ midores de energ(a conectados a los pines 28,? por ejemplo5 seguir%n consumiendo corriente 2el 8,? conti$ nuar% encendido5" Para *acer que el paso a modo sleep sea realmente e4iciente' antes de realizarlo de&er% asegurarse que todas las salidas sean llevadas a un estado que el consumo sea realmente m(nimo" 9ampoco *a# que olvidarse del consumo de las resistencias pull$up en los pines de entrada del PJ69P' si las *a puesto en servicio" 9oda entrada re4erida a masa consumir% corriente" Hn eventual reloj e+terno de&er% ser parado" Para otros PI s *a# m%s medidas a tomar' como el parar los convertidores analgicoRdigitales"

166

9odas las entradas no utilizadas as( como 9B UI ser%n pre4eri&lemente 4orzadas a masa' o a Vdd' puesto que si las deja 4lotantes un eventual cam&io de estado provocar% un peque)o consumo" J&serve que llega al mismo resultado con4igur%ndolas como salida" 1ote que en este punto contrariamente a ciertas in4ormaciones desen4ocadas encontradas en la redK Hn pin al aire no provoca ningDn riesgo de &loquear el PI K sus entradas est%n protegidas por diodos #' es m%s' se trata de un dispositivo programa&le no de una puerta lgica =J. donde sus salidas pueden variar en 4uncin de entradas no utilizadas" ,n su programa usted no utiliza' en principio' ninguna entrada que no estconectada a algo' luego su transicin no tiene ninguna repercusin e+cepto en caso de errores de programa$ cin" ,l riesgo de conmutacin es d-&il en un entorno cl%sico' puesto que las entradas no &asculan m%s que para tensiones del orden de VddR2 22'5 V cl%sicamente5 # esto *ace que' dada la impedancia de las entradas' tener una cierta inmunidad" 8a Dnica consecuencia de una entrada al aire en un PI son los pocos p< de consumo de&ido a una transicin inesperada" >a&r% comprendido que *ace 4alta considerar el pro&lema del consumo en su conjunto # dedicarse a colocar instrucciones sleep /sin ton ni son0 a lo largo de todo el programa" <l menos si la limitacin de consumo 4or$ ma parte de su cuaderno de cargas"

16.8 Conclusin
<*ora #a es capaz de poner el PI en modo sue)o con el 4in de economizar energ(a" 1o dudo que encontrar% aplicaciones para este modo de tra&ajo simple # practico"

167

17. El resto del datasheet


Por 4in *emos llegado al 4inal del estudio del 16:;4" ,n este cap(tulo vamos a recorrer el datas*eet para ver todo lo que aDn no *emos visto *asta a*ora" ,s una especie de revoltijo el que le propongo" ?e todas 4ormas no entrar- en los detalles t-cnicos que solo podr(an interesarle a los electrnicos" ,sta gente est% per4ectamente dotada para entender algo como la 4igu$ ra 3$1 del datas*eet" Para los dem%s' esto no aportar(a a&solutamente nada para la utilizacin de los PI " ,sta leccin le ense)ar% cmo entender el datas*eet" mo los datas*eet se ponen al d(a constantemente por parte de =I 6J >IP' lo cual es una mu# &uena cosa' les adjunto a la leccin el que me *a servido a m( para desarrollar este curso' # que se llama /16F84/#),0"

17.1 La estructura interna


:igura 3$1" <qu( podemos ver como est% construido el 16:;4" omo le dec(a anteriormente' esta in4ormacin tiene un limitado inter-s de cara a la utilizacin pr%ctica del micro controlador" < remarcar la anc*ura de los &uses internos que nos recuerdan las limitaciones de los modos de direcciona$ miento" Vea' por ejemplo que el P 2Program ounter5 solo tiene una anc*ura de 13 &its" ,l corazn del 16:;4' como en todo procesador' es la <8H" ,s en esta Unidad Aritm-tico Lgica donde se *acen toso los c%lculos" J&serve la unin privilegiada entre el registro W # la <8H"

17.2 La secuencia de decodificacin


:igura 3$2" Vemos claramente la divisin de un ciclo de instruccin en 4uncin de los 4 ciclos del oscilador ne$ cesarios" ,st%n detalladas cada uno de los 4 ciclos necesarios para una instruccin" Vemos el ejemplo 3$1 que muestra la ejecucin de un paso de programa" J&serve que' mientras se ejecuta una instruccin' la siguiente #a est% cargada 2/4etc*05" ,sto e+plica por qudurante un salto' la siguiente instruccin cargada no es la que de&er% ser ejecutada" ?e aqu( la necesidad de 2 ciclos de reloj suplementarios para cargar la instruccin correcta"

17.3 Organizacin de la memoria


,n la 4igura 4$1 vemos la organizacin de la memoria del PI " J&serve que la pila # el P est%n situados 4uera del espacio de direccionamiento' por lo que no son accesi&les por el programa"

17.4 Los registros especiales


8a ta&la 4$1 nos da una visin glo&al de los registros especiales" 8a primera columna nos da la direccin del registro' la segunda el nom&re sim&lico del registro' seguidamente el nom&re de cada &it" 8a penDltima columna nos da el valor de cada &it despu-s de una puesta en tensin' mientras que la Dltima nos da lo mismo para otros tipos de reset 23atc*dog # = 865" 8os &its anotados con B # 1 son aquellos en los que el nivel es el indicado" 8os &its anotados con /u0 son los &its no a4ectados 2unc*angedLsin cam&io5" 8os &its anotados con /+0 son los &its cu#o estado no es conocido en este momento"

16;

17.5 La electrnica de los puertos


8as 4iguras de 5$1 a 5$4 permiten a los electrnicos comprender las especi4idades de los puertos IJ a nivel de sus caracter(sticas el-ctricas" Ver%' como #a le indiqu-' que el pin 6<4' por ejemplo' es una salida de /colector a&ierto0' o m%s precisamente' de /drenador a&ierto0' con4iguracin que no permite imponer un nivel alto a la salida"

17.6 El registro de configuracin


,l registro de con4iguracin est% situado en la direccin B+2BB7' 4uera del espacio de direccionamiento normal del PI " .olo es accesi&le en el momento de la programacin del dispositivo" <cceder% al registro con a#uda de la directiva /d J1:IY0' o con la a#uda de la directiva /?<0 precedido de la directiva /J6Y B+2BB70" ,l dato que indica a continuacin de la directiva ?< precisar% el nivel de 14 &its Dtiles para el 16:;4 25 para el 16 ;45" 8a posicin # la e+plicacin de esos 14 &its est%n indicadas en la 4igura ;$1" 1o olvide que se trata de una pa$ la&ra de 14 &its 2como la instruccin5" < t(tulo de ejemplo' la l(nea siguienteK _CONFIG _CP_OFF & _WDT_ON & _PWRTE_ON & _HS_OSC orresponder% para el 16:;4 aK ORG DA 0x2007 B111111111111110

8e desaconsejo este tipo de pr%ctica" =%s a&ajo ver% por qu-"

17.7 Los diferentes tipos de oscilador


8a 4igura ;$3 nos muestra la con4iguracin de reloj que *emos utilizado para nuestro PI " .e trata de cuarzo e+terno" 8a resistencia 6. es inDtil para un cuarzo cl%sico en un entorno est%ndar" .i utiliza un resonador cer%mico con condensadores integrados en lugar de un cuarzo' podr% suprimir los condensadores 1 # 2" Pa$ ra una aplicacin ro&usta # comercial le aconsejo que lea /8a Pi&lia del oscilador de PI 0 de =ic*el .toXo3sXi' carga&le desde mi pagina 3e& en el curso parte 2" 8a ta&la ;$1 muestra los di4erentes valores en 4uncin de la 4recuencia as( como los modos correspondientes seleccionados en los &its de con4iguracin :J. 1 # :J. B si usted utiliza un resonador cer%mico" 8a ta&la ;$2 *ace lo mismo para osciladores a cuarzo" J&serve que los &its que se citan est%n integrados en d>.dJ. # otras con4iguraciones del oscilador" ,sto e+plica por qu- no los *a encontrado directamente *asta a*ora" 8a 4igura ;$4 indica cmo utilizar un oscilador e+terno en lugar de un oscilador interno" 6ecuerde que en este caso no de&e jam%s parametrizar su oscilador como 6 so pena de destruir su PI " 8as 4iguras ;$5 # ;$6 le muestra cmo construir un oscilador e+terno" 8e aconsejo' a t(tulo personal' utilizar en este caso el integrado 74> HB4 que 4unciona correctamente para 4recuencias iguales o superiores a 4 =>z ,vite los modelos de tipo 8. 2748.B45 so pena de tener pro&lemas" ,n mi caso' #o utilizo un montaje derivado del montaje paralelo indicado" =i montaje' para 4 =>z' utiliza una 6 de 3'3 =o*ms en lugar de 47 Uo*ms' reemplazo la resistencia ajusta&le por una 4ija de 2 Uo*ms # suprimo la 6 ajusta&le del e+tremo izquierdo del esquema" 6eemplazo los 2 condensadores por otros de 27 p:" 16Q

?ejo el modo oscilador como 6esistencia ondensador" ,n este modo' la oscilacin est% asegurada por dos componentes pasivos' sin necesidad de cuarzo 2por razones econmicas5" Htilice este modo solo en el caso en el que sus constantes de tiempo no son cr(ticas" onecte segDn la 4igura ;$7 # utilice una resistencia del orden de 47 Uo*ms # un condensador del orden de 27 p:" 1o olvide que la 4recuencia de ejecucin de una instruccin valdr% una cuarta parte de la 4recuencia del reloj" Htilice la siguiente 4rmula para calcular el tiempo de ciclo de su programa" .ea 9c# la duracin de un ciclo de instruccin :osc la 4recuencia del oscilador montadoK Tcy = 4 / Fosc # es la a&reviatura de / iclo 2de instruccin50 por lo que 9c# L periodo del ciclo # :c# L :recuencia del ciclo" Jsc es la a&reviatura de /Jscilador0 por lo que 9osc L periodo del oscilador # :osc L 4recuencia del oscilador" Por ejemplo' para un cuarzo de 4 =>zK T = 4 / 4000000 = 1 micro segundo N rec(procamenteK :osc L 4 R 9c# para calcular la 4recuencia que corresponde a un tiempo de ciclo dado" .i quiero un tiempo de ciclo de 1'5 ns nos *ar% 4alta un reloj a una cadencia deK Fosc = 4 / (1,5 * 10-6) = 2,667 * 106 = 2,667 MHz

17.7.1 La precisin del oscilador


1o olvide en sus c%lculos tener en cuenta el error que siempre e+iste" 8a tolerancia de su reloj es siempre tri$ &utaria del m-todo escogido" Hn reloj de cuarzo tendr% siempre mejores prestaciones que un reloj 6 " < t(tulo de ejemplo' suponga que quiere construir un reloj con una tarjeta &asada en PI " Vamos a calcular el orden de magnitud de los errores o&tenidos en 4uncin del tipo de oscilador utilizado" .upongamos que el logicial est% desarrollado correctamente # que el error de medida del tiempo a este nivel es nulo" omencemos por la red 6 " .i elige este modo para el reloj ciertamente que *a&r% *ec*o una mala eleccin" 8a 4recuencia del oscilador var(a enormemente en 4uncin de la temperatura' de la precisin de los componentes' que varia con el tiem$ po' # adem%s es di4erente de un componente a otro" 1o nos asom&remos de tener un error de *oras por d(a" 6ec*aza&le" .i decidimos usar un resonador cer%mico' la ta&la 12$1 nos da la precisin o&tenida en 4uncin de di4erentes marcas # modelos c*equeados por =I 6J >IP" ,stos valores nos dan una precisin del orden de B'5 Z" .a&iendo que un d(a tiene 24 *oras # que cada *ora tiene 36BB segundos' sa&emos que un d(a completo tendr% 24 + 36BB L ;64BB s" Hn error del B'5 Z nos dar% un error estimado de ;64BB + 5 + 1B$3 s" 1uestro reloj tendr% una posi&le deriva de 6 minutos por d(a"

17B

Pasemos al cuarzo" .egDn la ta&la tendremos un error t(pico de 5B ppm 2partes por milln5' es decir B'BB5 Z" alculemos la deriva de nuestro relojK 86444 9 ?4 9 1406 6 453J s ,ste es un resultado muc*o m%s acepta&le" 1uevamente' lea la documentacin precisa si su o&jetivo es tener una precisin m%+ima como es el caso" ,ste apartado *a tenido como o&jetivo *acerle sentir' a trav-s de un ejemplo concreto' el orden de magnitud de las precisiones que podemos tener con m-todos corrientes" J&serve que podemos tener aDn precisiones m%s grandes utilizando un reloj e+terno espec(4icamente conce$ &ido para estas aplicaciones o un contador de ciclos de la red el-ctrica" ,ste Dltimo m-todo es mu# preciso dado que las sociedades de produccin de energ(a el-ctrica tienen la o&li$ gacin de suministrar un determinado nDmero de ciclos cada 24 *oras # para ello *acen una vigilancia per$ manente de la 4recuencia de la red"

17.8 El reset
,n la 4igura ;$; tiene el esquema el-ctrico del reset interno del PI " 1o se inquiete' todo el tra&ajo #a est% *ec*o por usted" .implemente recuerde queK para *acer 4uncionar normalmente un PI ' conecte a M5 V el pin = 86" 8a puesta a masa de este pin provoca un reset del PI " .i quiere tener un &otn de reset en su montaje' conecte el pin = 86 a M5 V a trav-s de una resistencia de 1B Uo*ms" onecte el pulsador entre el pin = 86 # la masa como en el siguiente esquemaK

,ste esquema carece de los condensadores necesarios para una &uena con4ormidad electromagn-tica" Para *acerlo' coloque un condensador de 1BB n: entre Vdd # Vss lo m%s cerca posi&le de Vdd" >aga lo mismo con = 86 # Vss" 8a ta&la ;$3 le muestra todos los eventos relacionados al reset # sus e4ectos so&re el P 2donde se rami4icar% el programa5 # el registro .9<9H."

171

8a ta&la ;$4 es mu# interesante pues muestra el contenido de cada registro despu-s de un reset # despu-s de un despertar" 6ecuerde que el valor /+0 signi4ica estado desconocido' el valor /u0 signi4ica sin cam&ios # /q0 signi4ica que el estado depende de la causa que lo origin"

17.9 La puesta en tensin


,n el momento en que se conecta la alimentacin al PI un circuito interno analiza la tensin de alimentacin" .e genera un reset autom%tico en el momento en que esta tensin alcanza valores en el entorno de 1'2 a 1'7 V" ,ste es el reset de puesta en tensin 2Po3er Jn 6eset5" ,ste circuito no provoca un reset si la tensin &aja" ,s su misin gestionar este *ec*o si le causase pro&lemas" Por el contrario' otros PI como 16:;76 s( lo gestionan" >a&laremos de ello en el curso parte 2" ,ste reset dispara un timer interno independiente de la velocidad del PI " ,ste timer mantiene el PI parado durante un tiempo t(pico de 72 ms desde la deteccin de la condicin de reset" ,ste timer se llama /Po3er$ up 9imer0 o PW69" .e le puede poner 4uera de servicio por medio del &it PW69," 8e aconsejo tenerlo siempre en servicio e+cepto en los casos en los que el tiempo de arranque sea critico para su sistema" < continuacin' despu-s de pasado el tiempo precedente' tenemos un retardo suplementario &ajo la 4orma de una espera de 1B24 oscilaciones del reloj 2Jscillator start$up 9imer5" ,sto permitir% asegurar el 4uncionamiento esta&le de este oscilador" ,ste J.9 no se utiliza cuando el reloj es del tipo 6 ' # est% en servicio para las puestas en tensin # despertares 2no para las otras 4ormas de reset donde se supone que el reloj #a es esta&le5" 8a 4igura ;$1B nos muestra el cronograma t(pico de una puesta en tensin" 8o e+plico r%pidamente" .epa que el desplazamiento *orizontal de izquierda a derec*a representa el tiempo" 8a l(nea 1 muestra la llegada de la alimentacin 2Vdd5" Hna vez que esta alimentacin llega a 1'2R1'7 V' el pro$ cedimiento de puesta en tensin es enganc*ado" 8a segunda l(nea nos muestra que el arranque del proceso no depende del nivel de la l(nea = 86" ,n este ejemplo' esta l(nea pasa al estado alto un poco m%s tarde" .i la *u&iese conectado a M5 V' pasar(a a 1 al mis$ mo tiempo que la l(nea Vdd sin ninguna in4luencia" < continuacin el reset interno 2PJ65 se valida desde el momento en que la alimentacin pasa del punto pre$ cisado" .e alcanza despu-s el tiempo de 72 ms del PW69 si est% puesto en servicio" <l 4inal de este tiempo' el J.9 arranca sus 1B24 ciclos de reloj para los modos concernidos" ,l procedimiento est% a*ora aca&ado" .i en este momento = 86 est% a 1' el PI arranca directamente 2ta&la ;$1B5" .i = 86 est% a B' el PI arrancar% instant%neamente cuando pase a valer 1 2ta&la ;$115" 8a ta&la ;$13 nos muestra que pasar(a si la alimentacin su&e mu# lentamente mientras = 86 est% conectado a la alimentacin" ,n este caso' el reset interno aca&ar(a antes de alcanzar la tensin de alimentacin normal' lo que no es acon$ seja&le" ,n este caso utilice el esquema de la 4igura ;$Q para *acer m%s lenta la su&ida en tensin de = 86 # alargar el tiempo de reset" 8as 4iguras ;$14 # ;$15 nos indican los m-todos de proteccin a utilizar en caso de una &ajada de tensin sin parada completa"

172

17.10 Caracteristicas elctricas


< partir del cap(tulo 11 encontrar% todas las especi4icaciones el-ctricas del componente" ,sto es interesante para los electrnicos que desarrollan montajes espec(4icos" Para una utilizacin normal' las e+plicaciones da$ das son m%s que su4icientes" Para aplicaciones espec(4icas le *ar% 4alta estudiar estas ta&las m%s en detalle as( como el datas*eet general de los PI de rango medio" onsidero inDtil detallar m%s en pro4undidad estos te$ mas"

17.11 Portabilidad de los programas


>e aqu( un punto delicado" EGu- ocurrir% con su programa si cam&ia de modelo de PI F Veamos que de&e *acer para asegurar la porta&ilidad de sus programas" ?e todas 4ormas' la porta&ilidad a este nivel es ilusoria' esperamos sin em&argo tener que cam&iar lo menos posi&le" ?e&er% utilizar imperativamente las directivas previstas d J1:IY en detrimento de los accesos direc$ tos del estilo J6Y B+2BB7" ,stos emplazamientos # sus contenidos son suscepti&les de cam&io de un modelo a otro" ?esgraciadamente' incluso a nivel de con4iguraciones' las opciones son di4erentes de un modelo a otro" ?e&er% utilizar los 4ic*eros "inc de =I 6J >IP correspondiente al PI so&re el que quiere correr el programa" Por ejemplo /P16:;4"inc0" ,sto le asegurar% tener siempre las direcciones correctas para los registros correctos" 8os registros que cam&ian de &anco de un PI a otro son mu# raros' pero ve$ ri4(quelo" ?e&er% leer los nuevos datas*eet para analizar las di4erencias entre los componentes inicial # nuevo" .egDn necesidad' modi4ique las 4uentes" ,n ciertos casos' =I 6J >IP proporciona e+pl(citamente do$ cumentos de migracin' marcando los puntos a modi4icar 2por ejemplo migracin del 16:;76 al 16:;76<5" ,nsam&le a continuacin el programa despu-s de *a&er cam&iado la l(nea include por aquella conte$ niendo el nuevo 4ic*ero include' la directiva declarando el nuevo PI # *a&er indicado el &uen o&jeti$ vo del programa"

J&serve que su programa ser% tanto m%s 4%cilmente porta&le si sigui las consignas aportadas en este curso # si *a utilizado al m%+imo las declaraciones' de4ines # macros' # si *a comentado el programa" Igualmente' si *a comprendido lo que precede' un 4ic*ero "*e+ conce&ido para un componente no puede ser utilizado de ninguna 4orma para otro componente distinto' salvo en casos e+tremadamente raros" 1o espere poder colocar su 4ic*ero para un 16:;4 en un 16:;76 # que 4uncione" ,n la segunda parte del curso le e+plicar- como realizar esta migracin" Por el contrario' para un 16:;4< esto no conlleva ningDn pro&lema"

17.12 La puesta al da de los componentes


,n el ap-ndice , encontrara una ta&la con las di4erencias entre un 16 ;4 # un 16:;4" Vamos a ec*arle un vis$ tazo" 8a primera l(nea muestra que PW69, a cam&iado de nivel" ,n e4ecto' PW69, a 1 pone en servicio el timer so$ &re el reset de 72 ms para el 16 ;4" Para el 16:;4 es el nivel a B" .i *a utilizado la directiva d J1:IY ser% su4iciente con re ensam&lar su programa con el 4ic*ero P16:;4"inc que integrar% autom%ticamente la modi4icacin" Por el contrario si opt por utilizar una escritura directa de la direccin B+2BB7' a pesar de las advertencias de la lecciones' tendr% que modi4icar el programa" 173

8a capacidad de la 6<= para el usuario *a pasado de 36 octetos a 6;" Puede o&servar que =I 6J >IP *a a)adido un 4iltro al pin = 86 con el 4in de evitar par%sitos que puedan provocar un reset inesperado" ,sto alarga la duracin de la se)al necesaria para provocar un reset" < continuacin nos encontramos con una serie de advertencias so&re las caracter(sticas el-ctricas del PI " ,s$ tas advertencias le re env(an a di4erentes ta&las de caracter(sticas" Inmediatamente despu-s una correccin a nivel de 4uncionamiento del PJ69<' cuando el PI se utiliza con una 4recuencia in4erior a 5BB U>z" =I 6J >IP *a a)adido un /trigger .c*mitt0 a la entrada 6PB cuando se utiliza como interrupcin" Para los no electrnicos' simplemente esto limita la posi&ilidad de 4alsas interrupciones" 8a puesta a B de los &its 6 # 7 de ,,<?6 no provoca m%s una disminucin de la corriente consumida por el PI " ,s una correccin de un error" ,n el 16 ;4 el e4ecto de dejar estos pines a nivel alto provoca&a un consumo superior de corriente por parte del PI " ,l 4amoso P 2 ode Protect5 que en el 16 ;4 consta&a solo de 1 &it pasa a*ora a ser de Q &its" ,sto permite crear di4erentes tipos de proteccin de cdigo so&re otros PI de la 4amilia 2proteccin de la eeprom' protec$ cin de datos' etc"5" Hna vez m%s' si utiliz la directiva d J1:IY ser% su4iciente con recompilar el programa cam&iando el include por el que sea pertinente" Para los que no' de&er%n leer el datas*eet para cada nueva revisin del componen$ te # actuar en consecuencia" :inalmente la correccin del error interno cuando se pon(a a B el &it YI," ?e esta 4orma no se generar% una in$ terrupcin en el &ucle siguiente" ,l &ucle loop que era necesario para veri4icar la puesta a B de YI, #a no es necesario en el 16:;4"

17.13 Conclusin
<*ora se encuentra en posesin de toda la in4ormacin necesaria para desarrollar aplicaciones &asadas en un micro controlador 16:;4" ?e todas 4ormas' de&er% practicar muc*o antes de llegar a ser un cracX de la pro$ gramacin" =uc*as veces se dir% a s( mismoK /esto no es posi&le" ?e&er(a 4uncionar" =i 16:;4 2o 16:;4<5 es de4ectuoso0" ,n el QQ'QQZ de los casos se tratar% de un error de programacin 2o de un error de concepcin del *ard3are5 que usted resolver% despu-s de algunas *oras de arduo tra&ajo" >ace #a muc*o tiempo que se desarroll el 16:;4<" .i *u&iese algDn error en -l' *ace #a tiempo que estar(a resuelto" 1o se rinda # rel-ase la documen$ tacin' incluso si cree que #a la conoce de carrerilla" 8e *e *ec*o cometer errores a propsito # los *emos corregido inmediatamente" >e seguido ese camino con la 4inalidad de 4acilitarle la vida' mostr%ndole cosas que eran correctas en apariencia # e+plic%ndole el &uen camino para o&tener un resultado 4ia&le" 1o le vo# a dejar caerse todav(a # le vo# a e+plicar algunos trucos que resultan mu# pr%cticos para los pro$ gramas m%s corrientes" <Dn as(' a*ora #a est% en disposicin de tra&ajar en solitario" 8e *e ense)ado el diccionario de rimas' a su cargo escri&ir poes(a"

174

18. Trucos de programacin


,n este cap(tulo vamos a e+aminar m-todos simples para salir airosos de situaciones cl%sicas"

18.1 Las comparaciones


EGu- m%s simple que comparar dos nDmerosF .olo *ace 4alta *acer una sustraccin" .ea' por ejemplo' la comparacin de mem1 # mem2K
movf mem1 , w ; cargar mem1 subwf mem2 , w ; sustraer mem2 mem1

<*ora solo *a# que mirar los &its # \ del registro .9<9H. para sa&er el resultadoK .i \L1 las dos posiciones contienen el mismo valor" .i \LB # L1' el resultado es positivo' luego mem2 es ma#or que mem1" .i \LB # LB' el resultado negativo' mem2 es menor que mem1 .i solo desea comparar la identidad de los dos valores' sin modi4icar ' puede as( mismo utilizar la instruccin [J6"
movf mem1 , w ; cargar mem1 xorwf mem2 , w ; Si igual, todos los bits son 0 y Z se pone a 1

8as comparaciones mDltiples so&re la igualdad a unas constantes son un caso interesante puesto que tam&i-n *a# sitio para utilizar la astucia" <dmitamos un cdigo que pregunta estoK
Si valor = 1 -> ejecucin cdigo 1 Si valor = 2 -> ejecucin codigo 2 Etc.

Podemos economizar instrucciones usando /+ol30 # *aciendo calcular las di4erencias a MPASM" =e e+plicoK
movf variable,w ; carga variable xorlw 1 ; compara con 1 btfs STATUS,Z ; igual ? goto code1 ; Si, ejecutar codigo 1 xorlw 1^2 ; compara variable con valor 2 btfs STATUS,Z ; igual ? goto code2 ; Si, ejecutar codigo 2 xorlw 2^3 ; comparar con valor 3

,l truco est% en las dos l(neas en negrita" =ejor que recargar la varia&le para e4ectuar un /+orl3 con el valor 2' comparamos directamente el registro W con el valor 1^2 21 +or 25" =P<.= se va a encargar de calcular este valor" 8o que va a ocurrir es que' mirando lo que *a ocurrido con el primer +orl3 1' *a&remos al 4inal realizado la si$ guiente operacinK Varia&le +or 1 2 1 +or 25 siendo /1 +or 20 una constante que ser% calculada por =P<.=" Pero la operacin +or es asociativa 2podemos cam&iar el emplazamiento del par-ntesis5 luegoK 2 Varia&le +or 1 +or 1 5 +or 2 175

Pero el resultado del primer par-ntesis es la varia&le dado que dos inversiones seguidas equivalen a dejar las cosas como esta&an" 9oda esta operacin se resume en /varia&le +or 20" =oraleja' *emos comparado la varia&le con 1' despu-s con 2' despu-s con 3' etc" .in *a&er tenido que recargar la varia&le a cada paso" 8o que *ace 4alta recordar es que cuando tra&ajamos con constantes 2comparaciones' operaciones matem%ti$ cas' etc"5 e+isten a menudo 4ormas de usar la astucia para simpli4icarse la vida"

18.2 Sustraer un valor de w


.upongamos que tenemos un valor en W # que deseamos sustraer 5 de ese valor" ,l primer re4lejo es el si$ guienteK
Sublw 5

,s un error cl%sico' puesto que en realidad ejecutamos 25$35 en lugar de 23$55" 1os *ar% 4alta e4ectuar el complemento a 2 de este valor para o&tener el resultado correcto" Pero' trat%ndose nuevamente de una constante' dejemos que sea =P<.= el que *aga el tra&ajo por nosotros" ,4ectuemosK
Addlw -5

,videntemente' a)adir $5 equivaldr% a sustraer 5" >%galo por escrito si no queda realmente convencido" Por el contrario' la gestin del &it necesitar% un poco m%s de gimnasia" .e lo dejo a usted *acer # re4le+ionar"

18.3 Las multiplicaciones


E mo *acer una multiplicacinF ?e la misma manera que las *acemos a mano" Vamos a crear una rutina que multiplique juntos dos nDmeros de ; &its" ,l resultado necesitar% 1; &its' luego 2 octetos" Para o&tener el nDmero m%+imo de d(gitos del resultado de una multiplicacin' &asta con sumar el nDmero de d(gitos de los dos multiplicandos" 6ealicemos una multiplicacin manual" Vamos a multiplicar 12 por 13" Vamos a tra&ajar con 4 &its multiplica$ dos por 4 &its' con resultado so&re ; &its" ,sto es as( para reducir nuestra e+plicacin" >ag%moslo manual$ menteK

EGu- *emos *ec*oF >emos multiplicado 12 por cada ci4ra de 13 comenzando por la derec*a" >emos decala$ do un rango *acia la izquierda cada resultado intermedio antes de su suma 4inal" 8a particularidad en &inario es que solo *a# dos ci4ras' B # 1" Por lo tanto' o multiplicamos por B 2que nos da nada5 o multiplicamos por 1 2que nos da la copia del numero5" 176

Veamos' pues' que o&tenemos en &inarioK =ultiplicamos 11BB por 1" J&tenemos 11BB 2?O12O5 =ultiplicamos 11BB por B # decalamos a la izquierda" J&tenemos BBBB =ultiplicamos 11BB por 1 # decalamos *acia la izquierda" J&tenemos 11BB completado por BB' es de$ cir 11BBBB 2?O4;O5" =ultiplicamos 11BB por 1 # decalamos a izquierda" J&tenemos 11BB # completamos con BBB' es decir 11BBBBB 2?OQ6O5" .umamos todo o&teniendo 1BB111BB' es decir ?O156O"

.i realizamos este programa' necesitaremos 4 varia&les suplementarias para almacenar los resultados inter$ medios" ; en el caso de una multiplicacin de ; &its por ; &its" Podemos imaginarnos pasar de los resultados intermedios procediendo a la suma a medida que estos se van produciendo" J&tendremos el algoritmo siguienteK =ultiplicamos 11BB por 1" <lmacenamos en el resultado 4inal" =ultiplicamos 11BB por B" ?ecalamos una vez" .umamos al resultado 4inal" =ultiplicamos 11BB por 1" ?ecalamos dos veces" .umamos al resultado 4inal" =ultiplicamos 11BB por 1" ?ecalamos tres veces" .umamos al resultado 4inal"

Intente escri&ir este programa" ,sto resulta pr%ctico para las multiplicaciones de 4 &its" Para las de ; &its' de$ &er% realizar las sumas con nDmeros de 16 &its" ada vez tendr% que decalar m%s el multiplicador lo que im$ plicar%' o &ien modi4icarlo o &ien guardarlo 2lo que consumir% 1 octeto5" 6e4le+ionando un poco' se podr(a decir que mas que decalar el multiplicador a la izquierda' podr(amos decalar el resultado a la derec*a" ,sto nos dar% lo mismo' pero solo tendremos sumas de ; &its' siempre en el peso 4uerte del resultado" Veamos cmo 4unciona con nuestro ejemplo' para no *acerlo m%s largoK =ultiplicamos 11BB por 1" olocamos el resultado al 4ondo izquierdo del resultado" J&tenemos 11BBBBBB" ?ecalamos a la derec*a" J&tenemos B11BBBBB" =ultiplicamos 11BB por B" .umamos al resultado" J&tenemos B11BBBBB" ?ecalamos a la derec*a" J&tenemos BB11BBBB" =ultiplicamos 11BB por 1" .umamos el resultadoK 11BBBBBBMBB11BBBB L 1111BBBB" ?ecalamos a la derec*a" J&tenemos B1111BBB" =ultiplicamos 11BB por 1" .umamos el resultadoK 11BBBBBBMB1111BBB L 1BB111BBB 2Q &its5" ,l no$ veno &it est% en el carr#" ?ecalamos a la derec*a # o&tenemos 1BB111BB L ?O156O"

J&serve que sumamos siempre en el cuarteto de peso 4uerte 2centraje a la izquierda5" ,n el caso de una mul$ tiplicacin de ; &its por ; &its" .e sumar% en el octeto de peso 4uerte" <lgunas veces tendremos des&orda$ miento de la suma en el QS &it" 6ecuerde que se encuentra en el carr#" ,n el decalaje' el carr# se llevar% al re$ sultado por lo que recuperaremos autom%ticamente el QS &it' que pasar% a ser el ;S despu-s del decalaje a la derec*a" ,ste procedimiento es mu# simple de programar" omo prue&a veamos el pseudocdigo de multiplicacin de ; &its por ; &its"

177

Porrar el resultado" Para cada uno de los ; &its del multiplicadorK o .i &it L 1 a)adir multiplicando al peso 4uerte del resultado o ?ecalar 16 &its del resultado a la derec*a" o ?ecalar multiplicador a la derec*a" Pit siguiente"

.i ponemos adem%s el decalaje del multiplicador en la ca&eza' antes de compro&ar el &it' recuperaremos el &it a compro&ar en el carr#" ,l programa se convierte enK Porrar el resultado" Para cada uno de los ; &its del multiplicadorK o ?ecalar multiplicador a la derec*a" o .i carr# L 1 a)adir multiplicando al peso 4uerte del resultado o ?ecalar 16 &its del resultado a la derec*a" Pit siguiente"

J&serve que esto es mu# simple" Vamos a poner este pseudocdigo en 4orma de programa" Vamos a utilizar la varia&le multi como multiplicador' multan como multiplicando' result> como resultado peso 4uerte' result8 como resultado peso d-&il' multemp es el multiplicador temporal que ser% modi4icado # cmpt el contador de &ucles" ,l programa quedar% comoK
clrf resultH clrf resultL movlw 0x08 movwf cmpt movf multi , w movwf multemp movf multan , w loop rrf multemp , f btfsc STATUS , C addwf result , f rrf resultH , f rrf resultL , f decfsz cmpt , f goto loop ; borrar resultado peso fuerte ; idem peso dbil ; por 8 bits ; inicializa contador de bucles ; carga el multiplicador ; salva en multemp ;multiplicando en w ; ; ; ; ; ; ; decala multiplicador a la derecha test si bit que sale = 1 SI , aadir a peso fuerte decalar resultado peso fuerte decalar resultado peso dbil decrementa el contador de bucles no ha acabado , bit siguiente

Puede crear un peque)o pro#ecto para pro&ar este cdigo en el simulador" Ver% que 4unciona per4ectamente" Puede *acer una su&rutina o una macro a a)adir su 4ic*ero include propio" 8as dos Dltimas l(neas /rr40 realizan un decalaje del resultado en 16 &its" ,l &it perdido al decalar result> se re$ cupera en el carr# del decalaje de result8 # pasa a ser el &it7 2;S &it5" 9ruco de programacinK si la suma pre$ cedente *a tenido lugar' el QS &it resultante de la suma est% en el carr# # se convierte en el &7 de result>" Por el contrario' si no *a *a&ido suma' el carr# ser% B a e4ectos del test" Puede ver el inter-s de *a&er c*equeado el &it d-&il del multiplicador sirvi-ndose del carr#" ,st- seguro que' con la e+periencia' usted llegar% a este tipo de resultados" ,ste programa est% disponi&le &a$ jo la denominacin /multi"asm0" Hn truco a recomendar es ir a cargar las li&rer(as matem%ticas #a escritas en el sitio de =icroc*ip' # particu$ larmente' las li&rer(as <1256 # <1617" 9odo lo que all( *a# est% particularmente optimizado' incluso si ciertas optimizaciones est%n lejos de ser entendi&les sin un amplio &agaje matem%tico"

17;

18.4 Multiplicacin por una constante


,n el caso precedente' *emos e4ectuado la multiplicacin de 2 varia&les que pueden tomar cualquier valor" ,n el caso de utilizar una constante' es decir que conocemos el multiplicador a la *ora de conce&ir el programa' de&eremos' por razones de optimizacin' pro&ar de razonar en multiplicaciones por 2" Para realizar una multiplicacin por 2 solo necesitamos decalar *acia la izquierda" ,s mu# 4%cil de poner en pr%ctica" 1o olvide poner a B antes del decalaje para no meter un &it no deseado en la pala&ra decalada" .upongamos que de&e e4ectuar multiplicaciones por 1B 2decimal5" Vamos a intentar resolverlo con multiplica$ ciones por 2" ,s mu# simple" Para multiplicar por 1B *ar% 4altaK =ultiplicar por 2 2decalar a la izquierda5" =ultiplicar por 2 2L multiplicar por 4' decalar otra vez5" <)adir el operando original 2operando M operando + 2 L operando + 55" =ultiplicar por 2 2decalar a la izquierda5" Hna multiplicacin por 1B mu# r%pida" >acemos / +2 ' +2 ' M1 ' +20" 3 decalajes # una suma" ,n general' nos podemos arreglar para o&tener los resultados de las multiplicaciones por constantes usando este m-todo" ,sto le permitir% ganar un tiempo precioso en la programacin" Podemos ver un peque)o programa que multiplica un nDmero de 4 &its contenido en mem1 por 1B" ,l resul$ tado estar% en resul" Puede adaptarlo para ; &its 4%cilmente"
movf movwf bcf rlf rlf addwf rlf mem1 , w resul STATUS ,C resul , f resul , f resul , f resul , f ; ; ; ; ; ; ; carga operando en 4 bits salva en resultado borra el carry multiplica por 2 multiplica por 4 aade mem1 , multiplica por 5 multiplica por 10

18.5 Direccionamiento indirecto apuntando a 2 zonas diferentes


Imagine que tiene que copiar 15 varia&les de un emplazamiento de memoria a otro 2o comparar 2 zonas de memoria di4erentes' etc"5" 6%pidamente se va a encontrar con un pro&lema" .olo dispone de un puntero :.6 para apuntar so&re sus varia&les" 6ealicemos este programaK mem1 es la direccin de partida de la primera zona # mem2 es la direccin de par$ tida de la 2 segunda zona"
movlw movwf movlw movwf loop movf movwf movlw addwf movf movwf movlw addwf decfsz goto mem1 FSR 15 cmpt INDF , w tampon mem2-mem1 FSR tampon , w INDF (mem1-mem2)+1 FSR , f cmpt , f loop ; apuntamos a la primera zona ; inicializamos el puntero sobre la zona fuente ; 15 variables a transferir ;salvamos en contador de bucles ; ; ; ; ; ; ; ; ; cargamos fuente salvamos en un emplazamiento tampn diferencia entre los dos emplazamientos apuntamos al destino cargamos el valor fuente salvamos en destino diferencia entre destino y fuente siguiente aadimos al puntero decrementamos el contador de bucles

17Q

,ste programa es v%lido aunque no *a#a escogido las zonas de partida # destino" 1adie nos impide poner las varia&les en las zonas que nos convengan" Pongamos mem1 # mem2 en la zona de varia&les"
CBLOCK 0x10 mem1 : 15 ENDC CBLOCK 0x30 mem2 : 15 ENDC ; elegimos una zona de memoria en RAM ; 15 emplazamientos para la fuente

; elegimos una zona de memoria en RAM ; 15 emplazamientos para el destino

J' mejor aDn' aunque no vemos &ien la organizacin de las zonas utilizadas"
mem1 EQU 0x10 mem2 EQU 0x30

<*ora' la 4uente va de POBBB1BBBBO a POBBB11111O' # el destino de POBB11BBBBO a POBB111111O" .olo cam&ia el &it 5 de :.6 entre la 4uente # el destino" Para modi4icar los &its' no necesitamos el acumulador por lo que no tenemos que recargar el valor a trans4erir" Podemos modi4icar nuestro programa de la siguiente maneraK
movlw movwf movlw movwf loop movf bsf movwf bcf incf decfsz goto mem1 FSR 15 cmpt INDF , w FSR , 5 INDF FSR , 5 fsr , f cmpt , f loop ; apuntamos a la primera zona ; inicializamos el puntero sobre la zona fuente ; 15 variables a transferir ;salvamos en contador de bucles ; ; ; ; ; ; cargamos fuente apuntamos al destino salvamos en destino apuntamos a la fuente puntero en siguiente decrementamos el contador de bucles

on los PI que utilizan varios &ancos como el 16:;76' puede utilizar la misma direccin en 2 &ancos di4eren$ tes' # pasar de uno a otro modi4icando el &it I6P del registro .9<9H."

18.6 Las tablas en memoria de programa


.upongamos que necesitamos una ta&la de un tama)o importante" Por ejemplo una ta&la de 2BB elementos" E?nde la colocamosF ,n la 6<= no tenemos sitio" ,n la ,,P6J= tampoco" .olo nos queda la memoria de programa" ,l pro&lema es que el 16:;4' al contrario que el 16:;76' por ejemplo' no dispone de ningDn m-todo para leer los datos de la memoria de la zona de programa" ,l Dnico m-todo de acceso a esta parte es utilizar instruccio$ nes" .upongamos un caso simpleK queremos una ta&la que contenga el cuadrado de los nDmeros del B al 15" Podr$ (amos utilizar un su&programa de la siguiente 4ormaK *equeamos si el numero pasado como argumento L B" .i es s(' devolvemos B" *equeamos si el numero pasado como argumento L 1" .i es s(' devolvemos 1" *equeamos si el numero pasado como argumento L 2" .i es s(' devolvemos 4" ,tc" 1;B

Inmediatamente ver% que necesitamos varias instrucciones por cada valor de la ta&la" ,n el caso de una ta&la de 2BB elementos' no tendremos su4iciente memoria de programa para escri&irlo" Vamos a utilizar un truco" ,l corazn del truco consiste en utilizar la instruccin /retl30 que permite devolver un valor pasado como ar$ gumento" ,scri&amos nuestra ta&la &ajo la 4orma de retl3" Guedar%K
retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw 0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; cuadrado cuadrado cuadrado cuadrado cuadrado cuadrado cuadrado cuadrado cuadrado cuadrado cuadrado cuadrado cuadrado cuadrado cuadrado cuadrado de de de de de de de de de de de de de de de de 0 = 0 1 = 1 2 = 4 3 = 9 4 = 16 5 = 25 6 = 36 7 = 49 8 = 64 9 = 81 10 = 100 11 = 121 12 = 144 13 = 169 14 = 196 15 = 225

.olo nos queda encontrar un truco para re4erirnos a la l(nea correcta de esta ta&laRprograma" .i nos acorda$ mos de que podemos e4ectuar operaciones so&re el P 8' podremos utilizar esta propiedad" .upongamos que el numero a elevar al cuadrado est% contenido en el registro 3" .i' una vez so&re la primera l(nea de la ta&la' a)adimos 3 al P 8' saltaremos directamente so&re la l(nea correcta" ompletemos la su&ru$ tina" .olo necesitaremos a)adir delante de nuestra ta&la la l(neaK
carre addwf

PCL, f

; aadir w a PCL

.i cargamos 4 en 3 # e4ectuamos una llamada /call carre0' el programa se desviar% so&re esta l(nea' el P 8 se incrementar% en 4 # el programa ejecuta la l(nea /retl3 160" 6ecuerde' en e4ecto' que el P apunta siempre so&re la instruccin siguiente' luego' en el momento de la eje$ cucin de /add34 P 8 ' 40 apunta&a a la l(nea /retl3 B0" ,n este momento' de&e recordar que la direccin para una operacin so&re el registro P 8 est% completada por el contenido de P 8<9>" ?e&er%' pues' inicializar este correctamente con el contenido de la /pagina de ; &its0 de la direccin de su ta&la" Por ejemplo' si la ta&la est% en la direccin B+2BB' de&er% poner B+B2 en P 8<9>" <dem%s' la operacin so&re P 8 no modi4icar% autom%ticamente P 8<9> por lo que la ta&la no de&er% pasar de 256 elementos # no de&er% des&ordar de la pagina de ; &its siguiente" Hna p%gina es el espacio direccio$ nado por los 256 valores posi&les de P 8' sin tocar P 8<9>"

1;1

E mo evitar estoF Imponiendo a la ta&la una direccin de comienzo tal que la ta&la est% contenida en la misma /pagina0 de 256 elementos" ,sto nos permite utilizar una ta&la de 256 elementos" Veamos los emplazamientos posi&les para una ta&la de ese tama)oK ?ireccion POBBBBB BBBBBBBBO es decir B+BB" 1o utiliza&le por ser direccin del reset" ?ireccion POBBBB1 BBBBBBBBO es decir B+1BB" Primer emplazamiento utiliza&le" ?ireccion POBBB1B BBBBBBBBO es decir B+2BB" .egundo emplazamiento utiliza&le" ?ireccion POBBB11 BBBBBBBBO es decir B+3BB" Hltimo emplazamiento utiliza&le" .i su necesidad es de una ta&la m%s peque)a' podr% comenzar en otra parte' teniendo la precaucin de no causar des&ordamiento" Podr% a)adir la l(neaK org B+3BB antes de la etiqueta de comienzo de la su&rutina" J&serve que e+plico aqu( que esto es v%lido para las ta&las en las que el 4inal est% en la misma p%gina que el comienzo" omo la l(nea /add340 est% incluida en esa p%gina' *a&r% que sustraer esta l(nea de los 256 empla$ zamientos disponi&les" J&tendremos' puesK

;***************************************************** ; TABLA DE CUADRADOS ;***************************************************** ;----------------------------------------------------; No olvide que la directiva END se debe encontrar , despus de la ltima lnea de su programa. No deje ; esta directiva en el programa principal. ;----------------------------------------------------Org 0x300 ; direccin de la tabla carre addwf PCL, f ; aadir w a PCL retlw .0 ; cuadrado de 0 = 0 retlw .1 ; cuadrado de 1 = 1 retlw .4 ; cuadrado de 2 = 4 retlw .9 ; cuadrado de 3 = 9 retlw .16 ; cuadrado de 4 = 16 retlw .25 ; cuadrado de 5 = 25 retlw .36 ; cuadrado de 6 = 36 retlw .49 ; cuadrado de 7 = 49 retlw .64 ; cuadrado de 8 = 64 retlw .81 ; cuadrado de 9 = 81 retlw .100 ; cuadrado de 10 = 100 retlw .121 ; cuadrado de 11 = 121 retlw .144 ; cuadrado de 12 = 144 retlw .169 ; cuadrado de 13 = 169 retlw .196 ; cuadrado de 14 = 196 retlw .225 ; cuadrado de 15 = 225 END

1;2

.olo nos queda construir un peque)o programa que *aga llamadas a esta su&rutina"
;************************************************************ ; ARRANQUE SOBRE RESET ;************************************************************ org 0x000 ; direccin de arranque despus de reset

;************************************************************ ; PROGRAMA PRINCIPAL ;************************************************************ start clrf numero loop movf numero , w call carre incf numero , f btfss numero , 4 goto loop goto start

; borra el numero ; ; ; ; ; ; carga el numero toma el cuadrado del numero incrementa el numero chequea si numero > 15 NO , numero siguiente SI , comenzamos de nuevo

ompile el programa # p%selo al simulador" Vera que no 4unciona" EPor qu-F 9oda operacin en la que el P es el destino *ace intervenir al P 8<9>" >emos dejado el P 8<9> a B" 8a direc$ cin calculada no es la correcta" <ntes del salto de&er(amos a)adirK
movlw movwf 03 PCLATH

on el 4in de permitir a P 8<9> apuntar so&re la p%gina B+3BB despu-s del c%lculo de incremento de P 8" Podr(a reemplazar la l(nea org B+3BB porK
repere ORG (repere+.31) & 0x3E0

; direccin de la tabla

,l o&jetivo de esta manipulacin es o&tener autom%ticamente la primera direccin disponi&le para la que no *a&r% un des&orde de nuestro P 8 2para una ta&la de 32 elementos salto incluido5" Para una ta&la de 256 elementos 2salto incluido5 utilice /J6Y 2repereM2555 T B+3BB0" >aga el c%lculo a mano en un papel para con$ vencerse" >a# otros m-todos de *acerse' como utilizar una directiva de test 2I:5 para veri4icar que el 4inal de una ta&la est% en la misma p%gina que el comienzo" ,l 4ic*ero o&tenido est% &ajo la denominacin /ta&leau"asm0" ,s importante entender que es el conjunto de instrucciones /retl30 el que se de&e encontrar en la misma p%gina" ,n el caso precedente 2ta&la peque)a5' puede o&servar que *a# una instruccin que se encuentra #a en esta p%gina' lo que *ace disponer de un emplazamiento menos" Podr(amos *a&er modi4icado la ta&la en consecuencia' de manera que le primer elemento de la ta&la apunte al o44set B de la pagina de ; &its"
Org 0x2FF0 carre addwf PCL, f retlw 8 retlw 4 ; direccin de la tabla ; aadir w a PCL ; primer elemento de la tabla : direccin 0x300 ; segundo elemento de la tabla : direccin 0x301

1;3

.iempre para el caso de una ta&la de 256 elementos' vemos que de&emos empezar imperativamente la ta&la con un o44set de B 2P 8LB5" InDtil *acer una suma de B' ser% su4iciente con poner directamente 3 en el P 8' sea cual sea la direccin de esta imputacin' siempre # cuando que P 8<9> est- correctamente con4igurado" J&tendremos' puesK
carre movwf PCL org 0x300 retlw retlw 8 4

; ; ; ; ; ;

colocar w en PCL (direccin=continuacin programa principal direccin efectiva de la tabla (256 lugares disponibles) primer elemento de la tabla : direccin 0x300 segundo elemento de la tabla : direccin 0x301

18.7 Las variables locales


Hno de los reproc*es m%s usuales al PI 16:;4 es el nDmero restringido de emplazamientos de memoria 6<=" ,n cualquier caso' no de&emos creer que' &ajo el prete+to de que estamos programando en lenguaje ensam$ &lador' no dispongamos de varia&les locales" ?e *ec*o la utilizacin de este tipo de varia&les es mu# simple # reduce considera&lemente el nDmero de va$ ria&les necesarias en un programa" >e aqu( mi m-todo personal de utilizacin de este tipo de varia&les" omo recordatorio' este tipo de varia&les son varia&les que se utilizan en el interior de una su&rutina # que no sirven m%s una vez la rutina 4inalizada" Partamos de un programa imaginario que utiliza dos su&rutinas" 1" 8a primera su&rutina se llama /tempo0' utiliza 2 contadores para realizar un contaje de tiempo" 2" 8a segunda es la su&rutina /4onction0" 6eci&e un par%metro en W' de&e salvar el resultado en una va$ ria&le # utiliza otras 2 varia&les para sus c%lculos intermedios" 3" 8a condicin para el uso de varia&les locales id-nticas es que una su&rutina no llame a la otra"

18.7.1 Determinacin de las variables locales


.i e+aminamos las su&rutinas veremos que las 2 varia&les de la su&rutina /tempo0 solo son Dtiles en su inter$ ior" Podemos' pues' utilizar varia&les locales" 8a varia&le resultante de la su&rutina /4onction0 de&er% ser conservada despu-s de la ejecucin de la su&ruti$ na por lo que no puede ser una varia&le local" ?iremos que es una varia&le glo&al" Por el contrario' las 2 va$ ria&le utilizadas para los c%lculos intermedios no tendr%n ninguna utilizad posterior" .er%n varia&les locales"

18.7.2 Construccin sin variables locales


E mo ser(a nuestra zona de varia&les sin la utilizacin de varia&les localesF reemos nuestra zona de varia$ &lesK
CBLOCK 0x0C Cmpt1 : 1 Cmpt2 : 1 Resultat : 1 Interm1 : 1 Interm2 : 1 ENDC

; ; ; ; ;

contador 1 para tempo contador 2 para tempo resultado para fonction resultado intermedio 1 para fonction resultado intermedio 2 para fonction

Vemos que necesitaremos 5 varia&les" <*ora utilicemos varia&les locales" 1;4

18.7.3 Construccin con variables locales


Primero vamos a reservar los emplazamientos de memoria necesarios para las varia&les locales" ,l nDmero m%+imo de varia&les locales utilizadas por una 4uncin es de 2" 9endremos 2 varia&les locales" ?eclar-moslas" ?espu-s nos queda una varia&le glo&al a a)adir" reemos nuestra zona de datosK
CBLOCK 0x0C Local1 : 1 Local2 : 1 Resultat : 1 ENDC

; variable local 1 ; variable local 2 ; resultado para fonction

1os *ar% 4alta 3 varia&les en lugar de las 5 iniciales" Para estar m%s cmodos podemos atri&uir los mismos nom&res que anteriormente para nuestras varia&les locales a)adiendo simplemente unos ?,:I1, o ,GH"
#DEFINE #DEFINE #DEFINE #DEFINE Cmpt1 Local1 Cmpt2 Local2 Interm1 Local1 Interm2 Local2 ; ; ; ; contador 1 = variable local 1 contador 2 = variable local 2 resultado intermedio 1 = variable local 1 resultado intermedio 2 = variable local 2

N #a est%" .e aca& la necesidad de programar en para tener varia&les locales"

18.8 Divisin por una constante


>e aqu( un truco que me 4ue enviado por un internauta' 6ic*ard 8"K Para dividir un nDmero por una constante es su4iciente multiplicar ese nDmero por una constante que valga /256 dividido por la constante0" J&teniendo un resultado so&re 16 &its' el resultado de la divisin se encuentra en el octeto de peso 4uerte" E2e.#&*K Para dividir un nDmero por 1B &astar% multiplicar por 2256R1B5" ,n *e+adecimal 156R1B da B+1Q o B+1< 2*ace 4alta redondear5" Imaginemos que nuestra varia&le contiene el valor decimal 12B' es decir B+7;" .i multiplicamos B+7; por B+1< o&tenemos B+B 3B" ,l peso 4uerte es B+B ' que es 12 en decimal" .i *u&i-semos escogido B+1Q *a&r(amos o&tenido 11 como respuesta" .irvi-ndose de m%s octetos 265536 dividido por la constante' por ejemplo5 podemos mejorar la precisin"

18.9 Conclusin
<*ora tiene a su disposicin algunos trucos de programacin" ,l o&jetivo era el mostrarle los m-todos de ra$ zonamiento con la 4inalidad de permitirle desarrollar sus propios trucos # astucias"

1;5

19. Utilizacin de rutinas en un fichero separado


19.1 Preguntas y punto de partida
E mo podemos poner nuestras rutinas en 4ic*eros separadosF EPor qu- o&tengo mensajes de error del tipo /over3riting0 cuando intento *acerloF EPor qu- =<.= me da errores de enlace 2linX5 al a)adir 4ic*eros su$ plementariosF 9odas estas preguntas me las encuentro a intervalos regulares en mi correo por lo que #a es *ora de clari4icar las di4erentes maneras de proceder para colocar cdigo en 4ic*eros secundarios a a)adir al 4ic*ero principal" 8a primera cosa a comprender es que no *ace 4alta a)adir la re4erencia al 4ic*ero concernido en la jerarqu(a de un pro#ecto' dado que esto llevar% a =P<.= a creer que de&e leer multitud de 4ic*eros en el momento del ensam&lado' cosa que no corresponde a los 4ic*eros 4uente 2esto se conci&i para los 4ic*eros o&jeto en los que no estamos mu# interesados5" Vamos a colocar nuestros su&programas en un 4ic*ero separado" Por convencin nom&raremos el 4ic*ero con el su4ijo /"inc0" Por ejemplo' imagin-monos /mesroutines"inc0" ,+isten dos 4ormas de incluir contenido &ajo la 4orma 4uente en nuestro programa principal" omencemos por la m%s evidente"

19.2 Utilizacin directa de rutinas en el fichero


reamos un 4ic*ero /mesroutines"inc0 en el que ponemos /a lo &estia0 nuestros su& programas &ajo 4ormato de cdigo 4uente" Por ejemplo' imaginemos que deseamos utilizar dos su&rutinasK /ajoute16&its0 # /sous$ trait16&its0" ,scri&iremos en el cdigo 4uente simplemente el contenido de nuestras dos su&rutinasK
ajoute16bits Instruccin Instruccin Instruccin Instruccin return

1 2 3 n

soustrait16bits instruccin 1 instruccin 2 instruccin 3 instruccin n return

N as( para cada su&rutina que queramos incluir" J&serve que este 4ic*ero no contendr% ni directiva J6Y ni de$ claracin de varia&les tipo P8J U" Hn 4ic*ero a incluir no es un 4ic*ero autnomo' e inversamente' no incluimos un 4ic*ero autnomo del tipo asm en otro 4ic*ero asm' pues *a&r(a una imposi&ilidad de ensam&laje de&ido a la presencia de multitud de datos contradictorios en las mismas direcciones" 1os *ace 4alta a*ora incluir este cdigo en nuestro 4ic*ero 4uente principal 2nuestro 4ic*ero /asm05" ,sto se *ace insertando en la 4uente la l(neaK
#include <mesroutines.inc>

1;6

=P<.= reemplazar% nuestra l(nea hinclude por todo el contenido del 4ic*ero /"inc0" ,s una simple operacin de copiaRpega *ec*a autom%ticamente por =P<.=' no *a# ninguna inteligencia dentro" <tencin a la trampaK de&er% insertar la l(nea /hinclude0 no en el comienzo del 4ic*ero sino en la posicin e+acta donde de&er% ser copiadaRpegada la in4ormacin" ,sto por ejemplo' nos dar(a errorK
#include <mesroutines.inc> ORG 0x00 Instruccin 1 Instruccin 2 ; ; ; ; el cdigo se inserta en 0x00 lo que sigue ocupar la posicin 0x00 instruccin en 0x00 posicin ya ocupada instruccin en 0x01 posicin ya ocupada

EPor qu-F .implemente porque el contenido de /mesroutines"inc0 va a ser copiado delante de la directiva J6Y' # por de4ecto a partir de la direccin B+BB 2si no precisamos nada' este es el caso5' por lo que en la di$ reccin B+BB tendremos la primera instruccin de /ajoute16&its0 # la instruccin 1 del programa principal" =P<.= no puede' evidentemente' colocar dos instrucciones en el mismo sitio por lo que dar% un error de so&re escritura 2over3riting5 para las direcciones B+BB # siguientes" =e podr(a decirK si' pero #o *e escrito hinclude ^p16:;4"inc_ delante de la directiva J6Y B+BB # no *e tenido ningDn error" ,s del todo lgico puesto que su 4ic*ero /p16:;4"inc0 solo contiene de4iniciones' ninguna ins$ truccin" ,ste 4ic*ero no a)ade ningDn cdigo' por lo que no escri&e nada en la direccin B+BB" >ar% 4alta colocar la directiva include en el lugar correcto como por ejemploK
ORG 0x00 Goto main ORG 0x04 Interrupciones Main Instruccin 1 Call ajoute16bits #include <mesroutines.inc> Continuacin del programa ; el cdigo se inserta en 0x00 ; instruccin en 0x00 , correcto ; vector de interrupcin ; tratamiento de las interrupciones ; arranque real del programa despus del salto ; llamada a la subrutina , ejemplo ; el cdigo se inserta aqu ; continuacin eventual del programa

1;7

?e esta 4orma' sus rutinas se encontrar%n despu-s del programa principal # no *a# ninguna imposi&ilidad pa$ ra =P<.= de escri&ir el cdigo" =P<.= va simplemente a proceder a un copiaRpega impl(cito # ensam&lar% el siguiente cdigoK
ORG 0x00 Goto main ORG 0x04 Interrupciones main Instruccin 1 Call ajoute16bits ajoute16bits instruccin instruccin instruccin instruccin return ; el cdigo se inserta en 0x00 ; instruccin en 0x00 , correcto ; vector de interrupcin ; tratamiento de las interrupciones ; arranque real del programa despus del salto ; llamada a la subrutina , ejemplo

1 2 3 n

soustrait16bits instruccin 1 instruccin 2 instruccin 3 instruccin n return Continuacin del programa ; continuacin eventual del programa

Gueda el pro&lema de las varia&les" .i declaramos un &loque / P8J U0 en nuestro 4ic*ero de rutinas' vamos de nuevo a encontrarnos con una imposi&ilidadK dos &loques relativos a la misma direccin con contenidos di$ 4erentes" 9enemos dos 4ormas de procederK ?eclaramos dos &loques di4erentes" Hno en el programa principal 2 P8J U B+BB5 # otro en el 4ic*ero de rutinas 2 P8J U +5" ,sto presenta graves inconvenientes' puesto que podemos perder espacio en el programa principal' impedir la utilizacin de varia&les locales incluidas en las rutinas o impedir in$ cluir dos 4ic*eros di4erentes de rutinas" No le desaconsejo este m-todo" Htilizar varia&les no declaradas en las rutinas" ?espu-s del ensam&laje' =P<.= le indicar% cuales son las varia&les que 4altan # usted las podr% declarar en el P8J U del programa principal" ,s el m-todo que #o le aconsejo si adopta la 4orma de proceder que estamos descri&iendo 2ver% que las *a# mejo$ res5"

Prevemente' sus varia&les ser%n utilizadas en sus rutinas pero declaradas en la zona P8J U del programa principal" ,l 4ic*ero de rutinas contendr% l(neas del tipoK
movf variable1 , w

N varia&le1 de&er% ser declarada en el programa principal 24ic*ero "asm5 so pena de o&tener un error indican$ do que /varia&le1 no e+iste0"

1;;

8a ventaja de este m-todo consiste en incluir las rutinas tal como son siendo 4%cil de realizar' sin ninguna complicacin particular" ,s un m-todo que utilizo en casos particulares' por ejemplo' cuando una serie de 4i$ c*eros /"asm0 de un mismo pro#ecto 2ver pro#ecto ?omocan5 comparten las mismas rutinas a incluir 2&oo$ tloader comDn' estructura de programa comDn' etc"5" ,n un caso m%s general' este m-todo presenta una serie de inconvenientes ma#oresK ?espu-s de crear el 4ic*ero de su&rutinas' todo el contenido de este 4ic*ero es copiado en el 4ic*ero asm # ensam&lado" Por consiguiente' se colocar% en la memoria de programa todo el contenido del 4ic*ero /"inc0 incluso si no tiene necesidad de alguna de las su&rutinas" aso t(picoK tiene realizada una li&rer(a de rutinas matem%ticas conteniendo suma' resta' multiplicacin' divisin' etc" N en su programa solo necesita suma" Perder% parte del espacio de memoria de programa" ,st% o&ligado a declarar en el 4ic*ero /asm0 todas las varia&les citadas en el 4ic*ero /inc0 aunque al$ gunas de ellas no se utilicen por ser utilizadas por rutinas que no se van a usar" P-rdida de memoria 6<=" ,st% o&ligado a conocer todos los nom&res de las varia&les del 4ic*ero /inc0 # de utilizar los mismos nom&res en el programa principal" .i inclu#e dos 4ic*eros /inc0 con nom&res de etiquetas id-nticos' o&tendr% un error de ensam&laje 2imposi&le de resolver por =P<.=5" .i inclu#e dos 4ic*eros /inc0 con nom&res de varia&les id-nticas tiene el riesgo de producir &ugs en el programa principal' las mismas varia&les utilizadas por rutinas di4erentes sin que usted se d- cuenta 4orzosamente"

19.3 Encapsulacin de macros simples


,+iste un m-todo m%s sutil para crear el 4ic*ero /"inc0' es encapsular todas las su&rutinas en macros' como aqu(K
m_ajoute16bits instruccin instruccin instruccin instruccin return endm macro 1 2 3 n ; fin de macro macro ; encapsular en una macro ; encapsular en una macro

m_soustrait16bits instruccin 1 instruccin 2 instruccin 3 instruccin n return endm

; fin de macro

Partiendo de esto' lo ponemos en el comienzo del 4ic*ero /"asm0 con la 4inalidad de incluir en el 4ic*ero los macros conteniendo los su& programas al comienzo del programa principal 2con las otras directivas hinclude5 por ejemploK
#include <mesroutines.inc> ; aadimos las declaraciones de las macros ORG 0x00 ; el cdigo se inserta en 0x00 instruccin 1 ; instruccin en 0x00 , an no utilizada ; posicin correcta instruccin 2

1;Q

,sta vez ningDn error dado que una macro no se trans4orma en cdigo *asta que no se utiliza aunque sea de$ clarada" Por el momento nuestro cdigo /"asm0 no contiene ningDn cdigo contenido en el 4ic*ero /"inc0' esta es la argucia' simplemente le *emos dic*o que es lo que tiene que *acer si se encontrase el nom&re de uno de esos macros en el 4ic*ero 4uente" <*ora simplemente tendremos que poner una etiqueta de llamada seguida de la llamada a la macro' para co$ locar el cdigo de la macro en el sitio que queramos que est-" Imaginemos que solo necesitamos la suma' # no la resta' nuestro 4ic*ero 4uente quedar% de la siguiente maneraK
#include <mesroutines.inc> ; aadimos las declaraciones de las macros ORG 0x00 ; el cdigo se inserta en 0x00 Goto main ; instruccin en 0x00 , correcto ORG 0x04 Interrupciones main Instruccin 1 Call ajoute16bits ajoute16bits m_ajoute16bits ; vector de interrupcin ; tratamiento de las interrupciones ; arranque real del programa despus del salto ; llamada a la subrutina , ejemplo

; etiqueta = nombre del subprograma ; que contiene el cdigo de la macro

Ven"$2$s Incluimos el 4ic*ero de las macros al comienzo del programa' no importa si vamos a utilizar los su&$ programas o no" 1o declaramos m%s que las varia&les que vamos a utilizar realmente" .olo el cdigo necesario estar% presente cuando el 4ic*ero quede 4inalmente ensam&lado" 9odas las etiquetas pueden ser declaradas locales en las macros por lo que no *a# ningDn riesgo de duplicidad de etiquetas"

In(*nvenien"es ?e&er% conocer siempre el nom&re de las varia&les utilizadas en las macro a partir del 4ic*ero /asm0" .i inclu#e dos macros que utilizan los mismos nom&res de varia&les se arriesgar% a tener errores co$ mo en el primer m-todo

Pero e+iste un m-todo de evitar estos Dltimos o&st%culosK

19.4 Mtodo final


8os Dnicos inconvenientes que nos quedan est%n relacionados con las varia&les" ,+iste por lo tanto un m-todo para resolverloK utilizar macros con par%metros" 1os &astar% con modi4icar las macros inclu#endo el nom&re de las varia&les como par%metros' como a conti$ nuacinK
m_ajoute16bits macro var1,var2,result movf var1 , w addwf var2 , w movwf return endm result ; fin de macro ; macro con parmetros ; parmetros = nombre variables

1QB

,n nuestro 4ic*ero /"asm0 utilizaremos nuestra macro precisando el nom&re que *emos decidido dar a nues$ tras varia&les en el P8J U del programa principal" Imaginemos que decidimos declarar /operando10 # /operando20 a nuestras dos varia&les # a)adir /miresul$ tado0 como resultado' nos &astar% escri&ir en nuestro 4ic*ero 4uenteK
#include <mesroutines.inc> ; aadimos las declaraciones de las macros ORG 0x00 ; el cdigo se inserta en 0x00 Goto main ; instruccin en 0x00 , correcto ORG 0x04 Interrupciones main Instruccin 1 Call ajoute16bits ; vector de interrupcin ; tratamiento de las interrupciones ; arranque real del programa despus del salto ; llamada a la subrutina , ejemplo

ajoute16bits ; etiqueta = nombre del subprograma m_ajoute16bits operando1,operando2,miresultado ; macro con parmetros

Ven"$2$s 9odas las ventajas del m-todo precedente" 1o necesitamos conocer el nom&re de las varia&les' utilizamos nuestras propias varia&les' estas varia&les pueden ser locales 2reutilizadas para otras macros5" In(*nvenien"es 1inguno"

19.5 Conclusin
on estos m-todos dispone de la manera de crear sus propias li&rer(as de rutinas en cdigo 4uente' 4%cilmen$ te recupera&les # sin generar cdigo inDtil en el 4ic*ero ensam&lado" .eria idiota no aprovec*arse de ello' so$ &re todo si no le gusta muc*o lo de copiarRpegar' como a m("

1Q1

20. La norma ISO 7816


,l o&jetivo de este cap(tulo es mostrarle como realizar una aplicacin pr%ctica so&repasando los l(mites apa$ rentes del PI " >e elegido crear un esquema de programa de gestin de una tarjeta I.J7;16' pues es un tema de actualidad en el momento de la creacin de la primera versin del curso' so&re todo en lo que concierne a la decodi4icacin de emisiones de 9V por sat-lite" 9enga en cuenta que la decodi4icacin /para uso privado en un entorno no comercial0 2es lo que dice la le#5 es per4ectamente legal en P-lgica" ,n :rancia la legislacin *a evolucionado des4avora&lemente para las li&erta$ des individuales' desgraciadamente es tendencia" < d(a de *o#' pienso que es ilegal' en este pa(s' decodi4icar en el *ogar aDn para uso propio las ondas que nos &om&ardean a los ciudadanos sin nuestro consentimiento" ,n cualquier caso' es un e+celente prete+to para mostrar que es posi&le utilizar un 16:;4' desprovisto de la gestin serie' para comunicar de esta manera con el e+terior" ,sta parte se limitara a la norma en general' sin entrar en una aplicacin espec(4ica de la norma" ,l o&jetivo no es construir una aplicacin 2por ejemplo' una cerradura codi4icada5' sino m%s &ien como conce&irla por usted mismo" ?iscurso /pol(tico0K le recuerdo que esta norma es utilizada para las tarjetas de decodi4icacin sat-lite o 919' para las tarjetas de identidad' las tarjetas &ancarias # muc*as otras aplicaciones" .I el proveedor de la tarjeta lo desea' es mu# 4%cil crear tarjetas inviola&les" ,l *ec*o de sa&er cmo 4unciona una tarjeta o tener el cdigo 4uente' no es una condicin su4iciente para tener acceso a la in4ormacin codi4icada en su interior" ,sto le e+$ plica que si las tarjetas /piratas0 para sat-lites *an podido e+istir' es Dnicamente porque los proveedores de esas cadenas encriptadas lo *an querido as(' # son los mismos que llora&an por la p-rdida de ganancias" J&$ serve que esas tarjetas piratas #a no e+isten' nos quedaremos por lo tanto en la norma I.J 7;16" 8as tarjetas &ancarias &elgas no *an podido ser pirateadas jam%s' # si' &ajo ciertas circunstancias' las 4rancesas lo *an si$ do' es de&ido a la crasa negligencia de los &anqueros 4ranceses' per4ectamente enterados desde el principio de esta posi&ilidad' inducida por la utilizacin de una longitud de llave insu4iciente" Pero el ro&o *ace marc*ar la econom(a' lo que reporta dinero al estado" :in de la parte /pol(tica0"

20.1 Especificaciones tiles de la norma ISO 7816


Prevemente' veamos al principio algunas especi4icaciones Dtiles de la 4amosa norma 7;16' &ase de nuestra aplicacin 4icticia" ,ncontrar% estas tarjetas por cualquier lado en los comercios de componentes electrnicos' &ajo la denominacin /tarjeta para cerradura codi4icada0" Permiten realizar montones de aplicaciones' # los lectores est%n disponi&les por doquier" 1ecesitar% para comunicar con estas tarjetas un inter4ace cu#o es$ quema puede encontrar en internet &ajo la denominacin /P*oeni+0' # un logicial de comunicacin suminis$ trado con el inter4ace" 8as especi4icaciones son las siguientesK 8a tarjeta nos dispone de su propio reloj" ,ste es suministrado por el inter4ace o maestro' # general$ mente so&re el entono de los 4 =>z" iertas tarjetas modernas so&repasan este l(mite" ,l tiempo de separacin de cada &it est% de4inido por la norma como 1 &it emitido cada 372 impulsos del reloj maestro" ,sto nos da una velocidad del orden de Q6BB &audios con una 4recuencia de reloj de 3'57 =>z 2357BBBBR3725' o 1B752 &audios con un reloj de 4 =>z" ,sto le e+plica por qu- en muc*as tarjetas encontrara un reloj de 3'57 =>z que permite tra&ajar a una velocidad /est%ndar0 de Q6BB &audios" 8a transmisin es del tipo as(ncrono' con 1 &it de arranque' ; &its de datos' 1 &it de paridad par # 2 &its de parada" 8a comunicacin es del tipo /*al4$duple+0' es decir' la emisin # recepcin se e4ectDa por alternancia so&re la misma l(nea 4(sica de transmisin" 1Q2

20.1.1 Los comandos ISO 7816


,n este ejercicio vamos a utilizar los comandos /&idn0 de la norma I.J 7;16" >ace 4alta sa&er que nuestra tarjeta de&er% responder a los comandos organizados segDn el protocolo est%ndar de esta norma" 6eglaK la tarjeta no toma jam%s la iniciativa del intercam&io de in4ormacin" .olo responde a los comandos de la 4ormaK CLASE J en 4orma a&reviadaK CLASS INS P1 PJ LEN INSTRUCCIXN PARAMETRO1 PARAMETROJ LONBITUD

Veamos el signi4icado de cada uno de los octetos del comando reci&idoK CLASSK determina el grupo de instrucciones concernidas" .i el nDmero de instrucciones utilizadas no es eleva$ do' nadie nos impide utilizar solo una clase" ,s lo que *aremos en este ejercicio simpli4icado" INSK es la instruccin propiamente dic*a' o mejor' el comando" ,s este octeto el que determina la operacin a e4ectuar por la tarjeta en la clase precisada" P1 # PJK son dos par%metros que la tarjeta reci&e con el comando" .u signi4icado depende del comando en$ viado" Pueden ser no utiliza&les pero en cualquier caso *an de estar presentes" ,n general' si no se utilizan su valor se pone como B 2no es o&ligatorio5" LENK puede representar 2 cosas" ,l nDmero de octetos que componen el comando' en este caso la tarjeta se esperar% a reci&ir 8,1 octetos suplementarios antes de tratar el comando en su totalidad" J &ien' la longitud de la cadena de respuesta que el maestro espera reci&ir proveniente de la tarjeta" ,s la instruccin quien es$ ta&lece el rol de 8,1" <dvierta que e+isten modos e+tendidos por la norma I.J7;16 que permiten a la vez enviar # reci&ir muc*os octetos a la vez" ,ste modo est% de4inido como modo 9L1" ,n nuestro caso' consideraremos que la in4orma$ cin circula solo en un sentido a la vez dada una instruccin 2=odo 9LB5' como *ac(an las tarjetas de sat-lite de la -poca"

20.1.2 El protocolo de intercambio de informacin


Veamos cmo se desarrolla un intercam&io est%ndar de in4ormacin entre el maestro # la tarjeta I.J7;16" < la puesta en servicio' el maestro genera un RESET so&re el pin MCLR 2de la tarjeta5" 8a tarjeta res$ ponde con un cierto nDmero de octetos" ,sta respuesta se llama ATR' por Ans3er To Reset 2respuesta al reset5" ,l maestro env(a el comando lass I1. P1 P2 8,1 8a tarjeta reenv(a la instruccin como acuse de recepcin I1. ,l maestro env(a eventualmente los datos complementarios 8a tarjeta env(a eventualmente la respuesta 8a tarjeta env(a el status # pasa a modo de espera de comandos

1Q3

Por lo tanto' si consider%ramos la instruccin imaginaria B+14 de la clase B+?5 que necesitase una respuesta por parte de la tarjeta 2instruccin tarjeta$maestro5" ,l maestro precisa P1 L B+B1 # P2 L B+B2" 9endr(amos 2imagin%ndonos los octetos de dato5K ,l maestro env(a D? 14 41 4J 14 ?educimos que el maestro espera 16 octetos en recepcin 2B+1B L ?O16O5 8a tarjeta responde 14 2acuse de recepcin L instruccin reci&ida5 8a tarjeta env(a 41 4J 43 44 4? 46 4+ 48 4; 4A 4> 4C 4D 4E 4F 2por ejemplo5' es decir 16 octetos de respuesta' e+cluidos el acuse de recepcin # el estatus" 8a tarjeta env(a ;4 44 2estatus empleado en general para indicar /la operacin se *a realizado con -+i$ to05" ,l estatus puede in4ormar de un cierto nDmero de cdigos de error' propios de la tarjeta' del tipo /instruccin desconocida0' o /tarjeta con con4iguracin incorrecta0' etc"

< remarcar de pasada que ciertas tarjetas recurren a menudo a comandos designados como /4irmados0" .i la in4ormacin no est% encriptada con una llave registrada en la tarjeta 2oculta al usuario5 se o&tiene un error en el retorno" Por el contrario' si en las mismas condiciones' nos imaginamos una instruccin B+15 acompa)ada de octetos con destino a la tarjeta 2instruccin maestro$tarjeta5' tendr(amosK ,l maestro env(a D? 1? 41 4J 14 8a tarjeta responde 1? 2acuse de recepcin5 ,l maestro env(a 41 4J 43 44 4? 46 4+ 48 4; 4A 4> 4C 4D 4E 4F 2por ejemplo5" 8a tarjeta responde ;4 44

omo ve solo el sentido de circulacin de los 16 octetos de datos cam&ia # es la instruccin la que determi$ nar% cu%l es ese sentido" ,s siempre el maestro quien env(a la trama de partida # la tarjeta 2esclavo5 quien en$ v(a el acuse de reci&o # el estatus"

20.2 Las conexiones serie asncronas


,l intercam&io de in4ormacin entre el maestro # el esclavo se *acen a trav-s de una cone+in serie as(ncro$ na" Para entender lo que viene a continuacin en el capitulo' *ace 4alta entender que es lo que signi4ica esto" ,l modo serie est% caracterizado por que todos los &its de un octeto van a ser enviados en una serie' es decir' uno detr%s de otro" ,sto es por oposicin al modo paralelo en el que los &its son enviados todos al mismo tiempo' por lo que se necesitar(a un conductor el-ctrico por &it 2al menos5" <s(ncrono es lo opuesto de s(ncrono' es decir' que se trata de una cone+in que no provee un reloj destinado a indicar el principio # el 4inal de cada &it enviado" 9endremos necesidad de tener un mecanismo destinado a indicar la posicin de cada &it" J&serve que se tra$ ta en nuestro caso' de un modo as(ncrono un tanto particular' puesto que la tarjeta utiliza el mismo reloj que el maestro" 8a velocidad no ser%' e+cepcionalmente' dada en &audios sino en nDmero de impulsos de reloj" Hn &it cada 372 impulsos de reloj" ?ic*o de otra 4orma' aunque la comunicacin es as(ncrona' los intercam$ &ios en realidad est%n sincronizados por la utilizacin de un reloj comDn" ,s un tanto particular" Para reci&ir correctamente los &its enviados *ace 4alta convenir un protocolo de comunicacin" ,ste Dltimo de&e comprender las in4ormaciones siguientesK 8a velocidad de transmisin en &audios" ,l 4ormato' es decir' el nDmero de &its de arranque' el nDmero de &its de parada' el nDmero de &its de datos # el tipo de paridad" 1Q4

Vamos a*ora a e+plicar estos conceptos e indicar cu%les son sus valores en la norma I.J7;16"

20.2.1 El bit de arranque


,n reposo' la l(nea se encuentra en estado alto" ,l emisor a*ora' pasa la l(nea a estado &ajoK es el &it de arran$ que o start$&it" ,s este cam&io el que va a permitir detectar el comienzo de la recepcin de &its" 8os valores posi&les son 1 2 start$&it2s5" 8a norma I.J7;16 necesita solo 1 start$&it"

20.2.2 Los bits de datos


?espu-s de *a&er reci&ido el start$&it' se encuentran los &its de datos' comenzando por el &it B" 8as normas usuales utilizan 7 u ; &its de datos" Para la norma I.J7;16 tendremos ; &its de datos' lo que nos da valores admisi&les desde B+BB a B+:: para cada octeto reci&ido"

20.2.3 El bit de paridad


,l &it de paridad es una veri4icacin de que todo se *a desarrollado correctamente en la trans4erencia" ?es$ pu-s de una emisin' conta&ilizamos cada &it del env(o que val(a 1" <l 4inal de la cuenta a)adimos un &it a 1 o a B de manera que tengamos un nDmero par o impar de &its" ?iremos que utilizamos una paridad par si el nDmero de &its a 1' incluido el &it de paridad' es un nDmero par" ?e la misma 4orma' paridad impar dar(a un nDmero impar de &its a 1" J&serve que el &it de paridad no es indispensa&le en una transmisin as(ncrona" 9enemos entonces 3 posi&i$ lidades' par' impar o ninguna" ,n la norma I.J7;16 de&eremos utilizar paridad par"

20.2.4 El stop-bit
?espu-s de la recepcin de los &its precedentes' es imperativo poner la l(nea en estado alto para poder de$ tectar el start$&it del octeto siguiente" ,ste es el rol del stop$&it" 8os valores admisi&les son 1 2 stop$&its" ,n la norma I.J7;16 utilizaremos 2 stop$&its' simplemente un stop$&it con una duracin de 2 &its 2la l(nea no su4re cam&ios entre los dos stop$&its5"

20.2.5 Velocidad y tasa de envo


8a duracin de cada &it es una constante # depende de la velocidad de transmisin" Por ejemplo' para una ve$ locidad de Q6BB &audios' es decir Q6BB &its por segundo' cada &it durar% 1 s R Q6BB L 1B4'17 ns" ,l tiempo necesario para reci&ir un octeto completo es la suma del tiempo necesario para reci&ir cada uno de los &its del octeto" ,n el caso de la norma I.J7;16 utilizaremos 1 start$&it M ; &its de datos M 1 &it de paridad M 2 stop$&its L 12 &its" ,l tiempo total para reci&ir un octeto ser% de 125B ns" 8a tasa m%+ima en octetos por segundo ser% pues igual aK 9asa m%+ima L 1 R 2numero de &its I duracin de un &it5' que para la norma I.J7;16 ser%K 1 W 1J?4Y14 6 844 *("e"*s #*% se1'n)*/
06

1Q5

,sto para una velocidad de Q6BB &audios" ,ste valor no est% impuesto por la norma' por lo que podemos au$ mentar la tasa aumentando la velocidad" >a&lamos aqu( de tasa m%+ima puesto que estamos considerando que un octeto comienza al 4inal del prece$ dente' lo que no es o&ligatorio para una cone+in as(ncrona"

20.3 Adquisicin de bits


Vamos a representar o que aca&amos de decir en una 4orma gra4ica" ,n el eje vertical tendremos los niveles # en el *orizontal el tiempo"

,+aminemos esta gra4ica" 8a l(nea est% alta durante un tiempo indeterminado" 8lega el start$&it que comienza despu-s de un tiempo inde4inido" Vemos que el mejor momento para leer el &it B es a la mitad de su duracin con el 4in de tener el menor riesgo de error de timing posi&le" 6ecuerde que para la norma I.J7;16 la anc*ura de un &it es de 372 impulsos de reloj" omo nuestro PI divi$ de la 4recuencia del reloj por 4 para o&tener su 4recuencia de ciclos de instruccin' esto nos dar% una anc*ura de &it equivalente a 372 R 4 L Q3 ciclos de instruccin" ,l &it B ser% le(do a Q3 M 46 ciclos de instruccin despu-s del comienzo del start$&it" < continuacin podremos leer todos los &its a intervalos de tiempo de Q3 ciclos de instruccin" Hna vez le(do el &it de paridad tenemos 2 posi&ilidadesK .i deseamos continuar esta lectura con la lectura de otro octeto' nos de&emos posicionar en alguna parte del interior de los 2 &its de parada para estar listos a leer el siguiente start$&it" ?e&eremos es$ perar entre B'5 # 2'5 &its" .i deseamos enviar un octeto despu-s de esta lectura' no podremos *acerlo antes del 4inal del segun$ do stop$&it' es decir' un m(nimo de 2'5 &its"

Por curiosidad E u%l es entonces el octeto que *emos reci&ido en este ejemploF .implementeK &BL1 &1LB &2LB &3L1 &4LB &5L1 &6LB &1L1 Paridad L B 1Q6

,l octeto reci&ido es PO1B1B1BB1O' es decir' B+<Q" <provec*emos para veri4icar la paridad" 1umero de &its a 1 reci&idos L 4' por lo tanto paridad par' es con4orme a la norma I.J7;16' se presume que el octeto se *a reci$ &ido correctamente"

20.4 Caractersticas de las tarjetas estndar


,n las tarjetas comerciales' de tipo /tarjeta para cerradura codi4icada0 con 16:;4' las cone+iones utilizadas son' generalmente' las siguientesK

20.5 Creacin e inicializacin del proyecto


.iguiendo nuestro m-todo *a&itual' copieRpegue el 4ic*ero /m164;4"asm0 # renm&relo como /iso7;16"asm0" ree el pro#ecto en =P8<P" < continuacin rellene el enca&ezado del programaK
;*************************************************************************** ; Este fichero es la base de partida para la gestin de una tarjeta * ; respondiendo a la norma ISO 7816 * ; * ;*************************************************************************** ; * ; NOMBRE: ISO7816 * ; Fecha: 10/03/2001 * ; Autor: Bigonoff * ; * ;*************************************************************************** ; * ; Fichero requerido: P16F84.inc * ; * ;*************************************************************************** ; * ; - MCLR Comando de reset de la tarjeta Entrada * ; - RB4 SDA dato para la eeprom externa Bidireccional * ; - RB5 SCL reloj para la eeprom externa Salida * ; - RB7 DATA datos modo serie Bidireccional * ; * ;***************************************************************************

1Q7

?e4inimos la con4iguracinK no vamos a utilizar el 3atc*$dog para esta aplicacin # utilizaremos un reloj e+$ terno" 9endremosK

LIST p=16F84 #include <p16F84.inc> radix dec

; definicin del procesador ; definicin de las constantes ; trabajar en decimal por defecto

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC ; ; ; ; Proteccin de cdigo OFF Timer reset en power on en servicio Watch-dog fuera de servicio Oscilador de cuarzo de alta velocidad

alculemos a*ora el valor a codi4icar en el registro JP9IJ1K ?e&emos utilizar' por razones de compati&ilidad electrnica' la resistencia de re4erencia aM5 V del pin 6P7" 9endremos &7 del registro JP9IJ1 L B" Vamos a tra&ajar con el timerB" omo la distancia entre 2 &its es de Q3 instrucciones' vamos a tra&ajar sin pre divisor' lo que nos lleva a redi$ rigir el pre divisor al 3atc*$dog" Por lo tanto el valor para el registro JP9IJ1 ser%K
OPTIONVAL EQU 0x08 ; Valor del registro OPTION ; Resistencia Pull-up ON ; Pre divisor timer a 1

20.6 La base de tiempos


Vemos que vamos a necesitar 2 temporizacionesK una de Q3 instrucciones # otra de Q3M46 instrucciones' co$ rrespondientes a 1 # 1'5 &its" Vamos a construir la su&rutina"
;*************************************************************************** ; TEMPORIZACION * ; * ;*************************************************************************** ;--------------------------------------------------------------------------; temp_1bd : inicializa tmr0 para que la temporizacin se igual al ; equivalente de un bit y medio,es decir, 46 + 93 incrementos ; de tmr0 el tiempo necesario para llegar a la rutina ; temp_1b : espera que la diferencia entre la tempo precedente y la tempo ; actual sea de 1 bit, es decir 93 instrucciones ;--------------------------------------------------------------------------temp_1bd movlw -38 ; teniendo en cuenta 2 ciclos de parada de tmr0 movwf TMR0 ; inicializar tmr0 call temp_suite ; y esperar bit temp_1b movlw addwf temp_suite bcf temp_wait btfss goto return

-91 TMR0 , f

; diferencia entre 2 bits + 2 ciclos de parada ; aadir al valor actual

INTCON , T0IF

; borrar flag

INTCON , T0IF temp_wait

; espera desbordamiento ; no finalizado , esperar ; y salir

1Q;

E mo 4unciona esta rutinaF J&serve que tenemos 2 puntos de entrada' tempd1&d # tempd1&" omencemos por e+aminar el Dltimo punto" omenzamos por cargar la duracin correspondiente a Q1 instrucciones antes del des&ordamiento del timer' es decir B$Q1' o m%s simplemente' $Q1" 1o conviene olvidarse que un cierto nDmero de instrucciones *an sido #a ejecutadas despu-s del Dltimo paso por la rutina' despu-s a la emisin o recepcin del &it precedente 2# que perdemos 2 incrementos del timer por el *ec*o de su modi4icacin5" E u%l es el nDmero de instruccionesF .implemente el nDmero contenido en 9=6B' puesto que el Dltimo paso *a&(a esperado la puesta a B" 1o *a# que colocar $Q1 en tmrB' sino m%s &ien' a)adir $Q1 al contenido de 9=6B" ?e esta manera estaremos seguros que el des&orde de 9=6B se *ar% e+actamente Q3 ciclos despu-s del des$ &orde precedente' sea cual sea el nDmero de instrucciones ejecutadas entre las dos llamadas" Pien entendido' a condicin que el timer no se des&orde antes' pero esto implicar(a que no *emos tenido el tiempo necesario para ejecutar todo lo necesario entre 2 &its' por lo que' o el PI no es su4icientemente r%pido o el cdigo no est% su4icientemente optimizado en tiempo de ejecucin" < continuacin ponemos el 4lag 9BI: a B # esperamos a que el des&ordamiento del timer lo ponga a 1" ,+aminemos el punto de entrada tempd1&d" omenzamos por inicializar 9=6B con $3; para arrancar la tem$ porizacin de 4B instrucciones a partir de este punto" omo es al comienzo de la adquisicin cuando necesitamos un medio &it' no *a *a&ido un &it precedente por lo que de&emos colocar este valor # no realizar una suma" ,s m%s' entre la deteccin del start$&it # la iniciali$ zacin de 9=6B' *an pasado algunas instrucciones" Podemos considerar groso modo que *an pasado 6 ins$ trucciones' lo que nos da un valor a cargar de e246$65L$4B' # teniendo en cuenta los 2 ciclos perdidosK $3;" E u%l es en realidad el error permitidoF .implemente la mitad de la duracin de un &it' es decir 46 ciclos' con el 4in de no caer en el &it vecino" 1o estamos a 1 ciclo de distancia' pero *ace 4alta ser lo m%s preciso posi&le para el caso en el que una deriva de un aparato conectado no nos aumente nuestra imprecisin" >a# que pensar que el programador del logicial del maestro se *a podido servir de esta tolerancia tam&i-n" < continuacin llamamos a la su&rutina misma para esperar la duracin prevista' despu-s la su&rutina contin$ Da ejecutando la espera de Q3 ciclos" >emos esperado pues Q3M4B ciclos mas el tiempo de llamada de la ruti$ na mas el tiempo de retorno mas el tiempo eventual perdido en el &ucle de espera del start$&it' es decir' una duracin apro+imada de 1'5 &its" <dem%s esta rutina no utiliza ninguna varia&le"

20.7 Recepcin de un octeto


<*ora que *a comprendido como reci&ir un octeto en modo serie as(ncrono' es el momento de escri&ir nues$ tro su& programa de recepcin de un octeto" ,n este ejercicio no veri4icaremos si el &it de paridad reci&ido es correcto" < usted le dejo el integrar este test si le interesa" ,n ese caso de&er% leer Q &its # veri4icar si el nDmero de 1 es par" >a# muc*os m-todos posi&les' el m%s simple es el de utilizar el &it reci&ido como apli$ cando un [J6 so&re el &it de paridad' as( a cada &it 1 reci&ido' el &it de paridad es invertido' solo queda com$ parar al 4inal con el &it reci&ido" 1uestro su& programa de&er% e4ectuar las siguientes operacionesK 1" 2" 3" 4" ,sperar el comienzo del start$&it ,spera Q3M46 instrucciones Para cada uno de los &its reci&idos' leer el &it # colocarlo en la posicin correcta Posicionarse en cualquier lugar de los stop$&its

1QQ

>e aqu( nuestro su& programaK


;*************************************************************************** ; Recepcin de un octeto procedente del maestro * ;*************************************************************************** ;--------------------------------------------------------------------------; Carcter ledo en W. La paridad no se verifica ;--------------------------------------------------------------------------Receive ; espera el comienzo del star-bit , ------------------------------btfsc goto SERIAL Receive ; test si start bit lleg

; se posiciona a mitad del primer bit util , ---------------------------------------call temp_1bd ; espera 1 bit y medio

; recepcin del caracter , ---------------------movlw 0x08 movwf cmptbts Recloop bcf btfsc bsf rrf call decfsz goto ; para 8 bits ; en contador de bits

STATUS , C SERIAL STATUS , C caract , f temp_1b cmptbts , f Recloop

; ; ; ; ; ; ;

Carry = 0 test si bit = 0 carry = bit recibido entrar el bit por la izquierda esperar hasta mitad bit siguiente decrementar contador de bits NO es el ultimo , siguiente

; ahora apuntamos en el centro del bit de paridad ; queda pues espera +- 1,5 bits para estar en el segundo stop-bit ;--------------------------------------------------------------------------call movf return temp_1bd caract , w ; esperar 1,5 bits ; carga el carcter ledo ; volver

,ste su& programa no entra)a ninguna di4icultad particular" J&serve que' m%s que posicionar el &it reci&ido en la posicin correcta' lo *acemos entrar en el &7 sirvi-ndose de la instruccin /rr40" ,l &it precedente es empujado a la posicin &6 # as( sucesivamente" <l 4inal' el primer &it le(do estar% en la posicin &B # el Dltimo en la posicin &7' que es lo que &usc%&amos" on respecto a la Dltima temporizacin' en ese momento apuntamos al centro del QS &it' es decir' el de pari$ dad" omo no lo tratamos' no lo leemos" ?e&emos entonces posicionarnos en un entorno en el que la l(nea este a nivel /10' es decir' en uno de los stop$&its' con el 4in de comenzar a esperar un eventual nuevo carac$ ter" ?e&emos esperar entre B'5 # 2'5 &its" 8a su&rutina de 1'5 &its est% en esa zona de lleno # la podemos utilizar directamente" ,l su& programa utiliza varia&les que declararemos m%s adelante"

2BB

20.8 La emisin de un carcter


1o olvidemos que nuestra tarjeta no emite m%s que a requerimiento de un /maestro0" 1uestro programa de emisin ser% llamado despu-s del su&programa de recepcin de un octeto" ,s importante que nos acordemos que tra&ajamos en modo *al4$duple+' es decir' que la misma l(nea sirve pa$ ra entradas # para salidas" omo cada uno de los interlocutores *a&la por turno' *ace 4alta dejarle a cada uno el tiempo necesario para pasar de la lectura despu-s de un env(o" ,sto se llama /tiempo de retorno0" 9am&i-n nos tenemos que acordar que nuestra rutina de recepcin se encontrar% en alguna parte a la mitad de los stop$&its' por lo que *a# que dejar al emisor que aca&e de enviar los stop$&its" Hn &uen compromiso # la 4acilidad de escritura nos permiten elegir una espera de 1'5 &its antes de comenzar a emitir" >e elegido este valor pues esta temporizacin permite inicializar el timer" ,ste valor no es' de todas 4ormas' critico" >ace 4alta' simplemente' responder despu-s de que el maestro se ponga en modo recepcin # antes de que -l considere que la tarjeta no *a respondido" 1uestro programa va a e4ectuar las siguientes operacionesK 1" 2" 3" 4" 5" 6" ,sperar el tiempo escogido antes de la emisin Pasar a emisin # enviar el start$&it ,nviar los ; &its comenzando por &B Para cada /10 enviado invertir la paridad para o&tener una paridad par ,nviar los 2 stop$&its Pasar a recepcin

2B1

;*************************************************************************** ; Envio de un octeto hacia el lector de tarjeta * ;*************************************************************************** ;--------------------------------------------------------------------------; Envio del carcter contenido en W ;--------------------------------------------------------------------------Send movwf caract ; salva el carcter a enviar call temp_1bd ; espera 1 bit y medio BANK1 ; pasa al banco 1 bcf SERIAL ; puerto serie en salida BANK0 ; pasa al banco 0 ; enviar start-bit , ---------------bcf clrf call SERIAL parite temp_1b ; enviar 0 , start-bit ; borrar bit de paridad ; espera entre 2 bits

; enviar 8 bits de dato , --------------------Send_loop rrf rrf xorwf xorwf andlw xorwf call decfsz goto

caract , f caract , w parite , f PORTB , w 0x80 PORTB , f temp_1b cmptbts , f Sen_loop ; enviar paridad , --------------

; decalar , b0 en Carry ; carry en b7 de W ; posicionar paridad ;guardar 1 si cambio en SERIAL ; solo modificamos RB7 ; si Si invertir RB7 ; espera entre dos bits ; decrementa contador de bits ; no es el ultimo , siguiente

movf xorwf andlw xorwf call

parite , w PORTB , w 0x80 PORTB , f temp_1b

; ; ; ; ;

cargar paridad par calculada Si serial diferente de bit a enviar modificamos solo RB7 entonces invertir RB7 espera entre dos bits

; enviar 2 stop-bit , ----------------BANK1 bsf BANK0 call call return ; ; ; ; ; ; pasa a banco 1 pasa a entrada (y nivel alto) pasa a banco 0 espera entre dos bits espera entre dos bits retorno

SERIAL temp_1b temp_1b

.i *a estado atento *a&r% visto una ligera inversin en lo que concierne al 4inal del protocolo" ,n vez de enviar un 1 2stop$&it5 # esperar 2 &its' pasamos a entrada # despu-s esperamos 2 &its" ,sto es estrictamente id-ntico de&ido a la resistencia pull$up que *a&(amos activado # que impone un valor alto 2M 5 V5 en 6P7 cuando este pin est% puesto en entrada' nivel que corresponde al stop$&it" 8a rutina que sirve para enviar los ; &its utiliza la instruccin /+or340 en lugar de c*equear si el &it a emitir va$ le 1 B" 8a rutina comienza por poner el &it a emitir en la posicin &7" 2B2

EPor qu- &7F .implemente porque es tam&i-n en &7 de PJ69P donde lo de&emos modi4icar" ,n e4ecto utili$ zamos 6P7" ,l procedimiento utilizado nos permite posicionar al mismo tiempo el &it de paridad" ,4ectDe la operacin a mano so&re papel para convencerse" Intente escri&ir una rutina utilizando /&t4ss0 # /&t4sc0 # compare los resultados" Hnas pala&ras acerca del env(o del &it propiamente dic*o' es decir las 3 instruccionesK
xorwf andlw xorwf PORTB , w 0x80 PORTB , f ; Si serial diferente de bit a enviar ; modificamos solo RB7 ; entonces invertir RB7

omenzamos por leer el PJ69P # e4ectuamos un /+orl30 con el &it a enviar contenido en el registro W" omo W solo contiene este &it' de 6PB a 6P6 no ser%n modi4icados por las siguientes operaciones" .i el &it contenido en W es di4erente del que presenta 6P7' o&tendremos &7L1 en W" ,n el caso que &7 de W sea igual a 6P7 o&tendremos un B" 1o olvidemos que el / '30 nos permite guardar el resultado en W" .i aplicamos W a PJ69P e4ectuando un /+or340 invertiremos 6P7 Dnicamente si &7 de W vale 1' con otras pa$ la&rasK invertiremos 6P7 Dnicamente si su nivel actual es di4erente del nivel que necesitamos enviar" ,sto parece un poco retorcido' pero si intenta escri&ir esta rutina de otra 4orma' ver% que' tras muc*os ensa$ #os' llegar% a un resultado al menos tan largo' a causa de la paridad a gestionar" ,+cepto si admite modi4icar las otras l(neas de PJ69P 2puede *acerlo si no se utilizan para nada5" < destacar que puede ignorar el &it de paridad en recepcin' es su pro&lema" Por el contrario' est% o&ligado a posicionarlo correctamente en modo emisin puesto que *a# muc*as pro&a&ilidades de que el maestro este teni-ndolo en cuenta"

20.9 Inicializacin
Vamos a*ora a estudiar el cuerpo de nuestro programa principal" omo todo programa que se respeta' co$ menzaremos por la inicializacin" Va a ser mu# simple' se va a limitar a inicializar el registro JP9IJ1"
;*************************************************************************** ; INICIALIZACION * ;*************************************************************************** org init BANK1 movlw movwf BANK0 0x00 ; direccin de inicio despus de reset ; ; ; ; pasar a banco 1 carga mascara inicializa registro OPTION pasar a banco 0

OPTIONVAL OPTION_REG

20.10 Envio del ATR


<96 signi4ica <ns3er 9o 6eset' es decir' respuesta a un reset" ,s un comando enviado por la tarjeta despu-s de una puesta en tensin o despu-s de un reset generado por el maestro v(a cone+in del /= 860" ?e entrada vamos a esperar un poco a que el maestro est- listo para reci&ir nuestro env(o de <96" Puede ser necesario ajustar este tiempo en 4uncin de las caracter(sticas del maestro' que tendr% otras cosas para *acer al arranque antes de ocuparse de vuestra tarjeta"

2B3

;*************************************************************************** ; PROGRAMA PRINCIPAL * ; * ;*************************************************************************** start ; comenzamos esperando un poco , ---------------------------call temp_1bd ; espera de 1,5 bits

?espu-s #a podemos enviar el <96" Por razones de 4acilidad' *emos escrito el <96 en la zona de la eeprom in$ terna" >e escogido un <96 de 5 caracteres que me *e inventado" onsulte las caracter(sticas del maestro para conocer los <96 validos en su aplicacin"
;=========================================================================== ; ENVIO DEL ATR = ;=========================================================================== ;--------------------------------------------------------------------------; Envio de un ATR ficticio: el ATR est en los 5 octetos de 0x04 a 0x00 ; de la eeprom interna. El ATR est escrito en sentido inverso ;--------------------------------------------------------------------------movlw movwf ATR_loop decf call call decfsz goto 0x05 cmpt1 cmpt1 , w Rd_eeprom Send cmpt1 , f ATR_loop ; para 5 octetos ; en el contador de bucles = direccin ; ; ; ; ; direccin a leer = contador de bucles-1 leer octeto eeprom interna enviar al maestro decrementar contador si no acabado , siguiente

Observaciones
8a utilizacin de la instruccin /dec4sz0 4acilita la escritura de los &ucles' pero' como el contador de &ucles es al mismo tiempo el o44set de la posicin en la eeprom' el <96 se escri&ir% a la inversa' es decir' del Dltimo al primer octeto" ,n el entorno de la llamada a la su&rutina /6ddeeprom0' el contador de &ucles var(a de 5 a 1" 1uestra direc$ cin variar% de 4 a B por lo que la operacin /dec40 permite cargar en W el valor del contador de &ucles$1" 8a su&rutina /6ddeeprom0 no es otra cosa que nuestra macro de lectura de memoria eeprom trans4ormada en su& programa' a sa&erK
;*************************************************************************** ; Lectura de un octeto en eeprom interna * ;*************************************************************************** ;--------------------------------------------------------------------------; Lectura un octeto en eeprom. La direccin se pasa en W. Octeto ledo en ;--------------------------------------------------------------------------Rd_eeprom movwf EEADR ; direccin a leer en EEADR bsf STATUS , RP0 ; pasa a banco 1 bsf EECON1 , RD ; lanza la lectura eeprom bcf STATUS , RP0 ; pasa a banco 0 movf Rd_eeprom ; leer octeto eeprom interna call EEDATA , w ; carga el valor en W return ; retorno

2B4

Pensemos tam&i-n en escri&ir nuestro <96 en la zona eepromK


;*************************************************************************** ; DECLARACIONES DE LA ZONA EEPROM * ;*************************************************************************** Org 0x2100 ; direccion de comienzo de la zona eeprom ATR DE DE DE DE DE 0x07 0xAB 0xBB 0x01 0xB7 ; respuesta al ATR ; B7 01 BB AB 07

20.11 El envo de status


8a norma I.J 7;16 pide que cada emisin de una respuesta de la tarjeta sea seguida de 2 octetos de status que indican la manera como *a sido interpretado el comando" =e *e inventado el status para este ejercicio" ,l status /;B BB0 indicar% que el comando *a sido ejecutado co$ rrectamente 2QB BB es un valor usual5" Htilizar- /6B 4B0 para indicar que el comando no e+iste" Vamos a crear 2 su& programas" Hno que env(a el status est%ndar # el otro que env(a no importa que status"
;=========================================================================== ; ENVIO DE STATUS ESTANDAR = ;=========================================================================== ;--------------------------------------------------------------------------; Envio del status estndar, en este caso 0x80 0x00 ;--------------------------------------------------------------------------Statstd movlw call clrw call goto

0x80 Send Send classe

; ; ; ; ;

coge el primer octeto status lo enva borra W lo enva y trata clase

;=========================================================================== ; ENVIO DE STATUS ESPECIFICO = ;=========================================================================== ;--------------------------------------------------------------------------; Envio primero octeto contenido en W , despus contenido status2 ;--------------------------------------------------------------------------Statxx call movf call

Send status2 , w Send

; enva el valor en W ; carga byte a enviar ; enva el valor

2B5

20.12 Recepcin de la clase


<*ora nuestra tarjeta pasa a modo recepcin # atiende su primer comando" 1uestro programa' por razones de 4acilidad' solo gestiona una clase" 1os contentamos con leer el octeto' sin veri4icarlo ni tratarlo" .e trata de un ejercicio did%ctico"
;=========================================================================== ; LECTURA DE LA CLASSE = ;=========================================================================== ;--------------------------------------------------------------------------; Consideramos en este ejemplo que solo hay una clase valida ; esperamos la llegada de la clase y no la tratamos ;--------------------------------------------------------------------------Classe call

Receive

; lee el byte proveniente del maestro

20.13 Recepcin de INS, P1, P2 y LEN


,+aminemos a*ora la rutina de recepcin de la instruccin' de los par%metros P1 # P2' as( como de la longitud de la cadena"
;=========================================================================== ; LECTURA DE INS, P1, P2, LEN = ;=========================================================================== ;--------------------------------------------------------------------------; INS se colocara en la variable Ser_Ins, P1 en Ser_P1 y P2 en Ser_P2 ; la longitud de la cadena de datos en Ser_len ;--------------------------------------------------------------------------movlw movwf read_loop call movwf incf btfss goto Ser_Ins FSR Receive INDF FSR , f FSR , 0x04 read_loop ; apuntar sobre instruccin ; inicializar puntero ; ; ; ; lee un octeto salva en el sitio previsto apunta al siguiente chequea si llego a direccin 0x10

Vera que utilizamos el direccionamiento indirecto para guardar los octetos reci&idos en 4 emplazamientos consecutivos" ,legiremos las direcciones B+B a B+B:' que nos permite detectar 4%cilmente el 4in del coman$ do" ,n e4ecto' una vez que el 4S octeto est% guardado' :.6 apuntar% a B+1B 2POBBB1 BBBBO5 ser% su4iciente con c*equear el &it 4 para detectar el 4inal del &ucle' sin necesidad de tener un contador de &ucles suplementario"

20.14 Control de la instruccin recibida


Hna vez reci&ido el comando' de&emos tratar los di4erentes comandos reci&idos" ,n nuestro ejemplo did%cti$ co *e implementado solamente una instruccin" 8a Dnica instruccin valida es la B+25" ,sta instruccin calcula la suma de P1 # P2 # reenv(a el resultado" omo 8,1 contiene la longitud de la cadena de respuesta' si 8,1 es superior a 1' la respuesta se completar% con B+::" ualquier otra instruccin ser% con$ siderada como incorrecta"

2B6

Veamos nuestro testK


;=========================================================================== ; SWITCH SIGUIENDO LA INSTRUCCIN RECIBIDA = ;=========================================================================== ;--------------------------------------------------------------------------; Imaginamos que reaccionamos a una instruccin 0x25 ; Cualquier otra instruccin ser considerada incorrecta ;--------------------------------------------------------------------------; chequear instruccin recibida , ----------------------------movf sublw btfsc goto Ser_Ins , w 0x25 STATUS , Z Ins25 ; carga instruccin recibida ; compara con 0x25 ; test si igual

; tratar instruccin incorrecta , ----------------------------movlw 0x40 movwf status2 movlw 0x60 goto Statxx ; ; ; ; carga octet2 status a enviar coloca en variable carga octet1 status enva status

Vemos aqu( que si la instruccin reci&ida es B+25 saltamos al tratamiento de la instruccin" ,n caso contrario' enviamos el status /6B 4B0 que en nuestro caso signi4ica /instruccin incorrecta0"

20.15 Tratamiento de una instruccin


8legamos al tratamiento de la instruccin propiamente dic*o" Vamos a tratar la instruccin de la siguiente maneraK 1" omo en toda instruccin' reenviamos la instruccin reci&ida 2" 8a tarjeta reenv(a la suma P1MP2 3" 8a trama de env(o se completa con tantos B+:: como sean necesarios para que la longitud total sea igual a .erdlen 4" .e env(a nuestro status est%ndar /;B BB0

2B7

;=========================================================================== ; TRATAR INSTRUCCIN 25 = ;=========================================================================== Ins25 ; envio eco del comando , --------------------Ser_Ins , w ; carga instruccin recibida Send ; enva eco ; envio P1 + P2 , ------------Ser_P1 , w Ser_P2 , w Send

movf call

movf addwf call

; carga P1 ; + P2 ; envia resultado

decf btfsc goto

; Test longitud respuesta , ----------------------Ser_len , f ; puesto que resultado enviado STATUS , Z ; test si complete Statstd ; Si , enviar status estndar ; Completar con 0xFF , ------------------

Insloop movlw call decfsz goto

0xFF Send Ser_len , f Insloop

; ; ; ;

valor a enviar envia decrementar contador de bucles No acabado , siguiente

goto

; envio status estandar , --------------------Statstd ; Si , enviar status estndar

2B;

20.16 Las variables


1os queda declarar las varia&les utilizadas" >e decidido utilizar varia&les locales puesto que es posi&leK
;*************************************************************************** ; DECLARACION DE VARIABLES * ;*************************************************************************** CBLOCK 0x00C ; direccion de comienzo de la zona de variables Ser_Ins : 1 ; Instruccin ISO7816 Ser_P1 : 1 ; Parametro 1 ISO7816 Ser_P2 : 1 ; Parametro 2 ISO7816 Ser_len : 1 ; longitud dato ISO7816 local1 : 1 ; variable local 1 local2 : 1 ; variable local 2 local3 : 1 ; variable local 3 local4 : 1 ; variable local 4 temp_sauvw :1 ; salvaguardia de w para temp ENDC ; fin zona de variables ; Rutina ATR , ---------#DEFINE cmpt1 local1 ; contador de octetos para ATR ; Subrutina de envio y recepcion , -----------------------------#DEFINE caract local2 ; carcter a enviar #DEFINE parite local3 ; bit de paridad #DEFINE cmptbts local4 ; contador de bits ; Para STATUS , -----------#DEFINE status2 local1 ; octeto 2 de status ; Para instruccin 25 , ------------------#DEFINE cmpt2 local1 ; ocontador de octetos

20.17 Conclusin
<*ora #a sa&e comunicar un enlace serie as(ncrono" <dem%s #a tiene las nociones &%sicas necesarias para rea$ lizar una tarjeta que responda a la norma I.J7;16" 1inguna duda de que encontrar% numerosas aplicaciones con la teor(a aqu( e+puesta" 8e recuerdo que se trata de un ejemplo imaginario pero los casos que nos encontramos en la pr%ctica son mu# parecidos al ejemplo aqu( desarrollado # las t-cnicas utilizadas en el ejemplo *an sido usadas con -+ito en no pocas aplicaciones tra&ajando con tarjetas I.J7;16 realesK no se trata pues de pura teor(a" No *e pro$ &ado el so4t3are presentado con un lector de tarjetas I.J7;16" No *e reci&ido 2en la gloriosa -poca de la decodi4icacin de sat-lites5 no pocos correos de personas que co$ menzaron a leer el curso empezando por este cap(tulo' so&re todo en la -poca revuelta de la realizacin per$ sonal de tarjetas decodi4icadoras de emisiones de 9V v(a sat-lite" onviene no poner el carro antes de los &ue#es' # si este cap(tulo est% al 4inal del curso es por algo" omo an-cdota' si este curso e+iste es de&ido a las tarjetas I.J7;16 # a la decodi4icacin de emisiones v(a sat-lite" ,n aquel entonces #o era administrador de un gran 4oro centrado en la decodi4icacin v(a sat-lite # propuse la primera versin de este curso &ajo la 4orma de cap(tulos independientes presentados como leccio$ nes directamente en line en el 4oro" onta&a con aprovec*arme del tirn de la decodi4icacin para enganc*ar a los jvenes 2# menos jvenes5 a interesarse en la manera de 4uncionamiento real de un micro controlador" <ntes de esa -poca tra&aja&a con los ;B51' son estas tarjetas las que me *icieron adoptar los PI "

2BQ

Anexo 1 : Preguntas frecuentes (F.A.Q.)


Vo# a intentar responder aqu( al m%+imo de preguntas posi&les que se *acen los usuarios en general"

A1.1 Encuentro que 8 sub programas es poco


1o de&e con4undirse el nDmero de su& programas con el nDmero de anidamientos de los su& programas" ,l numero de su& programas es ilimitado 2dentro de los limites de memoria de programa disponi&le5" Hn anidamiento es cuando un su& programa llama a otro su& programa" Para contar el nivel de anidamientos' siga el camino de su programa en el orden de ejecucin" uente M1 para cada instruccin /call0 # $1 para cada /return0 o /retl30" .i su programa es correcto se de&en cumplir las siguientes 3 condicionesK 1" 8a cuenta no de&e dar jam%s un numero negativo 2" 8a cuenta no de&e pasar jam%s de ; 3" <l 4inal de la ejecucin del programa la cuenta ser% B <tencin' no olvide tener en cuenta las interrupciones 2ver ane+o <1"25"

A1.2 No utilizo ms que 8 anidamientos pero mi programa se bloquea


1o de&e olvidar que las interrupciones tam&i-n utilizan la pila" .i utiliza interrupciones' solo tiene derec*o a 7 niveles de anidamiento en lugar de ; 2menos las su&rutinas utilizadas eventualmente por la rutina de inte$ rrupcin5"

A1.3 Mi programa parece no salir jams de las interrupciones


.e *a olvidado de &orrar el 4lag que provoca la interrupcin" 1o olvide no salir de las interrupciones con re$ turn sino con ret4ie' sin lo cual las interrupciones no serian repuestas en servicio # no podr(a volver a entrar a ellas" Jtro error cl%sico es poner a B el 4lag 6PI: sin *a&er le(do previamente el PJ69P"

A1.4 No consigo utilizar el simulador, las opciones no aparecen


>a olvidado decirle a =P8<P que va a utilizar el simulador integrado" Va#a al menD /de&ugger $_ select tool0 # seleccione /=P8<P.I=0" on4igDrelo como se e+plico en el cap(tulo correspondiente"

A1.5 Recibo el mensaje de error EOF antes de la instruccin END


<&ra el 4ic*ero /"asm0 en el &loc de notas de Windo3s # veri4ique que se muestra correctamente' con la posi$ cin de l(neas correctas" .i no es este el caso' es que el 4ic*ero se *a escrito con un editor que no genera &ien los retornos de carro" ,n ese caso' trate de copiarRpegar este 4ic*ero en un 4ic*ero creado con otro editor"

21B

A1.6 Cmo desensamblar un fichero .hex?


8e vo# a descri&ir 2 m-todos para desensam&lar un 4ic*ero en 4ormato *e+adecimal" ,l primer m-todo utiliza =P8<PK 1" 2" 3" 4" Va#a al menD /:ile $_ import0 .elecciones el 4ic*ero /"*e+0 a desensam&lar .eleccione /Vie3 $_ program memor#0 .eleccione la pesta)a que corresponda a su deseo

,l segundo m-todo utiliza I $Prog' la c-le&re utilidad de programacin de PI 2*o# d(a pasada de moda5 dis$ poni&le por todas partes en su momentoK 1" argue el 4ic*ero /"*e+0 con el menD /:ile $_ open 4ile0 2" .eleccione /vie3 $_ assem&ler0" ,s todo

A1.7 Utilizacin de minsculas y maysculas


Por de4ecto =P8<P e4ectDa la distincin entre ma#Dsculas # minDsculas" .i esto le supone algDn pro&lema' puede modi4icar las propiedades de su pro#ecto" Para e4ectuar esta operacinK .eleccione /Project $_ &uild options $_ project0 .eleccione la pesta)a /=P<.= assem&ler0 ,scoja la opcin /disa&le case sensitivit#0 8e desaconsejo *acerlo puesto que su cdigo no ser% #a porta&le a todos los ensam&ladores"

A1.8 La eleccin del programador (tostadora)


>e decidido modi4icar radicalmente mi consejo inicial de las primeras versiones de este curso despu-s de la estrategia comercial de =icroc*ip que deja' en mi opinin' como opcin poco juiciosa la construccin de un programador /personal0" 9anto m%s cuanto que los programas m%s 4amosos de pilotaje de un programador no siguen verdaderamente la salida al mercado de nuevos modelos" .i decide construirlo usted mismo' al menos no constru#a uno del tipo l?= 24uente de pro&lemas evidente5' que se reconocen por el *ec*o de estar conectados al puerto serie 2com5 sin disponer de una alimentacin el-ctrica propia 2tira directamente de la alimentacin del puerto serie5" ,vite so&re todo construir un programador serie que tendr% que conectar' en caso de ausencia de puerto se$ rie en su P ' a trav-s de un convertidor H.PR6.232' # esto en general no 4uncionar% dado que la totalidad de las l(neas necesarias para el programador no est%n tenidas en cuenta en estos convertidores" =i consejo es claroK compre un programador o4icial PicUit o I ?3" 1o compre las versiones /20' no ser%n utiliza&les en los 4uturos PI " 8as ventajas son numerosasK Posi&ilidad de programar el PI directamente desde =P8<P 2sin necesidad de otro logicial5" ,l programador reconocer% todos los PI previstos en su versin de =P8<P' &astar% con poner al d(a a la salida al mercado de un nuevo PI " ,stos programadores 4uncionan tam&i-n como de&ugger so&re el circuito 2ver curso parte 45 por lo que podr% depurar /al vuelo0 todos los programas so&re los PI que posean la 4uncionalidad /I ?0' es decir la ma#or(a de los PI recientes 2no el 16:;45" 211

,star% seguro que su programador 4unciona # se podr% concentrar en cualquier otra cosa Dtil si su aplicacin no 4unciona" 8a garant(a es mu# e+tensa' el I ?2 que poseo' por ejemplo' est% considerado por =icroc*ip aDn en garant(a a pesar de muc*os a)os de utilizacin 2Egarant(a de por vidaF5"

Mi (*nse2* es (&$%*K no constru#a su propio programador e+cepto si solo va a programar un par de PI o que le es imposi&le comprar uno o4icial" ,vite los clones' 4uente potencial de pro&lemas # no tan &aratos" o$ mo pre4erencia compre un PicUit o un I ?3 o4icial"

A1.9 Tengo un error de stack


6eci&o &astantes correos de personas que me dicenK cuando ejecuto mi programa en paso a paso en =P8<P reci&o en un momento determinado un error del tipo /.tacX over4lo30 o /.tacX under4lo30" EGu- signi4ica este mensajeF ?e *ec*o' un mensaje /stacX over4lo30 puede signi4icar que *a so&repasado los ; niveles de anidamiento" 8e recuerdo que solo *a# ; emplazamientos en la pila 2stacX5 # que una nueva tentativa de apilamiento' de&ido a una su&rutina o una interrupcin' provocar% el derrum&e de la pila" ,n la ma#or parte de los casos se trata de un error en la estructura de su programa" ,l mensaje /stacX over$ 4lo30 ocurre si apila m%s de ; emplazamientos' el mensaje /stacX under4lo30 ocurre si usted desapila mas de lo que *a&(a apilado 2por ejemplo' return sin call5" Hn /stacX under4lo30 es siempre un error de programa$ cin" Para resolver estos pro&lemas' si no *a so&repasado los ; niveles 2ver <1"25' veri4ique los siguientes puntosK ada llamada v(a call de&e volver al programa por un return o un retl3" ada return o rtl3 encontrado de&e *a&er estado precedido de un call correspondiente" 8a salida de una su&rutina con un goto de&e llevar al programa a un punto donde encuentre un re$ turn" Un$ %'"in$ n* )e!e &&$.$%se 2$.Ls $ sG .is.$" 8a llamada de una 4uncin por s( misma es llamada /recursividad0 # es una pr%ctica corriente en lenguajes evolucionados para sistemas grandes 2P 5' pe$ ro no utilice jam%s este m-todo en un PI en los que la pila est% limitada' salvo si usted es un pro$ gramador particularmente /4ino0 para llegar a gestionar la recursividad simult%neamente con la capa$ cidad de la pila"

A1.10 Cules son las diferencias entre un 16F84 y un 16F84A?


Jtra pregunta que me llega regularmente al correo" 8e comento las principales di4erenciasK 8a 4recuencia m%+ima de reloj pasa de 1B =>z a 2B =>z 8a tensin m%+ima admisi&le pasa de 6V a 5'5V ,l reset necesita de un impulso de 2 ns so&re = 86 en lugar de 1 ns ,l tiempo de su&ida de la tensin de alimentacin tomado en cuenta para el arranque cam&ia 2ver da$ tas*eet5 8a corriente t(pica para la programacin de la memoria 4las* pasa de 7'3 m< a 3 m< 2concierne a los realizadores de programadores5 8a corriente de consumo t(pica se do&la entre un 16:;4 a 1B =>z # un 16:;4< a 2B =>z' pero es Dni$ camente la consecuencia del aumento de la velocidad 2a 1B =>z el consumo no es muc*o m%s gran$ de que en un 16:;45 ?i4erentes modi4icaciones de caracter(sticas el-ctricas 2tensiones de nivel' corrientes' etc"5 ?ivisin por 2'5 de los tiempos de escritura en memoria eeprom ?ivisin por 2'5 de los tiempos de escritura en memoria 4las* 212

6esumiendo' nada que concierna a la programacin' son di4erencias a nivel el-ctrico" .alvo si est% alimentan$ do su 16:;4 a 6V' podr% reemplazarlo por un 16:;4 sin cam&iar nada" ,ste curso se aplica indistintamente al 16:;4 # al 16:;4<"

A1.11 Tengo un error 173 despus del ensamblado


,n el momento de lanzar el ensam&laje' o&tiene un error 173' del tipoK Error [173] Source file path exceeds 62 characters ,sto signi4ica que el camino para acceder a su 4uente e+cede los 62 caracteres' lo que puede ser de&ido a la utilizacin de nom&res de 4ic*ero mu# largo o a numerosos directorios # su&directorios anidados" Por ejem$ ploK
C:\Mi_directorio\fuentes\fuentes_MPLAB\Curso\Curso_parte1\Ejercicios\test1.asm

.er% su4iciente con desplazar su directorio a una carpeta m%s pr+ima a la ra(z o reducir los nom&res de 4ic*e$ ro utilizados" Hn ejemplo correctoK C:\Curso_Pic_1\Ejercicios\test1.asm J' mejor aDn' colocar sus datos en una particin di4erenteK D:\Curso_Pic_1\Ejercicios\test1.asm ,ste pro&lema era 4recuente con las versiones 5"+ de =P8<P pero de&er(a desaparecer con versiones m%s re$ cientes dado que la longitud autorizada *a aumentado"

A1.12 El PIC16F84 est obsoleto por qu no utilizar un 16F628?


<lguna vez me *an *ec*o esta pregunta" iertos /anti$pic primarios0 incluso me *an agredido en algunos 4o$ ros acerca de esto" 8a respuesta es mu# simpleK no se trata aqu( de realizar un montaje espec(4ico # preciso' al contrario' el o&jetivo es e+plicar las &ases de 4uncionamiento de la 4amilia de PI 16:" ,l 16:;42<5 es el PI m%s simple de toda la 4amiliaK todos los mdulos e+plicados en este PI se encuen$ tran so&re la totalidad de los otros PI 16:" ?ic*o de otra 4orma' todo lo que estudiar% en este curso es direc$ tamente utiliza&le en toda la gama' nada se estudio inDtilmente" ,l 16:62; es un PI con 4uncionalidades suplementarias' 4uncionalidades que son e+plicadas en el curso parte 2 destinado a los PI 16:;7+ que era uno de los PI 16: m%s completos en el momento de escri&ir el cur$ so parte 2" ,l 16:;4 est% particularmente &ien adaptado para el aprendizaje de &ase de los PI de medio rango a pesar de que otros' como el 16:62;' lo destronen en relacin a capacidadesRprecio en el caso de una aplicacin re$ al" ,l cuaderno de cargas para un curso de aprendizaje no es el mismo que para una aplicacin concreta' lo que e+plica que el 16:;4 continDe siendo mi eleccin maestra para el estudio de los PI de rango medio" ,l 16:;7+' utilizado en el curso parte 2' es el prete+to para el aprendizaje de un amplio nDmero de 4uncionali$ dades que podemos encontrar en la ma#or parte de los otros modelos de la 4amilia de rango medio e incluso en los PI >ig*$,nd 1;: a&ordados en el curso parte 5" ?e nuevo' el 16:;7+ no es m%s que un prete+to de aprendizaje' no representa la mejor eleccin para una aplicacin en un caso real pr%ctico"

213

ompre mejor un 16:;42<5 para el estudio de este curso mejor que un 16:62; para que no tenga que resol$ ver pro&lemas no e+plicados en este curso que le distraigan del aprendizaje en s( mismo" 8e aseguro que tiene a ganar *aci-ndolo as(" ,l curso es gratuito Epuede *acer el sacri4icio de comprar un 16:;42<5' noF Hna vez aca&ado el aprendizaje &usque un PI que le convenga mejor a su aplicacin" .i ese PI dispone de 4uncionalidades avanzadas de las que usted tenga necesidad' tome en cuenta estudiar el curso parte 2" .i el *ec*o de que #o utilice el 16:;4 # el 16:;76 le molesta' tenga en cuenta los t(tulos de mis cursosK Parte 1K 8as 4unciones &%sicas Parte 2K 8as 4unciones avanzadas 4acultativas

A1.13 Utilizo una versin de MPLAB mas reciente


Jtra pregunta que me sigue llegando a menudo" 8os usuarios piensan juicioso utilizar este curso con una ver$ sin m%s reciente de =P8<P 2por ejemplo' la ;"+5 # se encuentran agarrotados con las operaciones mas &%sicas" Na *e dejado escrito que el curso inicialmente est% dise)ado para =P8<P 5"+ # pasarlo a =P8<P 6"6" ?es$ graciadamente las versiones evolucionan demasiado r%pidamente # me es imposi&le reescri&ir sin parar en 4uncin de las evoluciones" =i consejo es el siguiente con el 4in de evitar pro&lemasK para estudiar el curso' instale =P8<P 6"6 Dnica$ mente' esto le permitir% seguir el curso sin pro&lemas" Hna vez realizado el aprendizaje' p%sese a una versin m%s reciente' sa&iendo que la migracin la *ar% sin grandes pro&lemas una vez asimiladas las nociones &%si$ cas" Hna vez m%s' evite acumular o&st%culos' *%galo simple" Para cargar la versin antigua de =P8<PK 1" Va#a al sitio de =icroc*ipK 333"microc*ip"com 2" ,n la zona /searc*0 escri&a /=P8<P I?, <rc*ives0 3" ?e&er% llegar r%pidamente a una p%gina donde se encuentran las versiones arc*ivadas de =P8<P' co$ ja la que corresponda al curso elegido"

A1.14 Mi PIC virgen no oscila


>e a)adido este ane+o porque un internauta me comunic *a&er intentado pro&ar con un PI nuevo sin pro$ gramar con el 4in de sa&er si *a&(a entendido todo &ien a nivel electrnico" ,se internauta se rompi la ca&eza intentando comprender por qu- no ten(a ninguna traza de oscilacin en el cuarzo de su PI " Veamos que pasa&aK Hn PI contiene sus in4ormaciones de con4iguracin 2oscilador' 3atc*$dog' etc"5 en su memoria 4las*" ?e&ido a la tecnolog(a' &orrar este tipo de memoria conlleva poner todos los &its de cada casilla a 1" Hn vistazo a la 4igura ;"1 del datas*eet nos muestra que la seleccin del modo del oscilador se e4ect$ Da v(a 2 &itsK :J. 1 # :J. 2" ,n un PI nuevo estos dos &its estar%n a 1" Jtro vistazo so&re la e+plicacin de estos &its nos muestra que eso corresponde al modo 6 seleccio$ nado"

onclusinK un PI virgen est% con4igurado por de4ecto en 4uncionamiento del oscilador en modo 6 ' por lo que el cuarzo no puede oscilar" 6ecuerde' por precaucin' jam%s ponga un PI virgen en la tarjetaK comience siempre por programarlo # solo alim-ntelo a continuacin" 214

Contribucin voluntaria
8a realizacin de este curso me *a llevado &astante tiempo e inversiones 2documentacin' material' a&onos' etc"5" <s(' para permitirme continuar' les pido' si eso est% dentro de sus posi&ilidades' # si usted aprecia lo que *e *ec*o' contri&uir un poco' cada uno segDn sus posi&ilidades # sus deseos" 9engo necesidad de su a#uda para continuar con la aventura" ?e *ec*o' no dispongo realmente de la capaci$ dad para consagrar la totalidad de mi tiempo li&re a escri&ir cursos # programas sin reci&ir una peque)a a#u$ da" < pesar de todo' no quiero caer en la necesidad de impedir el acceso a los 4ic*eros e imponiendo un pago pa$ ra o&tenerlos" Guiero que queden disponi&les para todos segDn su necesidad" >e decidido instaurar un sistema de contri&ucin so&re una &ase voluntaria que permita a quien lo desee' en 4uncin de sus propios criterios' a#udarme 4inancieramente" 8 o&jetivo no es *acerme rico' es m%s &ien a#u$ darme a alcanzar el o&jetivo" 1o se trata de un pago ni de una o&ligacin" .e trata simplemente de una asistencia sin promesas ni contra$ tos" ontinuar- respondiendo a los correos de todo el mundo' sin distincin # sin preguntas so&re el asunto" Hn &uen m-todo consiste' para aquel que lo desee' descargar el documento escogido' leerlo o utilizarlo' # despu-s decidir si merece o no la pena a#udarme so&re la &ase de lo que usted *a#a *ec*o" .i es que s(' va#a a mi sitioK 333"a&celectronique"comR&igono44 o a 333"&igono44"org # siga la pagina /cours$ part10" <ll( encontrar% en la pagina /contri&utions0 el procedimiento a seguir" Piense que esas contri&uciones me son mu# Dtiles # me permiten continuar tra&ajando para usted" 1o olvide poner su email en caracteres de imprenta para que pueda responderle" 6espondo siempre a los correos reci&idos" <s( que si no o&tiene respuesta' no dude en contactarme para veri$ 4icar si *a *a&ido algDn pro&lema" .i no respondo a uno de sus emails' no es que sea grosero' es simplemente que no *e podido responderle 2su cuenta de correo est% llena' su direccin no es v%lida' no *e reci&ido su mensaje' su mensaje *a sido clasi4icado autom%ticamente como /spam0 por mi mensajer(a' etc"5 =uc*as gracias por adelantado a todos aquellos que me *an a#udado o est%n por a#udarme a continuar con este tra&ajo de largo recorrido"

215

Utilizacin del documento


8a presente o&ra est% destinada a 4acilitar la comprensin de la programacin de los PI en general' # del 16:;4 en particular" 8as continuaciones est%n disponi&les en mi sitio para descarga gratuita" omun(queme 2con educacin5 todo error constatado con el 4in de que la puesta al d(a sea e4ectuada por el inter-s de todo el mundo" Por razones de 4acilidad de mantenimiento # de puesta al d(a' *e decidido 2es mi Dnica e+igencia5 que este curso solo pueda ser descargado desde mi sitioK 333"&igono44"org Por 4avor' si encuentra mi curso en otros sitios' env(e un email al 3e&master del sitio en cuestin para pedirle que respete la Dnica regla del juego" ,nti-ndase &ien' #o autorizo 2recomiendo5 a los 3e&master a colocar un enlace a mi sitio" No *are lo mismo a la inversa si la demanda me es *ec*a" <s( espero el m%+imo de usuarios" 8a presente o&ra puede ser utilizada por todos' copiada #Ro impresa en su totalidad' a condicin de no modi$ 4icar nada" Puede ser utilizada como soporte de cursos en todo o en parte' a condicin de precisar la re4eren$ cia original # el enlace a mi sitio" <utorizo e+pl(citamente a las escuelas # otras organizaciones educativas a imprimir mi curso en nDmero elevado de ejemplares con el o&jetivo de prestar un servicio a los estudiantes" ,n ese caso' pido que la compra del curso no sea o&ligatoria # que se les in4orme a los estudiantes que tiene la posi&ilidad de descargarlo de mi sitio" Puede noti4icarme cualquier a&uso en ese sentido" 9odos los derec*os so&re el contenido de este curso # so&re los programas que lo acompa)an quedan pro$ piedad intelectual del autor' incluso si una noti4icacin contraria intenta demostrar lo contrario 2documento de la 3e&' por ejemplo5" ,l autor no podr% ser tenido como responsa&le de cualquier consecuencia directa o indirecta resultante de la lectura #Ro aplicacin del curso o los programas" ,st% pro*i&ida toda utilizacin comercial sin el consentimiento escrito del autor" 9odo resumen o cita a t(tulo de ejemplo de&e estar acompa)ada de la re4erencia al origen" ,spero no *a&er atentado contra ningDn derec*o de autor realizando esta o&ra # no *e utilizado m%s que los programas puestos graciosamente a disposicin pu&lica por parte de la sociedad =icroc*ip" 8os datas*eet est%n as( mismo disponi&les para descarga en el sitio de esa sociedadK *ttpKRR333"=icroc*ip"com .i le *a gustado esta o&ra' util(cela' si tiene cr(ticas' gracias si env(a un peque)o email" ,sto me permitir% sa$ &er si de&o continuar o no esta aventura con las siguientes partes"

216

.epa que respondo siempre a los correos' pero advierta queK 1o realizo programas de 4in de carrera para estudiantes 2incluso pagando5' es una peticin que me llega todas las semanas al correo" 1o tengo tiempo # creo que es un mal servicio el *acerlo" >aciendo un poco de *umor' si #o les diera mis tari4as' estos estudiantes se arriesgar(an a su4rir un in4arto" ?esgraciadamente' no tengo el tiempo su4iciente para corregir programas completos" InDtil enviarme programas con un mensaje del estilo de /esto no 4unciona Eme podr(a decir por qu-F Paso muc*o tiempo respondiendo correos' si adem%s tuviese que depurar programas me pasar(a el d(a entero" omprenda que esto es imposi&le' piense que usted no es el Dnico pregunt%ndome cosas" >%game preguntas precisas so&re lo que concretamente le parezca ine+acto" .i tiene aplicaciones personales' no dude en compartirlas con todos" Para *acer esto' env(emelas por email" on esta versin' intento responder a demandas leg(timas de personas que tra&ajan so&re di4erentes plata4ormas 2=ac' 8inu+' Windo3s' et"5" .i' a pesar de todo' la versin suministrada es ine+plota&le so&re su m%quina' gracias si me lo *ace sa&er" <dvierta de todas 4ormas' que este curso utiliza =P8<P para los ejercicios' *ar% 4alta eventualmente adaptar los ejercicios en 4uncin del logicial que le sea posi&le utilizar" <dvierta que =icroc*ip suministra a*ora una versin de =P8<P &autiza$ da como =P8<P$[' que corre en las plata4ormas m%s comunes" 1o dude en descargarla"

Yracias al 3e&master de 333"a&celectronique"com por al&ergarme gratuitamente" Yracias a P#te por su propuesta de al&ergarme gratuitamente" Yracias a Yrosvince por su propuesta de al&ergarme gratuitamente" Yracias a Pruno por *a&er asegurado algDn tiempo el pago de mi dominio" Yracias a 9*ierr# por *a&erme o4ertado mi nom&re de dominio # asegurar su pago" Yracias a todos aquellos que me *an reportado correcciones a e4ectuar" Yracias a todos aquellos que me *an enviado contri&uciones para compartir" Yracias a mi esposa # mis *ijos por su paciencia" Yracias a todos aquellos que me *an enviado emails motivantes" oltima precisinK es imposi&le que encuentre trazas de plagio aqu(' as( como en los cursos precedentes' te$ niendo en cuenta que no *e le(do ninguna o&ra so&re el sujeto e+cepto los datas*eet de =icroc*ip" 9odo *a salido de mis propias e+periencias" .i encuentra trazas de un plagio 2#a las vi5' sepa que son los otros quienes *an copiado' # esto tam&i-n es v%lido para las o&ras a la manera cl%sica 2este comentario no es inocente5" ,dicin terminada el BQRB2R2BB1' compilacin de lecciones separadas en una o&ra completa" Puesta al d(a revisin 2 el 15RB6R2BB1K correccin de algunos errores" Puesta al d(a revisin 3 el 24RB7R2BB1K correccin detallada con los :ri&ottes Puesta al d(a revisin 4 el 26R1BR2BB1K correccin de algunos peque)os errores encontrados" Puesta al d(a revisin 5 el 27RB2R2BB2K correccin de algunos errores tenaces" Puesta al d(a revisin 6 el 2BRB4R2BB2K alguna correccin' mejoras de los puntos que suscita&an pre$ guntas 4recuentes' paso a 4ormato pd4 con compresin rar para permitir la utilizacin en todas las maquinas' masculinizacin del t-rmino PI " Puesta al d(a revisin 7 el 2RBQR2BB2K correccin de errores sint%cticos # ortogr%4icos menores en al$ gunas pala&ras" <)adido de la pro*i&icin de distri&ucin 4uera de mi sitio 3e&" Puesta al d(a revisin ; el 25R1BR2BB2K peque)a correccin del cap(tulo 2"4" ,l enunciado citado en el ejemplo no corresponde a lo e4ectivamente desarrollado" orreccin del enlace *acia el sitio de =i$ croc*ip" =odi4icacin de las de4iniciones I. # 6I. " Puesta al d(a revisin Q el B1R11R2BB2K correccin de 4altas de ortogra4(a diversas" Puesta al d(a revisin 1B el B4R12R2BB2K supresin de una l(nea que se presta&a a con4usin en la p%gina 1;3' algunas correcciones menores' modi4icacin de contri&ucin pagina 2BQ" 217

Puesta al d(a revisin 11 el 1QRB4R2BB3K modi4icacin de los registros modi4icados por la instruccin sleep pagina 74' a)adido del programador en la lista de materiales necesarios' modi4icacin en el de$ 4ine de la pagina 123' correccin menor en pagina 7B" Puesta al d(a revisin 12 el 16RB6R2BB3K correcciones menores" Puesta al d(a revisin 13 el 1QRBQR2BB3K grandes modi4icaciones para pasar de =P8<P 5"5B a =P8<P I?, 6"3B" 1umeracin cam&iada' numerosas modi4icaciones en cap(tulos enteros" 6eimpre$ sin completa necesaria' 4ic*eros de ejemplo reconstruidos" Puesta al d(a revisin 14 el 11R12R2BB3K modi4icacin del esquema de la pagina 134' modi4icacin de radi+ por paso a =P8<P 6" Puesta al d(a revisin 15 el 13RB2R2BB4K correccin de un error repetitivo en los ejemplos # en el curso a nivel de la inicializacin de ,,<?6 2cam&io del &anco una l(nea demasiado pronto5' 4ic*eros ejemplo # maqueta" Puesta al d(a revisin 16 el BQRB3R2BB4K correccin pagina 5;'5Q" Puesta al d(a revisin 17 el BQRB6R2BB4K correcciones p%ginas 34 # 1Q;' ane+os' a)adido de un truco de programacin' (ndice de materias' modi4icacin de mi direccin de correo" Puesta al d(a revisin 1; el B2RB;R2BB4K a)adido del tiempo de despertar pagina 171' nota pagina 113" Puesta al d(a revisin 1Q el 27RB3R2BB6K correcciones diversas paginas' recolocacin de partes de cdigo de&ido a una modi4icacin accidental del ta&ulado' puesta al d(a pagina 2B' notas p%ginas 24 # 5;' a)adido de un ane+o" Puesta al d(a revisin 2B el B3RB4R2BB6K a)adido de un peque)o cap(tulo so&re consumo m(nimo en modo sleep" Puesta al d(a revisin 21 el 13R1BR2BB6K correcciones menores' paso de nDmeros >OBB++O a ; &its' a)adido de una nota pagina 44' revision21&' puesta al d(a del esquema del opto acoplador que *a&(a desaparecido" Puesta al d(a revisin 22 el 24RB1R2BB7K modi4icaciones importantes en todo aquello que trata del ti$ merB teniendo en cuenta la o&ligacin de considerarlos 2 ciclos perdidos en toda modi4icacin del 9=6B' modi4icacin de paginas 2Q'44'52'Q5 # 4ic*eros asm concernidos' correcciones menores' modi$ 4icacin concerniente al simulador 2era de la versin antigua de =P8<P5' modi4icacin pagina 21 a nivel de la e+plicacin de la mencin /$++0 que *a&(a olvidado adaptar a las diversas e+periencias e4ectuadas so&re el sujeto" Puesta al d(a revisin 23 el B4R11R2BB7K a)adido de una lista de consideraciones so&re el 3atc*$dog en el cap(tulo 15"3' correcciones ortogr%4icas o 4rases retorcidas' modi4icacin de un camino pagina 3;' precisin so&re el t-rmino /posicionado0' correccin de numero de &it pagina 12' decalaje de cier$ tos nDmeros de pagina' a la demanda amistosa de =icroc*ip' a)adido del s(m&olo a todo termino re4erente a =icroc*ip" Puesta al d(a revisin 24 el B;RB2R2BB;K modi4icacin menor pagina 47' reemplazo de sistema de nu$ meracin por numeracin' cap(tulos 12"7"2 a 12"7"4 re *ec*os 2a)adidos5 implicando la remuneracin de todas las pagina siguientes" Puesta al d(a revisin 25 el B7RBQR2BB;K correccin importante pagina 14B" Puesta al d(a revisin 26 el B;RB2R2BBQK correcciones menores p%ginas 5B # 63' a)adido del reset e+$ plicito del 4lag de una interrupcin de la interrupcin eeprom" Puesta al d(a revisin 27 el 15RB2R2BBQK precisiones concernientes al tiempo de latencia de las inte$ rrupciones en pagina 1BQ" Puesta al d(a revisin 2; el 24RB2R2BBQK a)adido de un p%rra4o so&re las unidades' adopcin del t-rmino Ui&i mas que de una simple nota" Puesta al d(a revisin 2Q el B5R1BR2B1BK correcciones paginas 1;' 1Q' 22' 41' 4Q' 56' a)adido e+plica$ ciones pagina 44 so&re el 4in de los programas 2directiva ,1?5' modi4icacin total del ane+o <1";" Puesta al d(a revisin 3B el 13R1BR2B1BK despu-s del a&andono de las versiones /20 de los PicUit # I ? ' modi4icacin del consejo en ane+o <1";" Puesta al d(a revisin 31 el 2;R11R2B1BK remarque modi4icado en pagina 14;' a)adido de un capitulo concerniente a la utilizacin de rutinas en 4ic*ero separado"

21;

Puesta al d(a revisin 32 el 13RB3R2B11K correccin enlace pagina Q' correcciones menores' a)adido ane+os" Puesta al d(a revisin 33 el 26R11R2B11K a)adido remarque pagina 12Q' correccin diversas paginas Puesta al d(a revisin 34 el B5RB1R2B13K 6evisin ma#or' li4ting completo del curso' supresin de so$ &re lineados 24acilidad de lectura5' correcciones' a)adido de e+plicaciones' modi4icacin de p%rra4os' modi4icacin de ciertos 4ic*eros suministrados' etc"

,n mi sitio 3e& encontrar% as( mismo toneladas de reportes de in4ormacin que le permitir%n volcarse en es$ te curso # so&re los otros 4ic*eros propuestos para descarga" Hse pre4erentemente el email para preguntas # envi de correcciones"

Re$&iD$(i*nK >i1*n*,,
.iteK *ttpKRR333"a&celectronique"comR&igono44 2gracias por el alojamiento5 ?ominioK 333"&igono44"org ,mailK &igocours7*otmail"com

9raduccin al espa)olK :ernando 6uano Vigo e ,spa)a =a#o 2B13

21Q

Vous aimerez peut-être aussi