ON 20040506@8:15:29 AM at page: http://www.piclist.compiclist/questions.htm#38113.0308217593 James Newton[JMN-EFP-786] published post 38113.0308217593 chin_kok_leong@yahoo.com asks: " pls, help me here!!!!!!!!
how can i connect my pic to my pc. i cant load my hex file to my pic.Y??????" |Delete 'P-' before: '' but after: 'nanawash5@aol.com asks:
I want know how to control two stepper motors for mobile robots;and make them slave to each other. Without affecting the torque and stepping sequences.

|Delete 'P-' before: '' but after: 'gerrett@globetrotter.net asks:
does anyone have assembler code to enable me to have a 32bit varable that is stored in eeprom of a pic 16f877 - add a 16 bit variable to it and then store this 32 bit sum again. therefore read - add - write
|Delete 'P-' before: '' but after: 'Fabio silveira Moura of Sinteck electronics asks: " Please,

i'm need c routines for LCD graphic with SED1520, for CCS compiler...

Thanks
"
  • ' ON 20040508@8:16:17 AM at page: http://www.piclist.com/techref/piclist/index.htm#38114.9759375 James Newton[JMN-EFP-786] published post 38114.9759375 /techref/piclist/q0.htm PICList.com Questions: |Delete 'P-' before: '' but after: 'criradu@yahoo.com asks:
    I wander there is any way to establish a 4 bits paralel interface between pic and LCD. I want to put a 64 frequency devider to increase the masured frequency. I need a pine from the pic to set it high if the frequency devider is in use, and low if is not. Any idea...?
    Thenks for your atention! Radu
    |Delete 'P-' before: '' but after: 'pastapora@hotmail.com asks: " fpp how to use? , please urgent!!!"
  • ' ON 20040517@12:22:32 PM at page: http://www.piclist.com/techref/piclist/index.htm# James Newton[JMN-EFP-786] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\piclist\index.htm&version=125 ON 20040517@4:41:22 PM at page: http://www.piclist.com/techref/piclist/projects.htm#38082.3136458333 James Newton[JMN-EFP-786] published post 38082.3136458333 /techref/microchip/language/c/io/lcd/hitachilcd-ak/index.htm Character LCD Interface |Delete 'P-' before: '' but after: '
    ;******************************************************************************
    ;
    ;		Weather Station Software
    ;
    ;	This program links a homemade weather station to a PIC 16F628A with display
    ;	and logger functions.  Wind direction, wind speed and a lightening detector
    ;	use Dallas One-Wire bus chips and a one-wire protocol. An SMT11 
    ;	relative humidity and temperature chip is also used and communicates using
    ;	a 2-wire protocol.
    ;
    ;	The data is displayed on a 2x24 LCD module using two screens.  
    ;	Display 1 shows temp, humidity, wind speed and wind direction.
    ;	Display 2 shows max/min temperature and lightning strikes. The display
    ;	toggles	when the Display Toggle button is pushed.  The weather data is
    ;	sampled every second for wind direction and lightning strikes, and every 2 seconds for
    ;	temperature, relative humidity, wind speed.  The data is also output on an RS-232
    ;	serial link (9600 baud) every minute. The PIC 16F628A pin layout:
    ;	
    ;
    ;	RA0	LCD Data
    ;	RA1	LCD Data
    ;	RA2	LCD Data
    ;	RA3	LCD Data
    ;	RA4
    ;	RA5	
    ;	RA6	LCD RS
    ;	RA7	LCD EN	
    ;
    ;	RB0	Switch input - Display Toggle
    ;	RB1	RS232 RX
    ;	RB2	RS232 TX
    ;	RB3	One-wire bus
    ;	RB4	2-wire Clock
    ;	RB5	2-wire Data
    ;	RB6	
    ;	RB7	
    ;
    ;	Routines for SHT11 temperature and humidity calculations were modified
    ;	from original code by Claudiu Chiculita http://www.ac.ugal.ro/staff/ckiku/software/sht11.htm
    ;			
    ;******************************************************************************
    ;                                                                     
    ;    Filename:	    weather.asm                                        
    ;    Date: 			18 November 2003                                 
    ;    File Version:  1.0                                               
    ;                                                                  
    ;    Author: 		A.Round                                        
    ;    Company: 		                           
    ;                                                              
    ;                                                              
    ;******************************************************************************
    ;                                                                   
    ;    Files required:	"m_lcd.h"
    ;                                                                     
    ;******************************************************************************
    ;                                                                  
    ;    Notes:	Version 1.0 - Initial Baseline                           
    ;                                   
    ;                                                                    
    ;                                                                    
    ;*****************************************************************************
    
    	list      p=16f628A           ; list directive to define processor
    	#include <p16F628A.inc>       ; processor specific variable definitions
    
    	__CONFIG   _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT 
    
    ; '__CONFIG' directive is used to embed configuration word within .asm file.
    ; The lables following the directive are located in the respective .inc file.
    ; See data sheet for additional information on configuration word settings.
    
    ;***** LCD HARDWARE DECLARATION *****
    
    LCD_DATA		EQU     PORTA
    LCD_DATA_TRIS	EQU     TRISA
    
    #define R_S	LCD_DATA,6  			; LCD Register Select control line RA6
    #define EN	LCD_DATA,7   			; LCD Enable control line RA7
    
    ;***** IC2 HARDWARE DECLARATION *****
    
    IC2			EQU     PORTB
    IC12_TRIS	EQU     TRISB
    
    #define IC2_CLOCK	IC2,6   		; IC2 clock line
    #define IC2_DATA	IC2,7   		; IC2 data line
    
    ;***** TWO WIRE HARDWARE DECLARATION *****
    
    TWO_WIRE		EQU     PORTB
    TWO_WIRE_TRIS	EQU     TRISB
    
    #define TWO_WIRE_CLOCK	TWO_WIRE,4   		; Two Wire Serial Clock line RB4
    #define TWO_WIRE_DATA	TWO_WIRE,5   		; Two Wire Serial Data line RB5
    
    ;***** 1-WIRE HARDWARE DECLARATION *****
    
    D1WIRE_PORT		EQU     PORTB
    D1WIRE_TRIS		EQU     TRISB
    
    #define D1WIRE		D1WIRE_PORT,3   	; 1-Wire Bus RB0
    
    
    ;***** VARIABLE DECLARATION *****
    
    	CBLOCK	0X20
    
    TEMP1						; Used in LCD subroutines, SHT-11 Time Out subroutine
    TEMP2						; Used in LCD_Hex subroutine, SHT-11 Time Out subroutine 
    TEMP3						; Used in 1-Wire Reset subroutine, SHT-11 Time Out subroutine
    CNTR						; Used in 1-Wire WB/RB, 1-Wire Reset subroutines
    CNTR1						; Used in 1-Wire RB, Read DS2423 subroutines
    CNTR2						; Used in 1-Wire Read DS2423 subroutine
    COUNT						; Used in RCOUNT macro
    START_COUNT					; Used to determine wind speed
    STORE						; Used in 16 Bit CRC subroutine
    CRC8						; Used for 8 bit CRC subroutine
    CRC16_HI					; Used for 16 bit CRC subroutine
    CRC16_LO					; Used for 16 bit CRC subroutine
    DELAY1						; Used in Delay macros
    DELAY2						; Used in Delay macros
    HALF_SEC_COUNT					; Used for Timer1 ISR routines
    TWO_SEC_COUNT					; Used for Timer1 ISR routines
    TA1						; Low byte DS2423 counter memory page address
    TA2						; High byte DS2423 counter memory page address
    WSPEED_VALUE					; Latest Wind Speed value
    FLAGS						; B0=0 Start Display B0=1 Second Display B1=0 call DS2423 table
    						; B1=1 call DS2450 table
    TEST						; Used for keyboard de-bounce
    DATAH						; MS byte from SHT11
    DATAL						; LS byte from SHT11
    CALCH						; Working temperature/RH/WD/LS MS byte
    CALCL						; Working temperature/RH/WD/LS LS byte
    TDATAHMAX					; Maximum temperature reading MS byte							
    TDATALMAX					; Maximum temperature reading LS byte
    TDATAHMIN					; Minimum temperature reading MS byte
    TDATALMIN					; Minimum temperature reading LS byte
    NEG						; Temperature sign register
    T10						; ASCII Temperature 10's
    T1						; ASCII Temperature 1's
    T01						; ASCII Temperature 0.1's
    TSIGN_MAX_VALUE					; maximum temperature sign (pos or neg)
    TSIGN_MIN_VALUE					; minimum temperature sign (pos or neg)
    T10MAX_VALUE					; ASCII Temperature 10's maximum value
    T10MIN_VALUE					; ASCII Temperature 10's minimum value
    T1MAX_VALUE					; ASCII Temperature 1's maximum value
    T1MIN_VALUE					; ASCII Temperature 1's minimum value
    T01MAX_VALUE					; ASCII Temperature 0.1's maximum value
    T01MIN_VALUE					; ASCII Temperature 0.1's minimum value
    R100						; ASCII Relative Humidity 100's
    R10						; ASCII Relative Humidity 10's
    R1						; ACSII Relative Humidity 1's
    WD100						; ASCII Wind direction 100's
    WD10						; ASCII Wind direction 10's
    WD1						; ASCII Wind direction 1's
    WS10						; ASCII Wind speed 10's
    WS1						; ASCII Wind speed 1's
    LS100						; ASCII Lightning Strikes 100's
    LS10						; ASCII Lightning Strikes 10's
    LS1						; ASCII Lightning Strikes 1's
    RH_32						; Raw Relative Humidity divided by 32								
    RH_128						; Raw Relative Humidity divided by 128
    RH						; Calculated Relative Humidity
    SHT_ERROR1					; ASCII SHT11 Error code
    SHT_ERROR2					; ASCII SHT11 Error code
    D1WIRE_ERROR					; 1 Wire Error code
    CHANNELC					; 8 bit ADC reading from Channel C pot in wind vane
    CHANNELD					; 8 bit ADC reading from Channel D pot in wind vane
    HIGH_ADDRESS					; temp register to pass table read address information
    LOW_ADDRESS					; temp register to pass table read address information
    SUBH						; Used in 16BIT subtraction routine
    SUBL						; Used in 16BIT subtraction routine
    DIGIT						; Used in binary to ASCII temperature conversion
    
    	ENDC
    
    	CBLOCK	0X70
    
    W_TEMP      
    STATUS_TEMP
    
    	ENDC
    
    
    ;**********************************************************************
    	ORG	0x000             	; processor reset vector
    	GOTO	MAIN              	; go to beginning of program
    	
    
    	ORG	0x004             	; interrupt vector location
    
    GIE_CLEAR
    	BCF	INTCON, GIE		; turn off interupts
    	BTFSC	INTCON, GIE		; make sure they are really turned off
    	GOTO	GIE_CLEAR
    	MOVWF   W_TEMP            	; save off current W register contents
    	MOVF	STATUS, W         	; move status register into W register
    	MOVWF	STATUS_TEMP       	; save off contents of STATUS register
    	MOVLW	' '			; clear 1 Wire error code
    	MOVWF	D1WIRE_ERROR
    
    	BTFSC	INTCON, INTF		; test to see if Display Change button has been pushed
    	GOTO	DISPLAY_CHANGE		: if yes, go to the display change routine
    	BTFSC	PIR1, TMR1IF		; test to see if Timer1 overflow 
    	GOTO	HALF_SEC		; if yes, go to time counting routine 
    	GOTO	ISR_OVER		; if no, go to ISR_OVER
    
    HALF_SEC
    	BCF	PIR1, TMR1IF		; Clear Timer1 interrupt flag
    	INCF	HALF_SEC_COUNT,F	; increment half seconds count
    	MOVFW	HALF_SEC_COUNT
    	BTFSS	HALF_SEC_COUNT, 0	; check to see if this was a whole second
    	GOTO	HALF_SEC1		; If yes, go to HALF_SEC1
    	GOTO	ISR_OVER		; If no, go to ISR_OVER and wait for next interrupt
    
    HALF_SEC1
    	MOVFW	HALF_SEC_COUNT		; check to see if 2 seconds has elapsed
    	ANDLW	b'00011111'
    	SUBLW	b'00000100'
    	SKPNZ
    	GOTO	HALF_SEC2		; If yes, update wspeed, wdir, temp, rh
    	CALL	WDIR_UPDATE		; If no, update wdir and lightning strikes
    	CALL	LSTRIKE_UPDATE
    	GOTO	ISR_OVER		; Go to ISR_OVER and wait for next interrupt
    
    HALF_SEC2
    	CLRF	HALF_SEC_COUNT		; Clear half seconds count
    	CALL	WSPEED_UPDATE		; update wspeed, wdir, temp, rh, lstrike
    	CALL	WDIR_UPDATE	
    	CALL	TEMP_RH_UPDATE
    	CALL	LSTRIKE_UPDATE
    	INCF	TWO_SEC_COUNT,F		; increment ten second count
    	MOVFW	TWO_SEC_COUNT
    	SUBLW	b'00011110'		; Check to see if one minute has past
    	SKPNZ
    	GOTO	HALF_SEC3		; If yes, go to HALF_SEC3	
    	GOTO	ISR_OVER		; If no, go to ISR_OVER and wait for next interrupt
    
    HALF_SEC3
    	CLRF	TWO_SEC_COUNT		; Clear 2 second counter
    	CALL	RS232_TX		; Send current readings to RS232
    	GOTO	ISR_OVER
    
    WSPEED_UPDATE
    	MOVLW	0xC0			; Load low byte counter memory page address
    	MOVWF	TA1
    	MOVLW	0x01			; Load high byte counter memory page address				
    	MOVWF	TA2
    	CALL	RCOUNT			; Read the counter value from the DS2423
    	MOVF	START_COUNT,W		; Move previous counter value into W
    	SUBWF	COUNT,W			; Subtract previous counter value from latest counter value
    	MOVWF	WSPEED_VALUE		; Store result in WSPEED_VALUE
    	MOVF	COUNT,W			; Overwrite previous counter value with latest counter value
    	MOVWF	START_COUNT
    	MOVF	WSPEED_VALUE,W
    	MOVWF	CNTR
    	MOVLW	HIGH WIND_SPEED
    	MOVWF	PCLATH
    	MOVLW	LOW	WIND_SPEED + 1
    	ADDWF	CNTR,W
    	BTFSC	STATUS,C
    	INCF	PCLATH,F
    	CALL	WIND_SPEED		; get BCD wind speed from look-up table
    	CALL	WS_BCD_ASCII		; convert BCD table value to ASCII
    	RETURN
    
    WDIR_UPDATE
    	CALL	DS2450_READ		; read value of two 360 degree potentiometers converted to
    	BCF	STATUS,C		; eight bit readings
    	MOVLW	0X0F
    	SUBWF	CHANNELD,W
    	BTFSS	STATUS,C		; if set, CHANNELD is greater than 0x0F
    	GOTO	WD_CC			; if not set, CHANNELD is less that 0x0F and use CHANNELC
    	BCF	STATUS,C
    	MOVLW	0XF0
    	SUBWF	CHANNELD,W			
    	BTFSC	STATUS,C		; if clear, CHANNELD is less than 0x0F
    	GOTO	WD_CC			; use Channel C pot as Channel D is near deadband			
    	GOTO	WD_CD			; use Channel D pot as Channel D is clear of deadband
    WD_CC
    	MOVLW	0X80			; add 180 degrees to the reading of Channel C pot
    	ADDWF	CHANNELC,W
    	GOTO	CALC_WD
    D_CD		
    	MOVF	CHANNELD,W
    CALC_WD		
    	MOVWF	CALCL			; calculate degrees from Channel C/D ADC converter values
    	CLRF	CALCH
    	MOVLW	D'14'			; multiply CHANNELD reading by 14 to give degrees*10
    	CLRF	CNTR
    	BSF	CNTR, 3
    	RRF	CALCL,F
    LOOP
    	SKPNC
    	ADDWF	CALCH,F
    	RRF	CALCH,F
    	RRF	CALCL,F
    	DECFSZ	CNTR,F
    	GOTO	LOOP
    
    	CALL	WD_ASCII		; convert degrees*10 into ASCII
    		
    	RETURN
    
    TEMP_RH_UPDATE				; Routines for SHT11 temperature and humidity calculations were modified
    					; from original code by Claudiu Chiculita
    	MOVLW	' '			; clear SHT11 error codes
    	MOVWF	SHT_ERROR1
    	MOVWF	SHT_ERROR2
    	CALL	SHT_CONNECTION_RESET	; reset SHT11 serial interface
    	MOVLW	0x03			; temperature conversion command
    	CALL 	SHT_DATA_ACQUIRE	; get temperature data. W will be 1 if an error was detected
    	ADDLW	D'0'				
    	BTFSS	STATUS,Z		; check for errors
    	GOTO	ISR_OVER		; if yes, go to ISR_OVER
    	MOVF	DATAL,W			; if no, move temperature reading LS byte to CALCL					
    	MOVWF	CALCL
    	MOVF	DATAH,W			; move temperature reading MS byte to CALCH
    	MOVWF	CALCH
    	MOVLW	HIGH(D'4000')		; calculate temperature by subtracting 4000
    	MOVWF	SUBH
    	MOVLW	LOW(D'4000')
    	MOVWF	SUBL	
    	CLRF	NEG
    	CALL	SUB16
    	BC	POS_TEMP		; if no carry then temperature is positive
    	MOVLW	HIGH(D'1')		; if carry, then temperature is negative
    	MOVWF	SUBH
    	MOVLW	LOW(D'1')
    	MOVWF	SUBL					
    	CALL	SUB16
    	COMF	CALCH,F
    	COMF	CALCL,F
    	INCF	NEG,F			; increment NEG to indicate negative temperature
    POS_TEMP
    	CALL	TEMP_ASCII		; convert temperature into ASCII and store in T10, T1, T01
    	CALL	SHT_CONNECTION_RESET	; reset SHT11 serial interface
    	MOVLW	0x05			; relative humidity conversion command
    	CALL 	SHT_DATA_ACQUIRE	; get relative humidity data. W is 1 if an error was detected
    	ADDLW	D'0'				
    	BTFSS	STATUS,Z		; check for errors
    	GOTO	ISR_OVER		; if yes, go to ISR_OVER
    	MOVF	DATAL,W			; if no, move relative humidity reading LS byte to CALCL					
    	MOVWF	CALCL
    	MOVF	DATAH,W			; move relative humidity reading MS byte to CALCH
    	MOVWF	CALCH
    	MOVLW	D'5'
    	MOVWF	CNTR			; number of right shifts for RH calculations
    
    LIN_RH1	
    	BCF	STATUS,C		; 5 right shifts to CALCH, CALCL to give raw reading/32
    	RRF	CALCH,F
    	RRF	CALCL,F
    	DECFSZ	CNTR,F
    	GOTO	LIN_RH1
    	MOVF	CALCL,W
    	MOVWF	RH_32			; raw RH reading divided by 32
    	MOVLW	D'2'
    	MOVWF	CNTR
    
    LIN_RH11	
    	BCF	STATUS,C		; 2 right shifts to CALCH, CALCL to give raw reading/128
    	RRF	CALCH,F
    	RRF	CALCL,F
    	DECFSZ	CNTR,F
    	GOTO	LIN_RH11
    	MOVF	CALCL,W
    	MOVWF	RH_128			; raw RH reading divided by 128
    	MOVF	DATAL,W			; move relative humidity reading LS byte to CALCL					
    	MOVWF	CALCL
    	MOVF	DATAH,W			; move relative humidity reading MS byte to CALCH
    	MOVWF	CALCH		
    	MOVLW	HIGH(D'1024')	
    	MOVWF	SUBH
    	MOVLW	LOW(D'1024')
    	MOVWF	SUBL	
    	CALL	SUB16
    	BTFSS	STATUS,C		; is relative humidity reading RH<1024
    	GOTO	LIN_RH2			; if yes, use RH% = RH_32 + RH_128 -3
    	MOVLW	HIGH(D'1546')		
    	MOVWF	SUBH
    	MOVLW	LOW(D'1546')
    	MOVWF	SUBL	
    	CALL	SUB16
    	BTFSS	STATUS,C		; is relative humidity reading 	1024<RH<2560?
    	GOTO	LIN_RH3			; if yes, use RH% = RH_31 + 4
    	MOVF	RH_128,W		; if no, then use RH% = RH_32 - RH_128 + 24
    	SUBWF	RH_32,W
    	ADDLW	D'24'
    	MOVWF	RH
    	SUBLW	D'100'
    	BTFSS	STATUS,C		; is result greater than 100%?
    	GOTO	LIN_RH_HUN		; yes, limit value to 100%
    	GOTO	LIN_RH_OVER		; no, finished
    
    LIN_RH_HUN
    	MOVLW	D'100'			; limit RH to 100%
    	MOVWF	RH					
    	GOTO	LIN_RH_OVER
    
    LIN_RH2
    	MOVF	RH_32,W			; RH% = RH_32 + RH_128 -3
    	ADDWF	RH_128,W
    	ADDLW	-D'3'
    	BTFSS	STATUS,C		; is result less than 0%?
    	GOTO	LIN_RH_ZERO		; yes, limit value to 0%
    	MOVWF	RH
    	GOTO	LIN_RH_OVER		; no, finished
    
    LIN_RH_ZERO
    	MOVLW	D'0'			; limit RH to 0%
    	MOVWF	RH
    	GOTO	LIN_RH_OVER
    
    LIN_RH3
    	MOVF	RH_32,W			; RH% = RH_31 + 4
    	ADDLW	D'4'
    	MOVWF	RH
    
    LIN_RH_OVER
    	CLRF	CALCH
    	MOVF	RH,W
    	MOVWF	CALCL
    	CALL	RH_ASCII		; convert RH into ASCII and store in R100, R10, R1
    	RETURN
    
    LSTRIKE_UPDATE
    	MOVLW	0xE0			; Load low byte counter memory page address
    	MOVWF	TA1		
    	MOVLW	0x01			; Load high byte counter memory page address
    	MOVWF	TA2
    	CALL	RCOUNT			; Read the counter value from the DS2423
    	MOVF	COUNT,W
    	MOVWF	CALCL
    	CLRF	CALCH
    	CALL	LS_ASCII
    	RETURN
    
    DISPLAY_CHANGE
    	BTFSC	FLAGS,0			; is start screen displayed?
    	GOTO	DISPLAY_CHANGE1		; if no, go to DISPLAY_CHANGE1
    	BSF	FLAGS,0			; if yes, set display flag
    	CALL 	SECOND_SCREEN		; put screen two on LCD
    	GOTO	DISPLAY_CHANGE2
    
    DISPLAY_CHANGE1
    	BCF	FLAGS,0			; clear display flag
    	CALL	START_SCREEN		; put start screen on LCD
    	
    DISPLAY_CHANGE2
    	MOVF	PORTB, W		; read PORTB
    	MOVWF	TEST			; store PORTB in TEST
    	BTFSS	TEST, 0			; has display key been released?
    	GOTO	DISPLAY_CHANGE2		; no, go to DISPLAY_CHANGE2
    	CALL	DELAY_KB		; 10 ms Keyboard debounce
    	MOVF	PORTB, W		; read PORTB
    	MOVWF	TEST			; store PORTB in TEST
    	BTFSS	TEST, 0			; has display key been released?
    	GOTO	DISPLAY_CHANGE2		; no, go to DISPLAY_CHANGE2
    	BCF	INTCON, INTF		; clear RB0 interupt flag
    	GOTO	ISR_OVER
    
    ISR_OVER
    	CALL	DISPLAY_UPDATE		; Update display
    
    	MOVF	STATUS_TEMP,W     	; retrieve copy of STATUS register
    	MOVWF	STATUS            	; restore pre-isr STATUS register contents
    	SWAPF	W_TEMP,F
    	SWAPF	W_TEMP,W          	; restore pre-isr W register contents
    	RETFIE                    	; return from interrupt
    
    ;***** INCLUDE FILES *****
    
    	#include "m_lcd.h"
    
    ;*************************************** TABLES *************************************
    
    ;***** 1-WIRE DEVICE ROM CODE TABLE *****
    ;	This needs to be modified should any of the 1-Wire devices be changed
    
    DS2423
    		MOVWF	PCL
    		DT	0x1D,0x56,0xA7,0x04,0x00,0x00,0x00,0x33
    DS2450
    		MOVWF	PCL
    		DT	0x20,0x1B,0xAD,0x00,0x00,0x00,0x00,0x93	
    
    ;***** SCREEN TABLES *****
    
    SCREEN1
    		MOVWF	PCL
    		DT	"TEMP   . ",0xDF,"C    RELH    %",0x00		
    
    SCREEN2
    		MOVWF	PCL
    		DT	"WSPD    KTS   WDIR    ",0xDF,"T",0x00	
    
    SCREEN3
    		MOVWF	PCL
    		DT	"TMIN   . ",0xDF,"C  TMAX   . ",0xDF,"C",0x00
    
    SCREEN4
    		MOVWF	PCL
    		DT	"LSTRIKES    ",0x00
    
    ;***** WIND SPEED LOOK-UP TABLE *****
    
    WIND_SPEED
    		MOVWF	PCL
    		DT	0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x05,0x05,0x05,0x06
    		DT	0x06,0x07,0x07,0x07,0x08,0x08,0x09,0x09,0x09,0x10,0x10,0x11,0x11,0x12,0x12,0x12
    		DT	0x13,0x13,0x14,0x14,0x14,0x15,0x15,0x16,0x16,0x16,0x17,0x17,0x18,0x18,0x18,0x19
    		DT	0x19,0x20,0x20,0x20,0x21,0x21,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x25,0x25,0x25
    		DT	0x26,0x26,0x27,0x27,0x27,0x28,0x28,0x29,0x29,0x29,0x30,0x30,0x31,0x31,0x31,0x32
    		DT	0x32,0x33,0x33,0x33,0x34,0x34,0x35,0x35,0x36,0x36,0x36,0x37,0x37,0x38,0x38,0x38
    		DT	0x39,0x39,0x40,0x40,0x40,0x41,0x41,0x42,0x42,0x42,0x43,0x43,0x44,0x44,0x44,0x45
    		DT	0x45,0x46,0x46,0x47,0x47,0x47,0x48,0x48,0x49,0x49,0x49,0x50,0x50,0x51,0x51,0x51
    		DT	0x52,0x52,0x53,0x53,0x53,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x57,0x57,0x58,0x58
    		DT	0x58,0x59,0x59,0x60,0x60,0x60,0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x64,0x64,0x64
    		DT	0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x68,0x68,0x69,0x69,0x69,0x70,0x70,0x71,0x71
    		DT	0x71,0x72,0x72,0x73,0x73,0x73,0x74,0x74,0x75,0x75,0x75,0x76,0x76,0x77,0x77,0x77
    		DT	0x78,0x78,0x79,0x79,0x80,0x80,0x80,0x81,0x81,0x82,0x82,0x82,0x83,0x83,0x84,0x84
    		DT	0x84,0x85,0x85,0x86,0x86,0x86,0x87,0x87,0x88,0x88,0x88,0x89,0x89,0x90,0x90,0x91
    		DT	0x91,0x91,0x92,0x92,0x93,0x93,0x93,0x94,0x94,0x95,0x95,0x95,0x96,0x96,0x97,0x97
    		DT	0x97,0x98,0x98,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99
    
    
    ;*************************************** DELAY MACROS *************************************
    
    ;***** SHORT DELAY MACRO *****
    
    D10USEC	MACRO	TCNST			; provides a delay equal to TCNST * 10 usecs
    	MOVLW	TCNST
    	MOVWF	DELAY1
    	CALL	D10USEC1
    	ENDM
    
    D10USEC1
    	NOP
    	NOP
    	NOP
    	NOP
    	NOP
    	NOP
    	NOP
    	DECFSZ	DELAY1, F
    	GOTO	D10USEC1
    	RETURN
    
    
    ;***** LONG DELAY MACRO *****
    
    DLONG	MACRO	TCNST			; provided a delay of TCNST * msec
    	MOVLW	TCNST
    	MOVWF	DELAY1
    	CALL	OUTER
    	ENDM	
    
    OUTER
    	MOVLW	D'110'			; close to 1.0 msec delay when set to 110
    	MOVWF	DELAY2
    INNER
    	NOP
    	NOP
    	NOP
    	NOP
    	NOP
    	NOP
    	DECFSZ	DELAY2, F		
    	GOTO	INNER
    	DECFSZ	DELAY1, F
    	GOTO	OUTER
    	RETURN
    
    
    
    ;*************************************** DELAY SUBROUTINES *************************************
    
    DELAY_KB
    	DLONG	D'10'
    	RETURN
    
    ;*************************************** LCD MODULE SUBROUTINES *************************************
    ; For KS0066U controller chips
    ; Note that lower bits of Port are being used
    
    ;***** LCD MODULE INITALIZATION SUBROUTINE *****
    
    LCD_Init
    	BANKSEL	LCD_DATA_TRIS
    	CLRF	LCD_DATA_TRIS
    	BANKSEL	LCD_DATA
    	CLRF	LCD_DATA
    	BCF	R_S			; write to the KS0066U IR. 
    	MOVLW	b'00000011'		; Command for 8-bit interface
            MOVWF   LCD_DATA        
            BSF     EN      
            NOP
    	NOP
            BCF     EN
    	DLONG	D'5'			; have to wait 5ms here
            BSF     EN	           	
            NOP
    	NOP                    
           	BCF     EN     
            D10USEC	D'12'			; have to wait 100us here
            BSF     EN	           	
            NOP
    	NOP                    
            BCF     EN
            D10USEC	D'10'			; have to wait 100us here
     	MOVLW	FUNC_SET		; Function Set
    	CALL	LCD_Cmd
    	MOVLW   DISP_OFF		; Display Off        
    	CALL	LCD_Cmd                
    	MOVLW   CLR_DISP		; Clear the Display
            CALL	LCD_Cmd
            MOVLW   ENTRY_INC		; Entry Cursor Increment 
            CALL	LCD_Cmd        
    	MOVLW   DISP_ON			; Display On, No Cursor
            CALL	LCD_Cmd
    	RETURN                                                 
            
    ;***** LCD_Nbl SUBROUTINE *****
    
    LCD_Nbl		
    	MOVWF   TEMP1			; Character to be sent is in
    					; W so put in Temp1
    	DLONG	D'2'			; Wait 2ms instead of Busy Check				
    	SWAPF	TEMP1, W       	
    	ANDLW   0x0F			; Get upper nibble into lower half port
    	MOVWF   LCD_DATA	        ; Send data to LCD
    	BSF     R_S			; Set LCD to data mode
    	CALL	LCDtglclk	        ; Toggle EN
    	MOVF	TEMP1, W
    	ANDLW   0x0F            	; Get lower nibble into upper half port
    	MOVWF   LCD_DATA	        ; Send data to LCD
    	BSF     R_S		       	; Set LCD to data mode
    	CALL	LCDtglclk		; Toggle EN
    	RETURN
    
    LCDtglclk
    	BSF     EN			; Toggle EN for LCD
    	NOP 
    	NOP
    	BCF     EN
    	RETURN
    
    ;***** LCD_Cmd SUBROUTINE *****
    
    LCD_Cmd	
    	MOVWF   TEMP1			; Command to be sent is in
    					; W so put in Temp1
    	DLONG	D'2'	
    	SWAPF	TEMP1, W
    	ANDLW   0x0F			; Get upper nibble into lower half port
    	MOVWF   LCD_DATA	        ; Send data to LCD
    	BCF     R_S			; Set LCD to command mode
    	CALL	LCDtglclk		; Toggle EN
    	MOVF	TEMP1, W
    	ANDLW	0x0F			; Get lower nibble into lower half port
     	MOVWF   LCD_DATA	        ; Send data to LCD
    	BCF     R_S			; Set LCD to command mode
    	CALL    LCDtglclk		; Toggle EN
    	RETURN        
    
    ;***** LCD_Hex SUBROUTINE *****
    
    LCD_Hex	
    	MOVWF	TEMP2			; Character to be sent is in
    					; W so put in Temp2
    	SWAPF	TEMP2, W
    	ANDLW   0x0F			; Get upper nibble into lower half port
    	CALL	LCD_Hex1		; Convert upper nybble to ASCII 
    	CALL	LCD_Nbl			; Output ASCII on LCD display 
         	MOVF	TEMP2, W
    	ANDLW	0x0F
    					; Get lower nibble into lower half port
     	CALL	LCD_Hex1		; Convert lower nybble to ASCII 
    	CALL	LCD_Nbl			; Output ASCII on LCD display 
    	RETURN
     
    LCD_Hex1
    	ADDLW	0xF6			; This routine converts a number in w to an  
    	BTFSC	STATUS, C		; ASCII hex number.  Result in W 
    	ADDLW	0x07 
    	ADDLW	0x3A 
            RETURN
    
    ;***** LCD_Clear SUBROUTINE *****
    
    LCD_Clear
           	MOVLW   CLR_DISP
          	CALL	LCD_Cmd 
          	RETURN
    
    ;***************************************LCD MODULE MACROS *************************************
    
    ;***** LCD_Move Macro *****
    
    LCD_Move	MACRO   Address 
           	MOVLW   Address ;(Address|0x80) 
           	CALL	LCD_Cmd 
           	ENDM
    
    ;*************************************** 1-WIRE SUBROUTINES *************************************
    
    
    ;***** 1-WIRE MATCH ROM SUBROUTINE *****
    
    MATCH_ROM
    	MOVLW	0X55			; MATCH ROM Command
    	MOVWF	TEMP1
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR		  
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVLW	D'8'			; 8 bytes of ROM ID data long
    	MOVWF	CNTR2
    
    MATCH_ROM1
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR
    	MOVF	HIGH_ADDRESS,W
    	MOVWF	PCLATH
    	INCF	LOW_ADDRESS,W
    	ADDWF	CNTR1,W
    	BTFSC	STATUS,C
    	INCF	PCLATH,F
    	BTFSS	FLAGS,1			; is FLAGS,1 set?
    	GOTO	CALL_DS2423		; no, call DS2423 table
    	CALL	DS2450			; yes, call DS2450 table
    	GOTO	NEXT
    
    CALL_DS2423
    	CALL	DS2423
    NEXT
    	MOVWF	TEMP1			; and output to 1820
    	CALL	WB			; One-Wire Write Byte subroutine
    	DECFSZ	CNTR2,F			; decrement count and skip next if=0
    	GOTO	MATCH_ROM2		; else increment address and read again
    	GOTO	MATCH_ROM3		; done sending ROM ID
    	
    MATCH_ROM2
    	INCF	CNTR1,F
    	GOTO	MATCH_ROM1
    
    MATCH_ROM3
    
    	RETURN
    
    
    ;***** 1-WIRE Reset SUBROUTINE *****
    
    RESET	
    	BANKSEL	D1WIRE_PORT
    	BCF	D1WIRE			; Set 1-Wire Bus low
    	BANKSEL	D1WIRE_TRIS
    	BCF	D1WIRE			; 1-Wire Bus direction = output, 1-wire forced low
    	D10USEC	D'50' 			; 500 µs DELAY 
    	BSF	D1WIRE			; 1-Wire Bus direction = input, 1-wire pulled up
    	BANKSEL	D1WIRE_PORT
    	D10USEC	D'6'			; 60 µs DELAY
    	CLRF	TEMP3			; Initialize samples register=0
    	MOVLW	D'36'			; 36 counts (180 µs)
    	MOVWF	CNTR			; Put 36 into count register
    	CALL	RESET1	
    	RETURN
    
    RESET1
    	BTFSS	D1WIRE			; Skip next if 1-wire is high
    	INCF	TEMP3,F			; Low so increment samples register
    	DECFSZ	CNTR,F			; Decrement count and skip next if=0
    	GOTO	RESET1			; Else go back, sample, decrement again
    	D10USEC	D'24'			; 240 µs DELAY 
    	RETURN				; Done (TEMP3 contains sampled low count)
    
    
    ;***** 1-WIRE WRITE SUBROUTINE *****
    ;	Input: Byte to write in TEMP1
    ;	     : Number of bits to send in CNTR
    ;
    
    WB		
    	CALL  WB0
    	RETURN
    WB0
    	RRF	TEMP1,F			; Rotate LSBit data into carry
    	BTFSS	STATUS,C		; Skip next if carry (data)=1
    	GOTO	WB2			; Else jump to data=0 routine
    WB1
    	CALL	W1S			; Call the write-1 time slot
    	GOTO	WB3			; Go on
    WB2
    	CALL	W0S			; Call the write-0 time slot
    WB3
    	DECFSZ	CNTR,1			; Decrement count and skip next if=0
    	GOTO	WB0			; Else go back and do another bit
    	RETURN				; Done sending all bits
    
    W1S
    	BANKSEL	D1WIRE_PORT
    	BCF	D1WIRE			; Force 1-wire I/O bit low
    	BANKSEL	D1WIRE_TRIS	
    	BCF	D1WIRE			; I/O direction=output, 1-wire forced low
    	D10USEC	D'1'
    	BSF	D1WIRE			; I/O direction=input, 1-wire pulled up
    	BANKSEL	D1WIRE_PORT
    	D10USEC	D'10'			; 100 µs DELAY
    	RETURN				; Done sending bit
    
    W0S
    	BANKSEL	D1WIRE_PORT
    	BCF	D1WIRE			; Force 1-wire I/O bit low
    	BANKSEL D1WIRE_TRIS		; Point to Bank1 (direction control)
    	BCF	D1WIRE			; I/O direction=output, 1-wire forced low
    	D10USEC	D'6'			; 60 µs DELAY
    	BSF	D1WIRE			; I/O direction=input, 1-wire pulled up
    	BANKSEL D1WIRE_PORT	
    	D10USEC	D'1'
    	RETURN				; Done sending bit
    
    
    ;***** 1-WIRE READ SUBROUTINE *****
    ;	Input: number of bits to read in CNTR
    ;	Output: read byte in TEMP1
    ;
    
    RB		
    	CALL RB0
    	RETURN
    
    RB0
    	CALL	RS			; Call the read time slot
    	MOVF	TEMP2,1			; Get the sampled low count
    	BCF	STATUS,C		; Clear carry (read data=0 setup)
    	BTFSC	STATUS,Z		; Skip next if sampled count <>0
    	BSF	STATUS,C		; Set carry (read data=1)
    	RRF	TEMP1,1			; Rotate data into the MSBit
    	DECFSZ	CNTR,1			; Decrement count and skip next if=0
    	GOTO	RB0			; Else go back and do another bit
    	RETURN				; Done reading all bits
    
    RS
    	BANKSEL	D1WIRE_PORT
    	BCF	D1WIRE			; Force 1-wire I/O bit low
    	BANKSEL D1WIRE_TRIS		; Point to Bank1 (direction control)
    	BCF	D1WIRE			; I/O direction=output, 1-wire forced low
    	D10USEC	D'1'			; 10 µs DELAY
    	BSF	D1WIRE			; I/O direction=input, 1-wire pulled up
    	BANKSEL D1WIRE_PORT
    	MOVLW	D'3'			; 3 count (15 µs)
    	MOVWF	CNTR1			; into count register
    	CLRF	TEMP2			; Initialize sample count=0
    RS2
    	BTFSS	D1WIRE			; Skip next if 1-wire input=1
    	INCF	TEMP2,1			; Low so increment samples register
    	DECFSZ	CNTR1,1			; Decrement count and skip next if=0
    	GOTO	RS2			; Else go back and decrement again
    	D10USEC	D'5'			; 50 µs DELAY
    	RETURN				; Done receiving bit
    	
    
    ;***** 16 bit CRC SUBROUTINE *****
    ;	Input: 	Byte for CRC in TEMP1
    ;	Output:	Original byte in TEMP1, 
    ;		CRC16_HI and CRC16_LO new value of CRC16
    ;
    
    DSCRC16	
    	MOVLW	D'8'			; 8 bits
    	MOVWF	CNTR			; store counter 
    	MOVF	TEMP1,W
    	MOVWF	STORE			; Store TEMP1
    Crc_Get_Bit
    	RRF	TEMP1,F			; Bit in C
    	MOVF	TEMP1,W			; Value to W
    	SKPNC
    	GOTO	Crc_In_1
    	BTFSS	CRC16_LO,0		; Lowest bit set ?
    	GOTO	Crc_Cont		; Go to count with C=0
    	SETC
    	GOTO	Crc_Cont		; Go to count with C=1
    Crc_In_1
    	BTFSC	CRC16_LO,0		; Lowest bit zero ?
    	CLRC				; If no, C=0 = complement
    Crc_Cont
    	SKPC
    	GOTO	Crc_Shift		; If C=0 only shift
    	BTFSC	CRC16_HI,6		; Complement 15th bit of CRC
    	GOTO	Crc1
    	BSF	CRC16_HI,6		; If clear, set
    	GOTO	Crc2
    Crc1
    	BCF	CRC16_HI,6		; If set, clear
    Crc2
    	BTFSC	CRC16_LO,1		; Complement 2nd bit of CRC
    	GOTO	Crc3
    	BSF	CRC16_LO,1
    	GOTO	Crc_Shift
    Crc3
    	BCF	CRC16_LO,1
    Crc_Shift
    	RRF	CRC16_HI,F		; 16bit rotate
    	RRF	CRC16_LO,F
    	MOVF	TEMP1,W
    	DECFSZ	CNTR,F
    	GOTO	Crc_Get_Bit
    	MOVF	STORE,W
    	MOVWF	TEMP1			; Restore TEMP1
    	RETURN
    
    ;***************************************READ DS2423 SUBROUTINE*************************************
    ;	Reads DS2423 Counter
    ;	Input:TA1 is low byte address, TA2 is high byte address
    ;	Output: counter value in COUNT
    
    RCOUNT	
    	CLRF	CRC16_LO
    	CLRF	CRC16_HI
    	CLRF	CNTR1
    	CLRF	COUNT
    
    	CALL	RESET
    	MOVF	TEMP3,W			; Move data into W
    	SKPNZ				; Check to see if it is zero
    	GOTO	ERROR_TRAP		; If it is zero, go to ERROR_TRAP
    
    	MOVLW	HIGH DS2423		; send Match Rom command using ID of DS2423
    	MOVWF	HIGH_ADDRESS
    
    	MOVLW	LOW  DS2423		; send Match Rom command using ID of DS2423
    	MOVWF	LOW_ADDRESS
    	BCF	FLAGS,1			; clear FLAGS,1 to indicate DS2423 table read
    
    	CALL	MATCH_ROM
    
    	MOVLW	0XA5			; READ COUNTER Command
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVF	TA1,W			; COUNTER Low Address Command
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVF	TA2,W			; COUNTER High Address Command
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    
    	MOVLW	D'32'
    	MOVWF	CNTR2
    SKIPD32
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	RB			; One-Wire Read Byte subroutine
    	CALL	DSCRC16
    	DECFSZ	CNTR2,F
    	GOTO	SKIPD32
    		
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	RB			; One-Wire Read Byte subroutine
    	CALL	DSCRC16
    	MOVF	TEMP1,W
    	MOVWF	COUNT			; transfer value to COUNT. Only interested in last byte of 
    					; counter
    	MOVLW	D'3'
    	MOVWF	CNTR2
    READD
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR
     	CALL	RB			; One-Wire Read Byte subroutine
    	CALL	DSCRC16
    	DECFSZ	CNTR2,F
    	GOTO	READD	
    
    	MOVLW	D'4'
    	MOVWF	CNTR2
    SKIPD2
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	RB			; One-Wire Read Byte subroutine
    	CALL	DSCRC16
    	DECFSZ	CNTR2, 1
    	GOTO	SKIPD2
    READCRC
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR
     	CALL	RB			; One-Wire Read Byte subroutine
    	COMF	CRC16_LO,F		
    	MOVF	CRC16_LO,W
    	SUBWF	TEMP1,W
    	SKPZ
    	GOTO	ERROR_TRAP
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR
     	CALL	RB			; One-Wire Read Byte subroutine
    	COMF	CRC16_HI,F
    	MOVF	CRC16_HI,W
    	SUBWF	TEMP1,W
    	SKPZ
    	GOTO	ERROR_TRAP
    	GOTO	CRC_OVER
    
    ERROR_TRAP
    	MOVLW	'E'
    	MOVWF	D1WIRE_ERROR
    	RETURN
    
    CRC_OVER
    	RETURN
    
    ;***************************************DS2450 INITIALIZATION SUBROUTINE*************************
    ;	Initialize DS2450 to do 8 bit conversions on Channel A,B,C,D with Vcc available (0X40 written to 
    ;	Memory location 1C)
    
    DS2450_INIT
    	CLRF	CRC16_LO
    	CLRF	CRC16_HI
    	CLRF	CNTR1
    
    	CALL	RESET
    	MOVF	TEMP3,W			; Move data into W
    	SKPNZ				; Check to see if it is zero
    	GOTO	ERROR_TRAP		; If it is zero, go to ERROR_TRAP
    
    	MOVLW	HIGH DS2450		; send Match Rom command using ID of DS2450
    	MOVWF	HIGH_ADDRESS
    
    	MOVLW	LOW  DS2450		; send Match Rom command using ID of DS2450
    	MOVWF	LOW_ADDRESS
    	BSF	FLAGS,1			; set FLAGS,1 to indicate DS2450 table read
    
    	CALL	MATCH_ROM
    
    	MOVLW	0X55			; Write Command
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVLW	0x0C			; Page 1 Channel C Control/Status Low Address 
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVLW	0x00			; Page 1 Channel C Control/Status High Address
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVLW	0x08			; Channel C Control, 8 bit conversion
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine	
    	CALL	READCRC
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR
     	CALL	RB			; One-Wire Read Byte subroutine
    	MOVLW	0x08
    	SUBWF	TEMP1,W
    	BTFSS	STATUS,Z
    	CALL	ERROR_TRAP1
    
    	CLRF	CRC16_LO
    	CLRF	CRC16_HI
    	MOVLW	0x0D
    	MOVWF	CRC16_LO
    	MOVLW	0x00
    	MOVWF	CRC16_HI
    	MOVLW	0x01			; Channel C Status, 5.12 Volts 
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	CALL	READCRC
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR
     	CALL	RB			; One-Wire Read Byte subroutine
    	MOVLW	0x01
    	SUBWF	TEMP1,W
    	BTFSS	STATUS,Z
    	CALL	ERROR_TRAP2
    
    	CLRF	CRC16_LO
    	CLRF	CRC16_HI
    	MOVLW	0x0E
    	MOVWF	CRC16_LO
    	MOVLW	0x00
    	MOVWF	CRC16_HI		
    	MOVLW	0x08			; Channel D Control, 8 bit conversion
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	CALL	READCRC
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR
     	CALL	RB			; One-Wire Read Byte subroutine
    	MOVLW	0x08
    	SUBWF	TEMP1,W
    	BTFSS	STATUS,Z
    	CALL	ERROR_TRAP3
    
    	CLRF	CRC16_LO
    	CLRF	CRC16_HI		
    	MOVLW	0x0F
    	MOVWF	CRC16_LO
    	MOVLW	0x00
    	MOVWF	CRC16_HI		
    	MOVLW	0x01			; Channel D Status, 5.12 Volts 
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	CALL	READCRC
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR
     	CALL	RB			; One-Wire Read Byte subroutine
    	MOVLW	0x01
    	SUBWF	TEMP1,W
    	BTFSS	STATUS,Z
    	CALL	ERROR_TRAP4
    	CALL	RESET
    
    	CLRF	CRC16_LO
    	CLRF	CRC16_HI
    	CLRF	CNTR1
    
    	CALL	MATCH_ROM
    
    	MOVLW	0X55			; Write Command
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVLW	0x1C			; Page 4 Low Address 
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVLW	0x00			; Page 4 High Address
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVLW	0x40			; VCC available alwyas
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine	
    	CALL	READCRC
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR
     	CALL	RB			; One-Wire Read Byte subroutine
    	MOVLW	0x40
    	SUBWF	TEMP1,W
    	BTFSS	STATUS,Z
    	CALL	ERROR_TRAP5
    	CALL	RESET	
    	RETURN
    
    ERROR_TRAP1
    	MOVLW	'1'
    	MOVWF	D1WIRE_ERROR
    	RETURN
    
    ERROR_TRAP2
    	MOVLW	'2'
    	MOVWF	D1WIRE_ERROR
    	RETURN
    
    ERROR_TRAP3
    	MOVLW	'3'
    	MOVWF	D1WIRE_ERROR
    	RETURN
    
    ERROR_TRAP4
    	MOVLW	'4'
    	MOVWF	D1WIRE_ERROR
    	RETURN
    
    ERROR_TRAP5
    	MOVLW	'5'
    	MOVWF	D1WIRE_ERROR
    	RETURN
    
    ;***************************************READ DS2450 SUBROUTINE*************************
    ;	Read results of 8 bit conversions on Channel C,D 
    
    DS2450_READ
    	CLRF	CRC16_LO
    	CLRF	CRC16_HI
    	CLRF	CNTR1
    
    	CALL	RESET
    	MOVF	TEMP3,W			; Move data into W
    	SKPNZ				; Check to see if it is zero
    	GOTO	ERROR_TRAP		; If it is zero, go to ERROR_TRAP
    
    	MOVLW	HIGH DS2450		; send Match Rom command using ID of DS2450
    	MOVWF	HIGH_ADDRESS
    
    	MOVLW	LOW	DS2450		; send Match Rom command using ID of DS2450
    	MOVWF	LOW_ADDRESS
    	BSF	FLAGS,1			; set FLAGS,1 to indicate DS2450 table read
    
    	CALL	MATCH_ROM
    
    	MOVLW	0X3C			; Convert Command
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVLW	0x0C			; input select mask 
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVLW	0x00			; read out control byte 
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	CALL	READCRC
    
    CONVER_WAIT
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR
     	CALL	RB			; One-Wire Read Byte subroutine
    	MOVLW	0xFF
    	SUBWF	TEMP1,W
    	BTFSS	STATUS,Z
    	GOTO	CONVER_WAIT
    	CALL	RESET
    
    	CLRF	CRC16_LO
    	CLRF	CRC16_HI
    	CLRF	CNTR1
    
    	CALL	MATCH_ROM
    
    	MOVLW	0XAA			; Read Command
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVLW	0x04			; Channel C Result Low Address
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVLW	0x00			; Channel C Result High Address
    	MOVWF	TEMP1
    	CALL 	DSCRC16	  
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	WB			; One-Wire Write Byte subroutine
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	RB			; One-Wire Read Byte subroutine
    	CALL	DSCRC16			; Channel C LS Byte
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	RB			; One-Wire Read Byte subroutine
    	CALL	DSCRC16			; Channel C MS Byte
    	MOVF	TEMP1,W
    	MOVWF	CHANNELC
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	RB			; One-Wire Read Byte subroutine
    	CALL	DSCRC16			; Channel D LS Byte
    	MOVLW	D'8'			; 8 bits long
    	MOVWF	CNTR	 
    	CALL	RB			; One-Wire Read Byte subroutine
    	CALL	DSCRC16			; Channel D MS Byte
    	MOVF	TEMP1,W
    	MOVWF	CHANNELD
    	CALL	READCRC
    	CALL	RESET
    
    	RETURN
    
    ;*************************************** SHT11 SUBROUTINES *************************************
    
    ;***** SHT11 TRANSMISSION START SUBROUTINE *****
    ; 	Leaves DATA as input at end of subroutine
    
    SHT_TX_START
    	BANKSEL	TWO_WIRE
    	BCF	TWO_WIRE_CLOCK		; set Clock line low
    	BCF	TWO_WIRE_DATA		; set Data line low
    	BANKSEL	TWO_WIRE_TRIS		
    	BCF	TWO_WIRE_CLOCK		; set Clock line as output
    	BCF	TWO_WIRE_DATA		; set Data line as output
    	BANKSEL	TWO_WIRE
    	BSF	TWO_WIRE_DATA		; set Data line high
    	BSF	TWO_WIRE_CLOCK		; set Clock line high
    	BCF	TWO_WIRE_DATA		; set Data line low	
    	BCF	TWO_WIRE_CLOCK		; set Clock line low
    	BSF	TWO_WIRE_CLOCK		; set Clock line high
    	BSF	TWO_WIRE_DATA		; set Data line high
    	BCF	TWO_WIRE_CLOCK		; set Clock line low
    	BANKSEL	TWO_WIRE_TRIS
    	BSF	TWO_WIRE_DATA		; set Data line as input
    	BANKSEL	TWO_WIRE
    
    	RETURN
    
    ;***** SHT11 WRITE BYTE SUBROUTINE *****
    ;	Input: Byte to write in TEMP1
    ;	     : Number of bits to send in CNTR
    ;	Output: Carry=1 if no ACK was received
    ;   	Leaves DATA as input at end of subroutine
    
    SHT_WRITE_BYTE
    	BANKSEL	TWO_WIRE
    	BCF	TWO_WIRE_CLOCK		; set Clock line low
    	BCF	TWO_WIRE_DATA		; set Data line low
    	BANKSEL	TWO_WIRE_TRIS
    	BCF	TWO_WIRE_CLOCK		; set Clock line as output
    	BCF	TWO_WIRE_DATA		; set Data line as output
    	BANKSEL	TWO_WIRE
    		
    SHT_WRITE_BYTE1
    	BCF	TWO_WIRE_CLOCK		; set Clock line low
    	RLF	TEMP1,F			; rotate MSB into Carry
    	BTFSS	STATUS,C		; is bit 1?
    	BCF	TWO_WIRE_DATA		; no, set Data line low
    	BTFSC	STATUS,C		; is bit 0?
    	BSF	TWO_WIRE_DATA		; no. set Data line high
    	BSF	TWO_WIRE_CLOCK		; set Clock line high
    	DECFSZ	CNTR,F			; have all bits been sent?
    	GOTO	SHT_WRITE_BYTE1		; no, go to SHT_WRITE_BYTE
    
    	BANKSEL	TWO_WIRE_TRIS
    	BSF	TWO_WIRE_DATA		; set Data line as input
    	BANKSEL	TWO_WIRE
    	BCF	TWO_WIRE_CLOCK		; set Clock line low
    	BSF	TWO_WIRE_CLOCK		; set Clock line high
    	BCF	STATUS,C		; clear Carry flag
    	BTFSC	TWO_WIRE_DATA		; is Data line low?
    	BSF	STATUS,C		; no, set Carry bit to indicate no ACK received
    	BCF	TWO_WIRE_CLOCK		; yes, set Clock line low
    		
    		RETURN		
    
    ;***** SHT11 READ BYTE SUBROUTINE *****
    ;	Input: Number of bits to read in CNTR
    ;	Output: Read byte in TEMP1
    
    
    SHT_READ_BYTE
    	BANKSEL	TWO_WIRE
    	CLRF	TEMP1
    	BCF	TWO_WIRE_CLOCK
    	BCF	TWO_WIRE_DATA
    	BANKSEL	TWO_WIRE_TRIS
    	BCF	TWO_WIRE_CLOCK
    	BSF	TWO_WIRE_DATA
    	BANKSEL	TWO_WIRE
    
    SHT_READ_BYTE1
    	BSF	TWO_WIRE_CLOCK
    	BCF	STATUS,C		
    	BTFSC	TWO_WIRE_DATA
    	BSF	STATUS,C
    	RLF	TEMP1,F
    	BCF	TWO_WIRE_CLOCK
    	DECFSZ	CNTR,F
    	GOTO	SHT_READ_BYTE1
    
    	BANKSEL	TWO_WIRE_TRIS
    	BCF	TWO_WIRE_DATA
    	BANKSEL	TWO_WIRE
    	BCF	TWO_WIRE_DATA
    	BSF	TWO_WIRE_CLOCK
    	BCF	TWO_WIRE_CLOCK
    	RETURN
    
    ;***** SHT11 WAIT FOR DATA SUBROUTINE *****
    ;
    WAIT_FOR_DATA
    	MOVLW	D'195'			; this gives a maximum 250 msec delay while waiting for the SHT-11  
    	MOVWF	TEMP1			; to finish the reading
    
    WAIT_FOR_DATA1	
    	CLRF	TEMP2			; inner nested counting loop
    
    WAIT_FOR_DATA2
    	BTFSS	TWO_WIRE_DATA		; is the data line low (SHT-11 signal that reading is finished)
    	RETLW	D'0'			; if yes, return with w egual to 0
    	DECFSZ	TEMP2,F			; if no, continue counting
    	GOTO	WAIT_FOR_DATA2
    	DECFSZ	TEMP1,F			; is TEMP1 now zero
    	GOTO	WAIT_FOR_DATA1		; if no, continue counting
    	RETLW	D'1'			; if yes, SHT-11 has timed out. Return with W equal to 1
    
    	
    ;***** SHT11 CONNECTION RESET SUBROUTINE *****
    
    SHT_CONNECTION_RESET
    	BANKSEL	TWO_WIRE
    	BCF	TWO_WIRE_CLOCK
    	BCF	TWO_WIRE_DATA
    	BANKSEL	TWO_WIRE_TRIS
    	BCF	TWO_WIRE_CLOCK
    	BCF	TWO_WIRE_DATA
    	BANKSEL	TWO_WIRE
    	MOVLW	D'9'
    	MOVWF	CNTR
    	BSF	TWO_WIRE_DATA
    
    SHT_CONNECTION_RESET1
    	BSF	TWO_WIRE_CLOCK
    	BCF	TWO_WIRE_CLOCK
    	DECFSZ	CNTR,F
    	GOTO	SHT_CONNECTION_RESET1
    		
    	RETURN
    		
    ;***** SHT11 DATA ACQUISITION SUBROUTINE *****
    ;	Input:	Command in W
    ;	Output:	Data in DATAH, DATAL
    ;		0 in W if data received
    ;		1 in W if communication timeout
    
    SHT_DATA_ACQUIRE
    	MOVWF	TEMP1
    	CALL	SHT_TX_START
    	MOVLW	D'8'
    	MOVWF	CNTR
    	CALL	SHT_WRITE_BYTE
    	BTFSC	STATUS,C		; has the SHT-11 issued an ACK for the command
    	GOTO	ERROR_NO_ACK     	; if no, go to error routine 
    	CALL	WAIT_FOR_DATA		; if yes, wait for end of reading
    	XORLW	D'1'			; did the SHT-11 timeout
    	BTFSC	STATUS,Z					
    	GOTO	ERROR_TIMEOUT		; if yes, go to error routine
    	MOVLW	D'8'			; if no, read first data byte
    	MOVWF	CNTR
    	CALL	SHT_READ_BYTE
    	MOVF	TEMP1,W
    	MOVWF	DATAH			; store first data byte in DATAH
    	MOVLW	D'8'			; read second data byte
    	MOVWF	CNTR
    	CALL	SHT_READ_BYTE
    	MOVF	TEMP1,W
    	MOVWF	DATAL			; store second data byte in DATAL
     	RETLW	D'0'			; return with W equal to 0 to indicate success
    
    ERROR_NO_ACK
    	MOVLW	'1'			; set ASCII error code 1 for no ack
    	MOVWF	SHT_ERROR2
    	GOTO	SHT_ERROR
    
    ERROR_TIMEOUT
    	MOVLW	'2'			; set ASCII error code 2 for timeout
    	MOVWF	SHT_ERROR2
    	GOTO	SHT_ERROR
    
    ERROR_CRC
    	MOVLW	'3'			; set ASCII error code 3 for wrong CRC
    	MOVWF	SHT_ERROR2
    	GOTO	SHT_ERROR
    
    SHT_ERROR
    	MOVLW	'E'			; set ASCII error code E for error detected
    	MOVWF	SHT_ERROR1
    	CALL	SHT_CONNECTION_RESET	; reset SHT-11 serial interface
    	RETLW	D'1'			; return with W equal to 1 to indicate error
    
    	
    
    
    ;***************************************LCD SCREEN SUBROUTINES *************************************
    
    ;***** START SCREEN *****
    
    START_SCREEN
    	CALL	LCD_Clear
    	CLRF	CNTR
    
    START_SCREEN1
    	MOVLW	HIGH SCREEN1
    	MOVWF	PCLATH
    	MOVLW	LOW	SCREEN1 + 1
    	ADDWF	CNTR,W
    	BTFSC	STATUS,C
    	INCF	PCLATH,F
    	CALL	SCREEN1
    	ANDLW	0xFF
    	BTFSC	STATUS, Z
    	GOTO	START_SCREEN2	
    	CALL	LCD_Nbl
    	INCF	CNTR,F
    	GOTO	START_SCREEN1
    
    START_SCREEN2
    	LCD_Move	0xC0
    	CLRF	CNTR
    
    START_SCREEN3
    	MOVLW	HIGH SCREEN2
    	MOVWF	PCLATH
    	MOVLW	LOW	SCREEN2 + 1
    	ADDWF	CNTR,W
    	BTFSC	STATUS,C
    	INCF	PCLATH,F
    	CALL	SCREEN2
    	ANDLW	0xFF
    	BTFSC	STATUS, Z
    	GOTO	START_SCREEN4	
    	CALL	LCD_Nbl
    	INCF	CNTR,F
    	GOTO	START_SCREEN3
    
    START_SCREEN4
    	RETURN
    
    ;***** SECOND SCREEN *****
    
    SECOND_SCREEN
    	CALL	LCD_Clear
    	CLRF	CNTR
    
    SECOND_SCREEN1
    	MOVLW	HIGH SCREEN3
    	MOVWF	PCLATH
    	MOVLW	LOW	SCREEN3 + 1
    	ADDWF	CNTR,W
    	BTFSC	STATUS,C
    	INCF	PCLATH,F
    	CALL	SCREEN3
    	ANDLW	0xFF
    	BTFSC	STATUS, Z
    	GOTO	SECOND_SCREEN2	
    	CALL	LCD_Nbl
    	INCF	CNTR,F
    	GOTO	SECOND_SCREEN1
    
    SECOND_SCREEN2
    	LCD_Move	0xC0
    	CLRF	CNTR
    
    SECOND_SCREEN3
    	MOVLW	HIGH SCREEN4
    	MOVWF	PCLATH
    	MOVLW	LOW	SCREEN4 + 1
    	ADDWF	CNTR,W
    	BTFSC	STATUS,C
    	INCF	PCLATH,F
    	CALL	SCREEN4
    	ANDLW	0xFF
    	BTFSC	STATUS, Z
    	GOTO	SECOND_SCREEN4	
    	CALL	LCD_Nbl
    	INCF	CNTR,F
    	GOTO	SECOND_SCREEN3
    
    SECOND_SCREEN4
    	RETURN
    
    ;***** DISPLAY UPDATE *****
    
    DISPLAY_UPDATE
    	BTFSC	FLAGS,0
    	GOTO	DISPLAY_UPDATE2
    	LCD_Move	0x84
    	MOVF	NEG,W
    	CALL	LCD_Nbl
    	MOVF	T10,W
    	CALL	LCD_Nbl
    	MOVF	T1,W
    	CALL	LCD_Nbl
    	LCD_Move	0x88
    	MOVF	T01,W
    	CALL	LCD_Nbl
    	LCD_Move	0X8C
    	MOVF	SHT_ERROR1,W
    	CALL	LCD_Nbl
    	MOVF	SHT_ERROR2,W
    	CALL	LCD_Nbl
    	LCD_Move	0x94
    	MOVF	R100,W
    	CALL	LCD_Nbl
    	MOVF	R10,W
    	CALL	LCD_Nbl
    	MOVF	R1,W
    	CALL	LCD_Nbl
    	LCD_Move	0xC5
    	MOVF	WS10,W
    	CALL	LCD_Nbl
    	MOVF	WS1,W
    	CALL	LCD_Nbl
    	LCD_Move	0xCC
    	MOVF	D1WIRE_ERROR,W
    	CALL	LCD_Nbl
    	LCD_Move	0xD3
    	MOVF	WD100,W
    	CALL	LCD_Nbl
    	MOVF	WD10,W
    	CALL	LCD_Nbl
    	MOVF	WD1,W
    	CALL	LCD_Nbl
    	GOTO	DISPLAY_UPDATE3
    
    DISPLAY_UPDATE2
    	LCD_Move	0x84
    	MOVF	TSIGN_MIN_VALUE,W
    	CALL	LCD_Nbl
    	MOVF	T10MIN_VALUE,W
    	CALL	LCD_Nbl
    	MOVF	T1MIN_VALUE,W
    	CALL	LCD_Nbl
    	LCD_Move	0x88
    	MOVF	T01MIN_VALUE,W
    	CALL	LCD_Nbl
    	LCD_Move	0x91
    	MOVF	TSIGN_MAX_VALUE,W
    	CALL	LCD_Nbl
    	MOVF	T10MAX_VALUE,W
    	CALL	LCD_Nbl
    	MOVF	T1MAX_VALUE,W
    	CALL	LCD_Nbl
    	LCD_Move	0x95
    	MOVF	T01MAX_VALUE,W
    	CALL	LCD_Nbl
    	LCD_Move	0xC9
    	MOVF	LS100,W
    	CALL	LCD_Nbl
    	MOVF	LS10,W
    	CALL	LCD_Nbl
    	MOVF	LS1,W
    	CALL	LCD_Nbl
    
    DISPLAY_UPDATE3
    	RETURN
    
    ;***************************************MATH SUBROUTINES *************************************
    
    ;***** 16 BIT SUBTRACTION *****
    ; 	Input: CALCH, CALCL , SUBH, SUBL
    ;	Output: CALCH=CALCH-SUBH, CALCL=CALCL-SUBL
    
    SUB16
    	BCF	STATUS,C
    	MOVF	SUBL,W
    	SUBWF	CALCL,F
    	MOVF	SUBH,W
    	BTFSS	STATUS,C
    	ADDLW	D'1'
    	SUBWF	CALCH,F
    
    	RETURN
    
    ;***** 16 BIT ADDITION *****
    ; 	Input: CALCH, CALCL , SUBH, SUBL
    ;	Output: CALCH=CALCH+SUBH, CALCL=CALCL+SUBL
    
    ADD16
    	MOVF	SUBL,W		
    	ADDWF	CALCL,F
    	MOVF	SUBH,W
    	BTFSC	STATUS,C
    	ADDLW	D'1'
    	ADDWF	CALCH,F
    	RETURN
    
    ;***** 16 BIT MACRO *****
    ; Loads SUBH, SUBL with ARGL
    
    LOADS	MACRO	ARGL
    	MOVLW	HIGH(ARGL)
    	MOVWF	SUBH
    	MOVLW	LOW(ARGL)
    	MOVWF	SUBL
    	ENDM
    
    ;***** BINARY TO ASCII CONVERSION MACRO*****
    ; 	Input: CALCH, CALCL, ARGL
    ;	Output: ASCII value in DIGIT based on CALCH,CALCL divided by ARGL 
    
    DODIGIT	MACRO	ARGL
    	LOADS	ARGL
    	CALL	DOSUB
    	ENDM
    
    DOSUB
    	MOVLW	'0'-1		
    	MOVWF	DIGIT			; tracks ASCII value of count
    
    DOSUB1	
    	INCF	DIGIT,F			; increment ASCII character
    	CALL	SUB16		
    	BTFSC	STATUS,C		; any carry?
    	GOTO	DOSUB1			; no, keep subtracting
    	CALL	ADD16			; yes, reverse the last subtraction
    	MOVF	DIGIT,W			; place ASCII value of count in W
    	RETURN
    
    ;***** TEMP DATA TO ASCII CONVERSION *****
    ;	Input:	Temp data is CALCH, CALCL
    ;	Output: ASCII characters in T10,T1,T01	(leading spaces removed and leading minus if req'd)
    
    TEMP_ASCII
    	DECFSZ	NEG,F
    	GOTO	TEMP_SIGN1		; temperature is positive, no sign required
    	MOVLW	'-'			; temperature is negative, sign required
    	MOVWF	NEG
    	GOTO	TEMP_SIGN2
    
    TEMP_SIGN1
    	MOVLW	' '			; temperature is positive, replace negative sign with space
    	MOVWF	NEG
    
    TEMP_SIGN2
    
    	DODIGIT	D'1000'			; count 10's of degrees
    	MOVWF	T10			; store result in T10
    	DODIGIT	D'100'			; count 1's of degrees
    	MOVWF	T1			; store result in T1
    	DODIGIT	D'10'			; count 0.1's of degrees
    	MOVWF	T01			; store result in T01
    
    	BCF	STATUS,C		; is temperature a new TMAX?
    	MOVF	DATAL,W
    	SUBWF	TDATALMAX,W
    	MOVF	DATAH,W
    	BTFSS	STATUS,C
    	ADDLW	D'1'
    	SUBWF	TDATAHMAX,W
    	BTFSC	STATUS,C
    	GOTO	OVER
    	MOVF	DATAH,W			; yes, update TDATAHMAX, TDATALMAX
    	MOVWF	TDATAHMAX
    	MOVF	DATAL,W
    	MOVWF	TDATALMAX
    	MOVF	T10,W
    	MOVWF	T10MAX_VALUE		; update T10MAX_VALUE
    	MOVF	T1,W
    	MOVWF	T1MAX_VALUE		; update T1MAX_VALUE
    	MOVF	T01,W
    	MOVWF	T01MAX_VALUE		; update T01MAX_VALUE
    	MOVF	NEG,W
    	MOVWF	TSIGN_MAX_VALUE		; update sign of maximum temperature
    OVER		
    	BCF	STATUS,C		; is temperature a new TMIN?			
    	MOVF	DATAL,W
    	SUBWF	TDATALMIN,W
    	MOVF	DATAH,W
    	BTFSS	STATUS,C
    	ADDLW	D'1'
    	SUBWF	TDATAHMIN,W
    	BTFSS	STATUS,C
    	GOTO	OVER1
    	MOVF	DATAH,W			; yes, update TDATAHMIN, TDATALMIN
    	MOVWF	TDATAHMIN
    	MOVF	DATAL,W
    	MOVWF	TDATALMIN
    	MOVF	T10,W
    	MOVWF	T10MIN_VALUE		; update T10MIN_VALUE
    	MOVF	T1,W
    	MOVWF	T1MIN_VALUE		; update T1MIN_VALUE
    	MOVF	T01,W		
    	MOVWF	T01MIN_VALUE		; update T01MIN_VALUE
    	MOVF	NEG,W
    	MOVWF	TSIGN_MIN_VALUE
    OVER1
    	BCF	STATUS,RP0		; check for leading zero
    	MOVLW	'0'
    	XORWF	T10,W
    	SKPZ
    	GOTO	ZERO_END		; no leading zero
    	MOVLW	' '			; leading zero found, replace with space
    	MOVWF	T10
    
    ZERO_END							
    
    	RETURN							
    
    ;***** RH DATA TO ASCII CONVERSION *****
    ;	Input:	RH data is in CALCH, CALCL
    ;	Output: ASCII characters in R100,R10,R1	(leading zeros removed)
    
    RH_ASCII
    	DODIGIT	D'100'			; count 100's of relative humidity 
    	MOVWF	R100			; store result in R100
    	DODIGIT	D'10'			; count 10's of relative humidity 
    	MOVWF	R10			; store result in R10
    	DODIGIT	D'1'			; count 1's of relative humidity
    	MOVWF	R1			; store result in R1
    
    	BCF	STATUS,RP0		; check for leading zeros
    	MOVLW	'0'
    	XORWF	R100,W
    	SKPZ
    	GOTO	RH_ZERO_END
    	MOVLW	' '			; 100's leading zero found, replace with space
    	MOVWF	R100
    	MOVLW	'0'
    	XORWF	R10,W
    	SKPZ
    	GOTO	RH_ZERO_END
    	MOVLW	' '			; 10's leading zero found, replace with space
    	MOVWF	R10
    
    RH_ZERO_END
    
    	RETURN
    
    ;***** WIND SPEED TO ASCII CONVERSION *****
    ;	Input:	WIND_SPEED look-up table value in W (BCD)
    ;	Output: ASCII characters in WS10,WS1	
    
    WS_BCD_ASCII
    	MOVWF	TEMP1
    	SWAPF	TEMP1,W
    	ANDLW	0x0F
    	ADDLW	0x30
    	MOVWF	WS10
    	BCF	STATUS,RP0		; check for leading zeros
    	MOVLW	'0'
    	XORWF	WS10,W
    	SKPZ
    	GOTO	WS_ZERO_END
    	MOVLW	' '			; 10's leading zero found, replace with space
    	MOVWF	WS10
    
    WS_ZERO_END
    	MOVF	TEMP1,W
    	ANDLW	0x0F
    	ADDLW	0x30
    	MOVWF	WS1
    	RETURN
    
    
    ;***** WIND DIRECTION TO ASCII CONVERSION *****
    ;	Input:	WD data is in CALCH, CALCL
    ;	Output: ASCII characters in W100,W10,W1	
    
    WD_ASCII
    	DODIGIT	D'1000'			; count 100's of relative humidity 
    	MOVWF	WD100			; store result in W100
    	DODIGIT	D'100'			; count 10's of relative humidity 
    	MOVWF	WD10			; store result in W10
    	DODIGIT	D'10'			; count 1's of relative humidity
    	MOVWF	WD1			; store result in W1
    	RETURN
    
    ;***** LIGHTING STRIKES TO ASCII CONVERSION *****
    ;	Input:	LS data is in CALCH, CALCL
    ;	Output: ASCII characters in LS100,LS10,LS1 (leading zeros removed)	
    
    LS_ASCII
    	DODIGIT	D'100'			; count 100's of relative humidity 
    	MOVWF	LS100			; store result in LS100
    	DODIGIT	D'10'			; count 10's of relative humidity 
    	MOVWF	LS10			; store result in LS10
    	DODIGIT	D'1'			; count 1's of relative humidity
    	MOVWF	LS1			; store result in LD1
    
    	BCF	STATUS,RP0		; check for leading zeros
    	MOVLW	'0'
    	XORWF	LS100,W
    	SKPZ
    	GOTO	LS_ZERO_END
    	MOVLW	' '			; 100's leading zero found, replace with space
    	MOVWF	LS100
    	MOVLW	'0'
    	XORWF	LS10,W
    	SKPZ
    	GOTO	LS_ZERO_END
    	MOVLW	' '			; 10's leading zero found, replace with space
    	MOVWF	LS10
    
    LS_ZERO_END
    	RETURN
    
    ;***************************************RS232 SUBROUTINES *************************************
    
    ;***** TX WEATHER DATA *****
    
    RS232_TX
    		
    	MOVLW	'T'
    	CALL	TX_DATA
    	MOVF	NEG,W
    	CALL	TX_DATA
    	MOVF	T10,W
    	CALL	TX_DATA
    	MOVF	T1,W
    	CALL	TX_DATA
    	MOVLW	'.'
    	CALL	TX_DATA
    	MOVF	T01,W
    	CALL	TX_DATA
    	MOVLW	'C'
    	CALL	TX_DATA
    	MOVLW	' '
    	CALL	TX_DATA
    	MOVLW	'R'
    	CALL	TX_DATA
    	MOVLW	'H'
    	CALL	TX_DATA
    	MOVLW	' '
    	CALL	TX_DATA
    	MOVF	R100,W
    	CALL	TX_DATA
    	MOVF	R10,W
    	CALL	TX_DATA
    	MOVF	R1,W
    	CALL	TX_DATA
    	MOVLW	0X25
    	CALL	TX_DATA
    	MOVLW	' '
    	CALL	TX_DATA
    	MOVLW	'W'
    	CALL	TX_DATA
    	MOVLW	'S'
    	CALL	TX_DATA
    	MOVLW	' '
    	CALL	TX_DATA
    	MOVF	WS10,W
    	CALL	TX_DATA
    	MOVF	WS1,W
    	CALL	TX_DATA
    	MOVLW	'K'
    	CALL	TX_DATA
    	MOVLW	'T'
    	CALL	TX_DATA
    	MOVLW	'S'
    	CALL	TX_DATA
    	MOVLW	' '
    	CALL	TX_DATA
    	MOVLW	'W'
    	CALL	TX_DATA
    	MOVLW	'D'
    	CALL	TX_DATA
    	MOVLW	' '
    	CALL	TX_DATA
    	MOVF	WD100,W
    	CALL	TX_DATA
    	MOVF	WD10,W
    	CALL	TX_DATA
    	MOVF	WD1,W
    	CALL	TX_DATA
    	MOVLW	'T'
    	CALL	TX_DATA
    	MOVLW	' '
    	CALL	TX_DATA
    	MOVLW	'L'
    	CALL	TX_DATA
    	MOVLW	'S'
    	CALL	TX_DATA
    	MOVLW	' '
    	MOVF	LS100,W
    	CALL	TX_DATA
    	MOVF	LS10,W
    	CALL	TX_DATA
    	MOVF	LS1,W
    	CALL	TX_DATA
    	MOVLW	0x0A
    	CALL	TX_DATA
    	MOVLW	0X0D
    	CALL	TX_DATA
    	RETURN
    
    TX_DATA
    	BANKSEL	PIR1
    	BTFSC	PIR1,TXIF		;check if transmitter busy
    	GOTO	TX_DATA1
    	GOTO	TX_DATA
    		
    TX_DATA1
    	MOVWF	TXREG
    	RETURN
    
    
    
    ;************** MAIN **************
    
    MAIN
    
    ;***** INITALIZE *****
    
    	CLRF	PORTA
    	CLRF	PORTB
    	CLRF	HALF_SEC_COUNT
    	CLRF	TWO_SEC_COUNT
    	CLRF	WSPEED_VALUE
    	CLRF	FLAGS
    
    	MOVLW	0xFF
    	MOVWF	TDATAHMIN
    	MOVWF	TDATALMIN
    	MOVLW	0x00
    	MOVWF	TDATAHMAX
    	MOVWF	TDATALMAX
    	MOVLW	' '
    	MOVWF	SHT_ERROR1
    	MOVWF	SHT_ERROR2
    	MOVWF	D1WIRE_ERROR
    	MOVWF	NEG
    	MOVWF	T10
    	MOVWF	T1
    	MOVWF	T01
    	MOVWF	T10MIN_VALUE
    	MOVWF	T1MIN_VALUE
    	MOVWF	T01MIN_VALUE
    	MOVWF	T10MAX_VALUE
    	MOVWF	T1MAX_VALUE
    	MOVWF	T01MAX_VALUE
    	MOVWF	TSIGN_MAX_VALUE
    	MOVWF	TSIGN_MIN_VALUE
    	MOVWF	R100
    	MOVWF	R10
    	MOVWF	R1
    	MOVWF	WD100
    	MOVWF	WD10
    	MOVWF	WD1
    	MOVWF	WS10
    	MOVWF	WS1
    	MOVWF	LS100
    	MOVWF	LS10
    	MOVWF	LS1	
    	
    	BANKSEL	OPTION_REG
    	MOVLW	b'00000000'		; Port B pullups, int falling edge RB0
    	MOVWF	OPTION_REG
    	BANKSEL	INTCON
    	MOVLW	b'11010000'		; GIE, PIE, RBIE enabled
    	MOVWF	INTCON
    	BANKSEL	PIE1
    	MOVLW	b'00000001'		; RCI, TXI, TMR1I enabled
    	MOVWF	PIE1
    	BANKSEL	CMCON
    	MOVLW	b'00000111'		; Comparators off 
    	MOVWF	CMCON
    	BANKSEL	T1CON
    	MOVLW	b'00110000'		; 1:8 pre-scale, Internal Clock, Timer1 disabled
    	MOVWF	T1CON
    
    	BANKSEL	SPBRG
    	MOVLW	D'25'			; 9600 baud
    	MOVWF	SPBRG
    	MOVLW	0x06			; set tris bits for TX and RX
    	IORWF	TRISB,F
    	MOVLW	0x24
    	MOVWF	TXSTA			; TX endabled and BRGH=1
    	BANKSEL	RCSTA
    	MOVLW	0x80			; enable serial port
    	MOVWF	RCSTA
    	MOVLW	'0'
    	MOVWF	TXREG
    		
    
    	DLONG	D'200'			; LCD power up delay
    
    	CALL	LCD_Init		; Initialize LCD Module
    
    	CALL	START_SCREEN		; display first screen
    
    	CALL	DS2450_INIT
    		
    	CALL	DISPLAY_UPDATE
    
    	BANKSEL	T1CON
    	BSF	T1CON, TMR1ON		; Turn Timer1 on
    
    WAIT	
    	GOTO	WAIT			; Wait for interrupts
    	
    	END
    
    |Delete 'P-' before: '' but after: 'researcher@freemail.it asks:
    I would like to use this frequency counter in an ancient radio receiver so does anybody know how I can subtract a constant value? ex: it should be interesting subtract 10.7MHz or 455KHz from the red value.
    |Delete 'P-' before: '' but after: '