;*******************************************************************
;  TEMP.ASM
;  Temperature Logging Data Acquisition System
;
;  Use with Philips 2322-640-63103 NTC Thermistor R/r=9.0, 10K@25C
;
;  Valid range of -50C to +125C.  Basic accuracy 2% within the 
;  range -30C to +80C.
;*******************************************************************
;   Target: PIC16C84
;
;   Hardware:  
;   Port B <> LTN211 Display
;   RB7       E  : Enable (H->L transition latches data)
;   RB6       KeyPad Input
;   RB5       Piezo Beeper Output
;
;   Port A <> ADC0831 Serial ADC
;   RA0       ADC Data (Input)
;   RA1       ADC Clock (Output)
;   RA2       ADC CS (Output)
;   RA3       Alarm Output (LED & Relay)
;
;*******************************************************************
;
     include         "picreg.equ"
;
;********************************************************************
;               Test Program
;*********************************************************************
LIST P=16C84

;Register Defines
Temp      equ    2E        ;temp storage during minus sign functions
ADCresult equ    2D        ;stores ADC reading
ADCCtr    equ    2C        ;stores count for reading 8 bits from serial ADC
MaxTemp   equ    2B        ;Temp. locations for Min and Max temp 
MinTemp   equ    2A        
HighAlarm equ    29        ;Current high/low alarm values
LowAlarm  equ    28        ;Stored as ADC values, not actual temps.
Temp2     equ    27        ;temp storage

;Registers for B2_BCD
H_Byte    equ     20       ;Input (Binary) values  
L_Byte    equ     21
R0        equ     22       ;Output (BCD) values
R1        equ     23
R2        equ     24
count     equ     26       ;Temp. registers for function
B2temp    equ     25

;Registers for Misc. Functions
DispChar   equ  10         ;Character to display on LCD
DelayTemp  equ  11         ;Temp Counter for time delay  
DelayT2    equ  12         ;Counter for LONG time delay
TempKey    equ  13         ;Temporary key press value
AlarmFlag  equ  14         ;Bit1=ALARM_ACTIVE

;Constant Defines
ADCCLK    equ    1
ADCDAT    equ    0
ADCCS     equ    2
ALARM     equ    1

;PIC Register Location Defines
EEDATA    equ     8   ;EEPROM register defines
EEADR     equ     9
EECON1    equ    88
EECON2    equ    89

;MAIN Program Begins
       goto    main        

