Controlar estaque de agua con un PIC

Muchas gracias.

Lo he hecho así, espero que esté bien el oscilador interno. (Hacías tiempo que no pasabas por aquí como antes, bienvenido).

Como dije antes haré el proyecto 1 a cables y puede que con pilas, que al pulsar un botón se active el PIC12F508 y poder ver el nivel que hay en el agua y sin consumir energía constantemente.

Código:
;+---------------------------------+
;¦ PROCESADOR A EMPLEAR PIC12F50x  ¦
;+---------------------------------+
SELECCIONAR    EQU 0          ;0=PIC12F508 1=PIC12F509
     IF            SELECCIONAR
    LIST        P=12F509
    INCLUDE        <P12F509.INC>
     ELSE
    LIST        P=12F508
    INCLUDE        <P12F508.INC>
     ENDIF 
;+-----------------------------------+
;¦ FUSIBLES, WASDOG, OSCILADOR ETC.. ¦
;+-----------------------------------+
    __CONFIG   _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC

    CBLOCK    0x08
    Flag
    TEMP
    ENDC

#DEFINE    S1    GPIO,2                ; Sensor S1.
#DEFINE    S2    GPIO,3                ; Sensor S2.
#DEFINE    LV    GPIO,0                ; Led verde.
#DEFINE    LA    GPIO,1                ; Led Amarillo.
#DEFINE    LR    GPIO,4                ; Led Rojo.
#DEFINE    M    GPIO,5                ; Motor.

; ZONA DE CÓDIGOS ********************************************************************

    ORG        0x1FF            ; Calibración del 
    movwf    OSCCAL            ; oscilador interno.

    ORG        0

Inicio
;    movwf   OSCCAL          ;CALIBRA EL OSCILADOR INTERNO 
;    movlw   b'11000010'     ;CONFIGURA TMR0 PRESCALER = 1:8
;    OPTION                     ;OSCILADOR = 4MHZ



    movlw    b'00001100'
    TRIS    GPIO            ;PUERTOS EN ALTO
    clrw

Principal    
    movf     GPIO,W                 ; Lee los sensores.
    andlw     b'00001100'         ; Máscara para quedarse con el valor de los sensores.
    movwf     TEMP                 ; CArga a un registro temporal para hacer el corrimiento
    bcf     STATUS,C             ;limpiamos el carry
    rrf     TEMP,F                 ;primer corrimiento a la derecha
    rrf     TEMP,W                 ;segundo corrimiento a la derecha y se almacena en W
    addwf     PCL,F                 ; Salta a la configuración adecuada.                    
    goto    Configuracion0
    goto    Configuracion1
    goto    Configuracion2
    goto    Configuracion3
Configuracion0
    movlw     b'00000001'    
    clrf    Flag    
    goto    ActivaSalida
Configuracion1
    movlw     b'00000010'    
    btfss    Flag,0        
    goto    ActivaSalida
Configuracion2        
    goto    Configuracion3
Configuracion3
    movlw    .1
    movwf    Flag
    movlw     b'00110000'            
    goto    ActivaSalida
ActivaSalida
    movwf    GPIO                
    goto     Principal

    END
Por otro lado, en el segundo bidón que tengo también de 1.000 L. Haré el proyecto 2 con el SFR05 compatible con el SFR04. Viendo el libro, parece sencillo de hacer.

NX-SFR05.jpg


