;; Хронограф с выводом результата на LCD дисплей (8х2 в одну строку) и COM порт.
 ;; Распиновка микросхемы
 ;; PIN I/O FROM TO
 ;;----------------------------------------------------------------------
 ;; A0 O E LCD E
 ;; A1 O RS LCD RS
 ;; A2 I BIT 2 SENSOR_1
 ;; A3 I BIT 3 SENSOR_2
 ;; A4 O
 ;; A5 O
 ;; A6 O
 ;; A7 O
 ;;
 ;; B0 0
 ;; B1 I RS232 RX PC RX
 ;; B2 O RS232 TX PC TX
 ;; B3 O
 ;; B4 O BIT 4 LCD BIT 4
 ;; B5 O BIT 5 LCD BIT 5
 ;; B6 O BIT 6 LCD BIT 6
 ;; B7 O BIT 7 LCD BIT 7
 ;;----------------------------------------------------------------------

 		list p=16F628A
 #include <PIC16F628A.INC>
 #include <shorts.inc>

 		__CONFIG _LVP_OFF & _MCLRE_OFF & _XT_OSC & _BODEN_OFF & _CP_OFF & _WDT_OFF & _PWRTE_ON
 ERRORLEVEL -302

 #DEFINE E PORTA, 0 ;; OUTPUT TO LCD
 #DEFINE RS PORTA, 1 ;; OUTPUT TO LCD
 #DEFINE SENSOR_1 PORTA, 2 ;; INPUT
 #DEFINE SENSOR_2 PORTA, 3 ;; INPUT

 CBLOCK 0X20
 CNTJ ;; FOR MS_DELAY
 ; BIT8, CNT1, CNT2, TEMP_MUL, HI16, LO16 ;; FOR MUL_BY_1000
 MS_TIME, MS_TIME_TEMP
 LO_BYTE, HI_BYTE ;; FOR LCD DRIVER
 CHAR ;; FOR DATA CONVERTION
 TEN_K, THOU, HUND, TENS, ONES
 DIVIDEND1, DIVIDEND2, DIVIDEND3, DIVISOR1, DIVISOR2
 DVDEND_HI, DVDEND_LO
 TIME_HI, TIME_LO, NUMH, NUML
 IF_ERROR ;; Признак ошибки
 ENDC

 ACC EQU 0x5C ; Most significant Byte
 SIGN EQU 0x62 ; save location for sign in MSB
 TEMP EQU 0x68 ; temporary storage
 DIVIDEND EQU 0x5C ; Most significant Byte
 DIVISOR EQU 0x65 ; Most significant Byte
 REMAIN EQU 0x60 ; Most significant Byte
 LOOPCOUNT EQU 0x63 ; loop counter

 ORG 0x000
 CALL init_pic
 GOTO MAIN

 ORG 0x004
 GOTO int_t

 init_pic
 ;----------------------------PORT I/O CONFIGURATION/SETUP-------------------------------
 BANK0
 MOVLW 0X07
 MOVWF CMCON ;; DISABLE CAPTURE/COMPARE MODULES.

 BANK1
 LOADF TRISA, B'00101100'
 LOADF TRISB, B'00000110' ;; SET BITS 1, 2 FOR USART.
 BSF OPTION_REG, NOT_RBPU ;; BCF/BSF = ENABLE/DISABLE PULL-UP.

 ;------------------POWER ON RESET CONFIGURATION/SETUP--------------------------
 BSF PCON, OSCF ;BCF/BSF = 37KHZ/4MHZ INTRC OR ER OSCILLATOR SPEED.

 ;--------------------------INTERRUPT CONFIGURATION/SETUP-------------------------------
 ; BANK1
 ; BCF INTCON, GIE ;BCF/BSF = DIS/ENABLE GLOBAL INTERRUPT.
 ; BCF INTCON, PEIE ;BCF/BSF = DIS/ENABLE Разрешение прерываний от переферийных модулей
 ; BCF INTCON, T0IE ;BCF/BSF = DIS/ENABLE Разрешение прерывания по переполнению TMR0
 ; BCF INTCON, INTE ;BCF/BSF = DIS/ENABLE RB0 INTERRUPT.
 ; BCF INTCON, RBIE ;BCF/BSF = DIS/ENABLE RB7-4 INTERRUPT.
 BSF PIE1, TMR1IE ;BCF/BSF = DIS/ENABLE Разрешение прерывания по переполнению TMR1
 ;--------------------------------------------------------------------------------------

 ;-------------------------USART CONFIGURATION/SETUP------------------------------------
 BANK1
 BCF PIE1, TXIE ;BCF/BSF = DIS/ENABLE TX INTERRUPT.
 BSF TXSTA, CSRC ;BCF/BSF = EXT/INTERNAL GENERATOR.
 BCF TXSTA, TX9 ;BCF/BSF = 8-BIT/9-BIT TRANSMISSION.
 BSF TXSTA, TXEN ;BCF/BSF = DIS/ENABLE TRANSMISSION.
 BCF TXSTA, SYNC ;BCF/BSF = A/SYNCHRONOUS MODE.
 BSF TXSTA, BRGH ;BCF/BSF = LO/HI SPEED BAUD RATE SELECT.
 LOADF SPBRG, .12 ;SET BAUD RATE TO 19.2 KBPS.
 BANK0
 BSF RCSTA, SPEN ;BCF/BSF = DIS/ENABLE SERIAL PORT.
 BCF RCSTA, RX9 ;BCF/BSF = 8-BIT/9-BIT TRANSMISSION.
 BSF RCSTA, SREN ;BCF/BSF = DIS/ENABLE SINGLE RECEIVE.
 BCF RCSTA, CREN ;BCF/BSF = DIS/ENABLE CONTINUOS RECEIVE.
 BSF RCSTA, SPEN ;BCF/BSF = DIS/ENABLE SERIAL PORT.
 ;--------------------------------------------------------------------------------------
 RETURN

 ;*********************MAIN***********************