Table  addwf   PC,1        ;calculate jump table location
       retlw   .50+80      ;location 0 - i.e. ADC reading of 0
       retlw   .50+80      ;Set BIT 7 for a negative quantity
       retlw   .50+80
       retlw   .50+80
       retlw   .49+80
       retlw   .46+80
       retlw   .43+80
       retlw   .40+80
       retlw   .39+80
       retlw   .37+80
       retlw   .35+80         
       retlw   .34+80
       retlw   .32+80
       retlw   .31+80
       retlw   .30+80   
       retlw   .29+80
       retlw   .27+80         ;location 10h
       retlw   .26+80         
       retlw   .25+80
       retlw   .24+80
       retlw   .24+80
       retlw   .23+80
       retlw   .22+80
       retlw   .21+80
       retlw   .20+80
       retlw   .19+80
       retlw   .19+80
       retlw   .18+80
       retlw   .17+80
       retlw   .16+80
       retlw   .16+80  
       retlw   .15+80   
       retlw   .15+80         ;location 20h
       retlw   .14+80         
       retlw   .13+80
       retlw   .13+80
       retlw   .12+80
       retlw   .12+80
       retlw   .11+80
       retlw   .11+80
       retlw   .10+80
       retlw   .9+80
       retlw   .9+80
       retlw   .8+80
       retlw   .8+80
       retlw   .7+80
       retlw   .7+80
       retlw   .6+80
       retlw   .6+80         ;location 30
       retlw   .5+80         
       retlw   .5+80
       retlw   .4+80
       retlw   .4+80
       retlw   .3+80
       retlw   .3+80
       retlw   .2+80
       retlw   .2+80
       retlw   .2+80
       retlw   .1+80
       retlw   .1+80
       retlw   .0 
       retlw   .0
       retlw   .1  
       retlw   .1
       retlw   .1          ;location 40
       retlw   .2          
       retlw   .2
       retlw   .2
       retlw   .3
       retlw   .3
       retlw   .4
       retlw   .4
       retlw   .4
       retlw   .5
       retlw   .5
       retlw   .6
       retlw   .6
       retlw   .6          
       retlw   .7
       retlw   .7
       retlw   .7          ;location 50
       retlw   .8
       retlw   .8
       retlw   .9
       retlw   .9
       retlw   .9
       retlw   .10
       retlw   .10
       retlw   .10
       retlw   .11
       retlw   .11
       retlw   .12
       retlw   .12
       retlw   .12
       retlw   .13
       retlw   .13
       retlw   .13         ;location 60
       retlw   .14
       retlw   .14
       retlw   .14
       retlw   .15
       retlw   .15
       retlw   .15
       retlw   .16
       retlw   .16
       retlw   .16
       retlw   .17
       retlw   .17
       retlw   .17
       retlw   .18
       retlw   .18
       retlw   .18
       retlw   .19         ;location 70
       retlw   .19
       retlw   .20
       retlw   .20
       retlw   .20
       retlw   .21
       retlw   .21
       retlw   .21
       retlw   .22
       retlw   .22
       retlw   .22
       retlw   .23
       retlw   .23
       retlw   .23
       retlw   .24
       retlw   .24
       retlw   .25         ;location 80
       retlw   .25
       retlw   .25
       retlw   .26
       retlw   .26
       retlw   .26
       retlw   .27
       retlw   .27
       retlw   .27
       retlw   .28
       retlw   .28
       retlw   .28
       retlw   .29
       retlw   .29
       retlw   .30 
       retlw   .30
       retlw   .31        ;location 90
       retlw   .31
       retlw   .31
       retlw   .32
       retlw   .32
       retlw   .33
       retlw   .33
       retlw   .33
       retlw   .34
       retlw   .34
       retlw   .34
       retlw   .35
       retlw   .35
       retlw   .35
       retlw   .36
       retlw   .36
       retlw   .37         ;location A0
       retlw   .37
       retlw   .38
       retlw   .38
       retlw   .38
       retlw   .39
       retlw   .40
       retlw   .40
       retlw   .40
       retlw   .41
       retlw   .41
       retlw   .42
       retlw   .42
       retlw   .42
       retlw   .43
       retlw   .43
       retlw   .44         ;location B0
       retlw   .45
       retlw   .45
       retlw   .46
       retlw   .46
       retlw   .46
       retlw   .47
       retlw   .47
       retlw   .48
       retlw   .48
       retlw   .49
       retlw   .50
       retlw   .50
       retlw   .51
       retlw   .51
       retlw   .52
       retlw   .52         ;location C0
       retlw   .53
       retlw   .53
       retlw   .54
       retlw   .55
       retlw   .55
       retlw   .56
       retlw   .56
       retlw   .57
       retlw   .57
       retlw   .58
       retlw   .59
       retlw   .60
       retlw   .61
       retlw   .61
       retlw   .62
       retlw   .62         ;location D0
       retlw   .63
       retlw   .64
       retlw   .65
       retlw   .66
       retlw   .66
       retlw   .67
       retlw   .68
       retlw   .69
       retlw   .70
       retlw   .71
       retlw   .72
       retlw   .73
       retlw   .73
       retlw   .74
       retlw   .76
       retlw   .77         ;location E0
       retlw   .78
       retlw   .80
       retlw   .81
       retlw   .82
       retlw   .83
       retlw   .85
       retlw   .86
       retlw   .87
       retlw   .89
       retlw   .91
       retlw   .92
       retlw   .94
       retlw   .96
       retlw   .98
       retlw   .100
       retlw   .105         ;location F0
       retlw   .107
       retlw   .110
       retlw   .112
       retlw   .115
       retlw   .120
       retlw   .125
       retlw   .125          
       retlw   .126        ;End of Table (F8)

main    movlw   b'01000000'   ;Port B all outputs except RB6
        tris    Port_B
        movlw   0             ;All Outputs LOW
        movwf   Port_B

        movlw   b'00000001'   ;RA0 input, RA1-RA4 outputs
        tris    Port_A
        movlw   b'00000100'   ;All Outputs LOW except ADC /CS high
        movwf   Port_A

	bsf     Port_B,5
        call    Delay         ;Wait for LCD to power-up and beep
        bcf     Port_B,5
        call    LCD_Init

        call    ReadADC       ;Initialize Min and Max temps to current
        movfw   ADCresult
        movwf   MaxTemp
        movwf   MinTemp

        clrf    AlarmFlag     ;Set Alarm OFF

        movlw   1             ;Initialize HIGH and LOW alarms from EEPROM
        call    ReadEE        ;W now contains data in EEPROM location 1                    
        movwf   HighAlarm
        movlw   2             ;Select EEPROM address 2
        call    ReadEE        ;W now contains data in EEPROM location 2                    
        movwf   LowAlarm
  