Código:
;********************************** Sensor_ Ultrasonido_01.asm **************************
;
;    ===================================================================
;      Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;      E. Palacios, F. Remiro y L. López.          www.pic16f84a.org
;       Editorial Ra-Ma.  www.ra-ma.es
;    ===================================================================
;
; Programa para un medidor de distancias hasta un objeto utilizando sensor por ultrasonido
; SRF04.
;
; Para el control del sensor en primer lugar se genera un  pulso de 10 µs a nivel alto por
; la línea RA3 que se conecta a la entrada de disparo del sensor. Seguidamente se espera a
; que en el sensor se ponga un nivel alto en la salida ECO que se conecta a la línea RA4 y 
; se utilizan las interrupciones por desbordamiento del Timer 0 para medir el tiempo que
; está en alto el pulso. Seguidamente se visualiza en el módulo LCD el valor de la distancia
; hasta el objeto expresada en centímetros.
;
; Por cada centímetro de distancia al objeto el SRF04 aumenta 60 µs la anchura del pulso.
; En este programa la distancia mínima que se puede medir es 3 cm y la máxima 250 cm.
;
; ZONA DE DATOS **********************************************************************

    LIST        P=16F84A
    INCLUDE        <P16F84A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK  0x0C
    Distancia                        ; Se expresará en centímetros.
    ENDC

#DEFINE  Disparo    PORTA,3            ; Disparo para iniciar la medida.
#DEFINE  Eco        PORTA,4            ; Pulso cuya anchura hay que medir.

MIN_DISTANCIA        EQU    .3
MAX_DISTANCIA        EQU    .250
TMR0_Carga60micros    EQU d'256'-d'27'; Valor obtenido experimentalmente con la
                                    ; ventana Stopwatch para una interrupción del
; Timer 0 cada 60 µs.  Si no mide correctamente por las tolerancias de los componentes habrá
; que hacer un ajuste fino de este valor, comprobándolo sobre las condiciones reales.
;
; ZONA DE CÓDIGOS ********************************************************************

    ORG     0
    goto    Inicio
    ORG    4
    goto    ServicioInterrupcion

Mensajes
    addwf    PCL,F
MensajeDistancia
    DT "   Distancia: ", 0x00
MensajeCentimetro
    DT " cm", 0x00
MensajeDistanciaMenor
    DT "Dist. MENOR de:", 0x00
MensajeDistanciaMayor
    DT "Dist. MAYOR de:", 0x00
Inicio
    call    LCD_Inicializa
    bsf        STATUS,RP0
    bcf        Disparo
    bsf        Eco
    movlw    b'00000000'                ; Prescaler de 2 para el TMR0.
    movwf    OPTION_REG
    bcf        STATUS,RP0
    bcf        Disparo                    ; Inicializa línea de disparo en bajo.
Principal
    clrf    Distancia                ; Inicializa el registro.
    bsf        Disparo                    ; Comienza el pulso de disparo.
    call    Retardo_20micros        ; Duración del pulso.
    bcf        Disparo                    ; Final del pulso de disparo.
Espera_Eco_1
    btfss    Eco                        ; Si ECO=0, espera el flanco de subida de la señal
    goto    Espera_Eco_1            ; de salida del sensor.
    movlw    TMR0_Carga60micros        ; Ya se ha producido el flanco de subida.
    movwf    TMR0                    ; Carga el Timer 0.
    movlw    b'10100000'                ; Autoriza interrupción del TMR0 (T0IE).
    movwf    INTCON
Espera_Eco_0
    btfsc    Eco                        ; Espera flanco de bajada de la señal de la salida
    goto    Espera_Eco_0            ; del SRF04.
    clrf    INTCON                    ; Se ha producido el flanco de bajada. Prohíbe interrup.
    call    Visualiza                ; Visualiza la distancia.
    call    Retardo_2s                ; Espera un tiempo hasta la próxima medida.
Fin    goto    Principal
    
; Subrutina "ServicioInterrupcion" ------------------------------------------------------
;
; Se ejecuta debido a la petición de interrupción del Timer 0 cada 60 µs que es el incremento
; de la anchura de pulso por centímetro de distancia medido. La variable "Distancia" contiene el
; valor de la distancia expresada en centímetros.
;
ServicioInterrupcion
      movlw    TMR0_Carga60micros        ; Carga el Timer 0.
    movwf    TMR0
    movlw    .1                        ; Se utiliza instrucción "addwf", en lugar de "incf"
    addwf    Distancia,F                ; para posicionar flag de Carry.
    movlw    MAX_DISTANCIA            ; En caso de desbordamiento carga su máximo valor.
    btfsc    STATUS,C
    movwf    Distancia
    bcf        INTCON,T0IF
    retfie

