
;****************************   Tarjeta PIC    ***************************
;
;                         INTETRFACE PC - HARWARE
;
; Descripción: el programa principal espera a recibir un telecomando del PC.
;              La recepción proboca una interrupción de baja prioridad que 
;              guarda los datos de los sensores, los interpreta y actua en 
;              en cosnsecuencia.
;
;              Paralelamente se iran enviando los datos al PC para su
;              monitorización.
;
;           
; Tipo Reloj: HS
; Velocidad Reloj: 10MHz
; Reloj Instruccion: 2,5 MHz = 0,4us
; Perro Guardian: deshabilitado
; Proteccion de codigo: OFF
; 
;*************************************************************************


;DATOS

	LIST     P=18F8722              ;Tipo de procesador
	INCLUDE <P18F8722.INC>          ;Definicion del archivo donde estan 
	                                ;definidos todos los registros del P18F8722 
	                                
	                                
;------------------ VARIABLES

TXDATO                         equ 0x10 ;Variables VARIAS
RXDATO                         equ 0x11
CONTADOR                       equ 0x12
GUARDA                         equ 0x13


CABECERA_PAQUETE               equ 0x14 ;Variables TELECOMANDO 
FIN_PAQUETE                    equ 0x15

TELEMETRIA_COMIENZO            equ 0x16 ;Variables TELEMETRIA
TEMP_PRIMARIA                  equ 0x17
TEMP_AMBIENTE                  equ 0x18
TIMESTAMP_H_MSB                equ 0x19
TIMESTAMP_L_MSB                equ 0x1A
TIMESTAMP_H_LSB                equ 0x1B
TIMESTAMP_L_LSB                equ 0x1C
TELEMETRIA_FIN                 equ 0x1D


;CODIGO

	ORG   0x00                     ;inicio en el vector de reset
	goto  INICIO                   ;va a la primera instrucción de programa
	
	ORG   0x08                     ;vector de interrupción de alta prioridad	
	goto  TIMESTAMP                ;subrrutina de atención a interrupción de alta prioridad
	
	ORG   0x18                     ;vector de interrupción de baja prioridad
	goto  TELECOMANDO              ;subrrutina de atención a interrupción de baja prioridad

MNBMNB
;*************************************************************************
;-------------------------------------------------------------------------
;********** RUTINA DE ATENCION A INTERRUPCION DE ALTA PRIORIDAD ********** 
;-------------------------------------------------------------------------	
;*************************************************************************
		 
TIMESTAMP  
          
        bcf   T1CON,TMR1ON             ;paramos TIMER_1
        bcf   PIR1,TMR1IF              ;limpiamos flag overflow
        
        movwf GUARDA                   ;guardamos el valor del registro W para no perderlo 
                                      
        incf  TIMESTAMP_L_LSB          ;incrementamos TIMESTAMP (contador 32 bits a 10us)
        btfss STATUS,C                 ;desbordamiento TIMESTAMP_L_LSB
        goto  SEGUIR 
        incf  TIMESTAMP_H_LSB        
        btfss STATUS,C                 ;desbordamiento TIMESTAMP_H_LSB
        goto  SEGUIR                         
        incf  TIMESTAMP_L_MSB
        btfss STATUS,C                 ;desbordamiento TIMESTAMP_L_MSB
        goto  SEGUIR 
        incf  TIMESTAMP_H_MSB        
   
SEGUIR        
        movlw B'01101011'              ;comparamos el TIMESTAMP para saber 
        cpfseq TIMESTAMP_H_MSB         ;si ha llegado a 5 HORAS
        goto SEGUIR2                   
        movlw B'01001001'                 
        cpfseq TIMESTAMP_L_MSB
        goto SEGUIR2  
        movlw B'11010010'                 
        cpfseq TIMESTAMP_H_LSB
        goto SEGUIR2 
        movlw B'00000000'                 
        cpfseq TIMESTAMP_L_LSB 
        goto SEGUIR2
        clrf TIMESTAMP_H_MSB
        clrf TIMESTAMP_L_MSB
        clrf TIMESTAMP_H_LSB
        clrf TIMESTAMP_L_LSB   
               
SEGUIR2
             
        movlw H'FF'                    ;precarga 5,8us + (4,2us en istrucciones)=10us
        movwf TMR1H 
        movlw H'FC'
        movwf TMR1L
        
        bsf   T1CON,TMR1ON             ;habilitamos TIMER_1
        
        movf GUARDA,W                  ;recuperamos el valor inicial de W
        
        retfie       
        
        