mainloop
        call   LCD_Cls

        call   ReadADC 

        ;Update MIN and MAX temps

        movfw   MaxTemp
        subwf   ADCresult,0  ;check if max temp exceeded
        btfss   STATUS,C
        goto    NotNewMax  
        movfw   ADCresult
        movwf   MaxTemp
NotNewMax
        movfw   MinTemp
        subwf   ADCresult,0  ;check if under min temp 
        btfsc   STATUS,C
        goto    NotNewMin  
        movfw   ADCresult
        movwf   MinTemp
NotNewMin

        ;Display current temperature
        movlw  80           ;Top Line
        movwf  DispChar
        call   LCD_Cmd
        movlw  'T'          ;Display "TEMP="
        movwf  DispChar
        call   LCD_Chr
        movlw  'E'
        movwf  DispChar
        call   LCD_Chr
        movlw  'M'
        movwf  DispChar
        call   LCD_Chr
        movlw  'P'
        movwf  DispChar
        call   LCD_Chr
        movlw  '='
        movwf  DispChar
        call   LCD_Chr

        movfw  ADCresult     ;Display current temp and "C"
        call   DisplayTemp
        movlw   'C'
        movwf   DispChar
        call    LCD_Chr

        bcf     AlarmFlag,ALARM  ;Turn off alarm flag
        movfw   HighAlarm
        subwf   ADCresult,0  ;check if high alarm exceeded
        btfss   STATUS,C
        goto    NoHighAlarm  

        bsf    AlarmFlag,ALARM   ;set alarm flag ON
        movlw  8B            ;End of Top Line
        movwf  DispChar
        call   LCD_Cmd
        movlw  'A'           ;Display "ALARM" 
        movwf  DispChar
        call   LCD_Chr
        movlw  'L'
        movwf  DispChar
        call   LCD_Chr
        movlw  'A'
        movwf  DispChar
        call   LCD_Chr
        movlw  'R'
        movwf  DispChar
        call   LCD_Chr
        movlw  'M'
        movwf  DispChar
        call   LCD_Chr

NoHighAlarm
        movfw   LowAlarm
        subwf   ADCresult,0  ;check if low alarm exceeded
        btfsc   STATUS,C
        goto    NoLowAlarm  

        bsf    AlarmFlag,ALARM   ;set alarm flag ON
        movlw  8B            ;End of Top Line
        movwf  DispChar
        call   LCD_Cmd
        movlw  'A'           ;Display "ALARM" 
        movwf  DispChar
        call   LCD_Chr
        movlw  'L'
        movwf  DispChar
        call   LCD_Chr
        movlw  'A'
        movwf  DispChar
        call   LCD_Chr
        movlw  'R'
        movwf  DispChar
        call   LCD_Chr
        movlw  'M'
        movwf  DispChar
        call   LCD_Chr

NoLowAlarm
        ;Display min and max temperatures
        movlw  b'11000000'  ;Bottom Line
        movwf  DispChar
        call   LCD_Cmd
        movlw  'M'          ;Display "MIN="
        movwf  DispChar
        call   LCD_Chr
        movlw  'I'
        movwf  DispChar
        call   LCD_Chr
        movlw  'N'
        movwf  DispChar
        call   LCD_Chr
        movlw  '='
        movwf  DispChar
        call   LCD_Chr

        movfw  MinTemp
        call   DisplayTemp

        movlw  b'11001000'  ;Bottom Line
        movwf  DispChar
        call   LCD_Cmd
        movlw  'M'          ;Display "MAX="
        movwf  DispChar
        call   LCD_Chr
        movlw  'A'
        movwf  DispChar
        call   LCD_Chr
        movlw  'X'
        movwf  DispChar
        call   LCD_Chr
        movlw  '='
        movwf  DispChar
        call   LCD_Chr

        movfw  MaxTemp
        call   DisplayTemp

        btfsc  AlarmFlag,ALARM  ;Check if Alarm is ON, if so, Beep 1 sec
	bsf    Port_B,5
        call   OneSecDly
        bcf    Port_B,5     ;Turn off beeper

        btfsc  AlarmFlag,1  ;Check if Alarm is ON, if so Light LED
        goto   AlmLedOn
        bcf    Port_A,3     ;LED Off
        goto   AlmLedOff 
