;=======================================================
; Проект 49. Термостат с гистерезисом
; PIC16F877A, 4 МГц. Датчик LM35 на AN0, опорное 2,56 В на RA3
; Нагреватель через реле — RC0, светодиод перегрева — RC1
; Уставка 25 град., гистерезис 2 град.
;=======================================================
        LIST    p=16F877A
        #include <p16f877a.inc>
        __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF

        cblock  0x20
        d1, d2, temp
        endc

SETPOINT equ    .25             ; уставка, градусы
HYST     equ    .2              ; гистерезис, градусы

        ORG     0x000
        goto    Start

Start
        bsf     STATUS,RP0
        clrf    TRISB           ; индикация температуры
        bcf     TRISC,0         ; выход на реле
        bcf     TRISC,1         ; светодиод
        movlw   b'00001001'     ; RA0 — датчик, RA3 — опорное
        movwf   TRISA
        movlw   b'00000101'     ; VREF+ = RA3
        movwf   ADCON1
        bcf     STATUS,RP0
        movlw   b'01000001'
        movwf   ADCON0
        bcf     PORTC,0
        bcf     PORTC,1

Main
        call    Measure
        movf    temp,w
        movwf   PORTB           ; показываем температуру

        ;--- ниже нижнего порога — греем ---
        movlw   SETPOINT - HYST
        subwf   temp,w
        btfss   STATUS,C
        bsf     PORTC,0

        ;--- выше верхнего порога — выключаем ---
        movlw   SETPOINT + HYST
        subwf   temp,w
        btfsc   STATUS,C
        bcf     PORTC,0

        ;--- аварийный перегрев ---
        movlw   SETPOINT + .10
        subwf   temp,w
        btfsc   STATUS,C
        goto    Overheat
        bcf     PORTC,1
        goto    Wait
Overheat
        bcf     PORTC,0         ; принудительно снимаем нагрев
        bsf     PORTC,1
Wait
        call    Delay
        goto    Main

Measure
        bsf     ADCON0,GO
MW      btfsc   ADCON0,GO
        goto    MW
        movf    ADRESH,w        ; при опорном 2,56 В код равен градусам
        movwf   temp
        return

Delay
        movlw   .200
        movwf   d1
DL1     movlw   .250
        movwf   d2
DL2     nop
        decfsz  d2,f
        goto    DL2
        decfsz  d1,f
        goto    DL1
        return

        END
