Académique Documents
Professionnel Documents
Culture Documents
z3463372
05/06/2014
Contents
1
OVERVIEW ........................................................................................................... 2
Keypad .............................................................................................................. 3
2.2
LCD ................................................................................................................. 3
2.3
GPS .................................................................................................................. 4
2.4
2.5
Interface............................................................................................................. 8
3.2
Keypad .............................................................................................................. 9
3.3
LCD ................................................................................................................ 10
3.4
GPS ................................................................................................................. 11
3.5
3.5.1
3.5.2
Waypoints .................................................................................................. 13
5.2
5.3
Power consumption.............................................................................................. 16
5.4
CONCLUSION ...................................................................................................... 16
APPENDIX ........................................................................................................... 17
OVERVIEW
The purpose of this report is to detail the necessary steps which were undertaken to produce a fully-functioning
global positioning system and to become familiar with the assembly language program that was used in its design.
In coordination with the provided PIC16F886 microcontroller, this project involved the assimilation of several
different modules and their interfacing through a variety of hardware and software means.
The final design involves implementing a system that is capable of displaying the users current global position
using latitude and longitude in degrees decimal minutes in response to a button press. If the system is unable to
obtain a lock on the satellite, an appropriate message must be displayed. The user must also have the ability to
input up to three waypoints, each of which corresponding to a specific time and location, with the system
signalling the user if they are not present at these specified locations at those particular times.
In retrospect, the project was commenced and accomplished as a series of small problems, with each stemming
from the criterions provided in the Detailed Design Criteria section. Through their eventual clarification, the
objectives of how to produce a successful GPS with the provided parts and the steps needed to be taken were
realised, with the remainder of this report detailing the creative and constructive processes involved.
The entire GPS system is designed to be a combination of individual components that will work in tandem with
one another to produce a viable working system for the user. The key physical components comprising the
system were the LCD, keypad and GPS module. As the entire system was designed to be portable, this implied
the use of a mobile power source that would allow the user to properly interface with the system.
As the LCD and the keypad were the only forms of interfacing between the user and the system itself, much
thought was placed into the user interface and the menus that were to be designed. It was apparent that a robust
user interface combined with favourable coding practice could produce a very intuitive system for the user. The
LCD will print messages and characters according to what menu the user is in and in response to any userprovided input. Five LEDs are also used alongside the LCD as a visual indication regarding the users
whereabouts in relation to their inputted waypoints. In conjunction with the keypad, the software used to
implement the final design of the system provides an intuitive and user-friendly experience, with all components
being powered off a Duracell Coppertop (6LR61) 9V battery.
The final design criteria for successfully producing this particular system are listed below:
-
2.1 Keypad
The keyboard provided is of a generic hexadecimal format and allows for numeric or alphanumeric information
to be entered. Internally, the keypad consists of touch-activated switches arranged in a matrix fashion of rows and
columns as shown in Figure 2.1.1. As an input device, this requires the first four pins (columns) to be outputs
and the last four pins (rows) to be inputs. The columns of the keypad were pulled up to 5V (active low) using
10k resistors. This was done so as to produce a unique output pattern whenever a key was pressed; with the
row of that particular key being connected to its corresponding column. Such a pattern was able to be detected
by sending a "walking-zero" pattern over the output lines (rows) and then by reading the input lines (columns);
searching for a '0'. The method of determining exactly which key was pressed will be explained under header 3.2
of section 3: Software Design. The circuit diagram in Figure 2 depicts the pin layout and connections that was
used to interface the keypad with the PIC microcontroller.
2.2 LCD
The LCD provided was a PC1601-A LCD display driven by the Samsung KS0066U, with the 64.5 x 13.8mm
viewing module providing either a single line or dual line display with up to sixteen characters at a time. Its presaved driver module includes ASCII character patterns which are able to be accessed using the relevant ASM
commands and supports sixteen custom-generated characters.
Although sufficient for our uses, this provided very limited interfacing possibilities for the user, with much
thought being invested into how this component would interface with the user and any possible restrictions that it
might impose. Rectangular in shape, the entire module itself measures 80.0 x 36.0mm, with a dot size of 0.55 x
0.75mm and dot pitch of 0.63 x 0.83mm. Positioned centrally downwards on the board, wire management was
imperative towards constructing a nice, clean interface, with wires being tightly routed back to the PIC.
This particular LCD module provided backlighting capabilities, and was able to illuminate the entire viewing
module, enhancing its use when in darker environments. The ability to tweak the viewing contrast was also
present, providing the user with a multitude of viewing experiences at the cost of power consumption, as will be
3
discussed in section 5.2: Power Consumption. Testing resulted in the conclusion that without any
backlighting, the display could be rather dim if not outdoors or using a peripheral light source. As such, it was
decided to implement the system with backlighting and with a small tweak also being made to the contrast; both
considerations aiming to improve the viewing experience.
In terms of pin functions and connections, Table 2.2.1 below describes the function for each pin, with the
appropriate connections made to the PIC shown by the circuit diagram in Figure 2.
Pin number
Symbol
Function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Vss
Vdd
Vo
RS
R/W
E
DB0
DB1
DB2
DB3
DB4
DB5
DB6
DB7
A
K
2.3 GPS
The Adafruit Ultimate GPS Breakout v3 module provided is built around the MTK3339 chipset and is able to
track up to 22 satellites on 66 channels. Powering off a CR1220 coin cell, the 'Fix' LED blinks at approximately
1Hz while searching for satellites and will blink once every 15 seconds when a fix is found to conserve power. As
the PIC16F886 microcontroller supports EUSART (Enhanced Universal Synchronous Asynchronous Receiver
Transmitter), the GPS module is able to be connected to the appropriate port of the PIC (PORTC) provided that
all relevant bits have been set, as shown in section 3: Software Design.
For the purposes of this project, it is not necessary to transmit to the GPS. For this particular system, we are only
to read from the GPS and to output the relevant data in a cohesive manner for the user to interpret. Upon
performing the necessary software requirements as will be described in the proceeding section, we were able to
connect the TX pin of the GPS module to the RX pin of PORTC,7 on the PIC. The only other ports to be
connected were the VIN (voltage in) and GND (ground) pins, as seen in Figure 2.
SOFTWARE DESIGN
As this system was heavily dependent on the software that would combine each of its components as a viable,
working product, it was important that the system contain an interface that was as intuitive and user-friendly as
possible. This was accomplished through the use of efficient coding technique so as to reduce the number of
operations necessary for the PIC to perform throughout its operation. System efficiency was paramount towards
obtaining an efficient final design, with 1806 lines of program memory being used by the PIC to implement the
final design of the system.
This was done by ensuring that all memory was
being managed as efficiently as possible through
the use of a variety of memory management
techniques, as will be discussed further in this
section. Such memory management was vital
towards producing an efficiently functioning
system, with program memory, general purpose
registers and electronically erasable memory
(EEPROM) all being considered as viable
methods of satisfying the design criteria towards
producing a functionally efficient system. The
block diagram in Figure 3.2 below depicts the
data and information transfer occurring between
each main component in the final design.
Interrupts were not used in the final design so as to obtain greater control over the system, determining which
functions and routines were to be executed and when. A system of counters and self-implemented flags were
used instead to manipulate the flow of subroutines from one operation to another; with this kind of
implementation proving difficult to use in regards to interrupts, as it would not be possible for the program to
directly access the call stack.
Figure 3.2:
Block diagram depicting
data and information flow
between each of the main
components
The form of implementation seen in Figure 3.2 used very little program memory, and proved far more efficient
in comparison to earlier iterations of the design. For the remainder of this section, the following headers will
describe the processes taking place in the flowchart provided in Figure 7.3 of the Appendix and will detail the
relevant levels of abstraction needed to implement each of the functions necessary in ensuring the systems
reliable operation.
3.1 Interface
The final design for this system contained two primary menus: the main home menu shown on system start-up
and the waypoint menu with which the user would input their desired coordinates. Being comprised of these two
high-level menus, the interface itself seamlessly allows the user to travel back and forth between the two; the two
main menus being linked through the use of on-screen instructions and smaller intermediate menus. This was
done so as to allow the user to intuitively operate the system without needing to enquire as to the specific
functions behind each key.
The home menu displays the ASCII values of the seven keys which each perform different functions, as seen in
Table 3.1.1.
as the relevant ASCII character of the key being pressed was written to the LCD screen, and the cursor
automatically being incremented.
Implementing the waypoint menu in such a fashion provided the user with a logical process of entering their
desired waypoint data without the use of any additional prompts. The A, B, C and D keys also allowed the
user to input the global bearings North, South, East and West; allowing the system to function across all
quadrants of the globe. Upon completing the fields, or by pressing the F key mid-operation, the user would be
returned to the main menu screen, with the Saved message being displayed if all required fields were correctly
entered.
3.2 Keypad
The keypad itself is a vital component of the system, as this is one of the only forms of interfacing that exists
between the user and the system. Although very arbitrary in format, it was important to have a robust keypad
function that would interpret the user's input according to what menu they were in.
As shown in Figure 7.4 of the Appendix, the 'store' and 'count' variables are used to perform the matrix
scanning for the keypad. Upon execution of the key scanning function, all port pins of PORTA must be set to
high excluding the first pin, and the carry flag set to high. This particular row pattern is stored inside the store
register, with the count register indicating the number of iterations with which to cycle between the rows. As
each iteration of the scanning loop is executed, the row pattern is re-energised and rotated throughout the
function using the rrf ASM command. Upon determining which row contained the key that had been pressed,
the column in which the key resided had to be found, and as a pair, could locate the keys position within the
matrix. This was done by performing the XOR (exclusive OR) operation. As the column pins were active low,
by performing the XOR operation on the output of the keypad with the data in the store register, any changes
in bit pattern could be determined, resulting in the relevant keys position being found.
As the scanning function for the keypad operates at a much faster rate than our human reaction times, a
debouncing function must be implemented so as to allow the user to comfortably interface with the system. The
release function seen in Figure 7.4 of the Appendix provides a reliable method of determining if the user has
held down a key for an extended period of time, rendering that particular key press as invalid.
Initially, the keypad's scanning system was designed to be a function that the program would initially enter before
looping consistently. When a button was pressed, the program would go to other pre-determined sections of
code, performing any operation that was previously defined for that key. This form of implementation worked
well for a majority of the project, however it was rather taxing on program memory, as it involved implementing
a look-up table for each menu of the interface. The more significant issue occurred with the final implementation
of the waypoint checking function, as this interfered with the counter that was being implemented for the
scanning system; as will be elaborated in section 5.1: Keypad redesign. In light of these issues, the keypad
scanning function was modified so as to be completely modular; being able to scan the matrix once before
returning to its parent function. This was done by having the keypad instead return the ASCII value of the key
that was pressed, with its parent function being able to manipulate the data upon return. If no keys had been
pressed, the output would be cleared and the scanning function would return a NULL result.
This form of implementation proved highly efficient and rendered the use of a look-up table obsolete. This
allowed for the use of peripheral menus without any additional program memory usage, not only improving
response time, but allowing for greater usability and an improved user interface.
9
3.3 LCD
For the system to be operational, the LCD was the centrepiece of the project, with all menus and designs catering
for its successful operation. In order to implement a robust LCD display function, separate sub-functions had to
first be implemented, which would collaborate with one another in order to produce the reliable outputs as seen
in the final design of the system.
In order to initialise the LCD and have it ready for the user, the read and write subroutines had to first be
implemented. This was performed by observing the read and write operation timing charts provided in
Appendix Figures 7.1 and 7.2. The main difference between writing instructions to the LCD and writing
information to the LCD is the status of the Register Select (RS) bit. When the RS bit is high, the byte written to
the LCD will be a printable character that the LCD can display; when low, the LCD will perform a predetermined function which will alter the LCDs internal operation. When writing an instruction from the micro
processing unit to the module, the enable of the LCD must first be off, and the information from the ports on the
PIC transferred to the data ports of the LCD. Clearing the Read/Write (R/W) bit, the enable must then be
pulsed in order to have the data correctly transferred to the LCD. This can be seen in Figure 7.4 with the
'write_op' subroutine responsible for writing all instruction sets to the LCDs data lines. Alternatively, the
write_MSB_LSB subroutine, differing only by the setting of the RS bit, is responsible for writing information to
the LCD which is able to be printed in the form of ASCII characters.
Reading from the LCD is slightly more troublesome, as this first involves storing the information held on the
ports of the PIC which are connected to the LCD. After disabling the RS bit and enabling the R/W bit, we must
set the enable bit of the LCD before transferring the saved data of the PIC ports to a separate register; in this
case, 'read_status'. This read operation is a necessity as the LCD cannot properly operate without it. Using simple
delays in the hope that the busy flag would be reset during the delayed period proved to be highly inefficient, and
resulted in the LCD performing unpredictably.
To ensure a successful write operation, the 'busy_check' subroutine must be used. In conjunction with the read
operation, this routine performs a bit check on the separate register containing the saved port information from
the PIC. By checking the third bit of the register, we are able to determine if the busy flag is 'high', indicating that
an internal operation is being processed. This bit must be checked, as during this time the next instruction cannot
be accepted until the busy flag has been returned to the 'low' state. This is an integral part of the LCD's
operation, as without it, the LCD will refuse to function correctly and will display incorrect characters. After
having composed these read and write subroutines, the initialisation routine was ready to be produced, as shown
below.
10
It would have been possible to implement the LCD in 8-bit mode, however this would require an entire port of
the PIC to be dedicated to only the data lines of the LCD. This would prove rather costly for the system's
implementation, as we only had 3 peripheral registers to work with (PORTA, PORTB and PORTC), each with
exactly 8 ports. To account for this, it was decided that the system would be implemented in 4-bit mode, with
each write operation being performed two nibbles at a time in order to transfer an entire instruction to the
module. This is shown by the 'write_init' and 'write_char', detailing the switching of the nibbles in the original
instruction; moving the least significant nibble first to the LCD, followed by the most significant, which in two
cycles allows for the LCD to be given the entire instruction set. This involves the use of a temporary register
'write_reg', which stores the original nibble pattern before swapping them and placing each in the 'W' register,
with the busy flag being checked between each nibble operation.
Having completed the necessary subroutines with which to read and write both characters and data to the
module, it was essential to account for the very limited user interface. With this particular module, the Samsung
KS0066U, certain regions of memory could be written to but not displayed on screen. This called for the
manipulation of the DDRAM addresses inside the LCD, which was the driver memory storing the characters
which were to be displayed. This resulted in the screen functioning as two separate halves, with one ranging from
DDRAM addresses 0 to 7, and the other ranging from DDRAM addresses 40 to 47. A counter was implemented
that would decrement once every time a character was written to the LCD, and upon having crossed to the
second half, peripheral counters were used to ensure that the information displayed onscreen did not push past
DDRAM address 47. In conjunction, the 'clearscreen' function in Figure 7.4 was used when the sixteen character
limit was reached, with the DDRAM counter being reset to its initial decimal value of '8'. By doing so, all
characters were able to be displayed perfectly on screen without any syntax errors or breaks in the printed string.
3.4 GPS
The EUSART on-board the PIC16F886 transmits and receives data using the standard non-return-to-zero (NRZ)
format. NRZ implies that consecutively transmitted data bits of the same value stay at the output level of that bit
without returning to a neutral level between each bit transmission; in other words, an NRZ transmission port
idles in the mark state. Each character transmission consists of one 'start' bit followed by 8 or 9 data bits and is
always terminated by one or more 'stop' bits. The 'start' bit is always a space, and the 'stop' bits are always marks,
11
with the most common data format being 8 bits. The EUSART transmits and receives the LSB first, with the
transmitter and receiver being functionally independent, however sharing the same data format and baud rate.
Moving the decimal value of '25' into the SPBRG register sets the baud rate to 9600bps, meaning that the onboard EUSART would be able to transmit one bit at a time at a speed of 9600 bits per second; a method of
communication also referred to as TTL serial communication. For the EUSART receiver to be enabled, the
following three control bits must be set like so:
All other EUSART control bits are assumed to be in their default state.
The EUSART on-board the PIC already has an in-built busy flag, indicating whether a byte has already been
stored in the buffer that is ready to be used. This flag, called the RCIF flag, must be set before the controller is
able to read the data from the RX port. After determining if the RCIF flag has been set, it is necessary to check
for any framing or over-run errors. A framing error indicates that a stop bit was not seen at the expected time,
and is accessed via the frame error (FERR) bit of the RCSTA register. Without either start or stop bit present,
the microprocessor would not be able to determine which byte the current information being read belongs to.
The over-run error occurs when the RX port is not being accessed and the buffer that stores the incoming string
becomes saturated and unable to hold any more data. However, handling these error checks are extremely
simple, and only involves resetting or moving the appropriate bits as seen in Figure 7.4, namely the CREN bits
and the RCREG register.
As the project brief required that the user be able to display their current latitude and longitude, it was necessary
to filter out the required strings from the stream of data provided by the GPS module. It was decided that in
order to store, display and refresh the user's current global coordinates, the '$GPRMC' string had to be obtained
from the output stream of the GPS, as this particular NMEA (National Marine Electronics Association) sentence
provided the time, fix status, latitude, longitude, ground speed, tracking angle and date. In regards to this
system, it was only the time, fix status, latitude and longitude that were of interest to us.
12
and write from the stored strings would prove inefficient and nearly as program intensive as simply reading from
the GPRs.
3.5.2 Waypoints
The method with which the user would set their desired waypoints worked similarly to the method used to store
the data obtained from the GPS, except that the data was now inputted via the keypad, with the ASCII value of
the key being printed to the LCD screen.
Having to account for three separate locations, the waypoints definitely consumed the most amount of memory,
with seventy-five general purpose registers being set aside; twenty-five of the registers dedicated to each
waypoint. Only twenty-five registers were needed for each waypoint as the periods and commas were both
ignored during the storage of the users inputted data. For optimum coding efficiency, the current GPS
coordinates were stored on the first bank of program memory, with the entire GPRs of the waypoints residing in
the second. Throughout the development of the final design, the 2048 line program memory threshold was never
crossed, and as such, neither of the PAGESELLING or BANKSELLING ASM commands was needed when
storing the users input into the relevant GPRs. This also resulted in not having to use relocatable code, with the
ASM file able to be compiled as an absolute form of code without requiring any sibling header files with which to
function.
Considering the amount of time required to perform the waypoint checking function (which could take up to an
entire second to perform), it was decided not to use the LCD to prompt the user whether they had arrived at a
particular waypoint. Instead, three 20mA blue LEDs would be used to signal the user's presence at a particular
13
waypoint. If the user was present at a waypoint during the specified time, the LED for that waypoint would turn
off. However, when not present, the LED would turn on. Albeit simple, this form of signalling was chosen so as
to improve the functionality of the system while executing the waypoint checking operation. This was done as
once the desired time had been reached, the checking function would perform extensive tests to determine the
position of the GPS compared to the waypoint. As seen in the flowchart of Figure 7.3 in the Appendix, the
number of subprograms to be executed was rather extensive, and the amount of time required was lengthy
compared to other executed routines. This would result in a considerable delay between the LCD interface and
the user. This implied that if the LCD were to display a message for each waypoint, the user would be locked out
of using the system for a full sixty seconds given the worst case scenario that all three waypoints were set to the
same time. The LCD would consistently display whether the user was at these three waypoints and would
interrupt any previous tasks the user was performing. The use of LEDs as a signal for waypoint checking allowed
the user to still interface with the system while it performed the automatic waypoint check once every eight
seconds, improving user functionality and ultimately the user experience. With one LED per waypoint, this
would prove sufficient in satisfying the design criteria.
Having visited the three locations B617, B616A and B421, the data obtained was tabulated and compared to the
survey coordinates provided. The data was obtained by positioning the antennae of the GPS module over the
golden bolts planted along the walkway of UNSW, with six readings taken from each of the locations B617,
B616A and B421. As will be discussed in section 5.2: Positional accuracies, these values were compared to
the coordinates provided by the UNSW School of Surveying, and would allow for the accuracy of the GPS
readings to be determined; with Table 4.1 below displaying the results.
Throughout the development and construction of the final design, many challenges were faced with the number
of goals to satisfy steadily increasing as the project progressed. This primarily came in the form of software, due
to the almost limitless ways of implementing the system, and also in regards to allowing the design meet the
criteria imposed by the results of the analyses. This section will discuss the various problems which were
encountered during the implementation of the final design and the analyses performed in order to produce a fully
functioning system.
14
At times, these fluctuations would induce a roll-over that would be necessary to consider if the user were to
accurately determine if they were at their waypoint. To account for this, a rounding function was implemented
so as to provide the user with some leeway when it came to comparing their current GPS coordinates with those
of the waypoints. It was determined that the best form of rounding would be to check the user's position within
a 36 metre grid-span in both the latitude and longitude direction. This was done by discarding the final two digits
of the latitude and longitude coordinates and by incrementing and decrementing the tens of milli-minutes;
effectively adding +/-1 to the current latitude and longitude readings provided by the GPS. By cross referencing
each set of coordinates with those stored for the waypoint, this would ensure that the users position was accurate
up to 18 metres in either positive or negative direction of latitude and longitude, improving the functionality of
the system and its usability when becoming mobile.
15
CONCLUSION
The project was a success as it was able to meet all relevant criterions provided by the design proposal and
resulted in a greater understanding regarding the functional aspects of microcontrollers. A deeper knowledge of
lower-level assembly language was also obtained through this interfacing of hardware of software and the
fundamentals of machine language and instruction sets.
16
APPENDIX
Figure 7.2: Time characteristics when reading data from the LCD
17
19
20
21
22
list
p=16f886
#include <p16f886.inc>
__CONFIG
_CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF
& _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG
_CONFIG2, _WRT_OFF & _BOR21V
cblock
0x020
COUNTERL
COUNTERH
INDEX
d1
d2
d3
write_reg
address_count
read_status
valid
EUSART_count
display_reg
count
store
WP_count
endc
w_temp EQU
status_temp
pclath_temp
0x7D
EQU
EQU
string
fix
lat_D
lat_M
lat_O
lon_D
lon_M
lon_O
H'30'
H'3B'
H'3D'
H'42'
H'47'
H'49'
H'4F'
H'54'
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
0x7E
0x7F
WP_1_time
WP_1_lat_D
WP_1_lat_M
WP_1_lat_O
WP_1_lon_D
WP_1_lon_M
WP_1_lon_O
EQU
EQU
EQU
EQU
EQU
EQU
EQU
H'A0'
H'A6'
H'AA'
H'AE'
H'AF'
H'B4'
H'B8'
WP_2_time
WP_2_lat_D
WP_2_lat_M
WP_2_lat_O
WP_2_lon_D
WP_2_lon_M
WP_2_lon_O
EQU
EQU
EQU
EQU
EQU
EQU
EQU
H'B9'
H'BF'
H'C3'
H'C7'
H'C8'
H'CD'
H'D1'
WP_3_time
WP_3_lat_D
WP_3_lat_M
EQU
EQU
EQU
H'D2'
H'D8'
H'DC'
23
WP_3_lat_O
WP_3_lon_D
WP_3_lon_M
WP_3_lon_O
EQU
EQU
EQU
EQU
H'E0'
H'E1'
H'E6'
H'EA'
WP_loop EQU
key_output
remove_count
keypad_xor
interf_delay1
interf_delay2
comp_reg
comp_count
comp_WP
comp_GPS
comp_WP_no
check_count
check_count2
temp_FSR
lon_looknice
round_reg
round_reg1
round_reg2
round_reg3
H'57'
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
H'58'
H'59'
H'5A'
H'5B'
H'5C'
H'5D'
H'5E'
H'5F'
H'60'
H'61'
H'62'
H'63'
H'64'
H'65'
H'66'
H'67'
H'68'
H'69'
;**********************************************************************
ORG
0x000 ; processor reset vector
nop
goto
main
; go to beginning of program
ORG
0x004
movwf
movf
movwf
movf
movwf
pclath_temp,w
; retrieve copy of PCLATH register
PCLATH ; restore pre-isr PCLATH register contents
status_temp,w
; retrieve copy of STATUS register
STATUS ; restore pre-isr STATUS register contents
w_temp,f
w_temp,w
; restore pre-isr W register contents
; return from interrupt
main
BANKSEL
ANSEL
clrf
ANSEL
clrf
ANSELH
BANKSEL
TRISA
movlw B'00001111'
movwf TRISA
clrf
TRISB
clrf
TRISC
24
clrf
TRISC
BANKSEL
PORTC
clrf
PORTC
clrf
write_reg
clrf
read_status
clrf
address_count
clrf
valid
clrf
EUSART_count
clrf
display_reg
clrf
count
clrf
store
clrf
WP_count
clrf
WP_loop
clrf
key_output
clrf
remove_count
clrf
keypad_xor
clrf
interf_delay1
clrf
interf_delay2
clrf
comp_reg
clrf
comp_count
clrf
comp_WP
clrf
comp_GPS
clrf
comp_WP_no
clrf
check_count
clrf
check_count2
clrf
temp_FSR
clrf
lon_looknice
movlw
movwf
movlw
movwf
movlw
movwf
D'8'
address_count
D'1'
check_count
D'1'
check_count2
LCD_initial
delay_150
goto
GPS
;------------------------------------------------------------------------;
INITIALISE MENU
;------------------------------------------------------------------------GPS
25
call
menu
goto
menu_nav
;------------------------------------------------------------------------;
KEYPAD FUNCTIONS
;------------------------------------------------------------------------check_count2_reset
movlw D'255'
movwf check_count2
check_count_reset
movlw D'255'
movwf check_count
goto
keyscan
keypad_input
decfsz check_count,1
goto
keyscan
decfsz check_count2,1
goto
check_count_reset
bsf
PORTC,4
movf
FSR,0
movwf temp_FSR
call
coord_read_time
call
check_valid
movf
temp_FSR,0
movwf FSR
bcf
PORTC,4
goto
check_count2_reset
keyscan
bsf
STATUS,0
movlw B'01111111'
movwf store
movlw D'04'
movwf count
rowscan movf
movwf
movf
nop
xorwf
movwf
btfss
goto
rrf
decfsz
goto
clrf
return
keypad_release
movf
movwf
movf
nop
xorwf
btfsc
goto
goto
store,0
PORTA
PORTA,0
store,0
keypad_xor
STATUS,2
keypad_release
store,1
count,1
rowscan
key_output
store,0
PORTA
PORTA,0
store,0
STATUS,2
setchar
keypad_release
setchar
movf
count,0
26
addwf
nop
goto
goto
goto
goto
PCL,1
count1
btfsc
call
btfsc
call
btfsc
call
btfsc
call
return
keypad_xor,0
store_1
keypad_xor,1
store_2
keypad_xor,2
store_3
keypad_xor,3
store_F
count2
btfsc
call
btfsc
call
btfsc
call
btfsc
call
return
keypad_xor,0
store_4
keypad_xor,1
store_5
keypad_xor,2
store_6
keypad_xor,3
store_E
count3
btfsc
call
btfsc
call
btfsc
call
btfsc
call
return
keypad_xor,0
store_7
keypad_xor,1
store_8
keypad_xor,2
store_9
keypad_xor,3
store_D
count4
btfsc
call
btfsc
call
btfsc
call
btfsc
call
return
keypad_xor,0
store_A
keypad_xor,1
store_0
keypad_xor,2
store_B
keypad_xor,3
store_C
movlw
movwf
return
'1'
key_output
movlw
movwf
return
'2'
key_output
movlw
movwf
return
'3'
key_output
count1
count2
count3
count4
store_1
store_2
store_3
27
store_4
movlw
movwf
return
'4'
key_output
movlw
movwf
return
'5'
key_output
movlw
movwf
return
'6'
key_output
movlw
movwf
return
'7'
key_output
movlw
movwf
return
'8'
key_output
movlw
movwf
return
'9'
key_output
movlw
movwf
return
'0'
key_output
movlw
movwf
return
'A'
key_output
movlw
movwf
return
'B'
key_output
movlw
movwf
return
'C'
key_output
movlw
movwf
return
'D'
key_output
movlw
movwf
return
'E'
key_output
store_5
store_6
store_7
store_8
store_9
store_0
store_A
store_B
store_C
store_D
store_E
store_F
movlw 'F'
movwf key_output
return
;------------------------------------------------------------------------;
MAIN MENU
;------------------------------------------------------------------------menu_nav
call
keypad_input
movlw
'0'
28
xorwf
btfsc
call
movlw
xorwf
btfsc
call
movlw
xorwf
btfsc
call
movlw
xorwf
btfsc
call
movlw
xorwf
btfsc
call
movlw
xorwf
btfsc
call
movlw
xorwf
btfsc
call
key_output,0
STATUS,2
print_time
'B'
key_output,0
STATUS,2
print_latitude
'C'
key_output,0
STATUS,2
print_longitude
'F'
key_output,0
STATUS,2
add_WP1
'E'
key_output,0
STATUS,2
add_WP2
'D'
key_output,0
STATUS,2
add_WP3
'A'
key_output,0
STATUS,2
remove_WP
goto
menu_nav
add_WP1
call
add_WP1_loop
call
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
goto
insert_WP1
movlw
movwf
goto
add_WP2
call
add_WP2_loop
call
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
double_check_WP1
keypad_input
'2'
key_output,0
STATUS,2
GPS
'1'
key_output,0
STATUS,2
insert_WP1
add_WP1_loop
WP_1_time
FSR
waypoint_add
double_check_WP2
keypad_input
'2'
key_output,0
STATUS,2
GPS
'1'
key_output,0
STATUS,2
29
goto
goto
insert_WP2
movlw
movwf
goto
add_WP3
call
add_WP3_loop
call
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
goto
insert_WP3
movlw
movwf
goto
insert_WP2
add_WP2_loop
WP_2_time
FSR
waypoint_add
double_check_WP3
keypad_input
'2'
key_output,0
STATUS,2
GPS
'1'
key_output,0
STATUS,2
insert_WP3
add_WP3_loop
WP_3_time
FSR
waypoint_add
double_check_WP1
call
clearscreen
call
delay_150
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
'A'
write_char
'd'
write_char
'd'
write_char
''
write_char
'W'
write_char
'P'
write_char
'1'
write_char
'?'
write_char
''
write_char
'Y'
write_char
'/'
write_char
'N'
write_char
'~'
write_char
'1'
write_char
'/'
write_char
30
movlw
call
'2'
write_char
return
double_check_WP2
call
clearscreen
call
delay_150
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
'A'
write_char
'd'
write_char
'd'
write_char
''
write_char
'W'
write_char
'P'
write_char
'2'
write_char
'?'
write_char
''
write_char
'Y'
write_char
'/'
write_char
'N'
write_char
'~'
write_char
'1'
write_char
'/'
write_char
'2'
write_char
return
double_check_WP3
call
clearscreen
call
delay_150
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
'A'
write_char
'd'
write_char
'd'
write_char
''
write_char
'W'
write_char
'P'
31
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
write_char
'3'
write_char
'?'
write_char
''
write_char
'Y'
write_char
'/'
write_char
'N'
write_char
'~'
write_char
'1'
write_char
'/'
write_char
'2'
write_char
return
remove_WP
call
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
clearscreen
delay_150
'E'
write_char
'r'
write_char
'a'
write_char
's'
write_char
'e'
write_char
''
write_char
'W'
write_char
'P'
write_char
''
write_char
'1'
write_char
'|'
write_char
'2'
write_char
'|'
write_char
'3'
write_char
'|'
write_char
'F'
32
call
remove_loop
call
write_char
keypad_input
movlw
xorwf
btfsc
call
movlw
xorwf
btfsc
call
movlw
xorwf
btfsc
call
movlw
xorwf
btfsc
goto
'1'
key_output,0
STATUS,2
remove_WP_1
'2'
key_output,0
STATUS,2
remove_WP_2
'3'
key_output,0
STATUS,2
remove_WP_3
'F'
key_output,0
STATUS,2
GPS
goto
remove_loop
remove_WP_1
movlw
movwf
movlw
movwf
call
goto
remove_WP_2
movlw
movwf
movlw
movwf
call
goto
remove_WP_3
movlw
movwf
movlw
movwf
call
goto
'1'
key_output
WP_1_time
FSR
remove_time
remove_message
'2'
key_output
WP_2_time
FSR
remove_time
remove_message
'3'
key_output
WP_3_time
FSR
remove_time
remove_message
remove_time
movlw D'6'
movwf remove_count
remove_loop_time
movlw '.'
movwf INDF
incf
FSR,1
decfsz remove_count,1
goto
remove_loop_time
remove_lat
movlw D'9'
movwf remove_count
remove_loop_lat
33
movlw
movwf
incf
decfsz
goto
remove_lon
movlw
movwf
remove_loop_lon
movlw
movwf
incf
decfsz
goto
return
'.'
INDF
FSR,1
remove_count,1
remove_loop_lat
D'10'
remove_count
'.'
INDF
FSR,1
remove_count,1
remove_loop_lon
remove_message
call
clearscreen
call
delay_150
movlw
call
movlw
call
movlw
call
movf
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
'W'
write_char
'P'
write_char
''
write_char
key_output,W
write_char
''
write_char
'n'
write_char
'o'
write_char
'w'
write_char
''
write_char
'r'
write_char
'e'
write_char
'm'
write_char
'o'
write_char
'v'
write_char
'e'
write_char
'd'
write_char
call
goto
delay_2
GPS
;------------------------------------------------------------------------;
UART FUNCTIONS
;-------------------------------------------------------------------------
34
overrun_error
BANKSEL
RCSTA
bcf
RCSTA,CREN
bsf
RCSTA,CREN
goto
RX
frame_error
BANKSEL
RCSTA
movf
RCREG,W
goto
RX
RX
BANKSEL
PIR1
btfss
PIR1,RCIF
goto
RX
BANKSEL
RCSTA
btfsc
RCSTA,FERR
goto
frame_error
btfsc
RCSTA,OERR
goto
overrun_error
BANKSEL
RCREG
movf
RCREG,W
BANKSEL
PORTA
return
coord_read
call
xorlw
btfss
goto
call
xorlw
btfss
goto
call
xorlw
btfss
goto
call
xorlw
btfss
goto
call
xorlw
btfss
goto
call
xorlw
btfss
goto
call
xorlw
btfss
goto
movlw
movwf
call
RX
'$'
STATUS,2
coord_read
RX
'G'
STATUS,2
coord_read
RX
'P'
STATUS,2
coord_read
RX
'R'
STATUS,2
coord_read
RX
'M'
STATUS,2
coord_read
RX
'C'
STATUS,2
coord_read
RX
','
STATUS,2
coord_read
D'37'
EUSART_count
store_EUSART
35
call
return
time_fix
movlw
movwf
movf
xorlw
btfss
goto
return
fix
FSR
INDF,W
'A'
STATUS,2
no_fix
movlw
movwf
btfsc
goto
btfsc
goto
incf
return
string
FSR
INDF,0
time_case_1
INDF,1
time_case_2
INDF,1
fix_check
time_fix
time_case_1
incf
btfsc
goto
btfsc
goto
decf
incf
return
FSR,1
INDF,2
time_case_1_4
INDF,3
time_case_1_4
FSR,1
INDF,1
time_case_1_4
decf
decf
decf
decf
decf
decf
INDF,1
INDF,1
INDF,1
INDF,1
FSR,1
INDF,1
return
time_case_2
decf
decf
incf
incf
incf
incf
incf
incf
incf
INDF,1
INDF,1
FSR,1
INDF,1
INDF,1
INDF,1
INDF,1
INDF,1
INDF,1
;Add 6 hours
return
print_time
call
call
movlw
clearscreen
delay_150
'T'
36
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
time_loop_1
movlw
movwf
time_loop_2
movwf
time_loop_3
call
movlw
xorwf
btfsc
goto
decfsz
goto
decfsz
goto
call
movlw
call
movlw
movwf
movlw
movwf
loop_time_hour
call
incf
decfsz
goto
movlw
call
movlw
movwf
loop_time_min
call
incf
decfsz
goto
movlw
call
movlw
write_char
'i'
write_char
'm'
write_char
'e'
write_char
':'
write_char
''
write_char
''
write_char
''
write_char
D'37'
interf_delay1
movlw D'255'
interf_delay2
keypad_input
'F'
key_output,0
STATUS,2
GPS
interf_delay2,1
time_loop_3
interf_delay1,1
time_loop_2
coord_read
B'10101000'
write_init
string
FSR
D'2'
display_reg
movf
INDF,W
write_char
FSR,1
display_reg,1
loop_time_hour
':'
write_char
D'2'
display_reg
movf
INDF,W
write_char
FSR,1
display_reg,1
loop_time_min
':'
write_char
D'2'
37
movwf
loop_time_sec
call
incf
decfsz
goto
goto
display_reg
movf
INDF,W
write_char
FSR,1
display_reg,1
loop_time_sec
time_loop_1
print_latitude
call
call
clearscreen
delay_150
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
'L'
write_char
'A'
write_char
'T'
write_char
':'
write_char
''
write_char
lat_reset
call
call
movlw
movwf
movlw
movwf
loop_lat movf
call
incf
decfsz
goto
coord_read
fix_check
lat_D
FSR
D'11'
display_reg
INDF,W
write_char
FSR,1
display_reg,1
loop_lat
lat_loop_1
movlw
movwf
D'100'
interf_delay1
lat_loop_2
movwf
lat_loop_3
call
movlw
xorwf
btfsc
goto
decfsz
goto
decfsz
goto
movlw D'255'
interf_delay2
keypad_input
'F'
key_output,0
STATUS,2
GPS
interf_delay2,1
lat_loop_3
interf_delay1,1
lat_loop_2
movlw
call
movlw
movwf
B'10000101'
write_init
D'3'
address_count
goto
lat_reset
38
print_longitude
call
call
bsf
movlw
call
movlw
call
movlw
call
movlw
call
clearscreen
delay_150
lon_looknice,0
'L'
write_char
'O'
write_char
'N'
write_char
':'
write_char
lon_reset
call
call
movlw
movwf
movlw
movwf
loop_lon movf
call
incf
decfsz
goto
coord_read
fix_check
lon_D
FSR
D'12'
display_reg
INDF,W
write_char
FSR,1
display_reg,1
loop_lon
lon_loop_1
movlw
movwf
D'100'
interf_delay1
lon_loop_2
movwf
lon_loop_3
call
movlw
xorwf
btfsc
goto
decfsz
goto
decfsz
goto
movlw D'255'
interf_delay2
keypad_input
'F'
key_output,0
STATUS,2
GPS
interf_delay2,1
lon_loop_3
interf_delay1,1
lon_loop_2
movlw
call
movlw
movwf
B'10000100'
write_init
D'4'
address_count
goto
lon_reset
store_EUSART
movlw string
movwf FSR
store_EUSART_loop
call
RX
movwf INDF
incf
FSR,1
39
decfsz
goto
return
EUSART_count,1
store_EUSART_loop
btfsc
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
lon_looknice,0
move
'N'
write_char
'o'
write_char
''
write_char
'f'
write_char
'i'
write_char
'x'
write_char
'.'
write_char
'.'
write_char
'.'
write_char
clrf
call
call
lon_looknice
delay_2
delay_2
goto
GPS
call
decf
return
increment_cursor
address_count,1
no_fix
move
;------------------------------------------------------------------------;
LCD FUNCTIONS
;------------------------------------------------------------------------LCD_initial
call
delay_150
movlw b'00000011'
call
write_op
call
delay_10
movlw b'00000011'
call
write_op
call
delay_10
movlw b'00000011'
call
write_op
call
delay_10
movlw b'00000010'
call
write_init
movlw b'01001000'
call
write_init
movlw b'00001000'
call
write_init
movlw b'00001100'
call
write_init
40
movlw
call
movlw
call
movlw
call
b'00000110'
write_init
b'00000001'
write_init
b'00001100'
write_init
call
call
clearscreen
delay_150
return
clearscreen
movlw
call
movlw
movwf
return
b'00000001'
write_init
D'8'
address_count
menu
call
call
clearscreen
delay_150
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
'|'
write_char
'A'
write_char
'-'
write_char
'O'
write_char
'-'
write_char
'B'
write_char
'-'
write_char
'C'
write_char
'|'
write_char
'|'
write_char
'F'
write_char
'-'
write_char
'E'
write_char
'-'
write_char
'D'
write_char
'|'
write_char
return
write_init
41
movwf
swapf
call
call
write_reg
write_reg,W
write_op
busy_check
movf
call
call
return
write_reg,W
write_op
busy_check
write_reg
write_reg,W
write_MSB_LSB
busy_check
movf
call
call
write_reg,W
write_MSB_LSB
busy_check
call
return
LCD_check
LCD_check
decfsz
return
call
return
DDRAM_change
movlw
call
call
return
address_count,1
DDRAM_change
B'10101000'
write_init
delay_10
42
read_op
BANKSEL
TRISB
movlw B'00001111'
movwf TRISB
BANKSEL
PORTB
bcf
bsf
nop
bsf
nop
movf
movwf
PORTB,5 ;RS is 0
PORTB,4 ;R/W is 1
bcf
bcf
bcf
PORTC,3 ;enable is on
PORTB,W
read_status
BANKSEL
clrf
TRISB
BANKSEL
return
busy_check
call
btfsc
goto
return
TRISB
PORTC
read_op
read_status,3
busy_check
;------------------------------------------------------------------------;
WAYPOINTS
;------------------------------------------------------------------------waypoint_add
movlw B'00001111'
call
write_init
call
call
clearscreen
delay_150
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
'T'
write_char
'i'
write_char
'm'
write_char
'e'
write_char
':'
write_char
''
write_char
''
write_char
''
write_char
movlw
call
movlw
B'10101000'
write_init
'H'
43
call
movlw
call
call
movlw
call
movlw
call
call
movlw
call
movlw
call
write_char
'H'
write_char
increment_cursor
'M'
write_char
'M'
write_char
increment_cursor
'S'
write_char
'S'
write_char
movlw
call
movlw
call
call
call
movlw
call
movlw
call
B'10101010'
write_init
':'
write_char
increment_cursor
increment_cursor
':'
write_char
B'10101000'
write_init
movlw D'3'
movwf WP_loop
waypoint_time
movlw D'2'
movwf WP_count
waypoint_loop_time
call
WP_set_keypad
decfsz WP_count,1
goto
waypoint_loop_time
call
increment_cursor
decfsz WP_loop,1
goto
waypoint_time
call
call
call
call
call
call
delay_150
delay_150
delay_150
delay_150
clearscreen
delay_150
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
'L'
write_char
'A'
write_char
'T'
write_char
':'
write_char
''
write_char
movlw
D'3'
44
movwf
movlw
call
movlw
call
movlw
call
movlw
call
call
movlw
call
movlw
call
movlw
call
movlw
call
call
movlw
call
address_count
'-'
write_char
'-'
write_char
'-'
write_char
'-'
write_char
increment_cursor
'-'
write_char
'-'
write_char
'-'
write_char
'-'
write_char
increment_cursor
'-'
write_char
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
movwf
B'10101001'
write_init
'.'
write_char
B'10101110'
write_init
','
write_char
B'10000101'
write_init
D'3'
address_count
movlw
movwf
waypoint_lat
movlw
movwf
waypoint_loop_lat
call
decfsz
goto
call
decfsz
goto
call
D'2'
WP_loop
D'4'
WP_count
WP_set_keypad
WP_count,1
waypoint_loop_lat
increment_cursor
WP_loop,1
waypoint_lat
WP_set_keypad
call
call
call
call
call
call
delay_150
delay_150
delay_150
delay_150
clearscreen
delay_150
movlw
call
movlw
'L'
write_char
'O'
45
call
movlw
call
movlw
call
write_char
'N'
write_char
':'
write_char
movlw
movwf
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
call
movlw
call
movlw
call
movlw
call
movlw
call
call
movlw
call
D'4'
address_count
'-'
write_char
'-'
write_char
'-'
write_char
'-'
write_char
'-'
write_char
increment_cursor
'-'
write_char
'-'
write_char
'-'
write_char
'-'
write_char
increment_cursor
'-'
write_char
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
movwf
B'10101001'
write_init
'.'
write_char
B'10101110'
write_init
','
write_char
B'10000100'
write_init
D'4'
address_count
movlw D'5'
movwf WP_count
waypoint_loop_lon_1
call
WP_set_keypad
decfsz WP_count,1
goto
waypoint_loop_lon_1
call
increment_cursor
movlw
movwf
D'4'
WP_count
waypoint_loop_lon_2
call
WP_set_keypad
decfsz WP_count,1
goto
waypoint_loop_lon_2
46
call
call
increment_cursor
WP_set_keypad
goto
saved
call
call
call
call
call
call
delay_150
delay_150
delay_150
delay_150
clearscreen
delay_150
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
''
write_char
''
write_char
''
write_char
''
write_char
''
write_char
'S'
write_char
'a'
write_char
'v'
write_char
'e'
write_char
'd'
write_char
''
write_char
''
write_char
''
write_char
''
write_char
''
write_char
''
write_char
call
delay_2
movlw
call
B'00001100'
write_init
goto
GPS
saved
increment_cursor
movlw B'00010100'
call
write_init
return
WP_set_keypad
47
call
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movlw
xorwf
keypad_input
'0'
key_output,0
STATUS,2
WP_set_keypad2
'1'
key_output,0
STATUS,2
WP_set_keypad2
'2'
key_output,0
STATUS,2
WP_set_keypad2
'3'
key_output,0
STATUS,2
WP_set_keypad2
'4'
key_output,0
STATUS,2
WP_set_keypad2
'5'
key_output,0
STATUS,2
WP_set_keypad2
'6'
key_output,0
STATUS,2
WP_set_keypad2
'7'
key_output,0
STATUS,2
WP_set_keypad2
'8'
key_output,0
STATUS,2
WP_set_keypad2
'9'
key_output,0
STATUS,2
WP_set_keypad2
'A'
key_output,0
STATUS,2
WP_set_keypadN
'B'
key_output,0
STATUS,2
WP_set_keypadS
'C'
key_output,0
STATUS,2
WP_set_keypadE
'D'
key_output,0
STATUS,2
WP_set_keypadW
'F'
key_output,0
48
btfsc
goto
STATUS,2
WP_set_keypadF
goto
WP_set_keypad
WP_set_keypad2
movf
movwf
call
incf
return
WP_set_keypadN
movlw
movwf
call
incf
return
WP_set_keypadS
movlw
movwf
call
incf
return
WP_set_keypadE
movlw
movwf
call
incf
return
WP_set_keypadW
movlw
movwf
call
incf
return
WP_set_keypadF
movlw
call
goto
key_output,0
INDF
write_char
FSR,1
'N'
INDF
write_char
FSR,1
'S'
INDF
write_char
FSR,1
'E'
INDF
write_char
FSR,1
'W'
INDF
write_char
FSR,1
B'00001100'
write_init
GPS
;------------------------------------------------------------------------;
WAYPOINT CHECKING
;------------------------------------------------------------------------coord_read_time
call
RX
xorlw
'$'
btfss
STATUS,2
goto
coord_read_time
call
RX
xorlw
'G'
btfss
STATUS,2
goto
coord_read_time
call
RX
xorlw
'P'
btfss
STATUS,2
goto
coord_read_time
call
RX
xorlw
'R'
btfss
STATUS,2
49
goto
call
xorlw
btfss
goto
call
xorlw
btfss
goto
call
xorlw
btfss
goto
movlw
movwf
call
call
return
compare_general
movf
incf
movwf
movf
movwf
movf
incf
movwf
movf
return
check_valid
movlw
movwf
movf
xorlw
btfss
goto
bcf
check_time
movlw
movwf
movlw
movwf
call
movlw
movwf
movlw
movwf
call
movlw
movwf
movlw
movwf
call
return
compare_time
movlw
coord_read_time
RX
'M'
STATUS,2
coord_read_time
RX
'C'
STATUS,2
coord_read_time
RX
','
STATUS,2
coord_read_time
D'12'
EUSART_count
store_EUSART
time_fix
comp_WP,0
comp_WP,1
FSR
INDF,0
comp_reg
comp_GPS,0
comp_GPS,1
FSR
INDF,0
fix
FSR
INDF,0
'A'
STATUS,2
no_valid
PORTC,5
WP_1_time
comp_WP
'1'
comp_WP_no
compare_time
WP_2_time
comp_WP
'2'
comp_WP_no
compare_time
WP_3_time
comp_WP
'3'
comp_WP_no
compare_time
string
50
movwf comp_GPS
movlw D'4'
movwf comp_count
compare_time_loop
call
compare_general
xorwf
comp_reg,0
btfss
STATUS,2
goto
no_match
decfsz comp_count,1
goto
compare_time_loop
call
coord_read
incf
comp_WP,1
incf
comp_WP,1
compare_lat_D
movlw lat_D
movwf comp_GPS
movlw D'3'
movwf comp_count
compare_lat_D_loop
call
compare_general
xorwf
comp_reg,0
btfss
STATUS,2
goto
not_at_WP
decfsz comp_count,1
goto
compare_lat_D_loop
movf
movwf
movf
movwf
movlw
movwf
movf
movwf
incf
movf
movwf
lat_checking_00
movlw
xorwf
btfss
goto
movlw
xorwf
btfss
goto
movlw
xorwf
btfsc
goto
lat_up_check_01
movf
movwf
movf
xorwf
btfss
comp_GPS,0
FSR
INDF,0
round_reg3
lat_M
FSR
INDF,0
round_reg2
FSR,1
INDF,0
round_reg1
'0'
round_reg2,0
STATUS,2
lat_checking_99
'0'
round_reg1,0
STATUS,2
compare_lat_D_continue
'0'
round_reg3,0
STATUS,2
compare_lat_D_continue
comp_WP,0
FSR
INDF,0
round_reg3,0
STATUS,2
51
goto
lat_lower_check_99
lat_up_check_follow_on_01
incf
FSR,1
movf
INDF,0
xorlw
'0'
btfss
STATUS,2
goto
not_at_WP
incf
movf
xorlw
btfss
goto
movf
movwf
incf
incf
incf
goto
FSR,1
INDF,0
'1'
STATUS,2
lat_middle_check_00
FSR,0
comp_WP
comp_WP,1
comp_WP,1
comp_WP,1
compare_lat_O
lat_middle_check_00
movf
INDF,0
xorlw
'0'
btfss
STATUS,2
goto
not_at_WP
movf
FSR,0
movwf comp_WP
incf
comp_WP,1
incf
comp_WP,1
incf
comp_WP,1
goto
compare_lat_O
lat_lower_check_99
decf
round_reg3,1
movf
INDF,0
xorwf
round_reg3,0
btfss
STATUS,2
goto
not_at_WP
incf
FSR,1
movf
INDF,0
xorlw
'9'
btfss
STATUS,2
goto
not_at_WP
incf
FSR,1
movf
INDF,0
xorlw
'9'
btfss
STATUS,2
goto
not_at_WP
movf
FSR,0
movwf comp_WP
incf
comp_WP,1
incf
comp_WP,1
incf
comp_WP,1
goto
compare_lat_O
lat_checking_99
52
movlw '9'
xorwf
round_reg2,0
btfss
STATUS,2
goto
compare_lat_D_continue
movlw '9'
xorwf
round_reg1,0
btfss
STATUS,2
goto
compare_lat_D_continue
movlw '9'
xorwf
round_reg3,0
btfsc
STATUS,2
goto
compare_lat_D_continue
lat_up_check_00
movf
comp_WP,0
movwf FSR
movf
INDF,0
incf
round_reg3,1
xorwf
round_reg3,0
btfss
STATUS,2
goto
lat_middle_check_99
lat_up_check_follow_on_00
incf
FSR,1
movf
INDF,0
xorlw
'0'
btfss
STATUS,2
goto
not_at_WP
incf
movf
xorlw
btfss
goto
movf
movwf
incf
incf
incf
goto
FSR,1
INDF,0
'0'
STATUS,2
not_at_WP
FSR,0
comp_WP
comp_WP,1
comp_WP,1
comp_WP,1
compare_lat_O
lat_middle_check_99
movf
INDF,0
decf
round_reg3,1
xorwf
round_reg3,0
btfss
STATUS,2
goto
not_at_WP
incf
movf
xorlw
btfss
goto
FSR,1
INDF,0
'9'
STATUS,2
not_at_WP
incf
movf
xorlw
btfss
goto
movf
movwf
FSR,1
INDF,0
'9'
STATUS,2
lat_lower_check_98
FSR,0
comp_WP
53
incf
incf
incf
goto
comp_WP,1
comp_WP,1
comp_WP,1
compare_lat_O
lat_lower_check_98
movf
INDF,0
xorlw
'8'
btfss
STATUS,2
goto
not_at_WP
movf
FSR,0
movwf comp_WP
incf
comp_WP,1
incf
comp_WP,1
incf
comp_WP,1
goto
compare_lat_O
compare_lat_D_continue
movlw H'40'
movwf comp_GPS
call
compare_general
xorwf
comp_reg,0
btfss
STATUS,2
goto
not_at_WP
compare_lat_M_first
movlw lat_M
movwf comp_GPS
call
compare_general
xorwf
comp_reg,0
btfss
STATUS,2
goto
not_at_WP
compare_lat_M_second
call
compare_general
movwf round_reg
movlw '0'
xorwf
round_reg,0
btfsc
STATUS,2
goto
normal_lat_checking_function
movlw '9'
xorwf
round_reg,0
btfsc
STATUS,2
goto
normal_lat_checking_function
movf
round_reg,0
incf
round_reg,1
movf
round_reg,0
xorwf
comp_reg,0
btfsc
STATUS,2
goto
lat_M_round2
decf
round_reg,1
movf
round_reg,0
xorwf
comp_reg,0
btfsc
STATUS,2
goto
lat_M_round2
decf
round_reg,1
movf
round_reg,0
xorwf
comp_reg,0
btfsc
STATUS,2
goto
lat_M_round2
54
goto
not_at_WP
normal_lat_checking_function
movf
round_reg,0
xorwf
comp_reg,0
btfss
STATUS,2
goto
not_at_WP
lat_M_round2
incf
comp_WP,1
incf
comp_WP,1
compare_lat_O
movlw lat_O
movwf comp_GPS
call
compare_general
xorwf
comp_reg,0
btfss
STATUS,2
goto
not_at_WP
compare_lon_D
movlw lon_D
movwf comp_GPS
movlw D'4'
movwf comp_count
compare_lon_D_loop
call
compare_general
xorwf
comp_reg,0
btfss
STATUS,2
goto
not_at_WP
decfsz comp_count,1
goto
compare_lon_D_loop
movf
comp_GPS,0
movwf FSR
movf
INDF,0
movwf round_reg3
movlw lon_M
movwf FSR
movf
INDF,0
movwf round_reg2
incf
FSR,1
movf
INDF,0
movwf round_reg1
lon_checking_00
movlw '0'
xorwf
round_reg2,0
btfss
STATUS,2
goto
lon_checking_99
movlw '0'
xorwf
round_reg1,0
btfss
STATUS,2
goto
compare_lon_D_continue
movlw '0'
xorwf
round_reg3,0
btfsc
STATUS,2
goto
compare_lon_D_continue
lon_up_check_01
movf
comp_WP,0
55
movwf FSR
movf
INDF,0
xorwf
round_reg3,0
btfss
STATUS,2
goto
lon_lower_check_99
lon_up_check_follow_on_01
incf
FSR,1
movf
INDF,0
xorlw
'0'
btfss
STATUS,2
goto
not_at_WP
incf
movf
xorlw
btfss
goto
movf
movwf
incf
incf
incf
goto
FSR,1
INDF,0
'1'
STATUS,2
lon_middle_check_00
FSR,0
comp_WP
comp_WP,1
comp_WP,1
comp_WP,1
compare_lon_O
lon_middle_check_00
movf
INDF,0
xorlw
'0'
btfss
STATUS,2
goto
not_at_WP
movf
FSR,0
movwf comp_WP
incf
comp_WP,1
incf
comp_WP,1
incf
comp_WP,1
goto
compare_lon_O
lon_lower_check_99
decf
round_reg3,1
movf
INDF,0
xorwf
round_reg3,0
btfss
STATUS,2
goto
not_at_WP
incf
FSR,1
movf
INDF,0
xorlw
'9'
btfss
STATUS,2
goto
not_at_WP
incf
FSR,1
movf
INDF,0
xorlw
'9'
btfss
STATUS,2
goto
not_at_WP
movf
FSR,0
movwf comp_WP
incf
comp_WP,1
incf
comp_WP,1
incf
comp_WP,1
goto
compare_lon_O
56
lon_checking_99
movlw '9'
xorwf
round_reg2,0
btfss
STATUS,2
goto
compare_lon_D_continue
movlw '9'
xorwf
round_reg1,0
btfss
STATUS,2
goto
compare_lon_D_continue
movlw '9'
xorwf
round_reg3,0
btfsc
STATUS,2
goto
compare_lon_D_continue
lon_up_check_00
movf
comp_WP,0
movwf FSR
movf
INDF,0
incf
round_reg3,1
xorwf
round_reg3,0
btfss
STATUS,2
goto
lon_middle_check_99
lon_up_check_follow_on_00
incf
FSR,1
movf
INDF,0
xorlw
'0'
btfss
STATUS,2
goto
not_at_WP
incf
movf
xorlw
btfss
goto
movf
movwf
incf
incf
incf
goto
FSR,1
INDF,0
'0'
STATUS,2
not_at_WP
FSR,0
comp_WP
comp_WP,1
comp_WP,1
comp_WP,1
compare_lon_O
lon_middle_check_99
movf
INDF,0
decf
round_reg3,1
xorwf
round_reg3,0
btfss
STATUS,2
goto
not_at_WP
incf
movf
xorlw
btfss
goto
FSR,1
INDF,0
'9'
STATUS,2
not_at_WP
incf
movf
xorlw
btfss
goto
FSR,1
INDF,0
'9'
STATUS,2
lon_lower_check_98
57
movf
movwf
incf
incf
incf
goto
FSR,0
comp_WP
comp_WP,1
comp_WP,1
comp_WP,1
compare_lon_O
lon_lower_check_98
movf
INDF,0
xorlw
'8'
btfss
STATUS,2
goto
not_at_WP
movf
FSR,0
movwf comp_WP
incf
comp_WP,1
incf
comp_WP,1
incf
comp_WP,1
goto
compare_lon_O
compare_lon_D_continue
movlw H'4D'
movwf comp_GPS
call
compare_general
xorwf
comp_reg,0
btfss
STATUS,2
goto
not_at_WP
compare_lon_M_first
movlw
movwf
call
xorwf
btfss
goto
lon_M
comp_GPS
compare_general
comp_reg,0
STATUS,2
not_at_WP
compare_lon_M_second
call
movwf
movlw
xorwf
btfsc
goto
movlw
xorwf
btfsc
goto
movf
incf
movf
xorwf
btfsc
goto
decf
movf
xorwf
btfsc
goto
compare_general
round_reg
'0'
round_reg,0
STATUS,2
normal_lon_checking_function
'9'
round_reg,0
STATUS,2
normal_lon_checking_function
round_reg,0
round_reg,1
round_reg,0
comp_reg,0
STATUS,2
lon_M_round2
round_reg,1
round_reg,0
comp_reg,0
STATUS,2
lon_M_round2
58
decf
movf
xorwf
btfsc
goto
goto
round_reg,1
round_reg,0
comp_reg,0
STATUS,2
lon_M_round2
not_at_WP
normal_lon_checking_function
movf
round_reg,0
xorwf
comp_reg,0
btfss
STATUS,2
goto
not_at_WP
lon_M_round2
incf
comp_WP,1
incf
comp_WP,1
compare_lon_O
movlw lon_O
movwf comp_GPS
call
compare_general
xorwf
comp_reg,0
btfss
STATUS,2
goto
not_at_WP
at_WP
movlw
xorwf
btfsc
bcf
movlw
xorwf
btfsc
bcf
movlw
xorwf
btfsc
bcf
return
not_at_WP
movlw
xorwf
btfsc
bsf
movlw
xorwf
btfsc
bsf
movlw
xorwf
btfsc
bsf
return
no_match
movlw
xorwf
btfsc
bcf
movlw
'1'
comp_WP_no,0
STATUS,2
PORTC,2
'2'
comp_WP_no,0
STATUS,2
PORTC,1
'3'
comp_WP_no,0
STATUS,2
PORTC,0
'1'
comp_WP_no,0
STATUS,2
PORTC,2
'2'
comp_WP_no,0
STATUS,2
PORTC,1
'3'
comp_WP_no,0
STATUS,2
PORTC,0
'1'
comp_WP_no,0
STATUS,2
PORTC,2
'2'
59
xorwf
btfsc
bcf
movlw
xorwf
btfsc
bcf
return
comp_WP_no,0
STATUS,2
PORTC,1
'3'
comp_WP_no,0
STATUS,2
PORTC,0
bsf
return
PORTC,5
no_valid
;------------------------------------------------------------------------;
DELAYS
;------------------------------------------------------------------------delay_10
movlw 0xCE
movwf d1
movlw 0x08
movwf d2
delay_10_0
decfsz d1, f
goto
$+2
decfsz d2, f
goto
delay_10_0
goto
$+1
nop
return
delay_150
movlw 0x2E
movwf d1
movlw 0x76
movwf d2
delay_150_0
decfsz d1, f
goto
$+2
decfsz d2, f
goto
delay_150_0
goto
$+1
nop
return
delay_2
movlw
movwf
movlw
movwf
movlw
movwf
delay_2_0
decfsz
goto
decfsz
goto
decfsz
goto
return
0x11
d1
0x5D
d2
0x05
d3
d1, f
$+2
d2, f
$+2
d3, f
delay_2_0
60
;------------------------------------------------------------------------;
END
;------------------------------------------------------------------------END
61