AlmLedOn
        bsf    Port_A,3
AlmLedOff

        ;Display High and Low Alarm Values           
        movlw  b'11000000'  ;Bottom Line
        movwf  DispChar
        call   LCD_Cmd
        movlw  'H'          ;Display "HI ="
        movwf  DispChar
        call   LCD_Chr
        movlw  'I'
        movwf  DispChar
        call   LCD_Chr
        movlw  ' '
        movwf  DispChar
        call   LCD_Chr
        movlw  '='
        movwf  DispChar
        call   LCD_Chr

        movfw  HighAlarm
        call   DisplayTemp

        movlw  b'11001000'  ;Bottom Line
        movwf  DispChar
        call   LCD_Cmd
        movlw  'L'          ;Display "LOW="
        movwf  DispChar
        call   LCD_Chr
        movlw  'O'
        movwf  DispChar
        call   LCD_Chr
        movlw  'W'
        movwf  DispChar
        call   LCD_Chr
        movlw  '='
        movwf  DispChar
        call   LCD_Chr

        movfw  LowAlarm
        call   DisplayTemp

        btfsc  AlarmFlag,ALARM  ;Check if Alarm is ON, if so, Beep 1 sec
	bsf    Port_B,5
        call   OneSecDly
        bcf    Port_B,5     ;Turn off beeper

        goto    mainloop

;KeyPad Scan Function
;Returns either 0 in w (no key pressed) or 1-4 in w for key pressed
;Fully debounced, waits for key release
ScanKey
        call    TestKey
        movwf   Temp2
        btfss   Temp2,7       ;Is w still null? (i.e. is bit 7 still set)
        goto    WaitForRls
        movlw   0             ;Nothing found, clear to <space>
        return
WaitForRls
        movwf   TempKey
WaitKeyLoop
        call    TestKey        
        movwf   Temp2
        btfss   Temp2,7       ;Is w still null? (i.e. is bit 7 still set)
        goto    WaitKeyLoop   ;Key still down .... wait for release
        movfw   TempKey       ;Put Key Return Value into w
        return

;KeyPad Non-debounced Scan Function
;Returns either 0 in w (no key pressed) or 1-4 in w for key pressed
;No debounce, active on key press
ScanKey2
        call    TestKey
        movwf   Temp2
        btfss   Temp2,7       ;Is w still null? (i.e. is bit 7 still set)
        return                ;w must contain 1-4
        movlw   0             ;Nothing found, clear to <space>
        return

;Return bit 7 high if no key pressed or 1-4 in w for key pressed
TestKey
        movlw   0             ;Make Port_B all low
        movwf   Port_B
        movlw   80            ;Pre-Load w with bit 7 high 
        bsf     Port_B,0      ;Make Key 1 row HIGH
        btfsc   Port_B,6      ;Check if key 1 pressed
        movlw   .1
        bcf     Port_B,0  
        bsf     Port_B,1      ;Make Key 2 row HIGH
        btfsc   Port_B,6      ;Check if key 2 pressed
        movlw   .2
        bcf     Port_B,1  
        bsf     Port_B,2      ;Make Key 3 row HIGH
        btfsc   Port_B,6      ;Check if key 3 pressed
        movlw   .4
        bcf     Port_B,2  
        bsf     Port_B,3      ;Make Key 4 row HIGH
        btfsc   Port_B,6      ;Check if key 4 pressed
        movlw   .8
        bcf     Port_B,3  
        return