;*************************************************************************        
;-------------------------------------------------------------------------
;********** RUTINA DE ATENCION A INTERRUPCION DE BAJA PRIORIDAD **********
;-------------------------------------------------------------------------
;*************************************************************************
        
        
TELECOMANDO              
        
        bcf   PIE1,RC1IE               ;deshabilitamos interrupción de recepción EUSART_1

        movf  RCREG1,W
        movwf CABECERA_PAQUETE
        bcf   RCSTA1,CREN              ;limpiamos posibles errores
        bsf   RCSTA1,CREN              ;deshabilitando y habilitando CREN
        
FIN_TELECOMANDO

       
        btfss PIR1,RC1IF               ;testeamos si el buffer de RX lleno(flag RC1IF=1)
        goto  FIN_TELECOMANDO          ;vacio = no hay dato (esperamos)
        movf  RCREG1,W
        movwf FIN_PAQUETE
        bcf   RCSTA1,CREN              ;limpiamos posibles errores
        bsf   RCSTA1,CREN              ;deshabilitando y habilitando CREN
        
                                       
;------------------ INTERPRETACION 

INTERPRETAR_TELECOMANDO                ;interpretamos la cabecera de telecomando obtenida 

TELECOMANDO_1                          ;Comienzo de Conexión

        movlw H'00'                 
        cpfseq CABECERA_PAQUETE        ;comparamos y si no es igual, pasamos al siguiente 
        goto  SOLICITUD_TELEMETRIA     
        goto  COMIENZO_CONEXION        
           

TELECOMANDO_2                          ;Solicitud de Telemetría

        movlw H'11'                 
        cpfseq CABECERA_PAQUETE        ;comparamos y si no es igual saltamos siguiente telecomando
        goto  SOLICITUD_TELEMETRIA
        goto  FINAL_CONEXION
        
TELECOMANDO_3                          ;2º Final de Conexión
        
        movlw H'FF'                 
        cpfseq CABECERA_PAQUETE        ;comparamos y si no es igual ERROR
        goto  FINAL_CONEXION 
        goto  SOLICITUD_TELEMETRIA     ;en caso de ERROR enviamos Telemetria
  
  
 ;------------------ EJECUCION DE TELECOMANDOS
                     
COMIENZO_CONEXION                      ; 1º
                        
        call  TEMPO                    ;primera cuenta de 10 us
        call  TOMAR_DATOS              ;recogemos datos de los sensores
        call  TELEMETRIA               ;enviamos datos de los sensores
        goto  FIN_INTERRUPCION_BAJA_PRIORIDAD
              
;------------------

SOLICITUD_TELEMETRIA                   ; 2º
      
        call  TOMAR_DATOS
        call  TELEMETRIA
        goto  FIN_INTERRUPCION_BAJA_PRIORIDAD

;------------------           

FINAL_CONEXION                         ; 3º
      
        reset                          ;reset por software, se inicializará de nuevo
     
FIN_INTERRUPCION_BAJA_PRIORIDAD

        bsf   PIE1,RC1IE               ;habilitamos interrupción de recepción EUSART_1
        bcf   TXSTA1,TXEN              ;deshabilitamos transmisión
        bsf   RCSTA1,CREN              ;habilitamos recepción 
        
        retfie                         ;salimos al programa principal    
        
       
;*************************************************************************	
;                    SUBRUTINA Tomar Datos sensores / Alarma
;************************************************************************* 

TOMAR_DATOS     
 
        movf  PORTH,W                  ;cogemos el dato del puerto H
        movwf TEMP_PRIMARIA            ;escribimos dato variable
        movf  PORTJ,W                  ;cogemos dato del puerto J
        movwf TEMP_AMBIENTE            ;escribimos dato variable 
        
PRIMARIA_BAJA                          ;interpretacion de la temperatura PEIMARIA (0-90ºC)    
        
        movlw  D'0'     
        cpfslt TEMP_PRIMARIA           ;comparamos si es menor a 0ºC
     	goto   PRIMARIA_ALTA           ;si es mayor comaparamos con mayor
        goto   ALARMA_PRIMARIA_BAJA    ;si es menor ALARMA_BAJA
        
PRIMARIA_ALTA
        
        movlw  D'90'
        cpfsgt TEMP_PRIMARIA           ;cpmparamos si es mayor a 90ºC
        goto   AMBIENTE_BAJA           ;si es menor pasamos a temperatura ambiente  
        goto   ALARMA_PRIMARIA_ALTA    ;si es mayor ALARMA_ALTA
       