; Subrutina "Visualiza" -----------------------------------------------------------------
;
; Visualiza la distancia expresada en centímetros. Se hace de manera que cuando haya que
; visualizar un número mayor de 99 las decenas siempre se visualicen aunque sean cero.
; Y cuando sea menor de 99 las decenas no se visualicen si es cero.
;
; Si la distancia es menor de 3 cm o mayor de 250 cm aparece un mensaje de error.
;
Visualiza
    call    LCD_Borra                ; Borra la pantalla anterior.
    movlw    MIN_DISTANCIA            ; Va a comprobar si es menor del mínimo admisible.
    subwf    Distancia,W                ; (W) = (Distancia) - MIN_DISTANCIA
    btfss    STATUS,C                ; ¿C=1?, ¿(W) positivo?, ¿(Distancia) >= MIN_DISTANCIA?
    goto    DistanciaMenor            ; No ha resultado menor, y salta al mensaje de error.
    movf    Distancia,W                ; Va a comprobar si es mayor del máximo admisible.
    sublw    MAX_DISTANCIA            ; (W)=MAX_DISTANCIA-(Distancia)
    btfsc    STATUS,C                ; ¿C=0?, ¿(W) negativo?, ¿MAX_DISTANCIA < (Distancia)?
    goto    DistanciaFiable            ; No, la medida de la distancia entra dentro del rango.
;
DistanciaMayor
    movlw    MAX_DISTANCIA            ; La distancia es mayor que el máximo.
    movwf    Distancia
    movlw    MensajeDistanciaMayor
    goto    VisualizaDistancia
;
DistanciaMenor
    movlw    MIN_DISTANCIA            ; La distancia es menor del mínimo fiable.
    movwf    Distancia
    movlw    MensajeDistanciaMenor
    goto    VisualizaDistancia
DistanciaFiable
    movlw    MensajeDistancia
VisualizaDistancia
    call    LCD_Mensaje
    movlw    .5                        ; Centra la medida de la distancia en la segunda línea 
    call    LCD_PosicionLinea2        ; de la pantalla.
    movf    Distancia,W
    call    BIN_a_BCD                ; Lo pasa a BCD.
    movf    BCD_Centenas,W            ; Primero las centenas.
    btfss    STATUS,Z                ; Si son cero no visualiza las centenas.
    goto    VisualizaCentenas
    movf    Distancia,W                ; Vuelve a recuperar este valor.
    call    BIN_a_BCD                ; Lo pasa a BCD.
    call    LCD_Byte                ; Visualiza las decenas y unidades.
    goto    Visualiza_cm
VisualizaCentenas
    call    LCD_Nibble                ; Visualiza las centenas.
    movf    Distancia,W                ; Vuelve a recuperar este valor.
    call    BIN_a_BCD                ; Lo pasa a BCD.
    call    LCD_ByteCompleto        ; Visualiza las decenas (aunque sea cero) y
Visualiza_cm                        ; unidades.
    movlw    MensajeCentimetro
    call    LCD_Mensaje
    return

    INCLUDE  <RETARDOS.INC>
    INCLUDE  <LCD_4BIT.INC>
    INCLUDE  <LCD_MENS.INC>
    INCLUDE  <BIN_BCD.INC>
    END
    
========
Un curiosidad, según veo este enlace de abajo hecho con el 16F88, tiene varios modo de hacer funcionar el SFR05. Lo programó con C, yo lo haré con ASM.

http://tech-freaks.net/?p=35

Saludo.






EDITO:

Ver Flash

Saludo.
 
Última edición:
Atrás
Arriba