ModeSet
ModeSetHi
        call    ShortDelay
        call    LCD_Cls
        movlw  'S'           ;Display "SET HIGH ALARM" 
        movwf  DispChar
        call   LCD_Chr
        movlw  'E'
        movwf  DispChar
        call   LCD_Chr
        movlw  'T'
        movwf  DispChar
        call   LCD_Chr
        movlw  ' '
        movwf  DispChar
        call   LCD_Chr
        movlw  'H'
        movwf  DispChar
        call   LCD_Chr
        movlw  'I'
        movwf  DispChar
        call   LCD_Chr
        movlw  'G'
        movwf  DispChar
        call   LCD_Chr
        movlw  'H'
        movwf  DispChar
        call   LCD_Chr
        movlw  ' '
        movwf  DispChar
        call   LCD_Chr
        movlw  'A'
        movwf  DispChar
        call   LCD_Chr
        movlw  'L'
        movwf  DispChar
        call   LCD_Chr
        movlw  'A'
        movwf  DispChar
        call   LCD_Chr
        movlw  'R'
        movwf  DispChar
        call   LCD_Chr
        movlw  'M'
        movwf  DispChar
        call   LCD_Chr

        movlw  b'11000000'  ;Bottom Line
        movwf  DispChar
        call   LCD_Cmd
        movlw  'H'          ;Display "HI ="
        movwf  DispChar
        call   LCD_Chr
        movlw  'I'
        movwf  DispChar
        call   LCD_Chr
        movlw  ' '
        movwf  DispChar
        call   LCD_Chr
        movlw  '='
        movwf  DispChar
        call   LCD_Chr

        movfw  HighAlarm
        call   DisplayTemp

        call    ScanKey2      ;Check if a key is pressed
        movwf   Temp2  
        btfsc   Temp2,0       ;If Key 1, go to next MODE (Set Low Alm)
        goto    ModeSetLow
        btfsc   Temp2,1       ;If "+", Increment HIGH alarm Value
        incf    HighAlarm
        btfsc   Temp2,2       ;If "-", Decrement HIGH alarm Value
        decf    HighAlarm
        goto    ModeSetHi

ModeSetLow
        call    ShortDelay
        call    LCD_Cls
        movlw  'S'           ;Display "SET LOW ALARM" 
        movwf  DispChar
        call   LCD_Chr
        movlw  'E'
        movwf  DispChar
        call   LCD_Chr
        movlw  'T'
        movwf  DispChar
        call   LCD_Chr
        movlw  ' '
        movwf  DispChar
        call   LCD_Chr
        movlw  'L'
        movwf  DispChar
        call   LCD_Chr
        movlw  'O'
        movwf  DispChar
        call   LCD_Chr
        movlw  'W'
        movwf  DispChar
        call   LCD_Chr
        movlw  ' '
        movwf  DispChar
        call   LCD_Chr
        movlw  'A'
        movwf  DispChar
        call   LCD_Chr
        movlw  'L'
        movwf  DispChar
        call   LCD_Chr
        movlw  'A'
        movwf  DispChar
        call   LCD_Chr
        movlw  'R'
        movwf  DispChar
        call   LCD_Chr
        movlw  'M'
        movwf  DispChar
        call   LCD_Chr

        movlw  b'11000000'  ;Bottom Line
        movwf  DispChar
        call   LCD_Cmd
        movlw  'L'          ;Display "LO ="
        movwf  DispChar
        call   LCD_Chr
        movlw  'O'
        movwf  DispChar
        call   LCD_Chr
        movlw  ' '
        movwf  DispChar
        call   LCD_Chr
        movlw  '='
        movwf  DispChar
        call   LCD_Chr

        movfw  LowAlarm
        call   DisplayTemp

        call    ScanKey2      ;Check if a key is pressed
        movwf   Temp2  
        btfsc   Temp2,0       ;If Key 1, go to next MODE (Clr Min/Max)
        goto    ModeSetClr
        btfsc   Temp2,1       ;If "+", Increment LOW alarm Value
        incf    LowAlarm
        btfsc   Temp2,2       ;If "-", Decrement LOW alarm Value
        decf    LowAlarm
        goto    ModeSetLow