AMBIENTE_BAJA                          ;interpretacion de las temperaturas para ALARMA_AMBIENTE
         
        movlw  D'0'     
        cpfslt TEMP_AMBIENTE           ;comparamos si es menor a 0ºC
	    goto   AMBIENTE_ALTA           ;si es mayor comparamos con mayor
        goto   ALARMA_PRIMARIA_BAJA    ;si es menor ALARMA_BAJA
        
AMBIENTE_ALTA
        
        movlw  D'60'
        cpfsgt TEMP_AMBIENTE           ;comparamos si es mayor a 90ºC
        goto   SEGUIR_ALARMA           ;si es menor salimos de las comparaciones    
        goto   ALARMA_AMBIENTE_ALTA    ;si es mayor ALARMA_ALTA    
        
SEGUIR_ALARMA
        
        return      
              
ALARMA_PRIMARIA_BAJA

        movlw  B'00000001'   
        movwf  PORTD                  ;encendemos led RD 0
        goto AMBIENTE_BAJA

ALARMA_PRIMARIA_ALTA

        movlw  B'00000010'
        movwf  PORTD                  ;encendemos led RD 1
        goto   AMBIENTE_BAJA

ALARMA_AMBIENTE_BAJA

        movlw  B'00000100'
        movwf  PORTD                  ;encendemos led RD 2
        goto   SEGUIR_ALARMA

ALARMA_AMBIENTE_ALTA

        movlw  B'00001000'
        movwf  PORTD                  ;encendemos led RD 3
        goto   SEGUIR_ALARMA
        
        
;*************************************************************************	
;                     SUBRUTINA Enviar Telemetría
;*************************************************************************

TELEMETRIA

        ;recorrer una tabla en RAM para enviarla
        
        movlw H'00'                    ;inicializamos cabecera y final de paquete
        movwf TELEMETRIA_COMIENZO
        movlw H'FF'
        movwf TELEMETRIA_FIN
        
        movlw D'7'        
        movwf CONTADOR                 ;inicializamos contador de variables de telemetría
        
        movlw TELEMETRIA_COMIENZO      ;inicializamos puntero de tabla
        movwf FSR0L
        
BUCLE_ADQUISICION
        
        call  LEER_TABLA
        decfsz CONTADOR,1
        goto  BUCLE_ADQUISICION
        
        return

;*************************************************************************	
;                   SUBRUTINA Leer Tabla Telemetría y enviarlo
;*************************************************************************

LEER_TABLA
        
        ;movlw H'35'                      ;dato de prueba para ver que lo trasmite porque las variables estan a cero
        movf  INDF0,W                  ;leemos dato de tabla 
        movwf TXDATO
     
;enviamos dato por puerto serie
        
        bsf   RCSTA1,SPEN               ;habilitamos comunicacion serie
        bsf   TXSTA1,TXEN              ;habilitamos transmisión
        bcf   RCSTA1,CREN              ;deshabilitamos recepción
        
        movf  TXDATO,W                 ;en el momento en que se pone el dato en TXREG1
        movwf TXREG1                   ;este es enviado

BUCLE 

        btfss TXSTA1,TRMT              ;esperamos registro TSR vacio (flag TRMT=1)  
        goto  BUCLE                    ;no vacio, esperamos
        bcf   PIR1,TX1IF
        incf  FSR0L,1                  ;incrementamos puntero de tabla
       
        return 
      
;*************************************************************************	
;                  SUBRUTINA Primera Cuenta 10us (TIMER_1)
;************************************************************************* 
 
TEMPO

        movlw B'10001000'              ;timer 16 bits y oscilador habilitado
        movwf T1CON               
        
        bsf   PIE1,TMR1IE              ;habilitamos interrupción TIMER_1 (overflow)
        bcf   PIR1,TMR1IF              ;limpiamos flag de interrupción TIMER_1 (flag de overflow)
        
        movlw H'FF'                    ;precarga de 16 bits (2 bytes)
        movwf TMR1H                    ;precarga byte alto
        movlw H'DB'                    ;precarga byte bajo
        movwf TMR1L                    ;precarga 7,4us + (2,6us en istrucciones)=10us
        
        bsf   T1CON,TMR1ON             ;habilitamos TIMER_1
        
        return
                                
                    
;------------------- SURUTINAS DEL PROGRAMA PRINCIPAL --------------------  
;*************************************************************************


;*************************************************************************	
;                   SUBRUTINA Inicialización Puertos 
;*************************************************************************
  