MAIN:
		CALL INIT_LCD

ERR_TEST:
		CALL CLEAR
		CALL GET_ERROR
		BTFSC IF_ERROR, 7
		GOTO ERR_TEST
		CALL CLEAR
 		CALL LCD_1

GET:
 		CALL GET_VELOCITY
 		CALL SEND_USART
 		CALL LCD_UPDATE
 		GOTO GET

 ;*****************END 0F MAIN******************

int_t
 		BCF T1CON, TMR1ON ;BCF/BSF = DISABLE/ENABLE TIMER1 ON.
		BCF PIE1, TMR1IF ;BCF/BSF = DISABLE/ENABLE Разрешение прерывания по переполнению TMR1

 		CLRF TMR1L ;; THEN, START TIMING.
		CLRF TMR1H

 		MOVF_F TMR1L, TIME_LO ;; FINALY, COPY TIMER1 INTO LO/HI BYTES.
 		MOVF_F TMR1H, TIME_HI

 		GOTO ERR_TEST

 ;Проверяем датчики
GET_ERROR: ;; DUAL SENSOR DETECTION.
 		BCF IF_ERROR, 7

 		LOADF CHAR, 0X00
 		CALL SET_ADDRESS

 		BTFSS SENSOR_1
 		GOTO $ + 3
		CALL D1_ER
		GOTO $ + 2
		CALL D1_OK

		LOADF CHAR, 0X40
		CALL SET_ADDRESS

		BTFSS SENSOR_2
		GOTO $ + 3
		CALL D2_ER
		GOTO $ + 2
		CALL D2_OK


		LOADF MS_TIME, .250 ;; 1.5 SEC DELAY.
		CALL MS_DELAY
		CALL MS_DELAY
		CALL MS_DELAY
		CALL MS_DELAY
		CALL MS_DELAY
		CALL MS_DELAY
		RETURN

D1_OK:
		CHR_LCD_OUT 'D'
		CHR_LCD_OUT '1'
		CHR_LCD_OUT '-'
		CHR_LCD_OUT 'O'
		CHR_LCD_OUT 'K'
		CHR_LCD_OUT ' '
		CHR_LCD_OUT ' '
		CHR_LCD_OUT ' '
		RETURN

D1_ER:
		CHR_LCD_OUT 'D'
		CHR_LCD_OUT '1'
		CHR_LCD_OUT '-'
		CHR_LCD_OUT 'E'
		CHR_LCD_OUT 'R'
		CHR_LCD_OUT ' '
		CHR_LCD_OUT ' '
		CHR_LCD_OUT ' '
		BSF IF_ERROR, 7
		RETURN

D2_OK:
		CHR_LCD_OUT 'D'
		CHR_LCD_OUT '2'
		CHR_LCD_OUT '-'
		CHR_LCD_OUT 'O'
		CHR_LCD_OUT 'K'
		CHR_LCD_OUT ' '
		CHR_LCD_OUT ' '
		CHR_LCD_OUT ' '
		RETURN
