Ahi va el programa y las subrutinas.el esquema escaneado ocupa bastante y no me deja subirlo al servidor, dejame tu correo y te lo mando
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 INCLUDE CBLOCK 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; ===================================================================