INICIALIZAR_PUERTOS

        clrf  PORTA                    ;limpiamos puerto A
        movlw B'00000000'              ;Puerto A de SALIDA
        movwf TRISA
        
        clrf  PORTB                    ;limpiamos puerto B
        movlw B'00000000'              ;Puerto B de SALIDA
        movwf TRISB
        
        clrf  PORTC                    ;limpiamos puerto C
        movlw B'10000000'              ;Puerto C de SALIDA (configurar TX1=1 y RX1=0)
        movwf TRISC
        
        clrf  PORTD                    ;limpiamos puerto D
        movlw B'00000000'              ;Puerto D de SALIDA (prueba led´s)
        movwf TRISD
        
        clrf  PORTE                    ;limpiamos puerto E
        movlw B'00000000'              ;Puerto E de SALIDA 
        movwf TRISE
                
        clrf  PORTF                    ;limpiamos puerto F
        movlw B'00000000'              ;puerto F de SALIDA 
        movwf TRISF
        
        clrf  PORTG                    ;limpiamos puerto G
        movlw B'11100100'              ;RG0,RG1,RG3 y RG4 como SALIDAS y RG2 como ENTRADA
        movwf TRISG
         
        clrf  PORTH                    ;limpiamos puerto H
        movlw B'11111111'              ;Puerto H de ENTRADA (sensor temperatura primaria)
        movwf TRISH
        
        clrf  PORTJ                    ;limpiamos puerto J
        movlw B'11111111'              ;Puerto J de ENTRADA (sensor temperatura ambiente)
        movwf TRISJ
        
        return

;*************************************************************************	
;                   SUBRUTINA Inicialización Registros 
;*************************************************************************

INICIALIZAR_REGISTROS

        movlw D'5'     
        movwf CONTADOR                 ;inicializamos contador de variables de telemetría
       
        movlw TELEMETRIA_COMIENZO
        movwf FSR0L                    ;inicializamos puntero de tabla
        
BUCLE_INICIACION
        
        clrf  INDF0                    ;limpiamos la variable
        incf  FSR0L,1                  ;incrementamos puntero de tabla
        decfsz CONTADOR,1
        goto  BUCLE_INICIACION
        
        return
   
;*************************************************************************	
;                   SUBRUTINA Inicialización Interrupciones
;*************************************************************************        
        
INICIALIZAR_INTERRUPCIONES      
           
        bsf   RCON,IPEN                 ;habilitamos prioridades de interrupción
        bsf   INTCON,GIEH               ;habilitamos interrupción de alta prioridad 
        bsf   INTCON,GIEL               ;habilitamos interrupción de baja prioridad
        bcf   IPR1,RC1IP                ;baja prioridad para interrupcion de recepción 
        bsf   IPR1,TMR1IP               ;alta prioridad para interrupción timrer_1
     
        
        return        
       
;*************************************************************************	
;                   SUBRUTINA Inicialización EUSART_1
;*************************************************************************         
       
INICIALIZAR_EUSART_1

        clrf  PORTC
        movlw b'10000000'
        movwf TRISC
        movlw .64                    ;9600 baudios
        movwf SPBRG1 
        movlw .0                  
        movwf SPBRGH1 

        bsf   TXSTA1,BRGH          
        bcf   BAUDCON1,BRG16
        
       
        bcf   TXSTA1,SYNC
        bsf   RCSTA1,SPEN
        bsf   RCSTA1,CREN

        bsf   PIE1,RC1IE                ;habilitamos interrupción de recepción EUSART_1
        
        return       
      
        
;************************************************************************* 
;-------------------------------------------------------------------------      
;------------------ oooOOO PROGRAMA PRINCIPAL OOOooo ---------------------
;-------------------------------------------------------------------------
;*************************************************************************


INICIO  

;------------------ INICIALIZAMOS LOS PUERTOS

        call  INICIALIZAR_PUERTOS
              
;------------------ INICIALIZAMOS PRIORIDAD PARA LAS INTERRUPCIONES

        call  INICIALIZAR_INTERRUPCIONES

;------------------ INICIALIZAMOS REGISTROS TELEMETRIA
        
        call  INICIALIZAR_REGISTROS    ;limpiamos los registros de telemetría
        
;------------------ INICIALIZAMOS LA USART_2

        call  INICIALIZAR_EUSART_1
        
;------------------ BUCLE DE ESPERA

BUCLE_DE_ESPERA     

       nop
       nop
       nop
       goto   BUCLE_DE_ESPERA
              
       END