D2_ER:
		CHR_LCD_OUT 'D'
		CHR_LCD_OUT '2'
		CHR_LCD_OUT '-'
		CHR_LCD_OUT 'E'
		CHR_LCD_OUT 'R'
		CHR_LCD_OUT ' '
		CHR_LCD_OUT ' '
		CHR_LCD_OUT ' '
		BSF IF_ERROR, 7
		RETURN
;---------------------------------------

 ;Первоначальная надпись на LCD
LCD_1:
		LOADF CHAR, 0X00
		CALL SET_ADDRESS
		CHR_LCD_OUT 'A'
		CHR_LCD_OUT 'W'
		CHR_LCD_OUT 'A'
		CHR_LCD_OUT 'I'
		CHR_LCD_OUT 'T'
		CHR_LCD_OUT ' '
		CHR_LCD_OUT '-'
		CHR_LCD_OUT ' '
		
		LOADF CHAR, 0X40
		CALL SET_ADDRESS
		
		CHR_LCD_OUT 'S'
		CHR_LCD_OUT 'H'
		CHR_LCD_OUT 'O'
		CHR_LCD_OUT 'O'
		CHR_LCD_OUT 'T'
		CHR_LCD_OUT '!'
		CHR_LCD_OUT '!'
		CHR_LCD_OUT '!'
		RETURN
;---------------------------------------

 ;DETECTION AND TIMING OF PROJECTILE
GET_VELOCITY: ;; DUAL SENSOR DETECTION.
		CLRF TMR1L ;; THEN, START TIMING.
		CLRF TMR1H
		BSF INTCON, GIE ;BCF/BSF = DISABLE/ENABLE Глобальное разрешение прерываний
		BSF INTCON, PEIE ;BCF/BSF = DIS/ENABLE Разрешение прерываний от переферийных модулей
		
		BTFSS SENSOR_1 ;; AWAIT DETECTION: ACTIVE HI.
		GOTO $ - 1
		
		BSF T1CON, TMR1ON ;BCF/BSF = DISABLE/ENABLE TIMER1 ON.
		
		BTFSS SENSOR_2 ;; NEXT, AWAIT DETECTION: ACTIVE HI.
		GOTO $ - 1
		
		BCF T1CON, TMR1ON ;BCF/BSF = DISABLE/ENABLE TIMER1 ON.
		
		BCF INTCON, GIE ;BCF/BSF = DISABLE/ENABLE Глобальное разрешение прерываний
		BCF INTCON, PEIE ;BCF/BSF = DIS/ENABLE Разрешение прерываний от переферийных модулей

		MOVF_F TMR1L, TIME_LO ;; FINALY, COPY TIMER1 INTO LO/HI BYTES.
		MOVF_F TMR1H, TIME_HI

		LOADF MS_TIME, .250 ;; 1 SEC DELAY BEFORE NEXT MEASUREMENT.
		CALL MS_DELAY
		CALL MS_DELAY
		CALL MS_DELAY
		CALL MS_DELAY
		RETURN
;---------------------------------------

 ;Отсылаем данные в RS232
SEND_USART:
		CALL TXWAIT
		MOVF_F TIME_HI, TXREG
		CALL TXWAIT
		MOVF_F TIME_LO, TXREG
		CALL TXWAIT 
		RETURN
 ;---------------------------------------

 ;Использовать эту задержку перед отправкой данных TXREG.
TXWAIT: 
		BANK1
		BTFSS TXSTA, TRMT ;; IF TX IS COMPLETED,
		GOTO $ - 1 ;; ELSE, WAIT
		BANK0 ;; THEN, CONTINUE.
		LOADF MS_TIME, .1
		CALL MS_DELAY
		RETURN
 ;--------------------------------------

 ;Вычисление скорости и вывод на LCD
