;; DONNIE JAMES 8, APRIL 2004 ;; ;; RS232 COMM COILGUN TIMER WITH LCD DISPLAY. ;; ;; PIC ;; PIN I/O FROM TO ;;----------------------------------------------- ;; A0 O E LCD E ;; A1 O RS LCD RS ;; A2 O ;; A3 O ;; A4 O ;; A5 (I) ;; A6 O ;; A7 O ;; ;; B0 0 ;; B1 I RS232 RX PC RX ;; B2 O ;; 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=16F628 INCLUDE "P16F628A.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 #DEFINE BUTTON1 PORTA, 5 ;INPUT CBLOCK 0X20; TEMPORARY STORAGE------------- CNTJ, CNTK, CNTL, CNT1, CNT2, CNT3, CNT4, CNT5 CNT6, CNT7, CNT8, CNT9, CNT10 MS_TIME, MS_TIME_TEMP, TEMP_MUL, TEMP2, TEMP_HI, TEMP_LO LO_BYTE, HI_BYTE ;//---FOR LCD DRIVER------// CHAR, CHAR1, CHAR2 ;//--FOR DATA CONVERTION--// TEN_K, THOU, HUND, TENS, ONES REMAINDER1, REMAINDER2 DIVIDEND1, DIVIDEND2, DIVIDEND3, DIVISOR1, DIVISOR2 DVDEND_HI, DVDEND_LO, DVSOR_HI, DVSOR_LO, QUOTIENT1, QUOTIENT2 BIT8, HI16, LO16 TIME_HI, TIME_LO, NUMH, NUML ENDC;--------END OF C BLOCK----------------- ;------PORT I/O CONFIGURATION/SETUP------------------------------- BANK0 MOVLW 0X07 MOVWF CMCON ;DISABLE CAPTURE/COMPARE MODULES. BCF STATUS, RP1 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, T0IE ;BCF/BSF = DIS/ENABLE TIMER1 INTERRUPT. BCF INTCON, INTE ;BCF/BSF = DIS/ENABLE RB0 INTERRUPT. BCF INTCON, RBIE ;BCF/BSF = DIS/ENABLE RB7-4 INTERRUPT. BCF PIE1, TMR1IE ;BCF/BSF = DIS/ENABLE TIMER1 INTERRUPT. ;------------------------------------------------------------------ ;-----TIMER0 CONFIGURATION/SETUP----------------------------------- BANK1 BCF OPTION_REG, T0CS ;BCF/BSF = INTERNAL/EXTERNAL CLOCK. BSF OPTION_REG, PSA ;BCF/BSF = ENABLE/DISABLE PRESCALER RATIOS. ;PRESCALER RATIO: 000=1:2 001=1:4 010=1:8 011=1:16 ; 100=1:32 101=1:64 110=1:128 111=1:256 BSF OPTION_REG, PS0 BSF OPTION_REG, PS1 BSF OPTION_REG, PS2 ;-----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 9.6 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. ;--- -TIMER1 CONFIGURATION/SETUP----------------------------------- BANK0 BSF T1CON, TMR1ON ;BCF/BSF = DISABLE/ENABLE TIMER1 ON. BCF T1CON, TMR1CS ;BCF/BSF = INTERNAL/EXTERNAL(RA6) CLOCK. ;------------------------------------------------------------------ ;*********MAIN************************** MAIN: CALL INIT_LCD CALL LCD_1 GET CALL GET_VELOCITY ;CALL TXWAIT ;MOVF_F TIME_HI, TXREG ;CALL TXWAIT ;MOVF_F TIME_LO, TXREG ;CALL TXWAIT CALL LCD_UPDATE GOTO GET ;**********END 0F MAIN****************** ;DETECTION AND TIMING OF PROJECTILE GET_VELOCITY: ;DUAL SENSOR DETECTION. BTFSS SENSOR_1 ;AWAIT DETECTION: ACTIVE HI. GOTO $ - 1 CLRF TMR1L ;THEN, START TIMING. CLRF TMR1H CALL USEC_10 BTFSS SENSOR_2 ;NEXT, AWAIT DETECTION: ACTIVE HI. GOTO $ - 1 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 ;--------------------------------------- ;USE THIS DELAY BEFORE SENDING DATA TO 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_1: CALL BLINK_OFF LOADF CHAR, 'C' ;DISPLAY "CG CHRONO " CALL SEND_CHAR ;DISPLAY "00.00MSEC 000M/S" LOADF CHAR, 'G' CALL SEND_CHAR LOADF CHAR, ' ' CALL SEND_CHAR LOADF CHAR, 'C' CALL SEND_CHAR LOADF CHAR, 'H' CALL SEND_CHAR LOADF CHAR, 'R' CALL SEND_CHAR LOADF CHAR, 'O' CALL SEND_CHAR LOADF CHAR, 'N' CALL SEND_CHAR LOADF CHAR, 'O' CALL SEND_CHAR LOADF CHAR, 0X40 CALL SET_ADDRESS LOADF CHAR, '0' CALL SEND_CHAR LOADF CHAR, '0' CALL SEND_CHAR LOADF CHAR, '.' CALL SEND_CHAR LOADF CHAR, '0' CALL SEND_CHAR LOADF CHAR, '0' CALL SEND_CHAR LOADF CHAR, 'M' CALL SEND_CHAR LOADF CHAR, 'S' CALL SEND_CHAR LOADF CHAR, 'E' CALL SEND_CHAR LOADF CHAR, 'C' CALL SEND_CHAR LOADF CHAR, ' ' CALL SEND_CHAR LOADF CHAR, '0' CALL SEND_CHAR LOADF CHAR, '0' CALL SEND_CHAR LOADF CHAR, '0' CALL SEND_CHAR LOADF CHAR, 'M' CALL SEND_CHAR LOADF CHAR, '/' CALL SEND_CHAR LOADF CHAR, 'S' CALL SEND_CHAR RETURN ;--------------------------------------- LCD_UPDATE: MLOOP1 LOADF CHAR, 0X40 ;GOTO LCD SECOND LINE. CALL SET_ADDRESS ;------------------------------- ;PLACE EXPERIMENTAL TIMINGS HERE ;150 M/S = 266USEC = 0X10A ;LOADF TIME_HI, 0X01 ;LOADF TIME_LO, 0X0A ;------------------------------- 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. MOVF_F TEN_K, CHAR ;DISPLAY "XX.XXMSEC" CALL SEND_CHAR MOVF_F THOU, CHAR CALL SEND_CHAR LOADF CHAR, '.' CALL SEND_CHAR MOVF_F HUND, CHAR CALL SEND_CHAR MOVF_F TENS, CHAR CALL SEND_CHAR LOADF CHAR, 'M' CALL SEND_CHAR LOADF CHAR, 'S' CALL SEND_CHAR LOADF CHAR, 'E' CALL SEND_CHAR LOADF CHAR, 'C' CALL SEND_CHAR LOADF CHAR, ' ' CALL SEND_CHAR 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 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 MOVF_F HUND, CHAR ;DISPLAY "XXX M/S" CALL SEND_CHAR MOVF_F TENS, CHAR CALL SEND_CHAR MOVF_F ONES, CHAR CALL SEND_CHAR LOADF CHAR, 'M' CALL SEND_CHAR LOADF CHAR, '/' CALL SEND_CHAR LOADF CHAR, 'S' CALL SEND_CHAR 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 DIVIDE_16_16: ;----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 ;--------------------------------------- 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 LO_BYTE, NUML SWAPF NUMH,W ANDLW 0X0F ADDLW 0XF0 MOVWF THOU ADDWF THOU,F ADDLW .226 MOVWF HUND ADDLW .50 MOVWF ONES MOVF NUMH,W ANDLW 0X0F ADDWF HUND,F ADDWF HUND,F ADDWF ONES,F ADDLW .233 MOVWF TENS ADDWF TENS,F ADDWF TENS,F SWAPF NUML,W ANDLW 0X0F ADDWF TENS,F ADDWF ONES,F RLF TENS,F RLF ONES,F COMF ONES,F RLF ONES,F MOVF NUML,W ANDLW 0X0F ADDWF ONES,F RLF THOU,F MOVLW 0X07 MOVWF TEN_K MOVLW .10 HD1: ADDWF ONES,F DECF TENS,F BTFSS 3,0 GOTO HD1 HD2: ADDWF TENS,F DECF HUND,F BTFSS 3,0 GOTO HD2 HD3: ADDWF HUND,F DECF THOU,F BTFSS 3,0 GOTO HD3 HD4: ADDWF THOU,F DECF TEN_K,F BTFSS 3,0 GOTO HD4 RETURN ;--------------------------------------- CLRF QUOTIENT1 CLRF QUOTIENT2 LOOP3 MOVF DVSOR_LO, W ;DIFFERENCE= DVDEND_LO - DVSOR_LO SUBWF DVDEND_LO, F BTFSC STATUS, C ;IF (+) GOTO LOOP3_2 ;THEN, CONTINUE TO DVDEND_HI DECF DVDEND_HI, F ;ELSE, BORROW FROM DVDEND_HI BTFSC STATUS, C ;IF DVDEND_HI IS (+) GOTO LOOP3_2 ;THEN, CONTINUE TO DVDEND_HI ;ELSE, INCF DVDEND_HI, F ;RETURN BORROW TO DVDEND_HI, MOVF DVSOR_LO, W ;RETURN DVSOR_LO TO DVDEND_LO, ADDWF DVDEND_LO, F ;AND EXIT LOOP GOTO LOOP3_END LOOP3_2 INCF QUOTIENT2, F MOVF DVSOR_HI, W ;DIFFERENCE= DVDEND_HI - DVSOR_HI SUBWF DVDEND_HI, F BTFSS STATUS, C ;IF (+) GOTO $ + 3 ;ELSE, INCF QUOTIENT1, F ;THEN, INC QUOTIENT1 AND LOOP GOTO LOOP3 DECF QUOTIENT1, F ;ELSE, DECREMENT QUOTIENT1 MOVF DVSOR_HI, W ;RETURN DVSOR_HI TO DVDEND_HI, ADDWF DVDEND_HI, F ;AND LOOP GOTO LOOP3 LOOP3_END 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 RETURN PULSE_E: BSF E GOTO $ + 1 GOTO $ + 1 GOTO $ + 1 BCF E CALL USEC_100 RETURN ;------------------------------------------- ;INPUT : CHAR, 'X' ;OUTPUT: SENDS THE CHARACTER TO THE LCD SEND_CHAR: MOVF_F CHAR, CHAR1 SWAPF CHAR, W MOVWF CHAR2 BSF RS ;SET LCD TO CHARACTOR MODE MOVF_F CHAR1, PORTB CALL PULSE_E MOVF_F CHAR2, PORTB CALL PULSE_E RETURN ;--------------------------------------- ;INPUT : CHAR, 'X' ;OUTPUT: SENDS THE COMMAND TO THE LCD SEND_COMM: MOVF_F CHAR, CHAR1 SWAPF CHAR, W MOVWF CHAR2 BCF RS ;SET LCD TO COMMAND MODE MOVF_F CHAR1, PORTB CALL PULSE_E MOVF_F CHAR2, PORTB CALL PULSE_E RETURN ;--------------------------------------- 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: ;PREREQUISITE- LOADF CHAR WITH ADDRESS. BSF CHAR, 7 CALL SEND_COMM RETURN BLINK_ON: LOADF CHAR, B'00001111' CALL SEND_COMM RETURN BLINK_OFF: LOADF CHAR, B'00001110' CALL SEND_COMM RETURN CURSOR_ON: LOADF CHAR, B'00001110' CALL SEND_COMM RETURN CURSOR_OFF: LOADF CHAR, B'00001100' CALL SEND_COMM RETURN ;--------------------------------------- ; END OF LCD DRIVER AND LCD COMMANDS ;--------------------------------------- ;--------------------------------------- USEC_10: GOTO $ + 1 GOTO $ + 1 GOTO $ + 1 RETURN USEC_20: GOTO $ + 1 GOTO $ + 1 GOTO $ + 1 GOTO $ + 1 GOTO $ + 1 GOTO $ + 1 GOTO $ + 1 NOP NOP RETURN USEC_100: CALL USEC_20 CALL USEC_20 CALL USEC_20 CALL USEC_20 GOTO $ + 1 GOTO $ + 1 GOTO $ + 1 GOTO $ + 1 GOTO $ + 1 GOTO $ + 1 GOTO $ + 1 NOP NOP RETURN ;--------------------------------------- ;MILLI SECOND DELAY ROUTINE ;DELAY = X MILLI-SECOND (4MHZ CLOCK). MS_DELAY: MOVF_F MS_TIME, MS_TIME_TEMP MS_LOOP MOVLW 0XA4 MOVWF CNTJ DECFSZ CNTJ, F GOTO $ - 1 MOVLW 0XA4 MOVWF CNTJ DECFSZ CNTJ, F GOTO $ - 1 DECFSZ MS_TIME_TEMP, F ;IF COUNTER ENDS, GOTO MS_LOOP ;ELSE- REPEAT RETURN ;THEN- EXIT LOOP ;--------------------------------------- END