Revision: 2450
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at February 20, 2007 20:19 by k2vol
Initial Code
'****************************************************************
'* Name : UTARC GPS setting Real Time Clock TEST *
'* Author : Daniel Bowen, Mike Coffey, Carl Lyster *
'* Notice : Copyright (c) 2007 UTARC www.utarc.org *
'* : All Rights Reserved *
'* Date : 2/20/2007 *
'* Version : 1.0 *
'* Notes : Reads standard NMEA GPS information and sets Real Time Clock chip to within 5 seconds of GPS time.
'* : Clock chip used is serial NJR NJU6355ED, PIC is 18F4620
'* : *
'****************************************************************
INCLUDE "MODEDEFS.BAS"
DEFINE OSC 20
DEFINE LOADER_USED 1
DEFINE HSER_BAUD 2400
DEFINE ADC_CLOCK 1
DEFINE ADC_BITS 10
DEFINE ADC_SAMPLEUS 50
SYMBOL LF=$0A
CMCON=$07
ADCON1=%00001100
TRISA=%00110111
TRISB=%01111101
TRISC=%10010100
TRISD=%10010100
TRISE=%00000000
'*** Pin assignments
Red VAR PORTE.0
Green VAR PORTE.1
Yellow VAR PORTE.2
RTCCE VAR PORTC.3
RTCCLK VAR PORTC.2
RTCD VAR PORTC.1
RTCIO VAR PORTC.0
GPSDataPin VAR PORTB.0
'****RTC VARIABLES****
dateTime VAR byte[7] 'Array for the RTC time input
YR VAR dateTime[0] 'RTC YEARS AS 2 HEX DIGITS
MO VAR dateTime[1] 'RTC MONTH AS 2 HEX DIGITS
DY VAR dateTime[2] 'RTC DAYS AS 2 HEX DIGITS
DW VAR dateTime[3] 'DAY OF WEEK NOT UESD
HR VAR dateTime[4] 'HOURS AS 2 HEX DIGITS
MN VAR dateTime[5] 'MINUTES AS 2 HEX DIGITS
SE VAR dateTime[6] 'SECONDS AS 2 HEX DIGITS
'***HEX-DEC Conversion Variables***
hexNum VAR BYTE 'used for converting hex to ascii
decNum VAR BYTE 'used for converting numbers to decimal integers
'***GPS Variables
gPSBaudMode CON 24764
gPSSentenceString VAR byte[90]
gPSSentenceCheckSumValid VAR BIT
gPSDataReceived VAR BIT
gPSFixValid VAR BIT
'value extraction variables
data_String VAR BYTE[20]
comma_Count VAR BYTE
char VAR BYTE
charPos VAR BYTE
extract_Item VAR BYTE
bLoop VAR BYTE
i VAR Byte
checkSum VAR BYTE
numlen VAR BYTE
asciiNumber VAR WORD
power var WORD
gPSSentenceId VAR BYTE[5]
LOW RTCCE
LOW RED
LOW GREEN
LOW YELLOW
START:
GOSUB SETLEDSFORGPS 'Set LED status lights for GPS status
EXTRACT_ITEM = 1 'UTC time
GOSUB extract_the_Value
HSEROUT ["GPS Time: ",dec extract_Item," ",STR data_string,CR,LF]
GOSUB RTCREAD
HSEROUT ["RTC Time: ",HEX HR, HEX MN, HEX SE, CR,LF]
GOSUB SYNCRTCWITHGPS
GOSUB RTCREAD
PrintTimeLoop:
GOSUB readGPS
GOSUB RTCREAD
EXTRACT_ITEM = 1 'UTC time
GOSUB extract_the_Value
HSEROUT ["GPS : ",dec extract_Item," ",STR data_string,CR,LF]
HSEROUT ["RTC: ",HEX HR, " ", HEX MN, " ", HEX SE, CR,LF]
GOTO PrintTimeLoop
END
GOTO START
SYNCRTCWITHGPS: 'This will sync Real Time Clock with the GPS to +/-5s
GOSUB readGPS
EXTRACT_ITEM = 1 'UTC time
GOSUB extract_the_Value
'convert hours, and minutes to hex
'Remove seconds from data string, then send hours/minutes to be converted
GOSUB asciiHextoInteger 'Will truncate to just Min and Sec in asciiNumber variable
SE = asciiNumber & $00FF 'save seconds
data_string[4] = 0
data_String[5]= 0
GOSUB asciiHextoInteger
MN = asciiNumber & $00FF 'Removes the first two hex digits, Save minutes
HR = asciiNumber >> 8 'Shift hours over to be only digits, save hours
'asciiNumber = asciiNumber >> 8
HSEROUT ["GPS HR: ", HEX HR, " MN: ",HEX MN, " SE: ", HEX SE, CR,LF]
'Increment the minutes to be saved, making sure not to exceed 59.
IF MN = $59 THEN
MN = $0
ELSE
MN = MN + $1 'set minute to the next one just arrived at
ENDIF
'wait for minutes to increment, then sync with RTC
WHILE SE < $55 'Keep Looping until the end of this minute
GOSUB readGPS
EXTRACT_ITEM = 1 'UTC time
GOSUB extract_the_Value '
GOSUB asciiHextoInteger 'Take ascii text string and convert it to integer number
SE = asciiNumber & $00FF 'Time in this variable currently only contains minutes and seconds
'HSEROUT [" ",HEX SE]
WEND
'HSEROUT ["Time to sync! GPS Seconds: ", HEX SE,cr,lf]
SELECT CASE SE 'PAUSE remaining Seconds till next minute, this doesn't really work very well
CASE 55
PAUSE 4900 'Pause 4.9 seconds
CASE 56
PAUSE 3900 'Pause 3.9 seconds
CASE 57
PAUSE 2900 'Pause 2.9 seconds
CASE 58
PAUSE 1900 'Pause 1.9 seconds
CASE 59
PAUSE 900 'Pause 0.9 seconds
END SELECT
GOSUB RTCSET
RETURN
SETLEDSFORGPS:
gPSSentenceId[0] = "G"
gPSSentenceId[1] = "P"
gPSSentenceId[2] = "G"
gPSSentenceId[3] = "G"
gPSSentenceId[4] = "A"
extract_Item = 6 'Fix good or bad
GOSUB readGPS
GOSUB extract_the_value
GOSUB ASCIIDECTOINTEGER
IF ASCIINUMBER > 0 then 'Set Green LED on if there's valid FIX data
HIGH GREEN
ELSE
LOW GREEN
ENDIF
IF gPSDataReceived = 1 THEN 'Set Yellow LED on if there is valid serial data
HIGH YELLOW
ELSE
LOW YELLOW
ENDIF
RETURN
RTCREAD: 'READ THE REAL TIME CLOCK CHIP
LOW RTCCLK 'SET CLOCK LOW
LOW RTCIO 'SET I/O TO READ
HIGH RTCCE 'ENABLE CHIP
SHIFTIN RTCD,RTCCLK,1,[YR\8] 'READ YEAR AS 2 HEX DIGITS
SHIFTIN RTCD,RTCCLK,1,[MO\8] 'READ MONTH AS 2 HEX DIGITS
SHIFTIN RTCD,RTCCLK,1,[DY\8] 'READ DAY OF MONTH AS 2 HEX DIGITS
SHIFTIN RTCD,RTCCLK,1,[DW\4] 'WE WILL NOT USE THE DAY OF WEEK
SHIFTIN RTCD,RTCCLK,1,[HR\8] 'READ HOURS AS 2 HEX DIGITS
SHIFTIN RTCD,RTCCLK,1,[MN\8] 'READ MINS AS 2 HEX DIGITS
SHIFTIN RTCD,RTCCLK,1,[SE\8] 'READ SECONDS AS 2 HEX DIGITS
LOW RTCCE 'DISABLE RTC CHIP
LOW RTCIO 'RTC CHIP TO READ MODE
RETURN
RTCSET: 'SET DATE AND TIME OF RTC CHIP
LOW RTCCLK 'SET CLK LOW
HIGH RTCIO 'ENABLE WRITE
HIGH RTCCE 'SELECT RTC
SHIFTOUT RTCD,RTCCLK,0,[YR\8] 'YEAR AS 2 HEX DIGITS
SHIFTOUT RTCD,RTCCLK,0,[MO\8] 'MONTH AS 2 HEX DIGITS
SHIFTOUT RTCD,RTCCLK,0,[DY\8] 'DAY OF MONTH AS 2 HEX DIGITS
SHIFTOUT RTCD,RTCCLK,0,[0\4] 'DAY OF WEEK NOT USED SET TO 0
SHIFTOUT RTCD,RTCCLK,0,[HR\8] 'HOURS 24 HOUR FORMAT 2 HEX DIGITS
SHIFTOUT RTCD,RTCCLK,0,[MN\8] 'MINUTES AS 2 HEX DIGITS
'SECONDS SET TO 0 AUTOMATICALLY
LOW RTCCE 'DESELECT RTC CHIP
LOW RTCCLK 'LOW CLOCK
LOW RTCIO 'RTC IN READ MODE FROM NOW ON
RETURN 'CLOCK STARTS ON RETURN
TIMEPROCESSING:
FOR i = 0 to 6' 'Convert Hex time into Decimal
hexNum = dateTime[i] 'copy number into converter var
GOSUB HEXTOINTEGER 'Convert hex number to Dec integer
dateTime[i] = decNum
NEXT
RETURN
HEXTOINTEGER:
decNum = (hexNum / 16) * 10 'Get 10s place value of hex representation
decNum = decNum + (hexNum // 16) 'add 10s place to ones place
RETURN
'******************************************************************************
'FROM HERE ON DOWN, THESE ARE DAN'S UTILITY ROUTINES FOR GPS, AS MODIFIED BY MIKE
'DO NOT ENTER UNLESS YOU ARE VERY BRAVE!!!
'**************************************************************************
' FUNCTION: READGPS
' INPUT: gPSDataPin CON, gPSBaudMode CON,
' gPSSentenceId BYTE array - GPS Sentence name
' Serial data stream on gPSDataPin, accepts up to 90 bytes
' starting with gPSSentenceId, and ending with CRLF
' OUTPUT: gPSSentenceString BYTE array of requested sentence.
' PURPOSE: Capture desired GPS sentence from ASCII GPS serial data.
' Calls functions to verify the sentence checksum.
'**************************************************************************
READGPS:
SERIN2 GPSDataPin, gPSBaudMode, 3000, NoData, [WAITSTR gPSSentenceId\5, STR gPSSentenceString\90 ]
gpsDataReceived = 1 'Note that we have received serial data from the GPS.
'hserin 3000, NoData, [WAITSTR gPSSentenceId\5, STR gPSSentenceString\90 ]
GOSUB GPSCOMPUTECHECKSUM
GOSUB GPSMATCHCHECKSUM
RETURN
'----[EXTRACT A VALUE BASED ON THE COMMA THAT IT FOLLOWS]----------------------
' Locates and extracts the value following the comma placed in EXTRACT_ITEM
' The extracted text is returned in array DATA_STRING with a NULL terminator
' If an invalid value is found, then 000000 will be returned in the array
EXTRACT_THE_VALUE:
FOR i = 0 to 19 STEP 1
DATA_STRING[i] = 0
NEXT
COMMA_COUNT = 0 ' Reset the comma counting variable
CHARPOS = 0 ' Start at the beginning of the array
WHILE CHARPOS < 199
CHAR = gPSSentenceString[CHARPOS] ' Scan the array to parse
If CHAR == "," Then
COMMA_COUNT = COMMA_COUNT + 1
ENDIF ' Increment COMMA_COUNT if a comma is found
If COMMA_COUNT == EXTRACT_ITEM Then ' Have we found the correct comma ?
BLOOP = 0 ' Yes. So....
' Repeat ' Form a loop
WHILE CHARPOS < 199
CHARPOS = CHARPOS + 1' Skip over the comma and keep scanning the array
CHAR = gPSSentenceString[CHARPOS] ' Extract the pieces of the value into CHAR
If CHAR = 0 Then Break
If CHAR = "," Then Break
DATA_STRING[BLOOP] = CHAR ' Fill DATA_STRING with the value
BLOOP = BLOOP + 1 ' Point to the next data piece
' Until CHARPOS >= 199 ' Keep looping until a terminator is found
WEND
DATA_STRING[BLOOP] = 0 ' Add a NULL to DATA_STRING
Endif
CHARPOS = CHARPOS + 1
WEND
BREAK:
Return
GOTO START
'**************************************************************************
' FUNCTION: ASCIIHEXTOINTEGER
' INPUT: data_String BYTE array of ASCII HEX number characters
' OUTPUT: asciiNumber WORD var with hex integer value of ascii
' PURPOSE: Converts ascii hex string of numbers into integer WORD
'**************************************************************************
ASCIIHEXTOINTEGER:
numlen = 0
asciiNumber = 0
char = 1
While char !=0
char = data_string[numlen]
numlen = numlen +1
WeND
pause 200
power = 1 ' Power of ten initially starting with 16^0
'**********************
' This subtracts integer 48 from ascii numerals, which have ascii values
' 0=48 1=49 2=50 etc. Then multiplies it times the place value of that
' number - 1's, 16's, 256's, 4096's etc using increasing powers of 16.
'**********************
for i = numlen-2 to 0 STEP -1
IF data_string[i] > 57 THEN 'ASCII exceeds decimal numbers, must be hex
'subtract 55 from ascii hex letters to get numbers
asciiNumber = asciiNumber + ((data_string[i]-55) * power)
else
asciiNumber = asciiNumber + ((data_string[i]-48) * power)
endif
power = power * 16
NEXT
RETURN
'**************************************************************************
' FUNCTION: ASCIIDECTOINTEGER
' INPUT: data_String BYTE array of ASCII decimal number characters
' OUTPUT: asciiNumber WORD var with integer value of ascii text number
' PURPOSE: Converts ascii string of decimal numbers into integer WORD
' NOTE: Will stop when a non-decimal character is encountered.
'**************************************************************************
ASCIIDECTOINTEGER:
numlen = 0
asciiNumber = 0
char = "1"
While (char !=0 AND (char >= "0" AND char <="9"))
char = data_string[numlen]
numlen = numlen +1
WeND
power = 1 ' Power of ten initially starting with 10^0
'**********************
' This subtracts integer 48 from ascii numerals, which have ascii values
' 0=48 1=49 2=50 etc. Then multiplies it times the place value of that
' number - 1's, 10's, 100's, 1000's etc using increasing powers of 10.
'**********************
for i = numlen-2 to 0 STEP -1
asciiNumber = asciiNumber + ((data_string[i]-48) * power)
power = power * 10
NEXT
RETURN
'**************************************************************************
' FUNCTION: GPSCOMPUTECHECKSUM
' INPUT: gPSSentenceID BYTE array, 5 byte
' gPSSentenceString BYTE array
' OUTPUT: checkSum BYTE var, containing computed hex checksum
' gPSSentenceCheckSumValid BIT var
' PURPOSE: Computes checksum of GPS Sentence ID plus sentence data.
' Uses bitwise XOR of each successive character.
'**************************************************************************
GPSCOMPUTECHECKSUM:
Checksum = 0
CHARPOS = 0 'first compute the checksum of the GPS Sentence ID
WHILE CHARPOS < 5
CHAR = gPSSentenceId[charpos]
IF char = 0 THEN FIRSTCHECKDONE
checkSum = checkSum ^ CHAR 'Bitwise XOR checksum
charpos = charpos + 1
WEND
FIRSTCHECKDONE:
'************************
'Compute the checksum of the rest of the sentence
' starting with the checksum from the GPS Sentence ID.
'************************
charPos = 0
WHILE CHARPOS < 80
CHAR = gPSSentenceString[charpos]
IF CHAR = "*" THEN CHECKDONE
IF char = 0 THEN CHECKDONE
checkSum = checkSum ^ CHAR 'Bitwise XOR checksum
charpos = charpos + 1
WEND
CHECKDONE:
RETURN
'**************************************************************************
' FUNCTION: GPSMATCHCHECKSUM
' INPUT: gPSSentenceString BYTE array with whole NMEA Sentence
' checksum BYTE var computed checksum
' OUTPUT: gPSsentenceCheckSumValid BIT var
' PURPOSE: Find checksum in NMEA string, starts with asterisk.
' compares reported checksum to computed checksum
'**************************************************************************
GPSMATCHCHECKSUM:
i=0
char = 1
WHILE char !="*" 'Search for asterisk checksum in array
char = gPSSentenceString[i]
i =i+1
IF char = 0 THEN
GOSUB GpsBadChecksum 'If no * found, abort checking
endif
WEND
data_string[0] = gPSSentenceString[i] 'transfer checksum from discovered
data_string[1] = gPSSentenceString[i+1] 'location.
data_String[2] = 0 'end with null
GOSUB ASCIIHEXTOINTEGER 'converts the ascii hex to integer
IF checksum = asciiNumber THEn
gPSSentenceChecksumValid = 1 'valid
ELSE
GOSUB GpsBadChecksum 'not valid
ENDIF
'HSEROUT ["Converted HEX: ",HEX2 asciiNumber, " Checksum Match: ",DEC gPSSentenceChecksumValid, CR]
RETURN
NoData:
gPSDataReceived = 0
HSEROUT ["No Serial data is being received at all!",CR]
RETURN
GpsBadChecksum:
gPSsentenceChecksumValid = 0
HSEROUT ["Corrupted data received from GPS.",CR]
RETURN
GpsNoFix:
gPSFixValid = 0
HSEROUT ["The GPS is working, but we don't have a position fix.",CR]
RETURN
GOTO START
' GPRMC
'RMC = Recommended Minimum Specific GPS/TRANSIT Data
'
'1 = UTC of position fix
'2 = Data status (V=navigation receiver warning)
'3 = Latitude of fix
'4 = N or S
'5 = Longitude of fix
'6 = E or W
'7 = Speed over ground in knots
'8 = Track made good in degrees True
'9 = UT date
'10 = Magnetic variation degrees (Easterly var. subtracts from true course)
'11 = E or W
'12 = Checksum
'****************************************************************************
' GPGGA
'GGA = Global Positioning System Fix Data
'
'1 = UTC of Position
'2 = Latitude
'3 = N or S
'4 = Longitude
'5 = E or W
'6 = GPS quality indicator (0=invalid; 1=GPS fix; 2=Diff. GPS fix)
'7 = Number of satellites in use [not those in view]
'8 = Horizontal dilution of position
'9 = Antenna altitude above/below mean sea level (geoid)
'10 = Meters (Antenna height unit)
'11 = Geoidal separation (Diff. between WGS-84 earth ellipsoid and
' mean sea level. -=geoid is below WGS-84 ellipsoid)
'12 = Meters (Units of geoidal separation)
'13 = Age in seconds since last update from diff. reference station
'14 = Diff. reference station ID#
'15 = Checksum
'****************************************************************************
Initial URL
http://www.utarc.org/wiki/index.php?title=Source_Code
Initial Description
Messy, yes, but it's available anyway.
Initial Title
PicBasic Interfacing PICMicro 18F to RTC and GPS
Initial Tags
Initial Language
PicBasic