ModeSetClr
        call    ShortDelay
        call    LCD_Cls
        movlw  'C'           ;Display "CLEAR MIN/MAX" 
        movwf  DispChar
        call   LCD_Chr
        movlw  'L'
        movwf  DispChar
        call   LCD_Chr
        movlw  'E'
        movwf  DispChar
        call   LCD_Chr
        movlw  'A'
        movwf  DispChar
        call   LCD_Chr
        movlw  'R'
        movwf  DispChar
        call   LCD_Chr
        movlw  ' '
        movwf  DispChar
        call   LCD_Chr
        movlw  'M'
        movwf  DispChar
        call   LCD_Chr
        movlw  'I'
        movwf  DispChar
        call   LCD_Chr
        movlw  'N'
        movwf  DispChar
        call   LCD_Chr
        movlw  '/'
        movwf  DispChar
        call   LCD_Chr
        movlw  'M'
        movwf  DispChar
        call   LCD_Chr
        movlw  'A'
        movwf  DispChar
        call   LCD_Chr
        movlw  'X'
        movwf  DispChar
        call   LCD_Chr
        movlw  '?'
        movwf  DispChar
        call   LCD_Chr

        movlw  b'11000000'  ;Bottom Line
        movwf  DispChar
        call   LCD_Cmd
        movlw  'P'          ;Display "PRESS + TO CLR"
        movwf  DispChar
        call   LCD_Chr
        movlw  'R'
        movwf  DispChar
        call   LCD_Chr
        movlw  'E'
        movwf  DispChar
        call   LCD_Chr
        movlw  'S'
        movwf  DispChar
        call   LCD_Chr
        movlw  'S'
        movwf  DispChar
        call   LCD_Chr
        movlw  ' '
        movwf  DispChar
        call   LCD_Chr
        movlw  '+'
        movwf  DispChar
        call   LCD_Chr
        movlw  ' '
        movwf  DispChar
        call   LCD_Chr
        movlw  'T'
        movwf  DispChar
        call   LCD_Chr
        movlw  'O'
        movwf  DispChar
        call   LCD_Chr
        movlw  ' '
        movwf  DispChar
        call   LCD_Chr
        movlw  'C'
        movwf  DispChar
        call   LCD_Chr
        movlw  'L'
        movwf  DispChar
        call   LCD_Chr
        movlw  'R'
        movwf  DispChar
        call   LCD_Chr

        call    ScanKey       ;Check if a key is pressed
        movwf   Temp2  
        btfsc   Temp2,0       ;If Key 1, go to next MODE (Done)
        goto    ModeSetDone
        btfsc   Temp2,1       ;If "+", Increment LOW alarm Value
        goto    ClrMinMax
        goto    ModeSetClr

ClrMinMax
        call    ReadADC       ;Initialize Min and Max temps to current
        movfw   ADCresult
        movwf   MaxTemp
        movwf   MinTemp

ModeSetDone
        call    ShortDelay

        movf    HighAlarm,w   ;Save HIGH and LOW alarms to EEPROM
        movwf   Temp
        movlw   1
        call    WriteEE       ;Write Hi Alarm to EEPROM location 1                    

        movf    LowAlarm,w 
        movwf   Temp
        movlw   2
        call    WriteEE       ;Write Lo Alarm to EEPROM location 2                    
 
        return

;Delay Functions for display (approx. 1 second)
OneSecDly
        movlw   .8
        movwf   Temp
DDelay  decfsz  Temp,1
        goto    DelayIt
        return 

DelayIt 
        call    LongDelay
        call    ScanKey       ;Check if a key is pressed
        movwf   Temp2  
        btfsc   Temp2,0       ;If Key 1, go to MODE operation
        call    ModeSet          
        goto    DDelay


;*******************************************************************
;  Internal functions 
;*******************************************************************
;** Read one byte from the ADC and store it in ADCresult
ReadADC                             
	 movlw   0               ; Clear out ADCresult register for new data
	 movwf   ADCresult
	 bcf     Port_A,ADCCS    ; Activate /CS line on the ADC to start
	 movlw   9               ; Set number of bits to read in = 8 +1 start
	 movwf   ADCCtr         ; Load this into the counter register
	 bsf     Port_A,ADCCLK   ; Pulse the ADC clock line High then Low
	 nop                     ;   signals the start of a conversion
	 bcf     Port_A,ADCCLK

Get_One_Loop                     ; This is the main loop, should execute 9 times
	 bsf     Port_A,ADCCLK   ; Pulse the ADC clock line hight then low
	 nop                     ;  to get the first bit
	 bcf     Port_A,ADCCLK
	 btfsc   Port_A,ADCDAT   ; Check the value of the data bit
	 goto    SetCarry
	 bcf     STATUS,C        ; If its a zero, put a zero into the Carry
	 goto    RotateBits
SetCarry
	 bsf     STATUS,C        ; Otherwise its a 1, put that into the carry
