Académique Documents
Professionnel Documents
Culture Documents
POR BIGONOFF
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
,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
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
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"
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"
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
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"
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"
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
15
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.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
< 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"
1Q
2B
21
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"
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
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
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
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"
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
8a utilizacin de esta de4inicin se realiza utilizando simplemente su nom&re en el programa" Por ejem$ ploK
bsf monbit ; poner mibit a 1
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"
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
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
,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"
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
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
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;
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
,+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)
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
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
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)
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)
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)
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)
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)
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)
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
63
omo ve todos los &its se *an decalado *acia la izquierda # queda so&re Q &its" E2e.#&* J
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
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
,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
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
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
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 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)
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)
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
9enemos que realizar varias operaciones para tener el dinero en nuestro &olsillo"
=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"
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/
,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
.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"
;1
;************************************************************************** ; 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
>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
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"
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
<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
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"
;;
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"
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
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"
Q1
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
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
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
Q4
,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"
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
,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"
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
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
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;
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
;********************************************************************* ; 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
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"
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"
,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
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
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"
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"
,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"
?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"
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"
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
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
;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
.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"
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"
,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
;********************************************************************** ; 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
;********************************************************************* ; 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
,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
< 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
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
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.
11Q
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
;********************************************************************** ; 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
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
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"
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"
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
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"
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
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"
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.
133
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
>a&remos utilizado las interrupciones para los mDltiplos de 255 # la lectura directa de tmrB para las unidades" 134
,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.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
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
.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
?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
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("
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"
143
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
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 * ; * ;************************************************************************
,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
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"
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"
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"
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"
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
.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"
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
; 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"
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"
157
15;
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"
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
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"
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 "
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
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.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
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
,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"
164
165
,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"
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
16;
?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
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"
172
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"
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
<*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"
,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"
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;
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
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."
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
; ; ; ; ;
contador 1 para tempo contador 2 para tempo resultado para fonction resultado intermedio 1 para fonction resultado intermedio 2 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
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
1 2 3 n
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"
; 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
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
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
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"
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"
Vamos a*ora a e+plicar estos conceptos e indicar cu%les son sus valores en la norma I.J7;16"
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"
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"
,+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"
1Q7
?e4inimos la con4iguracinK no vamos a utilizar el 3atc*$dog para esta aplicacin # utilizaremos un reloj e+$ terno" 9endremosK
; 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
-91 TMR0 , f
INTCON , T0IF
; borrar flag
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"
1QQ
; 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
; ; ; ; ; ; ;
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
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
; ; ; ; ;
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
.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
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
; ; ; ; ;
;=========================================================================== ; ENVIO DE STATUS ESPECIFICO = ;=========================================================================== ;--------------------------------------------------------------------------; Envio primero octeto contenido en W , despus contenido status2 ;--------------------------------------------------------------------------Statxx call movf call
2B5
Receive
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"
2B6
; 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"
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
; Test longitud respuesta , ----------------------Ser_len , f ; puesto que resultado enviado STATUS , Z ; test si complete Statstd ; Si , enviar status estndar ; Completar con 0xFF , ------------------
; ; ; ;
goto
2B;
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
21B
,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
,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"
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<"
.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"
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
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
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
21Q