LCD_UPDATE:
		CALL CLEAR
		MOVF_F TIME_HI, HI_BYTE
		MOVF_F TIME_LO, LO_BYTE
		CALL HEX16_TO_DEC5 ;; CONVERT HEX TO DECIMAL,
		CALL DEC_TO_LCD ;; THEN DECIMAL TO LCD DISPLAY.
		
		MEM_LCD_OUT TEN_K
		MEM_LCD_OUT THOU
		CHR_LCD_OUT '.'
		MEM_LCD_OUT HUND
		MEM_LCD_OUT TENS
		MEM_LCD_OUT ONES
		CHR_LCD_OUT 'm'
		CHR_LCD_OUT 's'

		 ; CALL LCD_TO_DEC
		 ;; CALCULATIONS TO METERS PER SECOND.
		 ; LOADF BIT8, .40 ;; DETECTOR DISTANCE = 40 MILLI-METERS
		 ; CALL MUL_BY_1000 ;; MULTIPLY DISTANCE MILLI-METERS BY 1000
		 ;
		 ; MOVF_F HI16, DIVIDEND1 ;; DIVIDE MILLI-METERS BY TIMING
		 ; MOVF_F LO16, DIVIDEND2 ;; 40,000 / TIME_HI:TIME_LO
		
		LOADF DIVIDEND1, 0x9C ;; Для дистанции 40мм
		LOADF DIVIDEND2, 0x40 ;; 40,000 / TIME_HI:TIME_LO
		
		MOVF_F TIME_HI, DIVISOR1
		MOVF_F TIME_LO, DIVISOR2
		CALL DIVIDE_16_16 ;; RETURNS DIVIDEND+0:DIVIDEND+1
		
		MOVF_F DIVIDEND+0, HI_BYTE ;; VELOCITY RESULT COPY
		MOVF_F DIVIDEND+1, LO_BYTE ;; VELOCITY RESULT COPY
		CALL HEX16_TO_DEC5
		CALL DEC_TO_LCD
		
		LOADF CHAR, 0X40 ;; GOTO LCD SECOND LINE.
		CALL SET_ADDRESS
		
		CHR_LCD_OUT ' '
		MEM_LCD_OUT THOU ;; DISPLAY "XXXXX M/S"
		MEM_LCD_OUT HUND
		MEM_LCD_OUT TENS
		MEM_LCD_OUT ONES
		CHR_LCD_OUT 'm'
		CHR_LCD_OUT '/'
		CHR_LCD_OUT 's'
		
		 ; CALL LCD_TO_DEC
		RETURN
 ;---------------------------------------

 ;BORROWED FROM MICROCHIP APP NOTES. EXTENSIVELY
 ;MODIFIED TO SUPPORT 16F628.
 ;DIVIDE 16BIT BY 16BIT
 ;INPUT : DVDEND_HI, DVDEND_LO, DVSOR_HI, DVSOR_LO
 ;OUTPUT: DIVIDEND+0, DIVIDEND+1
 ;----Define divide register variables---
 ; ACC EQU 0x5C ; Most significant Byte
 ; SIGN EQU 0x62 ; save location for sign in MSB
 ; TEMP EQU 0x68 ; temporary storage
 ; DIVIDEND EQU 0x5C ; Most significant Byte
 ; DIVISOR EQU 0x65 ; Most significant Byte
 ; REMAIN EQU 0x60 ; Most significant Byte
 ; LOOPCOUNT EQU 0x63 ; loop counter
 ;---------------------------------------
DIVIDE_16_16:
		MOVF_F DIVIDEND1, DIVIDEND+0
		MOVF_F DIVIDEND2, DIVIDEND+1
		MOVF_F DIVISOR1, DIVISOR+0
		MOVF_F DIVISOR2, DIVISOR+1
		CLRF REMAIN+0
		CLRF REMAIN+1
		MOVLW .16
		MOVWF LOOPCOUNT
LOOP1616:
		RLF ACC+0, W
		RLF REMAIN+1, F
		RLF REMAIN+0, F
		MOVF DIVISOR+1, W
		SUBWF REMAIN+1, F
		MOVF DIVISOR+0, W
		BTFSS STATUS, C
		INCFSZ DIVISOR+0, W
		SUBWF REMAIN+0, F
		BTFSC STATUS, C
		GOTO CONT1616
		MOVF DIVISOR+1, W
		ADDWF REMAIN+1, F
		MOVF DIVISOR+0, W
		BTFSC STATUS, C
		INCFSZ DIVISOR+0, W
		ADDWF REMAIN+0, F
		BCF STATUS, C
CONT1616:
		RLF ACC+1, F
		RLF ACC+0, F
		DECFSZ LOOPCOUNT, F
		GOTO LOOP1616
		RETURN
 ;---------------------------------------

 ;MULTIPY 8-BIT BY 1000
 ;INPUT = BIT8, ;OUTPUT = HI16, LO16
 ;MUL_BY_1000:
 ; CLRF HI16
 ; CLRF LO16
 ; MOVF_F BIT8, TEMP_MUL
 ; LOADF CNT1, .100
 ; LOADF CNT2, .10
 ;MUL1
 ; MOVF TEMP_MUL, W
 ; ADDWF LO16, F
 ; BTFSS STATUS, C ;; IF CARRY IS SET,
 ; GOTO $ + 2 ;; ELSE: SKIP
 ; INCF HI16, F ;; THEN: PROCESS
 ;
 ; DECFSZ CNT1, F
 ; GOTO MUL1
 ; LOADF CNT1, .100
 ; DECFSZ CNT2, F
 ; GOTO MUL1
 ; RETURN
 ;---------------------------------------

 ;CONVER 16BIT HEX INTO 5 DIGIT BCD
 ;INPUT : HI_BYTE, LO_BYTE
 ;OUTPUTS: TEN_K, THOU, HUND, TENS, ONES