RotateBits
	 rlf     ADCresult        ; Shift bits left from carry into ADReslt
	 decfsz  ADCCtr         ; Decrement Counter -
	 goto    Get_One_Loop    ;   Do it 9 times
	 bsf     Port_A,ADCCS    ; When done, Disable the ADC
	
        ;LIMIT max reading if necessary
        movlw  .248           ;limit reading of ADC to F8 to prevent
        subwf  ADCresult,0    ;going past last entry in jump table
        btfss  STATUS,C
        return
        movlw  .248           ;limit the ADC reading at end of jump table
        movwf  ADCresult
        return

;** Convert and Display a temperature at the current display location
DisplayTemp
        call   Table         ;goto jump table for alarm Celcius Temperature 

        movwf  L_Byte        ;load data for BCD display
        btfss  L_Byte,7      ;Test bit 7 (is it a negative number?)
        goto   NotNeg

        movlw  .45           ;ASCII minus sign
        movwf  DispChar
        call   LCD_Chr
        bcf    L_Byte,7      ;Convert to non-negative number

NotNeg
        clrf   H_Byte
        call   B2_BCD        ;convert to BCD

        ;Display R1 lo
        movfw   R1
        andlw   b'00001111'
        btfsc   STATUS,Z     ;Remove leading zeroes
        goto    BlankOne
        addlw   30            ;Turn into an ASCII digit
        movwf   DispChar
        call    LCD_Chr
BlankOne
        ;Display R2 hi then R2 lo
        swapf   R2,0
        andlw   b'00001111'
        addlw   30            ;Turn into an ASCII digit
        movwf   DispChar
        call    LCD_Chr
        movfw   R2
        andlw   b'00001111'
        addlw   30            ;Turn into an ASCII digit
        movwf   DispChar
        call    LCD_Chr

        movlw  ' '            ;Trailing blank to clear display
        movwf  DispChar
        call   LCD_Chr

        return  

;ReadEE: Reads a byte from the EEPROM of the PIC16C84
;        Parameters: location in EEPROM (0-63dec) in W
;        Returns: byte read in W register
ReadEE
        movwf   EEADR           ;Put desired address into EEADR
        bsf     STATUS,RP0      ;Select Register Page 1
        bsf     EECON1,0        ;RD operation flag
        bcf     STATUS,RP0      ;Select Register Page 0 again
        movf    EEDATA,W        ;Read data, put into W register
        return

;WriteEE: Writes a byte to the EEPROM of the PIC16C84
;         Parameters: location in EEPROM (0-63dec) in W
;                     data to be written in location 'Temp'
;         Note: Value in Temp is destroyed during write operation 
WriteEE:
        movwf   EEADR           ;Put desired address into EEADR
        movf    Temp,W          ;Put data to be written into EEDATA
        movwf   EEDATA
        movf    INTCON,W        ;Store old interrupt status in Temp
        movwf   Temp 
        bcf     INTCON,7        ;Turn off all interrupts
        bsf     STATUS,RP0      ;Select Register Page 1
        bsf     EECON1,2        ;Write Enable flag
        movlw   55h             ;Required sequence to write to EEPROM
        movwf   EECON2
        movlw   b'10101010'
        movwf   EECON2
        bsf     EECON1,1        ;WR operation flag
EEIsBusy
        btfsc   EECON1,1        ;Wait for BUSY flag to end
        goto    EEIsBusy
        bcf     EECON1,2        ;Disable Write Enable flag      
        bcf     STATUS,RP0      ;Select Register Page 0 again
        movf    Temp,w          ;Reset interrupts to original state
        movwf   INTCON
        return   

    
;*******************************************************************
;  LTN211 16 char by 2 LCD display functions for PICPROTO
;*******************************************************************
LCD_Init                      ;Initialize LTN211 LCD display
        movlw   33            ;Output 0x33 to LCD
        movwf   DispChar            
        call    LCD_Cmd
        movlw   32            ;Output 0x32 to LCD
        movwf   DispChar            
        call    LCD_Cmd
        movlw   28            ;Output 0x28 to LCD
        movwf   DispChar            ;  4 bit mode
        call    LCD_Cmd
        movlw   0C            ;Output 0x0C to LCD
        movwf   DispChar            ;  Display ON, Cursor&Blink Off
        call    LCD_Cmd
        movlw   06            ;Output 0x06 to LCD
        movwf   DispChar            ;  Entry Mode: AutoIncrement
        call    LCD_Cmd
        call    LCD_Cls
        return 

