Codigo:
;******************************* I2C_Display_Termometro_01.asm ************************;; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================;; Programa de control para un termómetro digital con el sensor de temperatura DS1624,; y visualización en cuatro displays.;; ZONA DE DATOS ********************************************************************** __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC LIST P=16F84A INCLUDECBLOCK 0x0C Registro50ms ; Guarda los incrementos cada 50 ms. ENDCTMR0_Carga50ms EQU -d"195" ; Para conseguir interrupción cada 50 ms.Carga2s EQU d"40" ; Leerá cada 2s = 40 x 50ms = 2000ms.; ZONA DE CÓDIGOS ******************************************************************** ORG 0 goto Inicio ORG 4 goto TermometroInicio call DS1624_Inicializa ; Configura el DS1624 e inicia la conversión. bsf STATUS,RP0 movlw b"00000111" ; Preescaler de 256 para el TMR0. movwf OPTION_REG bcf STATUS,RP0 movlw TMR0_Carga50ms ; Carga el TMR0 en complemento a 2. movwf TMR0 movlw Carga2s ; Y el registro cuyo decremento contará los 2 s. movwf Registro50ms movlw b"10100000" ; Activa interrupción del TMR0 (T0IE), movwf INTCON ; y la general (GIE).Principal goto Principal; Subrutina "Termometro" ----------------------------------------------------------------;; Esta subrutina lee y visualiza el termómetro cada 2 segundos aproximadamente. Se ejecuta; debido a la petición de interrupción del Timer 0, cada 50 ms. Para conseguir una; temporización de 2 s habrá que repetir 40 veces el lazo de 50 ms (40x50ms=2000ms=2s).;Termometro movlw TMR0_Carga50ms movwf TMR0 ; Recarga el TMR0. decfsz Registro50ms,F ; Decrementa el contador. goto Fin_Termometro ; No han pasado 2 segundos y por tanto sale. movlw Carga2s ; Repone el contador nuevamente. movwf Registro50ms call DS1624_LeeTemperatura ; Lee la temperatura. call DS1624_IniciaConversion ; Comienza conversión para la siguiente lectura. call VisualizaTermometro ; Visualiza el resultado de la lectura.Fin_Termometro bcf INTCON,T0IF retfie; Subrutina "VisualizaTermometro" -----------------------------------------------------------------;; Visualiza la temperatura en los cuatro displays de siete segmentos controlados por el SAA1064.; Se escribe comenzando por el final, por el display de la derecha.;; Entradas: - (DS1624_Temperatura), temperatura medida en valor absoluto.; - (DS1624_Decimal), parte decimal de la temperatura medida.; - (DS1624_Signo), indica signo de la temperatura.SAA1064_Direccion EQU b"01110000" ; SAA1064 como esclavo en bus I2C.VisualizaTermometro movf DS1624_Temperatura,W ; Hay que visualizar el valor absoluto de la call BIN_a_BCD ; temperatura en BCD. movwf DS1624_Temperatura ; Guarda el valor de la temperatura en BCD. call I2C_EnviaStart ; Envía condición de Start. movlw SAA1064_Direccion ; Apunta al SAA1064. call I2C_EnviaByte clrw ; El registro de control está en la posición 0. call I2C_EnviaByte movlw b"01000111" ; Palabra de control para luminosidad media call I2C_EnviaByte ; (12 mA) y visualización dinámica multiplexada. movlw "º" ; Escribe el símbolo de grados. call ASCII_a_7Segmentos ; Última letra debido a la disposición de los call I2C_EnviaByte ; displays. btfss DS1624_Signo,7 ; ¿Temperatura negativa? goto TemperaturaPositiva ; No, la temperatura es positiva.TemperaturaNegativa movf DS1624_Temperatura,W ; Recupera el valor de la temperatura en BCD. call Numero_a_7Segmentos ; Las unidades se pasan a código siete segmentos. call I2C_EnviaByte ; Lo envía al display. swapf DS1624_Temperatura,W ; Las decenas se pasan a código de siete call Numero_a_7Segmentos ; segmentos. call I2C_EnviaByte ; Lo envía al display. movlw "-" ; Visualiza el signo "-" de temperatura negativa. call ASCII_a_7Segmentos ; Lo pasa a siete segmentos. call I2C_EnviaByte ; Lo envía al display. goto Fin_VisualizaTemperaturaTemperaturaPositiva movf DS1624_Decimal,W ; Visualiza la parte decimal. call Numero_a_7Segmentos call I2C_EnviaByte ; Lo envía al display. movf DS1624_Temperatura,W ; Recupera el valor de la temperatura en BCD. call Numero_a_7Segmentos ; Las unidades se pasan a código siete segmentos. iorlw b"10000000" ; Le añade el punto decimal. call I2C_EnviaByte ; Lo envía al display. swapf DS1624_Temperatura,W ; Las decenas se pasan a código de siete call Numero_a_7Segmentos ; segmentos. call I2C_EnviaByte ; Lo envía al display.Fin_VisualizaTemperatura return INCLUDE INCLUDE INCLUDE INCLUDE INCLUDE END ; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================;**************************** Librería "DISPLAY_7S.INC **********************************;; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================;; Subrutinas para convertir un código ASCII en su valor equivalente en 7 segmentos y así; poder activar displays.;; Si el código ASCII es menor que el signo más "+" o mayor que la letra zeta "Z" obtiene; el código erróneo b"10000000" para encender sólo el punto decimal del display.;; Si se trata de un número hay que ejecutar la subrutina "Numero_a_7Segmentos" que convierte; un numero (de 0 a 9) en su equivalente en código de 7 segmentos.;; Entrada: En registro W, el dato en código ASCII a convertir.; Salida : En registro W, el código 7 segmentos. CBLOCK Display7s_Dato ; Aquí se reservará el valor del dato de entrada. ENDC Numero_a_7Segmentos andlw b"00001111" ; Se queda con el nibble bajo. addlw "0" ; Se pasa a ASCII sumándole el valor ASCII ; del "0" y ejecuta "ASCII_7_Segmentos".ASCII_a_7Segmentos movwf Display7s_Dato ; Guarda el valor del carácter. sublw " " ; Comprueba si es " " (espacio). btfsc STATUS,Z ; ¿Es distinta de " " (espacio)?, ¿Z=0? retlw 00h ; Es " ". Devuelve el código 7-Segmentos del " ". movf Display7s_Dato,W ; Recupera el valor del dato de entrada. sublw "Ñ" ; Comprueba si es "Ñ". btfsc STATUS,Z ; ¿Es distinta de "Ñ"?, ¿Z=0? retlw 55h ; Es "Ñ". Devuelve el código 7-Segmentos de "Ñ". movf Display7s_Dato,W ; Recupera el valor del dato de entrada. sublw "º" ; Comprueba si es "º". btfsc STATUS,Z ; ¿Es distinta de "º"?, ¿Z=0? retlw 63h ; Es "º". Devuelve el código 7-Segmentos de "º".; movf Display7s_Dato,W ; Comprueba si el código ASCII es mayor que la "Z". sublw "Z" ; (W)="Z"-(Display7s_Dato) btfss STATUS,C ; ¿C=1?, ¿(W) positivo?, ¿"Z">=(Display7s_Dato)? retlw b"10000000" ; Si el código ASCII es mayor que "Z" es un error. movlw "+" ; Averigua en qué orden está el carácter leído subwf Display7s_Dato,W ; dentro de la tabla de conversión, respecto del btfss STATUS,C ; primero que es "+". retlw b"10000000" ; Si el código ASCII es menor que "+" es un error.; addwf PCL,F ; Obtiene el código 7 segmentos.InicioTablaASCII DT 46h, 04h, 40h, 80h, 00h, 3Fh, 06h, 5Bh, 4Fh, 66h, 6Dh ; Signos y DT 7Dh, 07h, 7Fh, 67h, 41h, 88h, 00h, 48h, 00h, 00h, 00h ; números. DT 77h, 7Ch, 39h, 5Eh, 79h, 71h, 6Fh, 76h, 19h, 1Eh, 7Ah, 38h, 37h ; Letras. DT 54h, 3Fh, 73h, 67h, 50h, 6Dh, 78h, 1Ch, 3Eh, 1Dh, 70h, 6Eh, 49hFinTablaASCII;; Esta es la tabla para la visualización en display de siete segmentos (Ver figura 11-3). IF (FinTablaASCII > 0xFF) ERROR "¡CUIDADO!: La tabla ha superado el tamaño de la página de los" MESSG "primeros 256 bytes de memoria ROM. NO funcionará correctamente." ENDIF; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================;**************************** Librería "BUS_I2C.INC" ************************************;; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================;; Estas subrutinas permiten realizar las tareas básicas de control del bus serie I2C, ; por parte de un solo microcontrolador maestro.;; ZONA DE DATOS **********************************************************************; CBLOCK I2C_ContadorBits ; Cuenta los bits a transmitir o a recibir. I2C_Dato ; Dato a transmitir o recibido. I2C_Flags ; Guarda la información del estado del bus I2C. ENDC#DEFINE I2C_UltimoByteLeer I2C_Flags,0; - (I2C_UltimoByteLeer)=0, NO es el último byte a leer por el maestro.; - (I2C_UltimoByteLeer)=1, SÍ es el último byte a leer por el maestro.; La definición de las líneas SCL y SDA del bus I2C se puede cambiar según las; necesidades del hardware.#DEFINE SCL PORTA,3 ; Línea SCL del bus I2C.#DEFINE SDA PORTA,4 ; Línea SDA del bus I2C.;; Subrutina "SDA_Bajo" -------------------------------------------------------------------------------;SDA_Bajo bsf STATUS,RP0 ; Configura la línea SDA como salida. bcf SDA bcf STATUS,RP0 bcf SDA ; SDA en bajo. return;; Subrutina "SDA_AltaImpedancia" --------------------------------------------------------;SDA_AltaImpedancia bsf STATUS,RP0 ; Configura la línea SDA entrada. bsf SDA ; Lo pone en alta impedancia y, gracias a la bcf STATUS,RP0 ; Rp de esta línea, se mantiene a nivel alto. return;; Subrutina "SCL_Bajo" ------------------------------------------------------------------;SCL_Bajo bsf STATUS,RP0 bcf SCL ; Configura la línea SCL como salida. bcf STATUS,RP0 bcf SCL ; La línea de reloj SCL en bajo. return;; Subrutina "SCL_AltaImpedancia" --------------------------------------------------------;SCL_AltaImpedancia bsf STATUS,RP0 ; Configura la línea SCL entrada. bsf SCL ; Lo pone en alta impedancia y, gracias a la Rp bcf STATUS,RP0 ; de esta línea, se mantiene a nivel alto.SCL_EsperaNivelAlto btfss SCL ; Si algún esclavo mantiene esta línea en bajo goto SCL_EsperaNivelAlto ; hay que esperar. return;; Subrutina "I2C_EnviaStart" ------------------------------------------------------------;; Esta subrutina envía una condición de Start o inicio.;I2C_EnviaStart call SDA_AltaImpedancia ; Línea SDA en alto. call SCL_AltaImpedancia ; Línea SCL en alto. call Retardo_4micros ; Tiempo tBUF del protocolo. call SDA_Bajo ; Flanco de bajada de SDA mientras SCL está alto. call Retardo_4micros ; Tiempo tHD;STA del protocolo. call SCL_Bajo ; Flanco de bajada del reloj SCL. call Retardo_4micros return;; Subrutina "I2C_EnviaStop" -------------------------------------------------------------;; Esta subrutina envía un condición de Stop o parada.;I2C_EnviaStop call SDA_Bajo call SCL_AltaImpedancia ; Flanco de subida de SCL. call Retardo_4micros ; Tiempo tSU;STO del protocolo. call SDA_AltaImpedancia ; Flanco de subida de SDA. call Retardo_4micros ; Tiempo tBUF del protocolo. return;; Subrutina "I2C_EnviaByte" -------------------------------------------------------------;; El microcontrolador maestro transmite un byte por el bus I2C, comenzando por el bit; MSB. El byte a transmitir debe estar cargado previamente en el registro de trabajo W.; De la subrutina ejecutada anteriormente I2C_EnviaStart o esta misma I2C_EnviaByte, ; la línea SCL se debe encontrar a nivel bajo al menos durante 5 µs.;I2C_EnviaByte movwf I2C_Dato ; Almacena el byte a transmitir. movlw 0x08 ; A transmitir 8 bits. movwf I2C_ContadorBitsI2C_EnviaBit rlf I2C_Dato,F ; Chequea el bit, llevándolo previamente al Carry. btfsc STATUS,C goto I2C_EnviaUnoI2C_EnviaCero call SDA_Bajo ; Si es "0" envía un nivel bajo. goto I2C_FlancoSCLI2C_EnviaUno call SDA_AltaImpedancia ; Si es "1" lo activará a alto.I2C_FlancoSCL call SCL_AltaImpedancia ; Flanco de subida del SCL. call Retardo_4micros ; Tiempo tHIGH del protocolo. call SCL_Bajo ; Termina el semiperiodo positivo del reloj. call Retardo_4micros ; Tiempo tHD;DAT del protocolo. decfsz I2C_ContadorBits,F ; Lazo para los ocho bits. goto I2C_EnviaBit; call SDA_AltaImpedancia ; Libera la línea de datos. call SCL_AltaImpedancia ; Pulso en alto de reloj para que el esclavo call Retardo_4micros ; pueda enviar el bit ACK. call SCL_Bajo call Retardo_4micros return;; Subrutina "I2C_LeeByte" ---------------------------------------------------------------;; El microcontrolador maestro lee un byte desde el esclavo conectado al bus I2C. El dato; recibido se carga en el registro I2C_Dato y lo envía a la subrutina superior a través; del registro W. Se empieza a leer por el bit de mayor peso MSB.; De alguna de las subrutinas ejecutadas anteriormente I2C_EnviaStart, I2C_EnviaByte; o esta misma I2C_LeeByte, la línea SCL lleva en bajo al menos 5 µs.I2C_LeeByte movlw 0x08 ; A recibir 8 bits. movwf I2C_ContadorBits call SDA_AltaImpedancia ; Deja libre la línea de datos.I2C_LeeBit call SCL_AltaImpedancia ; Flanco de subida del reloj. bcf STATUS,C ; En principio supone que es "0". btfsc SDA ; Lee el bit bsf STATUS,C ; Si es "1" carga 1 en el Carry. rlf I2C_Dato,F ; Lo introduce en el registro. call SCL_Bajo ; Termina el semiperiodo positivo del reloj. call Retardo_4micros ; Tiempo tHD;DAT del protocolo. decfsz I2C_ContadorBits,F ; Lazo para los 8 bits. goto I2C_LeeBit;; Chequea si este es el último byte a leer para enviar o no el bit de reconocimiento; ACK en consecuencia.; btfss I2C_UltimoByteLeer ; Si es el último, no debe enviar ; el bit de reconocimiento ACK. call SDA_Bajo ; Envía el bit de reconocimiento ACK ; porque todavía no es el último byte a leer. call SCL_AltaImpedancia ; Pulso en alto del SCL para transmitir el call Retardo_4micros ; bit ACK de reconocimiento. Este es tHIGH. call SCL_Bajo ; Pulso de bajada del SCL. call Retardo_4micros movf I2C_Dato,W ; El resultado se manda en el registro de return ; de trabajo W. ; ===================================================================; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"; E. Palacios, F. Remiro y L. López.; Editorial Ra-Ma. www.ra-ma.es; ===================================================================
Codigo:
;**************************** Librería "DS1624.INC" *************************************
;
; ===================================================================
; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
; E. Palacios, F. Remiro y L. López.
; Editorial Ra-Ma. www.ra-ma.es
; ===================================================================
;
; Estas subrutinas permiten realizar las tareas de manejo del sensor de temperatura
; DS1624. Este sensor transmite la información vía serie a través de un bus I2C.
;
; ZONA DE DATOS **********************************************************************
CBLOCK
DS1624_Temperatura ; Parte entera de la temperatura medida.
DS1624_Decimal ; Parte decimal de la temperatura medida.
DS1624_Signo ; Signo de la temperatura medida.
ENDC
DS1624_DireccionEscritura EQU b"10010000"
DS1624_DireccionLectura EQU b"10010001"
Comando_ReadTemperature EQU 0AAh ; Comandos del DS1624.
Comando_StartConvert_T EQU 0EEh
Comando_AccessConfig EQU 0ACh
; Subrutina "DS1624_RedondeaDecimal" ----------------------------------------------------
;
; Esta subrutina redondea el valor del contenido del registro de trabajo W al valor más cercano
; con un decimal indicado en una tabla.
;
DS1624_RedondeoDecimal
addwf PCL,F
retlw d"0" ; (DS1624_Decimal)=b"0000". Mide 0,0000ºC. Redondeado a 0,0ºC.
retlw d"1" ; (DS1624_Decimal)=b"0001". Mide 0,0625ºC. Redondeado a 0,1ºC.
retlw d"1" ; (DS1624_Decimal)=b"0010". Mide 0,1250ºC. Redondeado a 0,1ºC.
retlw d"2" ; (DS1624_Decimal)=b"0011". Mide 0,1875ºC. Redondeado a 0,2ºC.
retlw d"3" ; (DS1624_Decimal)=b"0100". Mide 0,2500ºC. Redondeado a 0,3ºC.
retlw d"3" ; (DS1624_Decimal)=b"0101". Mide 0,3125ºC. Redondeado a 0,3ºC.
retlw d"4" ; (DS1624_Decimal)=b"0110". Mide 0,3750ºC. Redondeado a 0,4ºC.
retlw d"4" ; (DS1624_Decimal)=b"0111". Mide 0,4375ºC. Redondeado a 0,4ºC.
retlw d"5" ; (DS1624_Decimal)=b"1000". Mide 0,5000ºC. Redondeado a 0,5ºC.
retlw d"6" ; (DS1624_Decimal)=b"1001". Mide 0,5625ºC. Redondeado a 0,6ºC.
retlw d"6" ; (DS1624_Decimal)=b"1010". Mide 0,6250ºC. Redondeado a 0,6ºC.
retlw d"7" ; (DS1624_Decimal)=b"1011". Mide 0,6875ºC. Redondeado a 0,7ºC.
retlw d"8" ; (DS1624_Decimal)=b"1100". Mide 0,7500ºC. Redondeado a 0,8ºC.
retlw d"8" ; (DS1624_Decimal)=b"1101". Mide 0,8125ºC. Redondeado a 0,8ºC.
retlw d"9" ; (DS1624_Decimal)=b"1110". Mide 0,8750ºC. Redondeado a 0,9ºC.
retlw d"9" ; (DS1624_Decimal)=b"1111". Mide 0,9375ºC. Redondeado a 0,9ºC.
DS1624_FinTablaRedondeo
IF (DS1624_FinTablaRedondeo > 0xFF)
ERROR "¡CUIDADO!: La tabla ha superado el tamaño de la página de los"
MESSG "primeros 256 bytes de memoria ROM. NO funcionará correctamente."
ENDIF
; Subrutina "DS1624_Inicializa" ---------------------------------------------------------
;
; Configura el DS1624 para que trabaje en modo One-Shot.
DS1624_Inicializa
movlw DS1624_DireccionEscritura ; Apunta al dispositivo.
call I2C_EnviaByte
movlw Comando_AccessConfig ; Comando indicando que el próximo byte es la
call I2C_EnviaByte ; palabra de control.
movlw b"01001011" ; Carga la palabra de control para modo One-Shot.
call I2C_EnviaByte
call I2C_EnviaStop
; call DS1624_IniciaConversion ; Inicia la conversión de temperatura.
; return
; Subrutina "DS1624_IniciaConversion" ---------------------------------------------------------
;
; Inicializa el DS1624 para que comience la conversión de temperatura.
;
DS1624_IniciaConversion
call I2C_EnviaStart ; Configura el DS1624.
movlw DS1624_DireccionEscritura ; Apunta al dispositivo.
call I2C_EnviaByte
movlw Comando_StartConvert_T ; Comando que ordena el comienzo de la conversión
call I2C_EnviaByte ; de la temperatura.
call I2C_EnviaStop
return
; Subrutina "DS1624_LeeTemperatura" -----------------------------------------------------
;
; El DS1624 lee la temperatura en un formato ejemplificado como sigue:
;
; +125.0000 ºC 01111101 00000000
; + 25.0625 ºC 00011001 00010000
; + 0.5000 ºC 00000000 10000000
; + 0.0000 ºC 00000000 00000000
; - 0.5000 ºC 11111111 10000000
; - 25.0625 ºC 11100110 11110000
; - 55.0000 ºC 11001001 00000000
;
; Se observa que:
; - El formato es de dos bytes. El primer byte es la parte entera y el segundo la
; parte decimal.
; - Las temperaturas vienen dadas en complemento a 2.
; - Las temperaturas positivas comienzan con el bit MSB a cero: b"0xxxxxxx xxxxxxxx".
; - Las temperaturas negativas comienzan con e1 bit MSB a uno: b"1xxxxxxx xxxxxxxx".
;
; Esta subrutina lee la temperatura, proporcionando tres datos:
; Salida: - En (DS1624_Temperatura) la parte entera del valor de la temperatura medida.
; - En (DS1624_Decimal) la parte decimal del valor de la temperatura.
; - En (DS1624_Signo)=b"11111111" si la temperatura es negativa y
; (DS1624_Signo)=b"00000000" si es positiva.
;
DS1624_LeeTemperatura
bcf I2C_UltimoByteLeer
call I2C_EnviaStart
movlw DS1624_DireccionEscritura ; Apunta al dispositivo.
call I2C_EnviaByte
movlw Comando_ReadTemperature ; Comando de lectura de la temperatura.
call I2C_EnviaByte
call I2C_EnviaStart ; Comienza a leer.
movlw DS1624_DireccionLectura ; Apunta al dispositivo.
call I2C_EnviaByte
call I2C_LeeByte ; Lee el primer byte
movwf DS1624_Temperatura ; y lo guarda.
bsf I2C_UltimoByteLeer ; El próximo es el último byte a leer.
call I2C_LeeByte ; Lee el segundo byte
movwf DS1624_Decimal ; y lo guarda.
call I2C_EnviaStop
;
; Ahora deduce si la temperatura es positiva o negativa y halla su valor absoluto.
;
clrf DS1624_Signo ; Supone que la temperatura es positiva.
btfss DS1624_Temperatura,7 ; Si el bit MSB es "1", la temperatura es negativa.
goto DS1624_FinLeeTemperatura ; La temperatura es positiva y salta.
DS1624_TemperaturaNegativa
comf DS1624_Signo,F ; Indica que la temperatura es negativa.
comf DS1624_Decimal,F ; Para hallar el valor absoluto de la
comf DS1624_Temperatura,F ; temperatura invierte los dos registros y le
movlw .1 ; suma una unidad.
addwf DS1624_Decimal,F
btfsc STATUS,C ; Si hay acarreo tiene que llevarlo al byte superior.
incf DS1624_Temperatura,F ; Le suma 1.
DS1624_FinLeeTemperatura
swapf DS1624_Decimal,W ; Para las temperaturas es suficiente trabajar
andlw b"00001111" ; con un solo digito decimal, por lo que
call DS1624_RedondeoDecimal ; primero se queda con los 4 bits menos
movwf DS1624_Decimal ; significativo y pasa a redondear su valor.
movf DS1624_Temperatura,W ; En (W) la parte entera del valor absoluto de la
return ; temperatura.
; ===================================================================
; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
; E. Palacios, F. Remiro y L. López.
; Editorial Ra-Ma. www.ra-ma.es
; ===================================================================
;******************************** Librería "BIN_BCD.INC" ********************************
;
; ===================================================================
; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
; E. Palacios, F. Remiro y L. López.
; Editorial Ra-Ma. www.ra-ma.es
; ===================================================================
;
; Un número binario natural de 8 bits es convertido a BCD. El resultado se guarda en tres
; posiciones de memorias llamadas: BCD_Centenas, BCD_Decenas y BCD_Unidades.
;
; El procedimiento utilizado es mediante restas de 10, tal como se explicó en el capítulo 9.
;
; Entrada: En el registro W el número binario natural a convertir.
; Salidas: En (BCD_Centenas), (BCD_Decenas) y (BCD_Unidades).
; En el registro W también las decenas (nibble alto) y unidades (nibble bajo).
; Subrutina "BIN_a_BCD" -----------------------------------------------------------------
CBLOCK ; En las subrutinas no se debe fijar la dirección
BCD_Centenas ; de la RAM de usuario. Se toma a continuación de
BCD_Decenas ; la última asignada.
BCD_Unidades
ENDC
;
BIN_a_BCD
clrf BCD_Centenas ; Carga los registros con el resultado inicial.
clrf BCD_Decenas ; En principio las centenas y decenas a cero.
movwf BCD_Unidades ; Se carga el número binario a convertir.
BCD_Resta10
movlw .10 ; A las unidades se les va restando 10 en cada
subwf BCD_Unidades,W ; pasada. (W)=(BCD_Unidades) -10.
btfss STATUS,C ; ¿C = 1?, ¿(W) positivo?, ¿(BCD_Unidades)>=10?
goto BIN_BCD_Fin ; No, es menor de 10. Se acabó.
BCD_IncrementaDecenas
movwf BCD_Unidades ; Recupera lo que queda por restar.
incf BCD_Decenas,F ; Incrementa las decenas y comprueba si ha llegado
movlw .10 ; a 10. Lo hace mediante una resta.
subwf BCD_Decenas,W ; (W)=(BCD_Decenas)-10).
btfss STATUS,C ; ¿C = 1?, ¿(W) positivo?, ¿(BCD_Decenas)>=10?
goto BCD_Resta10 ; No. Vuelve a dar otra pasada, restándole 10 a
BCD_IncrementaCentenas ; las unidades.
clrf BCD_Decenas ; Pone a cero las decenas
incf BCD_Centenas,F ; e incrementa las centenas.
goto BCD_Resta10 ; Otra pasada: Resta 10 al número a convertir.
BIN_BCD_Fin
swapf BCD_Decenas,W ; En el nibble alto de (W) también las decenas.
addwf BCD_Unidades,W ; En el nibble bajo de (W) las unidades.
return ; Vuelve al programa principal.
; La directiva "END" se debe poner en el programa principal no aquí.
; ===================================================================
; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
; E. Palacios, F. Remiro y L. López.
; Editorial Ra-Ma. www.ra-ma.es
; ===================================================================
;**************************** Librería "RETARDOS.INC" *********************************
;
; ===================================================================
; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
; E. Palacios, F. Remiro y L. López.
; Editorial Ra-Ma. www.ra-ma.es
; ===================================================================
;
; Librería con múltiples subrutinas de retardos, desde 4 microsegundos hasta 20 segundos.
; Además se pueden implementar otras subrutinas muy fácilmente.
;
; Se han calculado para un sistema microcontrolador con un PIC trabajando con un cristal
; de cuarzo a 4 MHz. Como cada ciclo máquina son 4 ciclos de reloj, resulta que cada
; ciclo máquina tarda 4 x 1/4MHz = 1 µs.
;
; En los comentarios, "cm" significa "ciclos máquina".
;
; ZONA DE DATOS *********************************************************************
CBLOCK
R_ContA ; Contadores para los retardos.
R_ContB
R_ContC
ENDC
;
; RETARDOS de 4 hasta 10 microsegundos ---------------------------------------------------
;
; A continuación retardos pequeños teniendo en cuenta que para una frecuencia de 4 MHZ,
; la llamada a subrutina "call" tarda 2 ciclos máquina, el retorno de subrutina
; "return" toma otros 2 ciclos máquina y cada instrucción "nop" tarda 1 ciclo máquina.
;
Retardo_10micros ; La llamada "call" aporta 2 ciclos máquina.
nop ; Aporta 1 ciclo máquina.
nop ; Aporta 1 ciclo máquina.
nop ; Aporta 1 ciclo máquina.
nop ; Aporta 1 ciclo máquina.
nop ; Aporta 1 ciclo máquina.
Retardo_5micros ; La llamada "call" aporta 2 ciclos máquina.
nop ; Aporta 1 ciclo máquina.
Retardo_4micros ; La llamada "call" aporta 2 ciclos máquina.
return ; El salto del retorno aporta 2 ciclos máquina.
;
; RETARDOS de 20 hasta 500 microsegundos ------------------------------------------------
;
Retardo_500micros ; La llamada "call" aporta 2 ciclos máquina.
nop ; Aporta 1 ciclo máquina.
movlw d"164" ; Aporta 1 ciclo máquina. Este es el valor de "K".
goto RetardoMicros ; Aporta 2 ciclos máquina.
Retardo_200micros ; La llamada "call" aporta 2 ciclos máquina.
nop ; Aporta 1 ciclo máquina.
movlw d"64" ; Aporta 1 ciclo máquina. Este es el valor de "K".
goto RetardoMicros ; Aporta 2 ciclos máquina.
Retardo_100micros ; La llamada "call" aporta 2 ciclos máquina.
movlw d"31" ; Aporta 1 ciclo máquina. Este es el valor de "K".
goto RetardoMicros ; Aporta 2 ciclos máquina.
Retardo_50micros ; La llamada "call" aporta 2 ciclos máquina.
nop ; Aporta 1 ciclo máquina.
movlw d"14" ; Aporta 1 ciclo máquina. Este es el valor de "K".
goto RetardoMicros ; Aporta 2 ciclos máquina.
Retardo_20micros ; La llamada "call" aporta 2 ciclos máquina.
movlw d"5" ; Aporta 1 ciclo máquina. Este es el valor de "K".
;
; El próximo bloque "RetardoMicros" tarda:
; 1 + (K-1) + 2 + (K-1)x2 + 2 = (2 + 3K) ciclos máquina.
;
RetardoMicros
movwf R_ContA ; Aporta 1 ciclo máquina.
Rmicros_Bucle
decfsz R_ContA,F ; (K-1)x1 cm (cuando no salta) + 2 cm (al saltar).
goto Rmicros_Bucle ; Aporta (K-1)x2 ciclos máquina.
return ; El salto del retorno aporta 2 ciclos máquina.
;
;En total estas subrutinas tardan:
; - Retardo_500micros: 2 + 1 + 1 + 2 + (2 + 3K) = 500 cm = 500 µs. (para K=164 y 4 MHz).
; - Retardo_200micros: 2 + 1 + 1 + 2 + (2 + 3K) = 200 cm = 200 µs. (para K= 64 y 4 MHz).
; - Retardo_100micros: 2 + 1 + 2 + (2 + 3K) = 100 cm = 100 µs. (para K= 31 y 4 MHz).
; - Retardo_50micros : 2 + 1 + 1 + 2 + (2 + 3K) = 50 cm = 50 µs. (para K= 14 y 4 MHz).
; - Retardo_20micros : 2 + 1 + (2 + 3K) = 20 cm = 20 µs. (para K= 5 y 4 MHz).
;
; RETARDOS de 1 ms hasta 200 ms. --------------------------------------------------------
;
Retardo_200ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d"200" ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_100ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d"100" ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_50ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d"50" ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_20ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d"20" ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_10ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d"10" ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_5ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d"5" ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_2ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d"2" ; Aporta 1 ciclo máquina. Este es el valor de "M".
goto Retardos_ms ; Aporta 2 ciclos máquina.
Retardo_1ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d"1" ; Aporta 1 ciclo máquina. Este es el valor de "M".
;
; El próximo bloque "Retardos_ms" tarda:
; 1 + M + M + KxM + (K-1)xM + Mx2 + (K-1)Mx2 + (M-1) + 2 + (M-1)x2 + 2 =
; = (2 + 4M + 4KM) ciclos máquina. Para K=249 y M=1 supone 1002 ciclos máquina
; que a 4 MHz son 1002 µs = 1 ms.
;
Retardos_ms
movwf R_ContB ; Aporta 1 ciclo máquina.
R1ms_BucleExterno
movlw d"249" ; Aporta Mx1 ciclos máquina. Este es el valor de "K".
movwf R_ContA ; Aporta Mx1 ciclos máquina.
R1ms_BucleInterno
nop ; Aporta KxMx1 ciclos máquina.
decfsz R_ContA,F ; (K-1)xMx1 cm (cuando no salta) + Mx2 cm (al saltar).
goto R1ms_BucleInterno ; Aporta (K-1)xMx2 ciclos máquina.
decfsz R_ContB,F ; (M-1)x1 cm (cuando no salta) + 2 cm (al saltar).
goto R1ms_BucleExterno ; Aporta (M-1)x2 ciclos máquina.
return ; El salto del retorno aporta 2 ciclos máquina.
;
;En total estas subrutinas tardan:
; - Retardo_200ms: 2 + 1 + 2 + (2 + 4M + 4KM) = 200007 cm = 200 ms. (M=200 y K=249).
; - Retardo_100ms: 2 + 1 + 2 + (2 + 4M + 4KM) = 100007 cm = 100 ms. (M=100 y K=249).
; - Retardo_50ms : 2 + 1 + 2 + (2 + 4M + 4KM) = 50007 cm = 50 ms. (M= 50 y K=249).
; - Retardo_20ms : 2 + 1 + 2 + (2 + 4M + 4KM) = 20007 cm = 20 ms. (M= 20 y K=249).
; - Retardo_10ms : 2 + 1 + 2 + (2 + 4M + 4KM) = 10007 cm = 10 ms. (M= 10 y K=249).
; - Retardo_5ms : 2 + 1 + 2 + (2 + 4M + 4KM) = 5007 cm = 5 ms. (M= 5 y K=249).
; - Retardo_2ms : 2 + 1 + 2 + (2 + 4M + 4KM) = 2007 cm = 2 ms. (M= 2 y K=249).
; - Retardo_1ms : 2 + 1 + (2 + 4M + 4KM) = 1005 cm = 1 ms. (M= 1 y K=249).
;
; RETARDOS de 0.5 hasta 20 segundos ---------------------------------------------------
;
Retardo_20s ; La llamada "call" aporta 2 ciclos máquina.
movlw d"200" ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_10s ; La llamada "call" aporta 2 ciclos máquina.
movlw d"100" ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_5s ; La llamada "call" aporta 2 ciclos máquina.
movlw d"50" ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_2s ; La llamada "call" aporta 2 ciclos máquina.
movlw d"20" ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_1s ; La llamada "call" aporta 2 ciclos máquina.
movlw d"10" ; Aporta 1 ciclo máquina. Este es el valor de "N".
goto Retardo_1Decima ; Aporta 2 ciclos máquina.
Retardo_500ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d"5" ; Aporta 1 ciclo máquina. Este es el valor de "N".
;
; El próximo bloque "Retardo_1Decima" tarda:
; 1 + N + N + MxN + MxN + KxMxN + (K-1)xMxN + MxNx2 + (K-1)xMxNx2 +
; + (M-1)xN + Nx2 + (M-1)xNx2 + (N-1) + 2 + (N-1)x2 + 2 =
; = (2 + 4M + 4MN + 4KM) ciclos máquina. Para K=249, M=100 y N=1 supone 100011
; ciclos máquina que a 4 MHz son 100011 µs = 100 ms = 0,1 s = 1 décima de segundo.
;
Retardo_1Decima
movwf R_ContC ; Aporta 1 ciclo máquina.
R1Decima_BucleExterno2
movlw d"100" ; Aporta Nx1 ciclos máquina. Este es el valor de "M".
movwf R_ContB ; Aporta Nx1 ciclos máquina.
R1Decima_BucleExterno
movlw d"249" ; Aporta MxNx1 ciclos máquina. Este es el valor de "K".
movwf R_ContA ; Aporta MxNx1 ciclos máquina.
R1Decima_BucleInterno
nop ; Aporta KxMxNx1 ciclos máquina.
decfsz R_ContA,F ; (K-1)xMxNx1 cm (si no salta) + MxNx2 cm (al saltar).
goto R1Decima_BucleInterno ; Aporta (K-1)xMxNx2 ciclos máquina.
decfsz R_ContB,F ; (M-1)xNx1 cm (cuando no salta) + Nx2 cm (al saltar).
goto R1Decima_BucleExterno ; Aporta (M-1)xNx2 ciclos máquina.
decfsz R_ContC,F ; (N-1)x1 cm (cuando no salta) + 2 cm (al saltar).
goto R1Decima_BucleExterno2 ; Aporta (N-1)x2 ciclos máquina.
return ; El salto del retorno aporta 2 ciclos máquina.
;
;En total estas subrutinas tardan:
; - Retardo_20s: 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 20000807 cm = 20 s.
; (N=200, M=100 y K=249).
; - Retardo_10s: 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 10000407 cm = 10 s.
; (N=100, M=100 y K=249).
; - Retardo_5s: 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 5000207 cm = 5 s.
; (N= 50, M=100 y K=249).
; - Retardo_2s: 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 2000087 cm = 2 s.
; (N= 20, M=100 y K=249).
; - Retardo_1s: 2 + 1 + 2 + (2 + 4N + 4MN + 4KMN) = 1000047 cm = 1 s.
; (N= 10, M=100 y K=249).
; - Retardo_500ms: 2 + 1 + (2 + 4N + 4MN + 4KMN) = 500025 cm = 0,5 s.
; (N= 5, M=100 y K=249).
; ===================================================================
; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
; E. Palacios, F. Remiro y L. López.
; Editorial Ra-Ma. www.ra-ma.es
; ===================================================================




Ya lo he subido, este es el link.amigo me puedes pasar los archivos por favor vicsaga15@gmail.com
<a href="http://rapidshare.de/files/2282089/termometre_disp7seg.jpg.html" target="_blank">http://rapidshare.de/files/2282089/termometre_disp7seg.jpg.html[/url]
Salu2