HEX16_TO_DEC5:
		MOVF_F HI_BYTE, NUMH ;; MOVF f,d Пересылка регистра F
		MOVF_F LO_BYTE, NUML
		
		SWAPF NUMH,W ;; SWAPF f,d Обмен местами тетрад в f
		ANDLW 0X0F ;; ANDLW k Логическое "И" константы и W
		ADDLW 0XF0 ;; ADDLW k Сложение константы с W
		MOVWF THOU ;; MOVWF f Пересылка W в F
		ADDWF THOU,F ;; ADDWF f,d Сложение W с f
		ADDLW .226 ;; ADDLW k Сложение константы с W
		MOVWF HUND ;; MOVWF f Пересылка W в F
		ADDLW .50 ;; ADDLW k Сложение константы с W
		MOVWF ONES ;; MOVWF f Пересылка W в F
		MOVF NUMH,W ;; MOVF f,d Пересылка регистра F
		ANDLW 0X0F ;; ANDLW k Логическое "И" константы и W
		ADDWF HUND,F ;; ADDWF f,d Сложение W с f
		ADDWF HUND,F ;; ADDWF f,d Сложение W с f
		ADDWF ONES,F ;; ADDWF f,d Сложение W с f
		ADDLW .233 ;; ADDLW k Сложение константы с W
		MOVWF TENS ;; MOVWF f Пересылка W в F
		ADDWF TENS,F ;; ADDWF f,d Сложение W с f
		ADDWF TENS,F ;; ADDWF f,d Сложение W с f
		SWAPF NUML,W ;; SWAPF f,d Обмен местами тетрад в f
		ANDLW 0X0F ;; ANDLW k Логическое "И" константы и W
		ADDWF TENS,F ;; ADDWF f,d Сложение W с f
		ADDWF ONES,F ;; ADDWF f,d Сложение W с f
		RLF TENS,F ;; RLF f,d Вращение f влево через перенос
		RLF ONES,F ;; RLF f,d Вращение f влево через перенос
		COMF ONES,F ;; COMF f,d Инверсия регистра f
		RLF ONES,F ;; RLF f,d Вращение f влево через перенос
		MOVF NUML,W ;; MOVF f,d Пересылка регистра F
		ANDLW 0X0F ;; ANDLW k Логическое "И" константы и W
		ADDWF ONES,F ;; ADDWF f,d Сложение W с f
		RLF THOU,F ;; RLF f,d Вращение f влево через перенос
		MOVLW 0X07 ;; MOVLW k Пересылка константы в W
		MOVWF TEN_K ;; MOVWF f Пересылка W в F
		MOVLW .10 ;; MOVLW k Пересылка константы в W
HD1:
		ADDWF ONES,F ;; ADDWF f,d Сложение W с f
		DECF TENS,F ;; DECF f,d Декремент регистра f
		BTFSS 3,0 ;; BTFSS f,b Пропустить команду, если бит b=1
		GOTO HD1 ;; GOTO k Переход по адресу
HD2:
		ADDWF TENS,F ;; ADDWF f,d Сложение W с f
		DECF HUND,F ;; DECF f,d Декремент регистра f
		BTFSS 3,0 ;; BTFSS f,b Пропустить команду, если бит b=1
		GOTO HD2 ;; GOTO k Переход по адресу
HD3:
		ADDWF HUND,F ;; ADDWF f,d Сложение W с f
		DECF THOU,F ;; DECF f,d Декремент регистра f
		BTFSS 3,0 ;; BTFSS f,b Пропустить команду, если бит b=1
		GOTO HD3 ;; GOTO k Переход по адресу
HD4:
		ADDWF THOU,F ;; ADDWF f,d Сложение W с f
		DECF TEN_K,F ;; DECF f,d Декремент регистра f
		BTFSS 3,0 ;; BTFSS f,b Пропустить команду, если бит b=1
		GOTO HD4 ;; GOTO k Переход по адресу
		RETURN
