Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Interfacing 16F690 with GPS module

Status
Not open for further replies.
Hi,
Does anyone have experience interfacing a PIC with GPS? I'm trying to extract some sentances and display them on an LCD, but so far i can only obtain what appears to be
mostly junk from the module. To start I set the baud rate to 4800 on the uart and made the microcontroller recieve a character and display it. Sometimes a G or an R pops up, but the vast majority of what is recieved appears to be noise. I also have to keep toggling CREN because to keep the UART working (i'm not to concered by this. It's probably because the uart register is overflowing when the characters are displayed) . The module i'm uisng is the PMB-248 GPS Receiver. It has a TTL output so the voltage levels don't need converting.

**broken link removed**

This is the code i'm using to start it real mess, I'm trying to do several things.

I should also mention that i'm using a 14.7456Mhz osc

Code:
#include <p16F690.inc>
    __config (_HS_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
	


;----------------------------------------
; DELAY EQUATES
CNT          	  EQU 0X25         ;ADDRESS FOR COUNTER
CNT2          	  EQU 0X26         ;ADDRESS FOR COUNTER2
CNT3          	  EQU 0X27         ;ADDRESS FOR COUNTER3
CNT4          	  EQU 0X28         ;ADDRESS FOR COUNTER4
BREATH_ADC0	  	  EQU 0X29		   ;ADDRESS FOR RECEIVED BIT
BREATH_ADC1   	  EQU 0X2A
NUMBER_OF_BREATHS EQU 0X2B
CNT5																																																																																			  	  EQU 0X2C
BINARY		      EQU 0X2D
t1				  EQU 0X2E
w2			 	  EQU 0X2F
COUNTER 		  EQU 0X30
TEMP			  EQU 0X31
D1				  EQU 0X32
D0				  EQU 0X33
SAMPLEREG		  EQU 0X34
D2				  EQU 0X35
D3				  EQU 0X36
SAMPLEOLD 		  EQU 0X37
SAMPLENEW 		  EQU 0X38
D4				  EQU 0X39
D5				  EQU 0X3A
D6				  EQU 0X3B
SAMPLEOLDLOW	  EQU 0X3C
SAMPLEOLDHIGH	  EQU 0X3D
SAMPLENEWLOW	  EQU 0X3E
SAMPLENEWHIGH	  EQU 0X3F
W_Save			  EQU 0X40
STATUS_Save		  EQU 0X41
TOTALBREATHS	  EQU 0X42
SAMPLE1			  EQU 0X43
SAMPLE2			  EQU 0X44
SAMPLE3			  EQU 0X45
SAMPLE4			  EQU 0X46
SAMPLE5			  EQU 0X47
SAMPLE6			  EQU 0X48
SAMPLE7			  EQU 0X49
SAMPLE8			  EQU 0X50
SAMPLE9			  EQU 0X51
SAMPLE10		  EQU 0X52
SAMPLE11		  EQU 0X53
SAMPLE12		  EQU 0X54
TIMERCOUNTER	  EQU 0X55




; LCD EQUATES AND DEFINES
#DEFINE     DDRE   TRISB,7     ;DATA DIRECTION
#DEFINE     DDRRS  TRISB,4     ;DATA DIRECTION
#DEFINE     E      PORTA,2     ;ENABLE LINE ON LCD
#DEFINE     RS     PORTB,4     ;INSTRUCTION/DATA SELECT
#DEFINE 	RW	   PORTB,6
TEMP_LCD    EQU 0X3A           ;STORAGE FOR LCD
LCD         EQU PORTC          ;LCD DATA PORT
CLRSCR      EQU B'00000001'    ;COMMAND FOR CLRSCR
HOME        EQU B'00000010'    ;SENDS CURSOR TO HOME
ON          EQU B'00001100'    ;TURNS ON THE DISPLAY
OFF         EQU B'00001000'    ;TURNS THE DISPLAY OFF
LEFT        EQU B'00011000'    ;LEFT SHIFT
RIGHT       EQU B'00011100'    ;RIGHT SHIFT
LIN2        EQU B'11000000'    ;SETS TO LINE 2
TIMERCOMP	EQU	D'4'

;----------------------------------------
	; VECTOR FOR NORMAL START UP.
        ORG     0
        GOTO    START
NOP
NOP
NOP
ISR:
movwf     W_Save
movf      STATUS,w
movwf     STATUS_Save
BTFSS	  PIR1,TMR1IF
GOTO	  $-1
bcf		  PIR1,TMR1IF
INCF	  TIMERCOUNTER
MOVFW 	  TIMERCOUNTER 		    ;STORE NEW SAMPLE AND SUBTRACT IT FROM OLD
SUBLW	  D'10'
BTFSC	  STATUS,Z 
CALL      DISPLAYBREATHINGRATE 
MOVLW	  B'11011100'
MOVWF 	  TMR1L
MOVLW 	  B'00001011'
MOVWF	  TMR1H
movf      STATUS_Save,w
movwf     STATUS
swapf     W_Save,f
swapf     W_Save,w
retfie

; MAIN PROGRAM STARTS HERE:
START:
	   CLRW			; CLEAR W.	
        MOVWF   PORTA           ; ENSURE PORTA IS ZERO BEFORE WE ENABLE IT.
        MOVWF   PORTB           ; ENSURE PORTB IS ZERO BEFORE WE ENABLE IT.
		movwf 	PORTC
		BSF     STATUS,RP1
		movlw	H'00'
		movwf 	ANSEL
		MOVLW	B'00000000'		;DIGITAL/ANALOGUE
		movwf 	ANSELH
		BCF     STATUS,RP1
        BSF     STATUS,RP0      ; SELECT BANK 1
		MOVLW	B'01100101'
		MOVWF	OSCCON
        MOVLW   H'00'           ; MASK FOR PORTA FOR ALL OUTPUTS.
        MOVWF   TRISA           ; SET TRISA REGISTER.
        MOVLW   B'00100000'     ; MASK FOR PORTB FOR ALL OUTPUTS.
        MOVWF   TRISB           ; SET TRISB REGISTER.
		MOVLW	H'00'
		MOVwf	TRISC
	;	movlw   0x10           ; A2D Clock Fosc/8 4MHz CLOCK
    ;	movwf   ADCON1 	
     ;   BCF     STATUS,RP0      ; RESELECT BANK 0.
	;	MOVLW	B'10101101'		; ADCON0 . ADCON 0 BIT 7=0 LJ. BIT 6=0 VDD REF. BITS 5-2 1011 SEL AN11. BIT 1 GO/DONE BIT. BIT0=1 ENABLE IT.
	;	MOVWF	ADCON0
		CALL	UART_SETUP
	    CALL	INIT_LCD	; Initialse the LCD
 	    MOVLW   CLRSCR		; Clear the screen
  	    CALL    COMMAND		; Initiate the command in the W reg	=
	    CALL 	LETTER
LOOPY:
		MOVLW   CLRSCR		; Clear the screen
  	    CALL    COMMAND		; Initiate the command in the W reg	=
		CALL	RECEIVE
		SUBLW	D'0'
		BTFSC	STATUS,Z
		GOTO	LOOPY
		MOVWF	SAMPLE1
LOOPY1		CALL	RECEIVE
		SUBLW	D'0'
		BTFSC	STATUS,Z
		GOTO	LOOPY1
		MOVWF	SAMPLE2
LOOPY2		CALL	RECEIVE
		SUBLW	D'0'
		BTFSC	STATUS,Z
		GOTO	LOOPY2
		MOVWF	SAMPLE3
LOOPY3		CALL	RECEIVE
		SUBLW	D'0'
		BTFSC	STATUS,Z
		GOTO	LOOPY3
		MOVWF	SAMPLE4
LOOPY4		CALL	RECEIVE
		SUBLW	D'0'
		BTFSC	STATUS,Z
		GOTO	LOOPY4
		MOVWF	SAMPLE5
LOOPY5		CALL	RECEIVE
		SUBLW	D'0'
		BTFSC	STATUS,Z
		GOTO	LOOPY5
		MOVWF	SAMPLE6
LOOPY6		CALL	RECEIVE
		SUBLW	D'0'
		BTFSC	STATUS,Z
		GOTO	LOOPY6
		MOVWF	SAMPLE7
		MOVFW	SAMPLE1
		CALL	DISPLAY
		MOVFW	SAMPLE2
		CALL	DISPLAY
		MOVFW	SAMPLE3
		CALL	DISPLAY
		MOVFW	SAMPLE4
		CALL	DISPLAY
		MOVFW	SAMPLE5
		CALL	DISPLAY
		MOVFW	SAMPLE6
		CALL	DISPLAY
		MOVFW	SAMPLE7
		CALL	DISPLAY
		CALL	WAIT
		CALL	WAIT
		CALL	WAIT
		CALL	WAIT
GOTO LOOPY

GET_G:
MOVLW	0x60
MOVWF   FSR 
GPS0
CALL	RECEIVE
MOVWF	INDF 
MOVF	FSR 
SUBLW	0X70
BTFSC	STATUS,Z
CALL	DISPLAYGPS
INCF	FSR
GOTO	GPS0
RETURN 

DISPLAYGPS: 
MOVLW	0x60
MOVWF   FSR
GPS1:
MOVFW	INDF
CALL	DISPLAY 
MOVF	FSR 
SUBLW	0X70
BTFSC	STATUS,Z
RETURN 
INCF	FSR
GOTO	GPS1 


DISPLAYBREATHINGRATE:
MOVLW     CLRSCR		; Clear the screen
CALL      COMMAND
MOVLW	  'B'
CALL	  DISPLAY
MOVLW	  'R'
CALL	  DISPLAY
MOVLW	  ':'
CALL	  DISPLAY
CLRF	  TIMERCOUNTER
CLRF	  TOTALBREATHS
MOVFW	  SAMPLE11
MOVWF	  SAMPLE12
ADDWF 	  TOTALBREATHS
MOVFW	  SAMPLE10
MOVWF	  SAMPLE11
ADDWF 	  TOTALBREATHS
MOVFW	  SAMPLE9
MOVWF	  SAMPLE10
ADDWF 	  TOTALBREATHS
MOVFW	  SAMPLE8
MOVWF	  SAMPLE9
ADDWF 	  TOTALBREATHS
MOVFW	  SAMPLE7
MOVWF	  SAMPLE8
ADDWF 	  TOTALBREATHS
MOVFW	  SAMPLE6
MOVWF	  SAMPLE7
ADDWF 	  TOTALBREATHS
MOVFW	  SAMPLE5
MOVWF	  SAMPLE6
ADDWF 	  TOTALBREATHS 
MOVFW	  SAMPLE4
MOVWF	  SAMPLE5
ADDWF 	  TOTALBREATHS
MOVFW	  SAMPLE3
MOVWF	  SAMPLE4
ADDWF 	  TOTALBREATHS
MOVFW	  SAMPLE2
MOVWF	  SAMPLE3
ADDWF 	  TOTALBREATHS 
MOVFW	  SAMPLE1
MOVWF	  SAMPLE2
ADDWF	  TOTALBREATHS
MOVFW 	  NUMBER_OF_BREATHS
MOVWF	  SAMPLE1
ADDWF	  TOTALBREATHS
CLRF	  NUMBER_OF_BREATHS
MOVFW 	  TOTALBREATHS 	
CALL	  DISPLAYBCD
MOVLW	  ' '
CALL	  DISPLAY
MOVLW	  'b'
CALL	  DISPLAY
MOVLW	  'p'
CALL	  DISPLAY
MOVLW	  'm'
CALL	  DISPLAY

RETURN


INCFNOB:
	BTFSC	 SAMPLEREG,1
	INCF 	 NUMBER_OF_BREATHS 
	BSF		 SAMPLEREG,1
	RETURN
	

CHECK:
MOVLW  D'1'
MOVWF  SAMPLENEW 
MOVLW  D'2'
MOVWF  SAMPLEOLD 
;CALL   SAMPLENEW_GT_SAMPLEOLD
BTFSC  SAMPLEREG,0
GOTO   DISPLAY_K
GOTO   CHECK 
DISPLAY_K
MOVLW	'K'
CALL DISPLAY
GOTO CHECK 



TIMERCOUNTER_EQ_5
MOVFW 	TIMERCOUNTER 		    ;STORE NEW SAMPLE AND SUBTRACT IT FROM OLD
SUBLW	5
SKPZ 	
CALL    DISPLAYBREATHINGRATE

						 		;IF NEW SAMPLE IS GREATER THAN OLD THIS BIT WILL BE SET  
BTFSC	STATUS,C
BCF		SAMPLEREG,0	
RETURN 	 

SAMPLEOLD_GT_SAMPLENEW:
BTFSC	SAMPLEREG,1			;IF THIS BIT IS SET MEANS THAT THERE HAS BEEN A CHANGE IN VOLTAGE DIRECTION 
GOTO	INCFNOB
MOVFW	ADRESH
INCF	W					;NEEDS TO BE INCREMENTED SO CARRY FLAG DOESN'T SET WHEN THEY ARE EQUAL 
MOVFW	SAMPLENEW
SUBWF 	SAMPLEOLD  
BTFSS	STATUS,C
BCF 	SAMPLEREG,0 		;IF NEW SAMPLE IS GREATER THAN OLD THIS WILL BE CLEAR
MOVFW 	SAMPLENEW
MOVWF 	SAMPLEOLD


RETURN  
DISPLAYADC0:
MOVLW	  D'255'
MOVWF	  SAMPLEOLDLOW
MOVWF	  SAMPLEOLDHIGH
CLRF	  NUMBER_OF_BREATHS 
DISPLAYADC:
BSF       ADCON0,GO      ; start conversion
BTFSS     ADCON0,GO      ; this bit will change to zero when the conversion is complete
GOTO      $-1
MOVFW 	  ADRESH
MOVWF	  SAMPLENEWHIGH
MOVFW	  ADRESL
MOVWF	  SAMPLENEWLOW 
CALL	  LARGECOMPAREOLDGTNEW 
BTFSC	  SAMPLEREG,0
CALL	  INCFNOB
MOVFW	  NUMBER_OF_BREATHS
CALL 	  DISPLAYBCD 
CALL 	  TENTH_SEC_DELAY 
MOVLW     CLRSCR		; Clear the screen
CALL      COMMAND
MOVFW	  SAMPLENEWHIGH
MOVWF	  SAMPLEOLDHIGH
MOVFW	  SAMPLENEWLOW
MOVWF	  SAMPLEOLDLOW

GOTO 	  DISPLAYADC


DISPLAYADC0EDIT:
MOVLW	  D'255'
MOVWF	  SAMPLEOLDLOW
MOVWF	  SAMPLEOLDHIGH
CLRF	  NUMBER_OF_BREATHS 
DISPLAYADCEDIT:
BSF       ADCON0,GO      ; start conversion
BTFSS     ADCON0,GO      ; this bit will change to zero when the conversion is complete
GOTO      $-1
MOVFW 	  ADRESH
MOVWF	  SAMPLENEWHIGH
MOVFW	  ADRESL
MOVWF	  SAMPLENEWLOW 
CALL	  LARGECOMPAREOLDGTNEW 
BTFSC	  SAMPLEREG,0
CALL	  INCFNOB 
CALL 	  TENTH_SEC_DELAY 
MOVFW	  SAMPLENEWHIGH
MOVWF	  SAMPLEOLDHIGH
MOVFW	  SAMPLENEWLOW
MOVWF	  SAMPLEOLDLOW
GOTO 	  DISPLAYADCEDIT

RETURN

ADCTRIAL

BSF       ADCON0,GO      ; start conversion
BTFSS     ADCON0,GO      ; this bit will change to zero when the conversion is complete
GOTO      $-1
MOVFW 	  ADRESH 
MOVWF 	  SAMPLENEW
;CALL	  SAMPLENEW_GT_SAMPLEOLD
BTFSS	  SAMPLEREG,0
INCF 	  NUMBER_OF_BREATHS
MOVLW     CLRSCR		; Clear the screen
CALL      COMMAND	 
MOVFW	  NUMBER_OF_BREATHS
CALL 	  DISPLAYBCD
CALL 	  TENTH_SEC_DELAY
GOTO	  ADCTRIAL 

RETURN

DISPLAYBCD:
MOVWF 	BINARY 
CALL 	GETHNDS 
CALL 	LOOKUP_TABLE
CALL 	DISPLAY
MOVFW 	BINARY
CALL 	GETTENS
CALL 	LOOKUP_TABLE
CALL 	DISPLAY
MOVFW 	BINARY
CALL 	GETONES
CALL 	LOOKUP_TABLE
CALL 	DISPLAY
RETURN

	 	
LOOKUP_TABLE:
	;MOVF	  NUMBER_OF_BREATHS,W 
	ANDLW     B'00001111'	;STOP VALUE GOING BEYOND TABLE RANGE 
	ADDWF	  PCL	
	RETLW 	  '0'	               
	RETLW	  '1'
	RETLW	  '2'
	RETLW 	  '3'
	RETLW	  '4'
    RETLW 	  '5'
	RETLW     '6'
	RETLW 	  '7'
	RETLW	  '8'
	RETLW	  '9'



; ------------------------------------------- 
; RECEIVE CHARACTER FROM RS232 AND STORE IN W 
; ------------------------------------------- 
; This routine does not return until a character is received. 
; 
RECEIVE:
		 	
		 btfss PIR1,RCIF         ; (5) check for received data 
         goto RECEIVE 
		 BCF  RCSTA,CREN
		 BSF  RCSTA,CREN		 
		
        movf RCREG,W          ; save received data in W 
        return 
; 
; ------------------------------------------------------------- 
; SEND CHARACTER IN W VIA RS232 AND WAIT UNTIL FINISHED SENDING 
; ------------------------------------------------------------- 
; 
SEND:    
		movwf TXREG            ; send data in W 
		BCF PIR1,RCIF
 		BSF     STATUS,RP0
WtHere  btfss TXSTA,TRMT        ; (1) transmission is complete if hi 
       goto WtHere 
		 BCF     STATUS,RP0
        return 	
	
UART_SETUP:
		bsf	STATUS,RP0
        movlw D'191'              ; 0x19=9600 bps (0x0C=19200 bps) 
        movwf SPBRG 
        movlw b'00100100'       ; brgh = high (2) 
        movwf TXSTA             ; enable Async Transmission, set brgh 

        bcf STATUS,RP0          ; RAM PAGE 0 

        movlw b'10010000'       ; enable Async Reception 
        movwf RCSTA 
	    return 
;**************************lcdv6******************************
;Porta 1 for the enable and porta 2 for rs/ portb for lcd data
;*************************************************************
;************************************************************
; Initialize the LCD 
;************************************************************
INIT_LCD:
CALL  MILLSEC30	           ; '' ''
MOVLW B'00110000'                  ;tell display its two lines
CALL COMMAND                       ;output to the screen
CALL MILLSEC30
MOVLW B'00110000'
CALL COMMAND
MOVLW .100
CALL MDELAY
MOVLW B'00110000'
CALL COMMAND
MOVLW .100
CALL MDELAY
MOVLW B'00111100'					;FUNCTION SET
CALL COMMAND


MOVLW ON                           ;turn on display
CALL COMMAND                       ;output to the screen
MOVLW 0X01
CALL COMMAND
MOVLW B'00000110'                  ;shift along every write
CALL COMMAND                       ;output to the screen
RETURN
;************************************************************
; This routine is to set the lcd to the second line 
;************************************************************
SECOND_LINE:
MOVLW LIN2                     ;set to line 2
CALL COMMAND                   ;output to the screen
RETURN
;************************************************************
; THis executes a command in the W reg
;************************************************************
COMMAND:
BCF RS  
BCF	RW                       ;command coming
MOVWF LCD                      ;PUT OUT ONTO PORT
MOVLW .200                     ;delay time in microsecs
CALL MDELAY                    ;wait a while
MOVLW .250                     ;delay time in microsecs
CALL MDELAY                    ;WAIT
BSF E                          ;make sure the enable line is up 
MOVLW .200                     ;delay time
CALL MDELAY                    ;wait a while
MOVLW .250                     ;delay time in microsecs
CALL MDELAY                    ;WAIT
BCF E                          ;clock the data in
MOVLW .200                     ;delay time
CALL MDELAY                    ;wait a while
MOVLW .250                     ;delay time in microsecs
CALL MDELAY                    ;WAIT
BSF RS                         ;return to a data input
RETURN
;************************************************************
; This controls the module. When you call this 
; routine, the contents of the 'w' register is 
; displayed on the LCD screen. It is written in a 
; module like this for portability!! 
;************************************************************
DISPLAY:
BSF RS     
BCF	RW                    ;make sure it will accept data
MOVWF LCD                      ;send data to lcd
MOVLW .250                     ;delay time in microsecs
CALL MDELAY                    ;WAIT
MOVLW .250                     ;delay time in microsecs
CALL MDELAY                    ;WAIT
BSF E                          ;make sure the enable line is up 
MOVLW .250                     ;delay time
CALL MDELAY                    ;wait a while
MOVLW .250                     ;delay time in microsecs
CALL MDELAY                    ;WAIT
BCF E                          ;clock the data in
MOVLW .250                     ;delay time
CALL MDELAY                    ;wait a while
MOVLW .250                     ;delay time in microsecs
CALL MDELAY                    ;WAIT
RETURN
	
;*************************************************************
; 1 MICROSECOND DELAY 
;*************************************************************
MDELAY:
MOVWF CNT          ;LOAD DELAY TIME
COUNT:
NOP         ;TWO NO OPERATIONS
NOP                ;TO OBTAIN THE DELAY
DECFSZ CNT,1       ;DECREMENT THE COUNTER
GOTO COUNT         ;GOTO COUNT IF NOT FINISHED
RETURN


;*************************************************************
; 0.1 SECOND DELAY 
;*************************************************************
TENTH_SEC_DELAY:  ;99993 cycles
	movlw	0x1E
	movwf	D0
	movlw	0x4F
	movwf	D1
Delay_0
	decfsz	D0, f
	goto	$+2
	decfsz	D1, f
	goto	Delay_0

			;3 cycles
	goto	$+1
	nop

			;4 cycles (including call)
	return
;---------------------------------------------------------------
;30 MILLISECOND DELAY
;--------------------------------------------------------------
MILLSEC30:
			;29993 cycles
	movlw	0x6E
	movwf	D2
	movlw	0x18
	movwf	D3
Delay_1
	decfsz	D2, f
	goto	$+2
	decfsz	D3, f
	goto	Delay_0

			;3 cycles
	goto	$+1
	nop

			;4 cycles (including call)
	return




RETURN
HALF_SECOND_DELAY:
			;499994 cycles
	movlw	0x03
	movwf	D4
	movlw	0x18
	movwf	D5
	movlw	0x02
	movwf	D6
Delay_2
	decfsz	D4, f
	goto	$+2
	decfsz	D5, f
	goto	$+2
	decfsz	D6, f
	goto	Delay_2

			;6 cycles
	goto	$+1
	goto	$+1
	goto	$+1

RETURN

WAIT:		
movlw D'6'
movwf CNT3
movlw D'24'
movwf CNT4
movlw D'167'
movwf CNT5
loop decfsz CNT5,1
goto loop
decfsz CNT4,1
goto loop
decfsz CNT3,1
goto loop
return

        
 RETURN             ; all done!

GETHNDS	
		movwf	t1
        clrf    w2
gethnds_loop
		movlw	.100
		incf	w2,f
		subwf	t1,f
		btfsc	STATUS,C
		goto 	gethnds_loop
		decf	w2,w
		return		
;---
;This routine will return the number of decimal 
;tens from an 8-bit binary
;Loop based, so it might take some time...
;It needs getones too
GETTENS		movwf	t1
                clrf    w2
gettens_loop	movlw	.10
		incf	w2,f
		subwf	t1,f
		btfsc	STATUS,C
		goto 	gettens_loop
		decf	w2,w
		goto	GETONES

;---
;This routine will return the number of decimal 
;ones from an 8-bit binary	
GETONES		movwf	w2
		movlw	.10
deltens_loop	subwf	w2,f
		btfsc	STATUS,C
		goto 	deltens_loop
		addwf	w2,w
		return


;RECEIVE_DATE:
;	BTFSS	PIR1,RCIF
;	GOTO	RECEIVE_DATE
;	BTFSS	RCSTA,OERR
;	BCF		RCSTA,CREN
;	BSF		RCSTA,CREN
;	SUBLW	'G'
;	BTFSS	STATUS,2
;	GOTO	RECEIVE_DATE
;PLABEL:
;	BTFSS	PIR1,RCIF
;	GOTO	PLABEL
;	BTFSS	RCSTA,OERR
;	BCF		RCSTA,CREN
;	BSF		RCSTA,CREN
;	SUBLW	'P'
;	BTFSS	STATUS,2
;	GOTO	RECEIVE_DATE
;RLABEL:
;	BTFSS	PIR1,RCIF
;	GOTO	RLABEL
;	BTFSS	RCSTA,OERR
;	BCF		RCSTA,CREN
;	BSF		RCSTA,CREN
;	SUBLW	'R'
;	BTFSS	STATUS,2
;	GOTO	RECEIVE_DATE
;MLABEL:
;	BTFSS	PIR1,RCIF
;	GOTO	MLABEL
;	BTFSS	RCSTA,OERR
;	BCF		RCSTA,CREN
;	BSF		RCSTA,CREN
;	SUBLW	'M'
;	BTFSS	STATUS,2
;	GOTO	RECEIVE_DATE
;CLABEL:
;	BTFSS	PIR1,RCIF
;	GOTO	CLABEL
;	BTFSS	RCSTA,OERR
;	BCF		RCSTA,CREN
;	BSF		RCSTA,CREN
;	SUBLW	'C'
;	BTFSS	STATUS,2
;	GOTO	RECEIVE_DATE
;	CALL	COUNT_COMMA

;ADD9:
;COUNT_COMMA:
;	BTFSS	PIR1,RCIF
;	GOTO	COUNT_COMMA
;	BTFSS	RCSTA,OERR
;	BCF		RCSTA,CREN
;	BSF		RCSTA,CREN
;	SUBLW	','
;	BTFSS	STATUS,2
;	GOTO	COUNT_COMMA
;	INCF	COMMA
;	SUBLW	D'9'
;	BTFSS	STATUS,2
;	GOTO	ADD9
;	GOTO	STORE_DATE

   

;--------------------------------------------------------------------------------------
.;COMPARE 16-BIT NUMBER 
;--------------------------------------------------------------------------------------

LARGECOMPAREOLDGTNEW: 
; if( NEW < OLD)
; by unknown
; Y and X are unchanged.
MOVFW SAMPLEOLDLOW
SUBWF SAMPLENEWLOW,w
MOVFW SAMPLEOLDHIGH
SKPC ; c=0 indicates a borrow we need to propagate.
INCFSZ SAMPLEOLDHIGH,w ; handle xh=0xff correctly, unlike ``incf xh,w''.
SUBWF SAMPLENEWHIGH,w
SKPNC
BCF	  SAMPLEREG,0
SKPC  
BSF	  SAMPLEREG,0
RETURN 
; then:
; /* y is less than x */
 
TEST:
MOVLW	D'10'
MOVWF 	SAMPLEOLDHIGH 
MOVLW	D'10'
MOVWF	SAMPLENEWHIGH
MOVLW	D'4'
MOVWF 	SAMPLEOLDLOW 
MOVLW	D'4'
MOVWF	SAMPLENEWLOW
CALL 	LARGECOMPAREOLDGTNEW
BTFSC	SAMPLEREG,0
CALL    LETTER
GOTO	$
RETURN

LETTER:
CLRF	TIMERCOUNTER
MOVLW	'Y'
CALL 	DISPLAY
RETURN

INTERRUPTTEST: 
CALL	LETTER
bsf 	STATUS,RP0
bsf 	PIE1,TMR1IF 
bcf		STATUS,RP0
bsf 	INTCON,7 
BSF		INTCON,PEIE 
CLRF 	TMR1L
CLRF	TMR1H
MOVLW	B'00110000'
MOVWF	T1CON
BSF		T1CON,0 
call	LETTER
man:
nop 
nop
nop
MOVLW	'B'
CALL 	DISPLAY
CALL	WAIT
goto man
RETURN

TIMER1:
CLRF 	TMR1L
CLRF	TMR1H
MOVLW	B'00110000'
MOVWF	T1CON

BSF		T1CON,0
REPEAT:
BTFSS	PIR1,TMR1IF
GOTO	$-1
BCF		PIR1,TMR1IF
CALL 	LETTER
GOTO	REPEAT

end
 
You need to cut the rubbish, such as test subroutines that are not called, out of the code. It will make it easier for us to understand.

I can't work out where the main program loop is. There are all sorts of dead-end loops with no way out.

You have to have a way of dealing with the data from the USART fast enough that the USART does not overflow. You can achieve that with a USART interrupt, or by having a main loop that runs fairly quickly and includes checking the RCIF bit.

The code that I wrote to receive the strings from a GPS receiver checked the RCIF bit very often, and dealt with the bytes as they arrived.

You could store the whole of one NMEA string in one bank of the 16F690, which would mean that you could then have code to decode it. Just displaying certain fixed positions would show you if the receive routine were working.
 
This is wrong
Code:
MOVLW	B'01100101'
		MOVWF	OSCCON
Bit 0 is a 1 = Internal oscillator is used for system clock
You are using a crystal you want bit 0 to be 0 and bit 3 to be 1

With a crystal you don't need to set OSCCON

bit 3 OSTS: Oscillator Start-up Time-out Status bit(1)
1 = Device is running from the external clock defined by FOSC<2:0>
0 = Device is running from the internal oscillator (HFINTOSC or LFINTOSC)

bit 0 SCS: System Clock Select bit
1 = Internal oscillator is used for system clock
0 = Clock source defined by FOSC<2:0>
 
Can you get sense out of it via hyperterminal? The reason I ask is that I have one similar* that i got from China via eBay. It too claimed to be 4800 and all I got from it was rubbish.
I opened it up and traced a chip similar to a max232 (cannot recall the actual part No) and it lead to an empty space where a surface mount resistor pack 'should have been'. That's where I found the actual sentences. It works fine now.

*Mine has a board with four screened cans (two one side and two the other).
 
Last edited:
Yeah, turns out that was the problem. Not sure why i set the osccon register like that. It my first time programming, so alot of my code is trail and error based.
Can anyone tell me were i'm going wrong with this bit of code now. I'm trying to use indirect addressing to store the sentance, or at least some of it but it's not working. I know the first bit getting GPRMC works ok. It's the next to sections of code I am unsure of. Any suggestions?

Code:
RECEIVELOOP1:
CLRF	SAMPLE7
CALL	RECEIVE
SUBLW	'$'
BTFSS	STATUS,Z
GOTO 	RECEIVELOOP1
MOVLW	'$'
MOVWF	SAMPLE1
CALL	RECEIVE
SUBLW	'G'
BTFSS	STATUS,Z
GOTO 	RECEIVELOOP1
MOVLW	'G'
CALL	RECEIVE
SUBLW	'P'
BTFSS	STATUS,Z
GOTO 	RECEIVELOOP1
MOVLW	'P'
MOVWF	SAMPLE1
CALL	RECEIVE
SUBLW	'R'
BTFSS	STATUS,Z
GOTO 	RECEIVELOOP1
MOVLW	'R'
CALL	RECEIVE
SUBLW	'M'
BTFSS	STATUS,Z
GOTO 	RECEIVELOOP1
MOVLW	'M'
MOVWF	SAMPLE1
CALL	RECEIVE
SUBLW	'C'
BTFSS	STATUS,Z
GOTO 	RECEIVELOOP1
MOVLW	'C'
RECEIVECOMMA: 
CALL	RECEIVE
SUBLW	','
BTFSS	STATUS,Z

MOVLW	0X60		;load starting address
MOVWF	FSR		
STORESENTANCE:
CALL	RECEIVE 
MOVWF	INDF		;MOVE RECIEVED BYTE TO LOCATION BEING POINTED TO
INCF	FSR
MOVFW	FSR			;IF FSR GETS TO 7E GOTO DISPLAY SENTANCE
SUBLW	0X7E
BTFSS	STATUS,Z
GOTO	STORESENTANCE

MOVLW	0X60		;LOAD STARTING ADDRESS AGAIN
MOVWF	FSR
DISPLAYSENTANCE:	
MOVFW	INDF		;MOVE STORED DATA TO BE DISPLAYED
CALL	DISPLAY
INCF	FSR			
MOVFW	FSR			;IF FSR GETS TO 7E FINISH
SUBLW	0X7E
BTFSS	STATUS,Z
GOTO	DISPLAYSENTANCE
GOTO	$			;FINISH
 
If you want to receive from say $ to 0x0a then something like,
Code:
	movlw	Buffer
	movwf	FSR
	bcf	STATUS,IRP
Wait$	call	Receive
	sublw	'$'
	btfss	STATUS,Z
	goto	Wait$
Loop	call	Receive
	movwf	INDF
	incf	FSR,F
	sublw	0x0a
	btfss	STATUS,Z
	goto	Loop

;	buffer now contains 1 sentence
The above code assumes Buffer is in banks 0 or 1.

Mike.
 
Last edited:
If it helps, I've got 10F200 assembly code that parses $GPRMC strings in a manner that mimics the following pseudo C code;

Code:
;
;  const rom char hdr[] = { "GPRMC" };
;  const rom char tab[] = { line1 + 5,          // HDR: ^
;                           line2 + 5,          // UTC: ^
;                           line1 + 16,         // FIX: ^
;                           line3 + 6,          // LAT: ^
;                           line3 + 16,         // card char
;                           line4 + 5,          // LON: ^
;                           line4 + 16,         // card char
;                           line1 + 5 };        // wrap
;
;  #define parser (field <= 6)    // parser on (1) or off (0)
;
;  void main()
;  { initmcu();                   //
;    initlcd();                   //
;
;    while(1)
;    { data = Get232();           // get gps character
;      if(data == '$')            // if new 'sentence'
;      { field = 0; ndx = 0;      // reset field and index
;        putcmd(tab[field]);      // set lcd 'ddram' address
;      }                          //
;      else                       // not new sentence
;      { if(parser)               // if parser 'on'
;        { if(data == ',')        // if new field
;          { field++; ndx = 0;    // bump field, reset index
;            putcmd(tab[field]);  // set lcd 'ddram' address
;          }                      //
;          else                   // not new field
;          { if(field == 0)       // if header field
;            { if(data!=hdr[ndx]) // if not "GPRMC"
;                field |= 8;      // turn parser off
;            }                    //
;            putdat(data);        // print char to lcd
;            ndx++;               // bump field index
;          }                      //
;        }                        //
;      }                          //
;    }                            //
;  }                              //
;
There's obvious differences between what this code does (writing each character to the LCD as it comes in) and what you're trying to do (save each incoming character to an array), but if you think it might help to look at the project I would be happy to post it for you.

Cheerful regards, Mike
 

Attachments

  • GPS Monitor.png
    GPS Monitor.png
    27.4 KB · Views: 344
  • 10F200 LCD Experiment.txt
    15.4 KB · Views: 254
Last edited:
Status
Not open for further replies.

Latest threads

Back
Top