LCD_Cls                       ;Clear LCD display screen, home cursor
        movlw   01            ;Output 0x01 to LCD
        movwf   DispChar            ;  Clear Display
        call    LCD_Cmd
        movlw   02            ;Output 0x02 to LCD
        movwf   DispChar            ;  Home Cursor
        call    LCD_Cmd
        call    Delay
        call    Delay
        return 

LCD_L2  ;Set cursor to start of LCD line 2
        movlw   b'11000000'           
        movwf   DispChar            ;  Set Display Cursor to Line 2
        call    LCD_Cmd
        call    Delay
        call    Delay
        call    Delay
        return 

LCD_Cmd                       ;Send a command to the LCD display
        swapf   DispChar,0          ;Put upper nibble into lower of W
        andlw   b'00001111'   ;Mask off upper nibble
        movwf   Port_B
        bsf     Port_B,7      ;Toggle Enable HIGH then LOW again
        call    Delay
        call    Delay
        bcf     Port_B,7
        call    Delay
        call    Delay
        movfw   DispChar            ;send lower nibble to display
        andlw   b'00001111'   ;Mask off upper nibble
        movwf   Port_B
        bsf     Port_B,7      ;Toggle Enable HIGH then LOW again
        call    Delay
        call    Delay
        bcf     Port_B,7
        call    Delay
        call    Delay         ;?
        return 

LCD_Chr                       ;Send a Character to the LCD display
        swapf   DispChar,0    ;Put upper nibble into lower of W
        andlw   b'00001111'   ;Mask off upper nibble
        movwf   Port_B
        bsf     Port_B,4      ;Set bit 4 (Register Select) HIGH
        bsf     Port_B,7      ;Toggle Enable HIGH then LOW again
        bcf     Port_B,7
        movfw   DispChar      ;send lower nibble to display
        andlw   b'00001111'   ;Mask off upper nibble
        movwf   Port_B
        bsf     Port_B,4      ;Set bit 4 (Register Select) HIGH
        bsf     Port_B,7      ;Toggle Enable HIGH then LOW again
        bcf     Port_B,7
        call    Delay
        call    Delay         ;?
        return 

LongDelay                     ;Approx. 125 mS delay
        movlw   .255         
        movwf   DelayT2 
ldelaya call    Delay
        decfsz  DelayT2,1 
        goto    ldelaya 
        return

ShortDelay                     ;Approx. 25 mS delay
        movlw   .51         
        movwf   DelayT2 
sdelaya call    Delay
        decfsz  DelayT2,1 
        goto    sdelaya 
        return

Delay                         ;0.6ms delay for LCD initialization
        movlw   .250          ;Load Temp with constant for .3 ms
        movwf   DelayTemp 
delaya  decfsz  DelayTemp,1   ;Dec until zero
        goto    delaya 
        movlw   .250          ;Load Temp with constant for .3 ms
        movwf   DelayTemp 
delayb  decfsz  DelayTemp,1   ;Dec until zero
        goto    delayb 
        return

;*******************************************************************
;  Binary to BCD Converter
;
;  Input: Two bytes of RAM; L_Byte, H_Byte
;  Output: Three bytes of RAM; R0, R1, R2
;
;  Usage: Put value into L_Byte and H_Byte, call B2_BCD, result in
;         R2 is LSD and R1 is MSD: Four digits (nibbles) in 2 bytes
;         Lower 4 bits of LSD are least sig. digit, upper 4 are 2nd
;         digit.
;*******************************************************************

B2_BCD  bcf     STATUS,0        ;Clear carry bit
        movlw   .16
        movwf   count           ;Set counter to 16
        clrf    R0
        clrf    R1
        clrf    R2
loop16  rlf     L_Byte
        rlf     H_Byte
        rlf     R2
        rlf     R1
        rlf     R0
        decfsz  count
        goto    adjDEC
        RETLW   0

adjDEC  movlw   R2
        movwf   FSR      
        call    adjBCD
        movlw   R1
        movwf   FSR
        call    adjBCD
        movlw   R0
        movwf   FSR
        call    adjBCD
        goto    loop16

adjBCD  movlw   3
        addwf   0,W
        movwf   B2temp
        btfsc   B2temp,3        ;Test if result > 7
        movwf   0
        movlw   30
        addwf   0,w
        movwf   B2temp    
        btfsc   B2temp,7        ;Test if result > 7  
        movwf   0             ;Save as MSD
        RETLW   0  
        
;*******************************************************************

       END



