ASSEMBLER PARA SESIÓN COMPLETA MICROCONTROLADORES PIC POR:
El Registro PCL Existe un registro, llamado PCL, ubicado en la posición 0x02 en el banco de memoria, tiene mucho que ver con el flujo del programa, puesto que le asigna un número a cada línea de código. Todo empieza con la primera instrucción, esta tiene una posición indicada con un número en el registro PCL, cuando accede a esa posición, se lee la instrucción, se decodifica, y luego se ejecuta, una vez echo esto, el reloj del micro incrementa al contador de programa (PCL) en un unidad, esto hace que el PCL apunte a la segunda instrucción, ahora se lee esta segunda instrucción, se decodifica y también se ejecuta. Nuevamente, el reloj del sistema incrementa el PCL para que apunte a la tercera instrucción, la decodifique y la ejecute. Este proceso se repite hasta que termina el programa (es decir, cuando encuentra un END).
DIRECCIONAMIENTO INDIRECTO Estos 2 registros, y en algunos casos, junto al registro STATUS, pueden trabajar en conjunto para hacer un direccionamiento indirecto de la memoria de Datos (memoria RAM). Bien, que es eso del direccionamiento indirecto...?. Para entenderlo mejor estudiemos estos registros... REFERENCIA: http://perso.wanadoo.es/luis_ju/pic4/pic4 _07.html
DIRECCIONAMIENTO INDIRECTO Registro 04h (FSR) Es el Registro selector de registros, es un puntero en realidad, Recuerdas aquello de las interrupciones, pues bien, es la misma dirección, la 0x04h, cuando se producía una interrupción, el contador de programa apuntaba a esta dirección, y nosotros le decíamos por donde continuar, o escribíamos ahí lo que debía hacer. Ok. Ahora utilizaremos el registro contenido en esta dirección para seleccionar otros registros. Piensa, que si el FSR es un puntero de registros, pues, en un momento, puede apuntar a uno y en otro momento a otro. Ahora, la dirección del registro al que apunta, se copia en un registro llamado INDF, y este último registro, se actualiza en cada cambio del registro FSR, ahora... tienes una idea de lo que es el registro INDF...???
DIRECCIONAMIENTO INDIRECTO Registro 00h (INDF) Es el registro para direccionamiento indirecto de datos, a pesar de no ser un registro disponible físicamente (esto lo dice la hoja de datos); utiliza el contenido del registro FSR, para seleccionar indirectamente la memoria de datos o RAM. Si la dirección a la que apunta el FSR se copia en INDF, una instrucción aplicada a INDF, determinará lo que se debe hacer con el registro al que apunta. Veamos un ejemplo, de como trabajan estos dos registros, en colaboración el uno con el otro, y así lo entenderás mejor..
DIRECCIONAMIENTO INDIRECTO Ejemplo de direccionamiento indirecto El Registro 05 contiene el valor 10h El Registro 06 contiene el valor 0Ah Se Carga el valor 05 en el registro FSR (FSR = 05) La lectura del registro INDF retornará el valor 10h Se Incrementa el valor del registro FSR en 1 (FSR = 06) La lectura del registro INDF retornará el valor 0Ah.
DIRECCIONAMIENTO INDIRECTO REFER: http://perso.wanadoo.es/pictob/micropic16f84.htm#direccionamiento_indirecto
DIRECCIONAMIENTO INDIRECTO Veamos otro ejemplo pero en código. Lo que hace este miniprograma, es borrar el contenido de la memoria RAM entre 0x10-0x20 utilizando direccionamiento indirecto.
DIRECCIONAMIENTO INDIRECTO En la programación de los microcontroladores PIC la mayoría de las instrucciones emplean direccionamiento directo, pero también es posible que operen en un modo de direccionamiento directo. Para el direccionamiento indirecto se emplean dos registros especiales: el FSR y el INDF (este último no es un registro físico). El registro FSR se emplea para señalar o apuntar a una dirección de la memoria RAM cuyo contenido puede ser leído o escrito de forma indirecta empleando cualquier instrucción que use como operando al registro INDF. Esta forma de direccionamiento es particularmente útil cuando se manejan tablas o arreglos de datos.- REFER: Mis primeros programas en assembler [http://www.microsdesigns.com.ar/] Euler_df28@hotmail.com
DIRECCIONAMIENTO INDIRECTO Directo vs indirecto
MEMORIA EEPROM DE DATOS Esta memoria está basada en tecnología EEPROM, y tiene una longitud de 8 bits, del mismo modo que la memoria de datos. Su tamaño es de 64 bytes y está situada en un bloque distinto y aislado de la de datos. Los 64 bytes EEPROM de Memoria de Datos no forman parte del espacio normal direccionable, y sólo es accesible en lectura y escritura a través de dos registros, para los datos el EEDATA que se encuentra en la posición 0008h del banco de registros RAM y para las direcciones el EEADR en la 0009h. Para definir el modo de funcionamiento de esta memoria se emplean dos registros especiales, el EECON1 en la dirección 0088h y el EECON2 en 0089h.
MEMORIA EEPROM DE DATOS El PIC16F84 dispone de una zona de 64 bytes de memoria EEPROM, para almacenar datos que no se pierden all desconectar la alimentación. Esto es muy útil ya que permite guardar datos permanentemente Como cualquier otra memoria EEPROM se pueden realiar dos tipos de operaciones: Operación de Lectura Operación de Escritura o grabación Un ciclo de grabacion en una posicion EEPROM de datos dura unoos 10ms, un tiempo muy elevado para la velocidad del procesador, que se controla mediante un temporizador interno. Al escribir en una posicion de memoria ya ocupada automaticamente se borra el contenido que habia el nuevo dato, por lo que no hay comendo de borrado
MEMORIA EEPROM DE DATOS El PIC16F84 soporta de un millón de ciclos de escritura /borrado de su memoria EEPROM de datos y es capaz de guardar la información inalterada durante mas de 40 años
MEMORIA EEPROM DE DATOS Esta memoria no forma parte del espacion direccionable y solo es accesible para lectura y ecritura a traves de registros. Los registros relacionados con esta memoria EEPROM de datos son: EEDATA [EEPROM Data Register-08h]. guarda el contenido de una posición de la memoria EEPROM de datos antes de su escritura o después de su lectura, según leamos o escribamos en ella. Para leerla se sigue un proceso especial que se comentará mas adelante. Como ya sabemos la memoria EEPROM es bastante lenta, dato que tendremos en cuenta cuando accedamos a ella para escribirla, pues tarda unos 10 ms en completar el proceso EEADR [EEPROM Address Register-09h]. El registro EEADR (Dirección de EEPROM) guarda la dirección de la posición de memoria EEPROM cuando queramos acceder a ella, bien para su lectura, o bien para su escritura. El igual que con el registro anterior, veremos su uso más a fondo cuando lleguemos a las instrucciones que lo utilizan. El registro EEADR puede direcconar como máximo 256 bytes de los cuales sólo los 64 primeros están disponibles, con lo que los dos bits de mayor peso han de tener el valor de '0'
MEMORIA EEPROM DE DATOS EECON1[EEPROM Control Register-88h]. Este registro contiene configuraciones importantes acerca de la escritura y la lectura de la EEPROM de datos. En concreto tiene 5 bits de control, cuya distribución y significado es el siguiente. U (Unimplemented), No implementado. Se lee como 0. Bit 4 (flag): EEIF. Bit de interrupción de escritura en la memoria EEPROM ( EEPROM Interrupt Flag) 1: Este bit se pone a uno al terminar la operación de escritura en la EEPROM, y debe ponerse a cero por software 0: No se ha completado la operación de escritura o no ha empezado.
MEMORIA EEPROM DE DATOS Bit 3 (flag), WRERR. Bit de error de escritura (Write Error) 1: Este bit se pone a 1 si se produce un error de escritura de forma prematura (Reset o Watchdog). En este caso, los contenidos de EEADR y EEDATA no varían, de manera que el proceso pueda ser repetido correctamente. 0: Se ha completado la operación de escritura. Bit 2, WREN. Bit de habilitación de escritura. (Write Enable) 1: Este bit debe ser habilitado para poder escribir en la EEPROM 0: Deshabilita la escritura de datos en la memoria EEPROM. Bit 1, WR. Bit de control de escritura (Write Data) 1: Indica que se ha iniciado una operación de escritura. Este bit debe ponerse a uno para escribir un dato. 0: Indica que se ha completado una operación de escritura. El PIC lo pone automáticamente a cero Bit 0, RD. Bit de control de lectura (Read Data) 1: Inicia una lectura de la memoria EEPROM. Este bit debe ponerse a uno para poder leer un dato. 0: No se ha iniciado una lectura de la EEPROM. El PIC lo pone automáticamente a cero
MEMORIA EEPROM DE DATOS En el registro EECON1, los tres primeros bits no están implementados por los que su lectura es '0'. Los bits de control RD y WR inician operaciones de lectura y escritura respectivamente. Estos bits sólo pueden ser puestos a '1' por software, nunca a '0'. Son puestos a '0' cuando se completa la operación de lectura o escritura. Para leer una posición de memoria, se debe escribir la dirección en el registro EEADR y colocar a '1' el bit de control RD. El dato estará disponible en un próximo ciclo de instrucción, normalmente en el siguiente, en el registro EEDATA hasta que se lea otro o se escriba en este registro. Para escribir un dato en la EEPROM, se debe primero colocar la dirección en el registro EEADR y el dato en el registro EEDATA. Luego. Después se debe seguir una secuencia específica para comenzar a escribir cada byte, para garantizar no escribir datos en la EEPROM por error. La secuencia es: MOVLW MOVWF MOVLW MOVWF BSF 55h EECON2 ; Escribe 55h en EECON2 AAH EECON2 ; Escribe AAh en EECON2 EECON1,WR ; Pone WR a 1 para comenzar la escritura Además, el bit WREN del registro EECON1 debe estar puesto a '1' para habilitar la operación de escritura.
MEMORIA EEPROM DE DATOS EECON2 [EEPROM Control Register 2-89h]. Este registro no está implementado físicamente, por lo cual no se puede leer. Tan sólo sirve para un proceso de protección de escritura que consiste en copiar en él unos datos específicos, con el fin de evitar que un programa por error pueda programar la EEPROM, manipulando simplemente los bits del EECON1.
MEMORIA EEPROM DE DATOS Esta memoria no emplea ningún recurso externo de alimentación. Puede grabarse desde un programador de PIC al igual que el código de programa. La lectura de una posición de la memoria se obtiene en el registro EEDATA en el próximo ciclo de reloj, si bien podría tardar algo mas. La escritura es mucho mas lenta, tardándose del orden de unos 8 ms. Esta se controla mediante un temporizador interno
MEMORIA EEPROM DE DATOS Resumen de características: Memoria de datos de 64 bytes. Lectura rápida de un byte (en el tiempo de uno o varios ciclos de instrucción). Escritura de un byte en unos 8 ms. Se genera una interrupción cuando se completa la escritura de la memoria. 1.000.000 de ciclos de borrado/escritura. 40 años de retención de datos. Tecnología de baja potencia y alta velocidad CMOS Cuando el dispositivo está protegido por código, la CPU puede continuar leyendo y escribiendo en la memoria EEPROM, pero el programador del dispositivo ya no puede acceder esta memoria.
Uso de la EEPROM A continuación veremos a fondo cuales son los procesos más usuales de escritura y de lectura en la EEPROM. Lectura de la memoria EEPROM. Para leer de la memoria EEPROM han de seguirse los siguientes pasos: Escritura de la dirección que hay que leer en el registro EEADR. Poner a 1 el bit RD del registro EECON, para habilitar la lectura. Lectura del dato leído y espera a que termine la operación. El dato está disponible en el registro EEDATA.
Uso de la EEPROM Veamos dos ejemplos práctico. El primero (LECTURA1) presupone que el dato en EEDATA estará disponible rápidamente, y el segundo (LECTURA2) espera hasta confirmarlo LECTURA1 BCF STATUS,RP0 ; Selecciona banco 0 MOVLW MEM1 ; Dirección a leer de MOVWF EEADR ; la EEPROM BSF STATUS,RP0 ; Selecciona banco 1 BSF EECON1,RD ; Activar lectura BCF STATUS,RP0 ; Selecciona banco 0 MOVF EEDATA,W ; W se carga con el valor ; leído en eeprom.
Uso de la EEPROM (LECTURA2) espera hasta confirmarlo LECTURA2 BCF STATUS,RP0 ; Selecciona banco 0 MOVLW MEM1 ; Dirección a leer de MOVWF EEADR ; la EEPROM BSF STATUS,RP0 ; Selecciona banco 1 BSF EECON1,RD ; Activar lectura ESPERA BTFSC EECON1,RD ; Espera final de lectura GOTO ESPERA ; a que baje la bandera BCF STATUS,RP0 ; Selecciona banco 0 MOVF EEDATA,W ; W se carga con el valor ; leído en eeprom La memoria EEPROM es bastante lenta, por lo cual es importante esperar a que el ciclo de lectura termine, aunque algunas veces se omita. Pero es aún más importante esta espera en el ciclo de escritura, ya que la EEPROM puede tardar en ser escrita hasta 10 ms.
Uso de la EEPROM Escritura de la memoria EEPROM. El proceso de escritura es aún más complejo ya que deberemos hacer todo lo anterior y además escribir un código especial de protección. Estos pasos los vemos en las siguientes líneas: Poner a 1 (si no lo estaba) el bit WREN del registro EECON1 para habilitar la operación de escritura. Cargar en EEADR la dirección de la posición a escribir. Cargar en el registro EEDATA el valor a grabar. Ejecutar la siguiente secuencia que inicia la escritura de cada byte y además sirve de protección frente a errores eventuales. Esta secuencia siempre es la misma y ha de ejecutarse siempre. MOVLW 55H MOVWF EECON2 ; Escribe 55h en EECON2 MOVLF AAH MOVWF EECON2 ; Escribe AAh en EECON2 BSF EECON1,WR ; Coloca a 1 el bit de escritura
Uso de la EEPROM Escritura de la memoria EEPROM. Esta última instrucción inicia el proceso de escritura. Cuando se termina, el bit EEIF está a 1 y, si ha sido habilitada la interrupción de EEPROM haciendo uso del bit EEIE del registro INTCON, esta interrupción se genera. Mediante software es necesario poner a cero el bit EEIF.
Uso de la EEPROM Veamos un ejemplo de escritura típico que no utiliza interrupciones: ESCRITURA ; Establecer EEADR y EEDATA MOVLW DIRMEN1 MOVWF EEADR MOVLW DATO1 MOVWF EEDATA ; Escribe la dirección en EEADR ; Se escribe el dato en EEDATA BSF STATUS,RP0 ; Selecciona el banco 1 BSF EECON1,WREN ; Permiso de escritura activado ;Comienzo de la secuencia de escritura MOVLW 0x55 MOVWF EECON2 MOVLW 0xAA MOVWF EECON2 ; Se escribe el dato 55 h en EECON2 ; Se escribe AA h en EECON2 BSF EECON1,WR ; Comienza la escritura BCF EECON1,WREN ; Permiso de escritura desactivado ESPERA BTFSC EECON1,WR ; Espera a que termine la escritura GOTO ESPERA BCF STATUS,R0 ; Selecciona el banco 0.
Uso de la EEPROM La escritura de cada byte no se iniciará si la secuencia de introducir 55 y AA en EECON2, y activar el bit WR no se sigue exactamente. Considerándo lo anterior, es recomendable que durante la secuencia de inicio de escritura se deshabiliten las interrupciones, con el fin de evitar errores no deseados y habilitarlas posteriormente si van a ser utilizadas. Adicionalmente, el bit WREN de EECON1 debe ser activado para habilitar la escritura. Para evitar errores, también es recomendable que el bit WREN esté desactivado durante todo el programa excepto en el momento de la escritura. Debemos tener en cuenta que este bit no se pone a cero automáticamente mediante hardware. Una vez iniciado el ciclo de escritura, si ponemos a cero WREN, esto no afectará a el ciclo de escritura iniciado. En este caso el bit WR estará inhibido y no se podrá poner a uno. Después del ciclo, el bit WR es puesto a cero por hardware y el EEIF es puesto a uno (si EEIE lo está). Si EEIE, está habilitado, EEIF debe ser puesto a cero por software.
Uso de la EEPROM Veamos un ejemplo de escritura típico que utiliza interrupciones: ESCRITURA BCF STATUS,RP0 ; Selecciona el banco 0. ; Establecer EEADR y EEDATA MOVLW MEN1 MOVWF EEADR MOVLW DATO1 MOVWF EEDATA ; Escribe la dirección en EEADR ; Se escribe el dato en EEDATA BSF STATUS,RP0 ; Selecciona el banco 1 BSF EECON1,WREN ; Permiso de escritura activado BCF INTCON, GIE ; Deshabilita interrupciones. ;Comienzo de la secuencia de escritura MOVLW 0x55 MOVWF EECON2 MOVLW 0xAA MOVWF EECON2 ; Se escribe el dato 55 h en EECON2 ; Se escribe AA h en EECON2 BSF EECON1,WR ; Comienza la escritura BSF INTCON,GIE ; Habilita las interrupciones. BCF EECON1,WREN ; Permiso de escritura desactivado BCF STATUS,R0 ; Selecciona el banco 0
Uso de la EEPROM Verificación de la escritura Dependiendo de la aplicación, la experiencia en programación dice que los datos escritos en la EEPROM deben ser verificados comparándolos con el dato que se acaba de escribir. Esto debe usarse en aplicaciones en las que un bit de la EEPROM sufre ciclos de lectura/escritura hasta rozar el límite de las especificaciones. Generalmente el fallo de escritura en un bit de la EEPROM será un bit que se escribe como un 0 lógico pero devuelve un 1 debido a la pérdida de ese bit. La siguiente porción de código es un ejemplo de verificación del dato escrito:
Uso de la EEPROM Veamos un ejemplo de escritura típico que utiliza interrupciones: BCF STATUS,RP0 ; Nos situamos en el banco 0 MOVF EEDATA,W ; Debemos estar en el banco 0 BSF STATUS,RP0 ; Cambiamos al banco 1 BSF EECON1,RD ; Leemos el dato que se guarda en BCF STATUS,RP0 ; EEDATA, y cambiamos a banco 0 ; A continuación se comprueba que los datos en W en EEDATA son los mismos SUBWF EEDATA,W ; Restamos ambos valores BTFSS STATUS,Z ; Si la operación es cero, son iguales GOTO ERR_ESCRIT ; Si no son iguales, saltamos a ERR_ESCRIT... ; Si son iguales, seguimos con el programa.
Rutinas EEPROM A continuación se presentan dos rutinas para escribir y leer en la EEPROM: ;************************************************************** ; EEPROM_W: ; Graba un byte en la EEPROM de datos. La dirección será la contenida ; en EEADR y el dato se le supone previamente introducido en EEDATA ; EEPROM_W ESPERA bsf STATUS,RP0 ;Selecciona banco 1 bsf EECON1,WREN ;Permiso de escritura movlw b'01010101' ;Secuencia de escritura movwf movlw movwf EECON2 b'10101010' EECON2 bsf EECON1,WR ;Orden de escritura bcf EECON1,WREN ;Desconecta permiso de escritura btfss EECON1,EEIF ;Comprobar bandera de fin de escritura goto ESPERA bcf EECON1,EEIF ;Reponer flag de fin de escritura bcf STATUS,RP0 ;Selección banco 0 return ;**************************************************************
Rutinas EEPROM ;************************************************************** ; EEPROM_R: ; Lee un byte de la EEPROM. Se supone al registro EEADR cargado ; con la dirección a leer. En EEDATA aparecerá el dato leído. ; EEPROM_R bsf STATUS,RP0 ;Selección de banco 1 bsf EECON1,RD ;Orden de lectura bcf STATUS,RP0 ;Selección de banco 0 return ;**************************************************************
Rutinas EEPROM PIC16F873
Rutinas EEPROM PIC16F873
Rutinas EEPROM PIC16F873
Rutinas EEPROM PIC16F873
Rutinas EEPROM PIC16F873 Referencia: http://es.slideshare.net/daveteslandaz/ microcontroladores-asm
TMR0
INTCON
INTCON
INTCON
INTCON
INTCON
INTCON
TIMER0 El bloque funcional TIMER0/WATCHDOG es un contador (registro) de 8 bits, incrementado por hardware y programable. La cuenta máxima es de 255(el incremento es constante e independiente). CONTADOR: Cuenta los eventos externos(a través del pin RA4/TOCK1) TEMPORIZADOR: Cuenta los pulsos internos del reloj Se puede insertar un prescaler, es decir, un divisor de frecuencia programable que puede dividir por 2, 4, 8, 16, 32, 64, 128 o 256. La frecuencia de reloj (fosc/4). Posteriormente, con el uso del prescaler se puede dividir la frecuencia. El bloque del TIMER0 puede funcionar como WATCHDOG, lo que permite que durante el funcionamiento normal del microcontrolador, un desbordamiento (o timeout) del Watchdog provoque un reset (Watchdog Timer Reset). Para evitar el desbordamiento se debe, cada cierto tiempo y antes de que llegue el limite, ejecutar una instrucción CLRWDT que borra el Watchdog y que hace comenzar un nuevo conteo desde cero EULER DEZFIGUEROA Euler_df28@hotmail.com
TIMER0 Se basa en un oscilador RC interno, independiente del oscilador del microcontrolador y que no requiere ningún componente externo. El Wachdog cuenta incluso si el reloj conectado a OSC1/CLK1 y/o OSC2/CLK2 esta parado, por ejemplo por la ejecucion de una instrucicion SLEEP o por un defecto del cristal oscilador Los regisros implicados en la configuracion del TIMER0/WDT son los siguientes: OPTION_REG: configura el «hardware» del TIMER0/WDT. INTCON: permite trabajar con la interrupcion el TIMER0/WDT TRISA: habilita la patilla RA4. EULER DEZFIGUEROA Euler_df28@hotmail.com
PROGRAMAS EN CCS COMPILER REGISTRO OPTION_REG (DIRECCION RAM : 81H,/181H) [pic16f877] Euler_df28@hotmail.com
PROGRAMAS EN CCS COMPILER REGISTRO OPTION_REG (DIRECCION RAM : 81H,/181H) [pic16f877] Euler_df28@hotmail.com
PROGRAMAS EN CCS COMPILER REGISTRO OPTION_REG (DIRECCION RAM : 81H,/181H) [pic16f877] TOCS: Procedencia de las señales 1= RA4/TOCK1 0=Reloj interno TOSE: Tipo de flanco en el TOCK1/RA4: 1= Flanco descendente 0=Flanco ascendente PSA: Asignacion del divisor de frecuencias: 1= WDT 0=TMR0 Euler_df28@hotmail.com
PROGRAMAS EN CCS COMPILER REGISTRO OPTION_REG (DIRECCION RAM : 81H,/181H) [pic16f877] PS2:PS1:PS0: Determina el divisor de frecuencias a actuar según la siguiente tabla El tiempo de desbordamiento del TIMER0 se calcula según la siguiente ecuación: T =TCM. Prescaler.(256 Carga TMR0 ) Donde TCM es el ciclo maquina que se puede calcular mediante la ecuacion: TCM = 4/FOSC Euler_df28@hotmail.com
PROGRAMAS EN CCS COMPILER Bibliografía "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS". DE E. Palacios, F. Remiro y L. López. CCS C Compiler Manual PCD CCS INC FEBREO 2015 CCS C Compiler Manual PCB/PCM/PCH CCS INC FEBREO 2015 Compilador C CCS y simulador PROTEUS para Microcontroladores PIC Eduardo García Breijo Diseño y simulacion de Sistemas microcontrolados en lenguaje C Juan Ricardo Clavijo Mendoza Programacion en CCS para Microcontroladores PIC Aaron Castro Bazua Datasheets ING.