;---------------------------------------

 ;PREREQUISITE: LOAD THOU, HUND, TENS, ONES
 ;
 ;LCD_TO_DEC:
 ; MOVLW 0X30
 ; SUBWF TEN_K, F
 ; SUBWF THOU, F
 ; SUBWF HUND, F
 ; SUBWF TENS, F
 ; SUBWF ONES, F
 ; RETURN
 ;---------------------------------------

 ;PREREQUISITE: LOAD TEN_K, THOU, HUND, TENS, ONES
 ;
DEC_TO_LCD:
		MOVLW 0X30
		ADDWF TEN_K, F
		ADDWF THOU, F
		ADDWF HUND, F
		ADDWF TENS, F
		ADDWF ONES, F
		RETURN
 ;-----------------------------------------------

 ; LCD DRIVER AND COMMANDS FOR 4-BIT INTERFACE
 ;-----------------------------------------------
 ;PREREQUISITES: E, RS - OUTPUT
 ; PORTB 4-7 - OUTPUT
 ; MS_DELAY - SUBROUTINE
INIT_LCD:
		LOADF MS_TIME, .40
		CALL MS_DELAY ;; FUNCTION SET
		BCF RS ;; SET LCD TO COMMAND MODE
		LOADF PORTB, B'00100000'
		CALL PULSE_E
		LOADF PORTB, B'00100000'
		CALL PULSE_E
		LOADF PORTB, B'10000000'
		CALL PULSE_E
		LOADF MS_TIME, .1 ;; DISPLAY CONTROL
		CALL MS_DELAY
		LOADF PORTB, B'00000000'
		CALL PULSE_E
		LOADF PORTB, B'11110000'
		CALL PULSE_E
		LOADF MS_TIME, .1 ;; CLEAR DISPLAY
		CALL MS_DELAY
		LOADF PORTB, B'00000000'
		CALL PULSE_E
		LOADF PORTB, B'00010000'
		CALL PULSE_E
		LOADF MS_TIME, .1 ;; ENTRY MODE SET, .2
		CALL MS_DELAY
		LOADF PORTB, B'00000000'
		CALL PULSE_E
		LOADF PORTB, B'01100000'
		CALL PULSE_E
		
		LOADF MS_TIME, .2
		CALL MS_DELAY
		
		CALL BLINK_OFF
		CALL CURSOR_OFF
		RETURN

PULSE_E:
		BSF E
		GOTO $ + 1
		GOTO $ + 1
		GOTO $ + 1
		BCF E
		LOADF MS_TIME, .1
		CALL MS_DELAY
		RETURN
 ;-------------------------------------------

 ;INPUT : CHAR, 'X'
 ;OUTPUT: SENDS THE CHARACTER TO THE LCD
 ;SEND_CHAR:
 ; BSF RS ;; SET LCD TO CHARACTOR MODE
 ; MOVF CHAR, W
 ; MOVWF PORTB
 ; CALL PULSE_E
 ; SWAPF CHAR, W
 ; MOVWF PORTB
 ; CALL PULSE_E
 ; RETURN
 ;---------------------------------------

 ;INPUT : CHAR, 'X'
 ;OUTPUT: SENDS THE COMMAND TO THE LCD
SEND_CHAR:
		BSF RS ;; SET LCD TO CHARACTOR MODE
		GOTO $ + 2
		SEND_COMM:
		BCF RS ;; SET LCD TO COMMAND MODE
		MOVF CHAR, W
		MOVWF PORTB
		CALL PULSE_E
		SWAPF CHAR, W
		MOVWF PORTB
		CALL PULSE_E
		RETURN
 ;---------------------------------------
MS_DELAY:
		MOVF_F	MS_TIME, MS_TIME_TEMP

CLEAR: 
		LOADF CHAR, B'00000001'
		CALL SEND_COMM
		LOADF MS_TIME, .2
		CALL MS_DELAY
		RETURN

 ;HOME: 
 ; LOADF CHAR, B'00000010'
 ; CALL SEND_COMM
 ; LOADF MS_TIME, .2
 ; CALL MS_DELAY
 ; RETURN

SET_ADDRESS:
		BSF CHAR, 7
		CALL SEND_COMM
		RETURN

BLINK_OFF:
		LOADF CHAR, B'00001110'
		CALL SEND_COMM
		RETURN

CURSOR_OFF:
		LOADF CHAR, B'00001100'
		CALL SEND_COMM
		RETURN
 ;---------------------------
		END