You are on page 1of 206

Interfacing a GPS to an LCD using a Microcontroller

A. HENRICHSEN

Interfacing a GPS to an LCD using a Microcontroller


27/10/1998

Interfacing a GPS to an LCD using a Microcontroller


Prepared by: ¯ Arne Henrichsen, fourth-year student in the
Department of Electrical Engineering
at the University of Cape Town
Prepared for: ¯ The Department of Electrical Engineering
University of Cape Town

27/10/1998

This thesis is prepared in partial fulfillment of the requirements for the degree of BSc. in Electrical Engineering.

Acknowledgements
I would like to give my thanks to the following people for all their help and advice.
Mr G. Tattersfield, Department of Electrical Engineering, for his guidance as my thesis supervisor.
Mr J. Pinto, MSc. Student at the University of Cape Town, for his help with the Atmel Microcontroller.
Mr J. Salzwedel, Student at the University of Cape Town, for being a co-operative partner in sharing the GPS receiver, implementing the principles of the GPS and
the construction of the final GPS container.
And finally to the people at `Avnet Kopp', for lending us their copy of the Motorola GPS manual, and for donating the Motorola voltage regulator and Atmel
microcontroller free of charge.

Declaration
The work was my own, although this project could not have been accomplished without the help of the people mentioned in the Acknowledgements. The breakdown

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (1 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

of work on various aspects of the thesis is as follows:

Circuit Implementation
I received substantial help in the design of the external RAM for the microcontroller from Mr J. Pinto. I was responsible for the PCB layout using the program
Tango PCB and the testing of the circuit. The boards were produced by the `Electronics Supermarket' in Cape Town.

Design of the GPS box


The design and construction of the plastic box for the GPS circuitry was done by `Mr Plastic' from Montague Gardens.

Software Implementation
The C++ and assembly programs are my own, except for the help I received from Mr J. Pinto with the setting up of the RAM and ROM areas of the microcontroller.

Voltage Regulator
The voltage regulator used in the circuit was suggested by Mr N. Ballard from `Avnet Kopp'. The incorporation of the regulator into the circuit is entirely my own.

System Analysis
The final analysis of the GPS system is my own, as are the conlusions drawn.

Terms Of Reference
This Thesis was proposed by Mr G. Tattersfield, Programme Co-ordinator of Electro-Mechanical Engineering at the University of Cape Town. The briefing was
given on the 25 June 1998 and work commenced on the 13 July 1998.
Mr Tattersfield's specific instructions were:

1. To develop a hand-held GPS system using the following:


❍ The Motorola GPS Oncore Receiver

❍ A Liquid Crystal Display (LCD)

2. To investigate different microcontrollers and choose the most appropriate device to interface the GPS and LCD.
3. The system should be controlled by a small keyboard.
4. The GPS should be powered by a battery.
5. The hand-in date for the thesis is the 28 October 1998.

Synopsis

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (2 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

This thesis describes the investigation undertaken in implementing a hand-held Global Positioning System (GPS).

The objectives of this thesis were to use the Motorola Oncore GPS Receiver (Serial No. R3111G1111) in an embedded application and to build a user-friendly GPS
system, which would display all basic features of the GPS on a Liquid Crystal Display (LCD). A software based program would be controlled using a certain
number of keys, which would in turn operate and control the LCD and GPS.

The project was approached by first interfacing the GPS receiver to the PC via the serial port and the LCD to the PC via the parallel port. By studying the protocols
of the GPS and LCD, a program was implemented in C++. The next step in the design was to replace the PC using a suitable microcontroller. This microcontroller
was chosen to be the Atmel 89C55, as it had the necessary program memory and ports to substitute the PC. In order to program the Atmel chip, the already
implemented C++ code was converted into assembly language using a cross compiler. The final circuit was designed around the Atmel 89C55 chip.

In order to make the system more versatile, the user is able to switch between the microcontroller and the PC. This was achieved by providing an RS-232 connector,
which lets the GPS communicate with any computer. Power is provided by either a car battery or a `Gel' cell battery.

The major conclusions that could be drawn from the investigation are:

1. Most functions (position, status, data) could be implemented with the GPS and displayed on the LCD.
2. The use of the Atmel 89C55 microcontroller made the implementation of software and hardware easy as much help was available.
3. The system was succesfully tested and the layout of the keyboard and LCD made the system easy to use.

A GPS system was succesfully built and demonstrated. Since time was limited, some functions were not able to be implemented. Thus the following
recommendations can be made to improve the system:

1. Display the data obtained from the GPS graphically using the existing LCD, instead of using text as at present.
2. Implement the NMEA format for GPS data output using the RS-232 serial port.
3. Add non-volatile memory in order to store data from the GPS to be used later.
4. Display maps and plot the current position using a bigger colour screen/LCD.
5. Implement Differential GPS to get better position accuracies.

Glossary
BMP
- Bitmap Image
CG RAM
- Character Generator Random Access Memory
GPS

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (3 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

- Global Positioning System


LCD
- Liquid Crystal Display
NMEA
- National Marine Electronics Association
PC
- Personal Computer

Contents
1 Introduction
2 The Motorola Oncore GPS
2.1 Brief Description of GPS
2.2 Antenna Information
2.3 GPS Oncore Information
2.3.1 Electrical Specifications
2.3.2 The Serial Interface
2.4 Interface Protocol
2.4.1 Motorola Binary Format
2.4.2 Details of some Commands
2.5 NMEA Interface Standard
2.5.1 Brief Description of NMEA
2.5.2 Outline of Command Structure
3 The Graphics Liquid Crystal Display
3.1 Module Pin-out
3.2 Status Check
3.3 Setting the Cursor and Address Pointer
3.4 Generating User Defined Characters
3.5 Displaying Graphics
4 The Atmel 89C55 Microcontroller
4.1 External RAM
4.2 The Serial Port
4.3 The Keypad
4.4 Other Microcontroller Connections
5 Software Development

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (4 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

5.1 PC application
5.2 Microcontroller application
6 Description of Power Supply
6.1 Switching between the Microcontroller and PC
7 System Analysis and Errors
7.1 Keypad Scanning Routine
7.2 Microcontroller serial port
7.3 GPS Differential Mode
7.4 External RAM
7.5 LCD Contrast Voltage
8 Conclusion
9 Recommendations
10 Bibliography
A GPS Oncore Commands
B Almanac Parameters
C LCD Controller Notes
D Circuit Diagrams
E C++ Code
F Assembly Code
G Included Disc

List of Figures
2.1 Oncore GPS Receiver (from the `GT PLUS ONCORE RECEIVER' pamphlet, available from Motorola).
3.1 User defined character of the degree sign
3.2 Bitmap Image displayed on LCD
3.3 Graphics Data Format
4.1 External RAM taken and modified from [Atmel,1997]
4.2 Keypad used in this thesis
5.1 Program Flow Diagram
B.1 Details of Subframe 5
C.1 Character Code Map from the T6963C
D.1 Circuit Diagram for External RAM
D.2 Interface Diagram for LCD

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (5 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

D.3 Microcontroller and PC to GPS


D.4 Keypad Connections
D.5 Power Supply and Contrast Voltage
D.6 PCB Circuit Design
D.7 PCB Circuit Keyboard Design

List of Tables
2.1 Oncore Power - Data Connector Pin Assignments [Motorola, 1996].
2.2 Oncore Interface Protocol [Motorola, 1996]
3.1 Relationship between CG RAM and Offset register
5.1 Virtual KeyBoard
A.1 Commands from GPS used for Thesis
A.2 NMEA Commands
A.3 Format Commands
B.1 Parameters of Subframe 4 and 5

Chapter 1
Introduction
This thesis sets out the results of the design and construction of a hand-held GPS receiver system.

The NAVigation Satellite and Ranging (NAVSTAR) GPS is an all weather, radio based, satellite navigation system that enables users to accurately determine 3-
dimensional position, velocity and time worldwide. The GPS system has been developed by the US Department of Defense and the service it provides is free to an
unlimited number of users [Motorola, 1996]. Receivers like the Motorola Oncore are inexpensive and easily obtainable and allow the inclusion of the receiver in
embedded applications. This gives the designer the freedom of designing a system suitable to a wide range of people [Motorola, 1996].

The Objectives of this thesis was to build a GPS system with the following aspects:

1. Must be hand-held.
2. Must be able to display all relevant information on a Graphics LCD.
3. The interfacing must be done using a microcontroller.

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (6 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

The thesis is restricted to the objectives outlined above due to the limited time that was available. It is up to the recommendations to provide details of other aspects
that could be included in a GPS system.

This thesis will first investigate the protocols associated with the Motorola Oncore GPS Receiver and the functions to be included in the project. Based on this
information and the visual requirements needed to display all necessary data, the graphics LCD screen is discussed. The method of displaying a bitmap image is
outlined here in detail. The choice of the Atmel 89C55 microcontroller will be discussed next, focusing on the suitability as an interface between the GPS and LCD.
Following this, there will be certain sections describing software development and the final circuit will be described with the chosen power supply. The whole
system will be analysed and discussed. Finally, conclusions are made about the design and effectiveness of the GPS system and recommendations are made about
further improvements that could be implemented.

Chapter 2
The Motorola Oncore GPS
As the GPS receiver forms the central part of this thesis, the first thing to do was to get a good understanding of the functions and requirements this particular GPS
receiver can provide. This was done using the Motorola GT/UT Oncore User's Guide [Motorola, 1996].

2.1 Brief Description of GPS


The overall Global Positioning System consists of three major segments: the space segment, the ground segment, and the user segment. These are detailed below
from the Motorola Oncore User's Guide [Motorola, 1996].

Space Segment:
This consists of the 24 satellites that make up the GPS. These satellites are found in 6 orbital planes and are equally spaced about the equator and inclined at
55 degrees. The satellites are found at an altitude of 20 183km.
Ground Control Segment:
This segment consist of a master control center and a number of monitoring stations. This network of stations tracks the satellites and precisely determines
their orbits. At certain intervals they will update the almanac ephemeris and other system data which the satellites transmit to the users.
User Segment:
The user segment consists of all the GPS receivers. The GPS receiver's position is determined by the geometric intersection of several simultaneously
observed ranges (satellite to receiver distance) from the satellites with known co-ordinates in space. The receiver measures the time required for a satellite
signal to reach the receiver. This transmission time is determined using code correlation techniques. This means that each satellite has a unique code
sequence that is identical to a code sequence generated by the receiver. The receiver code is shifted until maximum correlation between the 2 codes exist.
This time shift is multiplied by the speed of light and gives the distance to each satellite. Factors like satellite and receiver clock errors and propagation
delays are included in that signal. A minimum of 4 satellites need to be tracked in order to solve for 4 unknown parameters (i.e. latitude, longitude, altitude

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (7 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

and clock offset). If one of these parameters is known and fixed, one only needs to track 3 satellites.

2.2 Antenna Information


The major components included in the antenna is a microstrip patch antenna, a ceramic RF filter and a signal preamplifier. This antenna is designed to collect the L1
band signals transmitted from GPS satellites at a frequency of 1575.42 MHz. The signals are then amplified and relayed to the receiver. The signal is first
preamplified within the antenna and this is made possible by the external power supply supplied by the Oncore receiver. The antenna module draws 22 mA of
current at 5 Vdc, directly from the antenna connector.

The Oncore receiver is capable of detecting the presence of an antenna. An antenna sense circuit can detect under current (open circuit), over current (shorted or
exceeding maximum receiver limits), or a valid antenna connection [Motorola, 1996].

The above information is available through 2 I/O messages, namely the `Position/Status/Data' and `Self-Test' message.

2.3 GPS Oncore Information


The Motorola Oncore Receiver is a compact and lightweight module, especially designed to be used in embedded applications. It has 8 channels which enables it to
track 8 satellites simultaneously. A RF signal processing circuit converts the RF signal received from the antenna to an intermediate frequency (IF) which is passed
on to an analog-to-digital converter which digitizes the signal. This digitized IF signal is routed to the 8 channels for code correlation, carrier tracking and filtering.
A microprocessor decodes and processes satellite data and computes position, velocity and time [Motorola, 1996].

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (8 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure 2.1: Oncore GPS Receiver (from the `GT PLUS ONCORE RECEIVER' pamphlet, available from Motorola).

2.3.1 Electrical Specifications

The Oncore receiver operates on a +5 Vdc regulated power source. The power source chosen for this thesis will be described in detail later. The data I/O serial port
interface is inverted TTL (5 V logic). The receiver has a 10-pin, power/data connector and a miniature RF connector for the antenna connection [Motorola, 1996].

The following table lists the assigned signal connections of the Oncore receiver:

Pin No. Signal Name Description


1 Battery Externally applied backup power ( ≤ + 5 Vdc)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (9 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

2 +5 Power +5Vdc regulated main power


3 Ground Ground (receiver)
4 Vpp Flash memory programming voltage
5 RTCM Input Differential correction input pin
6 1 PPS 1 Pulse per second signal
7 1 PPS RTN 1 pulse per second return
8 TTL TXD Transmit 5V logic
9 TTL RXD Receive 5V logic
10 TTL RTN Transmit / Receive return

Table 2.1: Oncore Power - Data Connector Pin Assignments [Motorola, 1996].

5V PWR:
4.75 Vdc to 5.25 Vdc
Battery or Backup PWR:
2.5 Vdc to 5.25 Vdc

2.3.2 The Serial Interface

To connect the GPS Oncore receiver to a PC, the TTL signal levels of the receiver have to be converted to RS-232 signal levels (i.e. TTL: 0V to be converted to +3
to +25Volts and TTL: 5V to -3V to -25Volts) To achieve this, the MAX232 driver ( or LT1032 ) is placed in the circuit which operates from a +5V power supply
and uses a charge pump to generate the negative supply needed.

2.4 Interface Protocol


The folowing table lists the interface protocol parameters:

Format: Motorola
Type: Binary
Baud Rate: 9600bps
Data Bits: 8 bits

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (10 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Start/Stop: 1/1
Parity: none

Table 2.2: Oncore Interface Protocol [Motorola, 1996]

The I/O port on the receiver operates under interrupt control. The incoming data is stored in a buffer that is serviced by the Oncore every 1.0 seconds.

2.4.1 Motorola Binary Format

The Oncore Receiver uses binary data messages consisting of a number of binary characters. A data message can be divided into the following sections [Motorola,
1996]:

Message Start:
@@ - (2 x 40hex) denotes the start of the binary message
Message ID:
(A..Z)(a..z, A..Z) - ASCII upper-case letter, followed by an ASCII lower-case or upper-case letter. These 2 characters together identify the message type and
imply the correct message length and format.
Binary Data Sequence:
This consists of a variable number of bytes of binary data dependent on the command type.
Checksum:
C - This is the exculsive-or of all bytes after the @@ and prior to the checksum.
Message Terminator:
<CR> <LF> - carriage return and line feed characters denoting the end of the binary message.

A list of all commands used in this thesis are found in Appendix A.

Every Oncore receiver input command has a corresponding response message to determine if the command has been accepted or rejected. If a correct command has
been received, the receiver will perform the requested function.
A binary message is considered received if the following checks out:

● the message started with @@ and is terminated with a carriage return and line feed character.
● the message is the correct length for its type
● the checksum validates.

[Motorola, 1996]

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (11 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

The data field contains binary data which can either be integer or floating point data. Negative numbers are stored as two's complement numbers.

The Oncore receiver will reject the entire command if one of its input parameters is out of range. For example, to change the GMT offset, the range of hours to be
changed is between -23 and +23. If a command is send requesting to change the GMT offset to 24 hours, the entire command is rejected and the original setting is
kept.

Response messages are identified in the same way as the Oncore receiver decodes the commands.

2.4.2 Details of some Commands

As describing each of the commands will take up many pages, only some commands will be descibed in more detail. These are taken from [Motorola, 1996].

1. The structure of the `Latitude'command is highlighted. All other commands follow the same structure but may be of different lengths. Input Command: ¯
Poll current Latitude:
@@AdxxxxC<CR><LF>
where xxxx = 4 out of range bytes (99hex99hex99hex99hex)
Message length is 11 bytes.

Change current Latitude:


@@AdddddC<CR><LF>
where dddd = latitude in milliarcseconds (mas)
(-324 000 000 .. 324 000 000) (-90o .. 90o)

Response Message: @@AdddddC<CR><LF>

To convert milliarcseconds to degrees, the following relationship is used: 1o = 3 600 000 mas

2. The `Position/Status/Data' command combines nearly all other commands. The response message contains the date, time, position, velocity, geometry, the
satellite visibility and tracking status, and the status of each of the 8 channels. The message length is 76 bytes. It is possible to poll the receiver once or to
request a updated message at certain intervals.
3. The Almanac data output message contains satellite data. This almanac data is loaded into the onboard RAM of the Oncore receiver and takes about 15
minutes after power-up to be broadcast from the satellites. As there are 34 satellites, there are 34 response messages. Almanac data is transmitted in words 3-
10 of subframe 5 (pages 1-25), and words 3-10 of subframe 4 (pages 2-5, 7-10, and 25) of the satellite broadcast message.
Appendix B shows the format of the parameters that are situated in words 3-10 [GPS ICD-200].

As this message requires a big buffer (1122 bytes at least) to store the values in, this command has only been implemented on the PC and not on the

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (12 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

microcontroller.

2.5 NMEA Interface Standard


The Oncore receiver supports the National Marine Electronics Associatian (NMEA) 0183 format for GPS data output [NMEA,1997]. Using the `Switch to NMEA'
command makes it possible to change the serial data format of the serial port. The baud rate is switched from 9600 to 4800 and the input commands are only
recognized in NMEA format.

Due to time limitations, this format was not implemented. It is, however, compared to the Motorola Binary Format.

2.5.1 Brief Description of NMEA

The National Marine Electronics Association (NMEA) developed this standard to allow a satisfactory direct data interface between electronic marine instruments,
navigation equipment and communications equipment. This standard defines electrical signal requirements, data transmission protocol and timing for a 4800-baud
serial data bus. The intended application for this standard is between a single TALKER to one or many LISTENERS in one-way serial data transmission. The data
and commands are in the form of ASCII characters and as in the Motorola binary format, certain sequences of ASCII characters convey information about the
position, altitude etc. Each ASCII character has 8 data bits with the most significant bit always set to zero. Valid characters are the ASCII characters from 20h to
7Eh except some characters defined as reserved characters [NMEA,1997].

2.5.2 Outline of Command Structure

The following gives an outline of the reply message the Oncore receiver will send to an electronic navigation instrument [NMEA,1997]:

Start of sentence:
This is the ASCII character `$'= 24h
[Adress field:] This field consists of 5 characters. The first 2 characters identify the TALKER. In the case of the GPS, this code consists of the 2 ASCII
characters `GP'. The last 3 characters are the sentence formatter or message ID.
Field delimiter:
The character `,' = 2Ch starts each field except the address and checksum fiels. If it is followed by a null field, it indicates that no data is present.
Data Sentence block:
This consists of a series of data fields containing all the data that is transmitted. The sequence is identified by the sentence formatter.
Checksum Delimiter:
The character `*' = 2Ah follows the last data field and indicates that a 2 byte hex value follows from the checksum.
Checksum field:
This is the same as in the Motorola Binary format: all data between the `$' and the `*' are exclusive-or'ed together.
Terminates the sentence:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (13 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

<CR> = 0Dh and <LF> = 0Ah.

To request such a message from the Oncore, the following command needs to be sent [Motorola, 1996]:

Start of command:
$PMOTG, where the P identifies the message as Proprietary format; MOT stands for Motorola and G for GPS.
[Command field:] This field consists of 3 characters and corresponds to the sentence formatter of the address field above. The Oncore receiver has 7 NMEA
commands which are outlined in Appendix A.
Update Rate:
4 bytes instruct the receiver to output the message once or continuously.

The command also includes field delimiters, a checksum field and the 2 terminating characters.

As can be seen above, the NMEA format is similar to the Motorola Binary Format. The NMEA Format makes it easier for an electronic navigation instrument that
supports NMEA to communicate with the GPS.

As the information from NMEA commands can also be requested through the Motorola Binary Format, the NMEA Format was not implemented. The project could
have been expanded to include an electronic navigation instrument that communicates with the GPS.

Chapter 3
The Graphics Liquid Crystal Display
One of the requirements for this thesis was to display all information from the GPS on a LCD. A Graphics display was chosen as the biggest text display only had 40
characters by 4 lines. The display used is a 240 X 64 pixel graphics display from Varitronix (MGL(S)-24064-G-LED03). This was the biggest display the budget
could afford. With a 6 X 8 character font, text of 40 characters by 8 lines could be displayed which is sufficient for this thesis.

This chapter will describe the LCD controller from Toshiba (T6963C) and how to display a uncompressed black and white bitmap image on the screen.

3.1 Module Pin-out


This section will describe some of the pins from the LCD.

1. The supply voltage is +5 Volts with a negative contrast voltage of about -10 Volts. This contrast voltage depends on the display type and temperature. In the

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (14 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

final circuit a charge pump (LT1054) is included to generate the required negative voltage. As its input +12 Volts is used (directly from Car battery or `Gel'
cell battery) which is inverted to -12 Volts. A potentiometer is included in the circuit to enable a variable negative contrast voltage.
2. There are 4 control pins: /WR (Write), /RD (Read), /CE (Chip enable) and C\/D (data/command register). These pins are used to write data or commands,
or to read the status byte [Toshiba,1997].
Write data:
The data to be written should be set on D0-7 and
C/\D taken low
/WR taken low (/RD should be high)
/CE must be pulsed low for greater than 80ns
Write command:
The command should be set on D0-7 and
C/\D taken high
/WR taken low (/RD should be high)
/CE must be pulsed low for greater than 80ns
Read Status:
To check the status of the controller:
C/\D taken high
/RD taken low (/WR should be high)
/CE must be pulsed
After approximately 150ns the data can be read from D0-7
/CE taken high
3. This LCD enables the user to choose the font size of the text characters. The fonts available are either 8x8 or 6x8 pixels. A 6x8 font was chosen in order to
increase the number of characters per row to 40. Only 30 characters are available per row with an 8x8 font.

3.2 Status Check


Before data or commands are read or written, a status read must be performed. This means checking that Status bit 0 (STA0) and Status bit 1 (STA1) are set to 1. If
they are set to zero, the controller is still busy executing a command or an internal read/write is taking place [Toshiba,1997].

It was only possible to interface to the parallel port of the PC if the port was bidirectional. As some PC's only have an output port, a delay of 1ms was inserted before
writing the data. As the Atmel microcontroller has bidirectional ports, this was not needed as the status byte can be read directly.

3.3 Setting the Cursor and Address Pointer


On initialisation, the text and graphics home address have to be defined. The address can be anywhere in the RAM area available (8k). The text home address was
chosen to be 0000h and the graphics home address to be 0200h. In this way, text and graphics data will not interfere with one another.

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (15 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

The user can choose between either graphics or text mode. In text mode there are certain cursor functions: a 1-8 line cursor, blinking or on/off. The cursor is moved
according to the following equation:

address = TextBASE + (y * BYTES PER ROW) + x

where y = [0,8], x = [0,63] and BYTES PER ROW = 40 with a 6X8 font
FromJohn P. Beale's program (May 3-4, 1997, beale@best.com)

The cursor pointer is not automatically moved with each write. Only the address pointer is incremented / decremented to the next position. The address pointer is
also set up according to the above equation.

3.4 Generating User Defined Characters


Appendix C shows the character map available to this LCD controller. The character codes are different from ASCII codes. To display an ASCII number means
subtracting 20h which will be then the correct index into the character map. As this character map does not contain all ASCII characters, it was necessary to generate
one's own character. The degree sign character was defined in the following way:

1. The `Offset Register' command is used to determine the external character CG RAM area. As seen in Appendix C, characters are already defined from 00h
to 7Fh. User defined characters can be from 80h to FFh in CG RAM.
The following table will help chosing the nescessary Offset register data [Toshiba,1997]:

Offset Register data CG RAM area


00000 0000 to 07FFh
00001 0800 to 0FFFh
00010 1000 to 17FFh
00011 1800 to 1FFFh
... ... ...
11110 F000 to F7FFh
11111 F800 to FFFFh

Table 3.1: Relationship between CG RAM and Offset register

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (16 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

As this LCD only has 8k of RAM available, only the first 4 offset data numbers are usable. The CG RAM area used was from 1800 to 1FFFh, so that
character 80h will take up locations 1C00 to 1C07h (1800h + 80h*8 lines). This meant using an offset register number of 3h.

2. Then to set character number 80h to a user defined character:

Figure 3.1: User defined character of the degree sign

To store this character in RAM, the address pointer has to be set to 1C00h and the 8 bytes from Figure 3.1 written to it. Setting then the address pointer to
80h will display the degree sign on the LCD.

3.5 Displaying Graphics


To display an image on the LCD involves a number of steps:

1. To create an image in black and white the Microsoft Paint Program was used. A canvas exactly the same size, in pixels, as the LCD was set up in the paint
program.

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (17 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure 3.2: Bitmap Image displayed on LCD

2. This image was saved in uncompressed `Tiff' format, now stored in negative mode. A black pixel is thus stored as a logical `0' and a white pixel as a logical
`1'. As the LCD is in positive mode, the image will be inverted. To remedy this, the bits were inverted when writing to the LCD.
3. To convert the image into hexadecimal form, a freeware program called bin2hex.exe was used. It is available from the following website:
http://www.hantronix.com. This program creates a text file which can be edited to the user's needs. The bytes of the image are listed in the following way:

00 15 12 32 ac ...

4. A `Hantronix' Application Note [Hantronix] says that one must delete the first 25 bytes from that text file, as these bytes are part of the `Tiff' header. This
was found not to be true. The text file in question consisted of 2260 bytes. To subtract 25 would give 2235 bytes. The LCD only needs 1920 bytes (30 bytes
in a row by 64 pixels (rows)). Thus the `Tiff' header which should be subtracted is 340 bytes long.
5. When reformatting the text file (using a simple text editor) to be included in an assembly program, the bytes will look like the following (see also page 122):

db 000h 015h 012h 032h 0ach ...

6. The data is formatted as shown below: This applies to the 240X64 Pixel Display.

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (18 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure 3.3: Graphics Data Format

7. The graphics area in RAM needs to be set up to how many bytes later one wants the next line to start at. This can be the same number of bytes to fill one
line of the screen for most efficient use of the RAM. If one would set the number of bytes in RAM less than the number of bytes per row the image gets
corrupted as certain bits / bytes get overwritten. With an 8X8 font there are 30 bytes in a row as in the `Tiff' file. But as a 6X8 font is used, the RAM had to
be set up to 40 bytes per row. The following equation which sets the address for each of the bytes in the text file on the LCD is taken from John P. Beale's
program (May 3-4, 1997, beale@best.com):

address = GraphicsBASE + (row * BYTES PER ROW) + (column / 6)

where row = [0,63], column = [0,239] and BYTES PER ROW = 40 with a 6X8 font

To set the bits on the LCD the `Set bit within byte' command is used.

8. As mentioned above, the image consists of 1920 bytes. Most of the pixels on the image were not set. To compress the same image the number of interstitial
`zero' bytes were counted and replaced with a number representing the number of `zero' bytes.

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (19 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

For example: The following sequence of bytes:

0aah 0deh 000h 000h 000h 000h 0ffh

would be converted to this:

0aah 0deh 4 0ffh

In this way the image was compressed to ±1000 bytes. The display routine simply jumps over the number and offsets the address by the required number of bytes.

(The code which displays the image on the LCD is found on page 89-90.)

Chapter 4
The Atmel 89C55 Microcontroller
After interfacing the GPS and the LCD to the PC and implemeting the code in C++, it became evident that the microcontroller to be used had to have at least 16
kbytes of Onboard ROM. This came from the fact that the image and the C-code would take up much memory. The microcontroller also needed approximately 512
bytes of RAM, half of it used for the buffer to store the GPS data in and the rest for program variables. A UART serial port was also needed.

Two microcontrollers were considered: the XC68HC705C9A from Motorola and the 89C55 from Atmel. As the Motorola microcontroller was not available, the
Atmel microcontroller was chosen as it has 20 kbytes of Flash, 256 bytes of RAM and a UART serial port. Another interesting fact was that the Flash Memory was
electronically and not UV erasable and made debugging and program development faster. The only drawback was that not enough Onboard RAM was available.

4.1 External RAM


As the program needed another 256 bytes of RAM, a small RAM array was inserted in the circuit.

The following figure shows the hardware configuration for accessing up to 2 kbytes of external RAM (see also Figure D.1):

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (20 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure 4.1: External RAM taken and modified from [Atmel,1997]

The 3 lines from Port 2 were strapped to +5V as they were not needed. Port 0 supplied the address and data and only 256 bytes could be accessed, which gave an
overall total of 512 bytes of RAM.

In order to access the external RAM, the `movx' instruction was used instead of the normal `mov' instruction. The address is placed on Port 0 and is latched with the
`ALE' pin after which the data is read or written from RAM.

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (21 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

The Atmel 89C55 makes use of 4 register banks. Only register bank `zero' was used during program execution which meant that the other 3 register banks were used
as additional 21 bytes of RAM.

4.2 The Serial Port


The serial port was used in Mode `1' with 8 data bits and 1 start and 1 stop bit. The onboard timer/counter1 was used to generate the nescessary baud rate of 9600.
With an oscillator frequency of 11.059MHz the following equation was used to determine the reload value for TH1 (the timer/counter high byte 1):

TH1 = 256 - [(Oscillator Frequency)/( 384 ×Baud Rate)] = 253

[Atmel,1997]

The serial port was setup so that it could generate an interrupt whenever it received an character, in this case from the Oncore GPS receiver. The characters are read
from the microcontroller serial buffer (SBUF) and stored in a temporary circular buffer.

4.3 The Keypad


The program required 7 keys to control the LCD and GPS. The following concept on scanning a keypad is taken and modified from: [Yeralan S and Ahluwalia A,
1995]. The keys were arranged in the following way (see also Figure D.4):

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (22 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure 4.2: Keypad used in this thesis

Each pushbutton has 2 terminals with one connected to a column rail and the other to a row rail. The row and column rails are then connected to the microcontroller
Port 1. The columns are then driven low by the port and the rows are read in. If no key has been pressed, the rows read `1'. When a row is detected to be `0', it
indicates that a key has been pressed. To detect which key has been pressed, the microcontroller loops through each column, driving 1 column at a time low and
inspects the row. The row will be grounded when the column in which the key resides is driven low. In this way the keys can be identified. Each key has a number
associated with it and this number is stored in the global variable `key'.

This particular keypad is implemented to invoke an interrupt. The 2 rows are combined into an AND gate. As the rows are normally at a logic level `1' , the output

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (23 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

of the AND gate is also a `1'. When a key is pressed, the `1' to `0' transition at the AND gate will trigger the interrupt.

A debouncing scheme has also been implemented. After the pressed key has been identified, the rows are checked until the key has been released. Only then does
the program continue.

(The code which implements the keypad scanning is found on page 78.)

4.4 Other Microcontroller Connections


It was decided that the LCD's data pins should be connected to Port `0' of the microcontroller(see figure D.2). To drive the LCD, pull-up resistors had to be inserted.
These pull-up resistors do not interfere with the external RAM. Accessing external RAM also does not have any effect on the LCD as the LCD control lines (on Port
`2') are inactive.

Chapter 5
Software Development
Two types of programs were implemented. A program was written in C++ for the PC and another was written in assembly language for the microcontroller. Both
programs are identical: they implement the same routines in different languages.

5.1 PC application
In order to get a better understanding of both the GPS and LCD, the thesis was first implemented on the PC. The GPS Oncore was connected to the PC via the serial
port and the LCD was connected to the PC via the parallel port. The program was developed using Borland C++ for DOS, as the author has had previous experience
with it.

The following diagram shows the program flow of the main routines:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (24 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (25 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure 5.1: Program Flow Diagram

If a key has been pressed, the program will decide which Menu to display and which command to send to the GPS. The GPS will then send information back. As the
serial port was interrupt driven, every time the GPS Oncore send back data, an interrupt service routine would store the incomming characters in an ringbuffer (see
code on page 57).The main program would then check to see if the headpointer and tailpointer of the ringbuffer are equal or not. If not equal, then the ringbuffer
received new data and a routine had to decide which command had been send back. A command is identified by the 3rd and 4th character of each sequence (see
Appendix A). For each command from the GPS Oncore there is a display function which operates on the data in the ringbuffer and displays it in the best possible
way (see code in Appendix E).

5.2 Microcontroller application


The microcontroller had to use the same routines as the PC. The only difference is the implementation of the keypad. The PC has the whole keyboard available to
input strings of numbers. It was decided to use only seven keys with the microcontroller. These are the Up and Down Keys, Left and Right Keys, Enter Key, Escape
Key and a Menu Key. This meant that a virtual keyboard had to be implemented on the LCD. The four `arrow' keys were used to scroll through the virtual keyboard
and the `Enter' key used to select a number. The XY coordinates on the LCD display were used as an index into a Look-up Table to get the correct number selected.
The number was then stored in an array. To leave the virtual keyboard, the user has to select the `*' character. The `arrow' keys were used in the same way as
outlined above to scroll through the different LCD menus.

0123
*456
789

Table 5.1: Virtual KeyBoard

The program flow is exactly the same as for the PC. A cross-compiler was used to change the C++ code to assembler. As the Engineering Departement did not have
a cross-compiler, a demo cross-compiler was used. This cross-compiler (HI-TECH C compiler for the 8051) only generated 500 lines of assembly code. Therefore it
was nescessary to break up the C++ code into smaller pieces and cross-compile these sections individually. It was then nescessary to edit the assembly code and
insert the names of the allocated variables in RAM, as the cross-compiler did not do so.

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (26 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Assembly code was not generated for all functions. The cross-compiler left it to the user to generate code for 32-bit division and displaying strings. 32-bit division
was implemented by means of successive subtraction [Yeralan S and Ahluwalia A, 1995].

To display strings of characters the following code was used:


lcall lcdprint
db "The Oncore Receiver.",0

If a subroutine is called, the return address is pushed onto the stack. On entering this subroutine (lcdprint), the return address is popped again from the stack into the
data pointer. This data pointer will now point to the first character of the string, `T'. The data pointer is incremented after each character is displayed. If the data
pointer points to a `0', the routine returns to the calling program. As the return address was already popped from the stack, a `jump' is made to the address pointed to
by the data pointer, which points now to the instruction after the `0' (see code on page 86).

As the LCD character generator RAM only displays one character at a time, a number consisting of several characters had to be split up into its individual
characters. For example, the number `125' had to be split up into `1', `2', and `5'. This was achieved by dividing the number by `10', storing the remainder in an array
and later displaying the variables in the array. To show how this works the above number is used:

125 / 10 = 12 with a remainder of `5'


12 / 10 = 1 with a remainder of `2'
1 / 10 = 0 with a remainder of `1'

The remainder numbers are stored in an array and then displayed individually (see code on page 106).

Chapter 6
Description of Power Supply
A prerequisite for this thesis was to make the GPS portable. This meant running the GPS of batteries. It was decided to use a `Gel' cell battery and as another
alternative a car battery. The `Gel' cell battery was chosen as it was small enough and is rechargeable. It supplies 12 Volts with 2.2Ah.

As the GPS, LCD and microcontroller need a +5 Volt supply, a voltage regulator was needed. The voltage regulator chosen initially was the LM340. This regulator
is designed to change only 10 Volts to the required 5 Volts by dissipating the extra power. Using the `Gel' cell battery with the LM340 wasn't so desirable as the
power regulator had to dissipate an extra 2 Volts. As the car battery supplies 14 Volts when the car is running and the `Gel' cell battery supplies 12 Volts, the
regulator finally chosen was the MC34167 from Motorola. This is a fixed frequency power-switching regulator which changes any voltage ranging from 7-35 Volts
to 5 Volts (see figure D.5).

The box which houses the GPS circuitry has an extra compartment to hold the `Gel' cell battery. In order to prevent connecting the car battery to the circuit while the

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (27 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

`Gel' cell battery is still in the compartment, the connector can only be plugged in inside the compartment with the `Gel' cell battery removed.

6.1 Switching between the Microcontroller and PC


To switch between the microcontroller and the PC a Quad Bilateral Switch (HCF4066) was used. Using a `double throw, double pole' switch the bilateral switch and
the power to the microcontroller and LCD was controlled (See Figure D.3).

Chapter 7
System Analysis and Errors
The following sections will describe some areas in the GPS system where errors occur or where the design is not very efficient. The errors are mostly timing related,
as in the keypad scanning routine. Another factor which will be discussed is the expanding of the external RAM from 256 bytes to 2 kbytes.

7.1 Keypad Scanning Routine


A major problem is that the keys do not respond sometimes when pressed. This is due to other routines still running and setting the `key' variable back to zero,
which indicates that no key was pressed. The user then has to press the key a couple of times before the program will function in the normal way again.

The key debouncing routine is very efficient, although sometimes the keys react to fast by `jumping' over certain functions in the program. This could be due to the
fact that the microcontroller is too fast and already `sees' the next key being pressed. This is minimal though and does not really affect the program.

7.2 Microcontroller serial port


Incoming data from the GPS receiver via the serial port is slow (9600 bps) in comparison to the program execution of the microcontroller (at a frequency of 11.059
MHz). The incoming data is stored in a circular buffer, but at the same time data can be read from it. To prevent the tailpointer from `catching' the headpointer in the
circular buffer, every time data is read from the buffer a delay is inserted in the program. The length of the delay was determined by trial and error and is about
50ms. This gives the serial interrupt routine time to store all incoming characters in the buffer.

7.3 GPS Differential Mode


The GPS receiver is only accurate to ±100m in the horizontal position and ±156m in the vertical position. Only military users have access to the more accurate

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (28 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

satellite code to give them accuracies of centimetres or millimetres. A civilian user could get an accuracy of 1-5 meters by using the GPS Oncore receiver in
differential mode (DGPS). This means that a link between a base station, of which the exact position is known and fixed, and a GPS receiver exist so that the GPS
receiver can receive correction messages from the base station. A base station can be a GPS receiver being at a fixed location sending its correction messages to
another receiver. The GPS GT Oncore receiver, like the one used in this project, is capable of accepting these messages through one of its pins (Pin 5). But as only
one GPS receiver was available, the differential mode could not have been implemented. The GPS receiver also has to be capable of generating these correction
messages. The VP Oncore receiver from Motorola is capable of generating these correction messages.

In South Africa there are some base stations where these correction messages are available. The user has to buy `airtime' from them in order to receive these. A
possible way of using the Oncore receiver in differential mode would be to have a cell-phone link between the base staion and the GPS receiver in order to receive
these correction messages.

7.4 External RAM


Only 256 bytes of external RAM was used, but the chip can provide up to 2 kbytes of memory. Being able to access this amount of memory, the 2 functions
`Almanac data' and `Visible Satellites' could also be implemented with the microcontroller, as these functions need a bigger circular buffer to store data in. Due to
time limitations this was not done, but it could be easily implemented by using the 3 unused address lines provided on the RAM chip. These address lines are tied to
+5 Volts, but could be connected to the unused pins of port 2 of the microcontroller. The extra address has to be then placed onto the port 2 pins before a `write' or
`read' is to be done to external RAM.

7.5 LCD Contrast Voltage


Switching from the `Gel' cell battery to the car battery and vice versa means adjusting the LCD contrast voltage every time using the provided potentiometer.
Initially the design provided only the use of one battery and only later included the use of the car battery. As this is not an ideal situation, this contrast voltage should
be made battery (voltage) independent. This could be done by adding another voltage inverter and by routing the 2 batteries separately to the 2 voltage inverters.

Chapter 8
Conclusion
The project undertaken to design and build a GPS system was succesfully completed. The final system is hand-held, user-friendly and reliable. From the
implementation process and work carried out on the GPS, the following conclusions can be drawn:

1. Microcontroller. The use of the Atmel 8051 microcontroller made the implementation of software and hardware very easy, as much help was available in
form of literature and cross-compilers.
2. Battery. The `Gel' cell battery is well suited for hand-held applications, and as it is rechargeable it can be used many times.

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (29 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

3. Method of Operation. The lay-out of the keyboard and LCD as well as the integration of the battery into a separate compartment made the system easy to
use. Making use of a virtual keyboard reduces the number of keys on the box but does not reduce the functionability.
4. Cost. The cost of this GPS system is ± R2000.00 which is initially more expensive than commercially available GPS systems that can be obtained
nowadays for less and are much smaller. But having a clear understanding of the Motorola Oncore GPS receiver means that more functions can be
implemented at a later stage to the user's preferences.

Chapter 9
Recommendations
As time was limited, many functions of the Oncore receiver could not be implemented. Therefore the following recommendations can be made:

1. Implement the NMEA protocol and use an electronic navigation system to communicate with the GPS.
2. Use the LCD more extensively by displaying the position of the GPS receiver or satellites graphically, instead of only using text.
3. Add non-volatile external memory to record data (i.e. position) in order to recall it later, or use it with the PC together to plot co-ordinates on a map.
4. Display a map and plot the current position on it, using a bigger colour screen.
5. Implement Differential GPS using the existing GPS receiver to get better position accuracies.

Bibliography
[Atmel,1997]
Atmel Corporation Microcontroller Data Book, San Jose California, 1997.
[GPS ICD-200]
GPS Interface Control Document: p86,p123-130
[Hantronix]
A simple way to create Bitmap Images for Graphics LCD's
[Motorola, 1996]
Motorola, GT/UT Oncore User's Guide, p2.1-2.3, 3.2-3.3, 3.7, 5.1-5.3, 6.1-6.45.
[NMEA,1997]
National Marine Electronics Association, NMEA 0183, Standard for Interfacing Marine Electronic Devices, Version 2.20, January1, 1997.
[Toshiba,1997]
Toshiba T6963C Data Sheet, Toshiba Corporation, 07/04/1997
[Yeralan S and Ahluwalia A, 1995]
Programming and Interfacing the 8051 Microcontroller, Addison-Wesley Publishing Comapany, Massachusetts: p75-111, p176-181, p185-195.

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (30 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Appendix A
GPS Oncore Commands
Function Description Binary Command
Time Time of day @@Aa
Time GMT Offset @@Ab
Time Date @@Ac
Position Latitude @@Ad
Position Longitude @@Ae
Position Height @@Af
Position Satellite Mask Angle @@Ag
Receiver Atmosphere Correction Mode @@Aq
Time Time Mode @@Aw
Receiver Visible Satellite Status message @@Bb
Almanac Almanac Data Output @@Be
Time Leap Second Pending Status @@Bj
Receiver Set-to-Defaults @@Cf
Receiver Receiver ID @@Cj
Position Position/Status/Data @@Ea
Receiver Self-Test @@Fa

Table A.1: Commands from GPS used for Thesis

Command name Description


GPGGA Global Positioning System Fix Data
GPGLL Geographic Position - Latitude/Longitude
GPGSA GPS DOP and Active Satellites

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (31 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

GPGSV GPS Satellites in View


GPRMC Recommended Minimum Specific GPS / Transit Data
GPVTG Course over Ground and Ground Speed
GPZDA Time and Date

Table A.2: NMEA Commands

The following 2 commands are used with the NMEA data format:

Command name Description


@@Ci Switch to NMEA Format
$PMOTG,FOR, Switch to Motorola Binary Format

Table A.3: Format Commands

Appendix B
Almanac Parameters
Parameters No. of Bits Scale Factor Units
e 16 2-21 dimensionless
toa 8 212 seconds
δi** 16* 2-19 semi-circles
Omegadot 16* 2-38 semi-circles/second
(A)1/2 24 2-11 meters1/2
(Omega)0 24* 2-23 semi-circles
ω 24* 2-23 semi-circles

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (32 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

M0 24* 2-23 semi-circles


af0 11* 2-20 seconds
af1 11* 2-38 sec/sec

Table B.1: Parameters of Subframe 4 and 5

* These parameters are represented in 2's Complement with the sign bit in the MSB.
** Relative to 0.3 semi-circles.

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (33 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure B.1: Details of Subframe 5

The following pages of subframe 4 have the same format as above: 2-5, 7-10.

Appendix C
LCD Controller Notes

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (34 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure C.1: Character Code Map from the T6963C

Appendix D
Circuit Diagrams

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (35 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (36 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure D.1: Circuit Diagram for External RAM

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (37 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (38 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure D.2: Interface Diagram for LCD

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (39 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (40 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure D.3: Microcontroller and PC to GPS

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (41 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (42 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure D.4: Keypad Connections

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (43 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (44 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure D.5: Power Supply and Contrast Voltage

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (45 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (46 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (47 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Figure D.6: PCB Circuit Design

Figure D.7: PCB Circuit Keyboard Design

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (48 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Appendix E
C++ Code
The following files make up the 'GPS' program in C++ code:

[Writegps.cpp (p50):] Includes the main program from which commands are send to the GPS and messages from the GPS are decoded.
Gps.h (p54):
Contains the function which sends characters to the GPS and reads characters from the ringbuffer.
Lcd.h (p56):
Contains lcd routines to display characters on the LCD.
Disp.h (p60):
Contains routines which format the data received from the GPS and display it.
Pic.h (p72):
Contains the array holding the bytes for the picture displayed on the LCD.

These files are also included on the attached disc.

FILE: WRITEGPS.CPP

#include <conio.h>
#include <dos.h>
#include <math.h>
#include <string.h>
#include <bios.h>

#include "pic.h"
#include "lcd.h"
#include "gps.h"
#include "disp.h"

void main(void)
{
int num1, num2, num3;
int hours, minutes, sign, time, atmos, sat, fix, angle;
char index1, index2;
char s;
int flag = 1, tag = 1, check = 1, count = 0;

//make sure control lines are at correct levels


lcd_setup();
//initialize LCD memory and display modes
lcd_init();

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (49 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

outp(PORT + 1, 0); //Turn off interrupts

//Save old interrupt vector for later recovery


oldport1isr = getvect(INTVECT);

setvect(INTVECT, PORTINT);//Set interrupt vector entry


//COM1 - 0x0C
//COM2 - 0x0B

outp(PORT + 3, 0x80); //Set Dlab on


//Set Baud rate - Divisor Latch Low Byte
outp(PORT + 0, 0x0C);
//0x03 = 38 400 BPS - default
//0x01 = 115 200 BPS
//0x02 = 56 700 BPS
//0x0C = 9 600 BPS
//0x18 = 4 800 BPS
//0x30 = 2 400 BPS
//Set Baud rate - Divisor Latch High Byte
outp(PORT + 1, 0x00);
//8 bits, no parity, 1 stop bit
outp(PORT + 3, 0x03);
outp(PORT + 2, 0xC7); //FIFO control register
outp(PORT + 4, 0x0B); //Turn on DTR, RTS, and OUT2

outp(0x21,(inp(0x21) & 0xEF)); //Set programmable interrupt


//controller
//COM1 (IRQ4) - 0xEF
//COM2 (IRQ3) - 0xF7

outp(PORT + 1, 0x01); //Interrupt when data received

Disp_Pic(); //Display opening picture: hit any key to get to


//main menu

do
{
while(bufferin != bufferout)
{
index1 = Buffer();
index2 = Buffer();
index1 = Buffer();
index2 = Buffer();

tag = 1;

switch(index1)
{
case 'A':
switch(index2)
{
case 'a':
Disp_Aa(0);

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (50 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

break;
case 'b':
Disp_Ab();
break;
case 'c':
Disp_Ac(0);
break;
case 'd':
Disp_Ad(0);
break;
case 'e':
Disp_Ae(0);
break;
case 'f':
Disp_Af(0);
break;
case 'g':
Disp_Ag();
break;
case 'q':
Disp_Aq();
break;
case 'w':
Disp_Aw();
break;
}
break;
case 'B':
switch(index2)
{
case 'b':
Disp_Bb();
break;
case 'j':
Disp_Bj();
break;
}
break;
case 'C':
switch(index2)
{
case 'b':
Disp_Cb();
break;
case 'f':
Disp_Same(0);
break;
case 'j':
Disp_Cj();
break;
}
break;
case 'E':
switch(index2)
{
case 'a':

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (51 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

flag = Disp_Ea(flag);
break;
}
break;
case 'F':
switch(index2)
{
case 'a':
Disp_Fa();
break;
}
break;
case 'S':
switch(index2)
{
case 'z':
Disp_Same(1);
break;
}
break;
}
}

if(kbhit())
{
if(tag == 1)
{
num1 = 0;
tag = 0;
}
////////////////UNDO INTERRUPTS AGAIN//////////////////
else
num1 = Key_Press_0();

switch(num1)
{
/////////////////////////////////////////////////////////
case MAIN_MENU:
Main_Menu();
break;
case POS_STA_DAT:
Sub_Menu1();

num2 = Key_Press_1();

if((check == 0) && (num2 != 1))


{
lcd_clear_text(); //write spaces
cput(0x94); //Graphics OFF & Text ON, cursor blinking

lcd_xy(0,3); //first character, 3 line


lcd_print("Disable first polling command!!!!");
num2 = 10;
}

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (52 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

switch(num2)
{
case POS_STATUS_DATA:
Pos_Menu(check);

num3 = Key_Press_3();

switch(num3)
{
case POS_1:
Data_To_Gps(pos_status_data, 4, 1, 0, 0, 0);
if(count == 1)
{
flag = 1;
count = 0;
}
if(flag == 0)
{
flag = 2;
count = 1;
}
check = 1;
break;
case POS_2:
Data_To_Gps(pos_status_data, 4, 1, 10, 0, 0);
if(count == 1)
count = 0;
flag = 0;
check = 0;
break;
case POS_3:
Data_To_Gps(pos_status_data, 4, 1, 20, 0, 0);
if(count == 1)
count = 0;
flag = 0;
check = 0;
break;
case POS_4:
Data_To_Gps(pos_status_data, 4, 1, 30, 0, 0);
if(count == 1)
count = 0;
flag = 0;
check = 0;
break;
}
break;

case LATTITUDE:
Data_To_Gps(lattitude, 8, 0, 0, 0, 0);
break;

case LONGITUDE:
Data_To_Gps(longitude, 8, 0, 0, 0, 0);
break;

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (53 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

case HEIGHT:
Data_To_Gps(height, 9, 0, 0, 0, 0);
break;

case DATE:
Data_To_Gps(date, 8, 0, 0, 0, 0);
break;

case TIME_OF_DAY:
Data_To_Gps(time_of_day, 7, 0, 0, 0, 0);
break;

case SATELLITES:
Data_To_Gps(satellites, 5, 0, 0, 0, 0);
break;

case ALMANAC:
Data_To_Gps(almanac, 5, 0, 0, 0, 0);
break;
}
break;
////////////////////////////////////////////////
case GPS_MODES:
Sub_Menu2();

num2 = Key_Press_2();

if(check == 0)
{
lcd_clear_text(); //write spaces
cput(0x94);//Graphics OFF & Text ON, cursor blinking

lcd_xy(0,3); //first character, 3 line


lcd_print("Disable first polling command!!!!");
num2 = 10;
}

switch(num2)
{
case GMT:
Gmt_Menu();

num3 = Key_Press_4();

switch(num3)
{
case GMT_POLL:
Data_To_Gps(gmt_poll, 7, 0, 0, 0, 0);
break;

case GMT_CHANGE:
lcd_clear_text(); //write spaces
cput(0x97);//Graphics OFF & Text ON, cursor blinking

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (54 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcd_xy(4,0); //first character, 3 line


lcd_print("Enter offset in hours(-23 .. 23):");
Numbers( 0 );
s = Key_Press_5();
Numbers( 1 );
hours = Key_Press_6();

lcd_clear_text(); //write spaces


cput(0x97); //Graphics OFF & Text ON, cursor blinking

lcd_xy(4,0); //first character, 3 line


lcd_print("Enter offset in minutes(0 .. 59):");
Numbers( 1 );
minutes = Key_Press_6();

if(s == '-')
sign = 0xFF;
else if(s == '+')
sign = 0;

Data_To_Gps(gmt_change, 4, 3, sign, hours, minutes);


break;
}
break;

case TIME_MODE:
Time_Menu();

num3 = Key_Press_4();

switch(num3)
{
case TIME_MODE_POLL:
Data_To_Gps(time_mode_poll, 5, 0, 0, 0, 0);
break;

case TIME_MODE_CHANGE:
Time_Change();

time = Key_Press_4() - 1;
Data_To_Gps(time_mode_change, 4, 1, time, 0, 0);
break;
}
break;

case LEAP_SECOND:
Data_To_Gps(leap_second, 5, 0, 0, 0, 0);
break;

case ATMOSPHERE:
Atmos_Menu();

num3 = Key_Press_4();

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (55 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

switch(num3)
{
case ATMOSPHERE_POLL:
Data_To_Gps(atmosphere_poll, 5, 0, 0, 0, 0);
break;

case ATMOSPHERE_CHANGE:
Atmos_Sub_Menu();
atmos = Key_Press_3() - 1;
Data_To_Gps(atmosphere_change, 4, 1, atmos, 0, 0);
break;
}
break;

case SATELLITE_MASK:
Mask_Menu();

num3 = Key_Press_4();

switch(num3)
{
case MASK_POLL:
Data_To_Gps(mask_poll, 5, 0, 0, 0, 0);
break;

case MASK_CHANGE:
Mask_Sub_Menu();
Numbers( 1 );

angle = Key_Press_6();
Data_To_Gps(mask_change, 4, 1, angle, 0, 0);
break;
}
break;
}
break;
///////////////////////////////////////////////////////////
case RECEIVER_FUNC:
Sub_Menu3();

num2 = Key_Press_0();

if(check == 0)
{
lcd_clear_text(); //write spaces
cput(0x94); //Graphics OFF & Text ON, cursor blinking

lcd_xy(0,3); //first character, 3 line


lcd_print("Disable first polling command!!!!");
num2 = 10;
}

switch(num2)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (56 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

{
case GPS_ID:
Data_To_Gps(gps_id, 4, 0, 0, 0, 0);
break;

case GPS_SELFTEST:
Data_To_Gps(gps_selftest, 4, 0, 0, 0, 0);
break;

case GPS_SET_DEFAULTS:
Data_To_Gps(gps_set_defaults, 4, 0, 0, 0, 0);
break;
}
break;
}
}
} while(num1 != 4);

cput(0x98); // Graphics ON, Text OFF, display stored picture

outp(PORT + 1, 0); //Turn off interrupts


outp(0x21, (inp(0x21) | 0x10)); //Mask IRQ using PIC
//COM1 (IRQ4) - 0x10
//COM2 (IRQ3) - 0x08

setvect(INTVECT, oldport1isr); //Restore old interrupt vector


}

FILE: GPS.H

#define PORT 0x3F8 //COM1 = 0x3F8


//COM2 = 0x2F8
#define INTVECT 0x0C //Com Port's IRQ here
#define DATA_READY 1

#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif

int bufferin = 0;
int bufferout = 0;
int buffer[2049];

char pos_status_data[4] = { '@', '@', 'E', 'a' };


char lattitude[8]
= { '@', '@', 'A', 'd', 0x99, 0x99, 0x99, 0x99 };
char longitude[8]
= { '@', '@', 'A', 'e', 0x99, 0x99, 0x99, 0x99 };
char height[9]

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (57 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

= { '@', '@', 'A', 'f', 0x99, 0x99, 0x99, 0x99, 0x99 };


char date[8]
= { '@', '@', 'A', 'c', 0xFF, 0xFF, 0xFF, 0xFF };
char time_of_day[7]
= { '@', '@', 'A', 'a', 0xFF, 0xFF, 0xFF };
char satellites[5] = { '@', '@', 'B', 'b', 0 };
char almanac[5] = { '@', '@', 'B', 'e', 0 };

char gmt_poll[7]
= { '@', '@', 'A', 'b', 0xFF, 0xFF, 0xFF };
char gmt_change[4] = { '@', '@', 'A', 'b' };
char time_mode_poll[5]= { '@', '@', 'A', 'w', 0xFF };
char time_mode_change[4] = { '@', '@', 'A', 'w' };
char leap_second[5] = { '@', '@', 'B', 'j', 0 };
char atmosphere_poll[5] = { '@', '@', 'A', 'q', 0xFF };
char atmosphere_change[4] = { '@', '@', 'A', 'q' };
char mask_poll[5] = { '@', '@', 'A', 'g', 0xFF };
char mask_change[4] = { '@', '@', 'A', 'g' };

char gps_id[4] = { '@', '@', 'C', 'j' };


char gps_selftest[4] = { '@', '@', 'F', 'a' };
char gps_set_defaults[4] = { '@', '@', 'C', 'f' };

void interrupt (*oldport1isr)(__CPPARGS);

//Interrupt servive routine (ISR)


void interrupt PORTINT(__CPPARGS)
//for PORT (COM1)
{
int status;
do
{
status = inp(PORT + 5);
if (status & DATA_READY)
{
buffer[bufferin] = inp(PORT);
bufferin++;
if(bufferin == 2048)
bufferin = 0;
}
} while(status & DATA_READY);

outp(0x20,0x20);
}

void Data_To_Gps(char data[], int max, int flag,


int var1, int var2, int var3)
{
int i, checksum = data[2];

for(i = 0; i < max; i++)


{
outp(PORT, data[i]); //send char to serial port
delay(1);

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (58 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

if(i > 2)
checksum ^= data[i];
}
checksum ^= var1 ^ var2 ^ var3;

if(flag == 1)
{
outp(PORT, var1); //send char to serial port
delay(1);
}
else if(flag == 2)
{
outp(PORT, var1); //send char to serial port
delay(1);
outp(PORT, var2); //send char to serial port
delay(1);
}
else if(flag == 3)
{
outp(PORT, var1); //send char to serial port
delay(1);
outp(PORT, var2); //send char to serial port
delay(1);
outp(PORT, var3); //send char to serial port
delay(1);
}
outp(PORT, checksum); //send char to serial port
delay(1);
outp(PORT, 0x0D); //send <CR> to serial port
delay(1);
outp(PORT, 0x0A); //send <LF> to serial port
delay(1);
}

int Buffer()
{
int ch;
ch = buffer[bufferout];
delay(2);
bufferout++;
if(bufferout == 2048)
bufferout = 0;

return ch;
}

long Bytes(int num)


{
long b;
int i;
for(i = 0; i < num; i++)
{
if(i == 0)
b = Buffer();
b <<= 8;

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (59 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

b = b | Buffer();
}
return b;
}

void End()
{
int byte;
byte = Buffer();
byte = Buffer();
byte = Buffer();
}

FILE: LCD.H

//////////////////////////////////////////////////////
//Program to control a T6963C-based 240x64 pixel LCD display
////////////////////////////////////////////////////////

#define CEHI outp(pcont, (inp(pcont) & 0xfe))//take PC 1 HI


#define CELO outp(pcont, (inp(pcont) | 0x01))//take PC 1 LO

#define RDHI outp(pcont, (inp(pcont) & 0xfd))//take PC 14 HI


#define RDLO outp(pcont, (inp(pcont) | 0x02))//take PC 14 LO

#define WRHI outp(pcont, (inp(pcont) | 0x04))//take PC 16 HI


#define WRLO outp(pcont, (inp(pcont) & 0xfb))//take PC 16 LO

#define CDHI outp(pcont, (inp(pcont) & 0xf7))//take PC 17 HI


#define CDLO outp(pcont, (inp(pcont) | 0x08))//take PC 17 LO

/* ---- Definitions concerning LCD internal memory --- */

#define G_BASE 0x0200 //base address of graphics memory


#define T_BASE 0x0000 //base address of text memory
#define BYTES_PER_ROW 40 //how many bytes per row on screen

//This will be 30 with 8x8 font, 40 with 6x8 font,


//for both Text & Graphics modes. Font selection by
//FS pin on LCD module:
//FS=High: 6x8 font. FS=Low: 8x8 font.

void dput(int byte); //write data byte to LCD module


int sget(void); //check LCD display status pbrt
void cput(int byte); //write command byte to LCD module
//make sure control lines are at correct levels
void lcd_setup();
void lcd_init(); //initialize LCD memory and display modes
//send string of characters to LCD
void lcd_print(char *string);
void lcd_clear_graph(); //clear graphics memory of LCD
void lcd_clear_text(); //clear text memory of LCD

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (60 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

//set memory pointer to (x,y) position (text)


void lcd_xy(int x, int y);
//set single pixel in 240x64 array
void lcd_setpixel(int column, int row);
void Disp_Pic();
int array[15];

#define BASE 0x378 //base address for parallel port LPT1:


int pdata = BASE; //par.port data register
int pcont = BASE+2;//par.port control register

////////////////////////////////////////////////////////////
void lcd_clear_graph() //clear graphics memory of LCD
{
int i;

dput(G_BASE%256);
dput(G_BASE>>8);
cput(0x24); //addrptr at address G_BASE

for (i = 0; i < 2560; i++)


{
dput(0); //write data
cput(0xc0); //inc ptr
} //end for(i)
} //end lcd_clear_graph()

void lcd_clear_text()
{
int i;

dput(T_BASE%256); //set low address


dput(T_BASE>>8); //set high address
cput(0x24); //addrptr at address T_BASE

for (i = 0; i < 320; i++)//40 chars in a line * 8 lines


{
dput(0); //write space
cput(0xc0); //inc ptr
} //end for(i)
} //lcd_clear_text()

//send string of characters to LCD


void lcd_print(char *string)
{
int i;
int c;

for (i = 0; i < strlen(string); i++)


{
c = string[i] - 0x20; //convert ASCII to LCD char address
if (c<0)
c=0;

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (61 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

dput(c); //write character


cput(0xc0); //increment memory ptr.
} //end for
} //end lcd_print

//send string of characters to LCD


void lcd_print_num(long num, int f)
{
long c;
int temp;
int count = 0, i;

temp = num;
while(1)
{
c = num % 10;

array[count] = char(c);//convert ASCII to LCD char address


count++;
num = num / 10;

if(num == 0)
break;
}
if((f == 1) && (temp > 0) && (temp < 10))
{
array[count] = char(0);
count++;
}
for(i = count - 1; i >= 0 ; i--)
{
c = array[i] | 0x10;
if (c<0)
c=0;
dput(c); //write character
cput(0xc0); //increment memory ptr.
}
} //end lcd_print_num

//send string of characters to LCD


void lcd_print_float(float num)
{
long c, n;
int count1 = 0, count2 = 0, count3 = 0, i;
int temp;

if((num > 0) && (num < 1))


{
while(1)
{
num = num * 10;
count1++;
if(num >= 1)
break;
}

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (62 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

}
temp = count1;
while(1)
{
n = num;
if((n < num) || (n > num))
{
num = num * 10;
count1++;
}
else if(n == num)
break;
}

n = num;

while(1)
{
c = n % 10;

array[count2] = char(c);//convert ASCII to LCD char address


count2++;
n = n / 10;

if(n == 0)
break;
}

if(count2 > count1)


{
for(i = (count2 - 1); i >= 0 ; i--)
{
if(((count2 - count1) == count3) && (count1 != 0))
lcd_print(".");

c = array[i] | 0x10;
count3++;
if (c<0)
c=0;
dput(c); //write character
cput(0xc0); //increment memory ptr.
}
}
else if(count2 <= count1)
{
c = 0x10;
dput(c); //write character
cput(0xc0); //increment memory ptr.
lcd_print(".");
count1--;
for(i = (count2 - 1); i >= 0 ; i--)
{
while((temp - 1) > count3)
{
c = 0x10;

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (63 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

dput(c); //write character


cput(0xc0); //increment memory ptr.
count3++;
}
c = array[i] | 0x10;
if (c<0)
c=0;
dput(c); //write character
cput(0xc0); //increment memory ptr.
}
}
} //end lcd_print_float

//set single pixel in 240x64 array


void lcd_setpixel(int column, int row)
{
int addr; //memory address of byte containing pixel to write

addr = G_BASE + (row * BYTES_PER_ROW) + (column / 6);


dput(addr%256);
dput(addr>>8);
cput(0x24); //set LCD addr. pointer
//set bit-within-byte command
cput(0xf8 | (5 - (column % 6)) );

} //end lcd_setpixel()

//set memory pointer to (x,y) position (text)


void lcd_xy(int x, int y)
{
int addr;

addr = T_BASE + (y * BYTES_PER_ROW) + x;


dput(addr%256);
dput(addr>>8);
cput(0x24); //set LCD addr. pointer

} //lcd_xy()

/* ===================================================
* Low-level I/O routines to interface to LCD display
* based on four routines:
*
* dput(): write data byte
* cput(): write control byte
* sget(): read status
* ===================================================
*/
//make sure control lines are at correct levels
void lcd_setup()
{
CEHI; //disable chip
RDHI; //disable reading from LCD
WRHI; //disable writing to LCD
CDHI; //command/status mode

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (64 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

} //end lcd_setup()

void lcd_init() //initialize LCD memory and display modes


{
dput(G_BASE%256);
dput(G_BASE>>8);
cput(0x42); //set graphics memory to address G_BASE

dput(BYTES_PER_ROW%256);
dput(BYTES_PER_ROW>>8);
cput(0x43); //n bytes per graphics line

dput(T_BASE%256);
dput(T_BASE>>8);
cput(0x40); //text memory at address T_BASE

dput(BYTES_PER_ROW%256);
dput(BYTES_PER_ROW>>8);
cput(0x41); //n bytes per text line

cput(0x80); //mode set: Graphics OR Text, ROM CGen

cput(0xA7); //cursor is 8 lines high

dput(0x00);
dput(0x00);
cput(0x21); //put cursor at (x,y) location

//define own char(degree sign)


dput(0x03);
dput(0x00);
cput(0x22); //offset register set / set CG RAM
dput(0x00);
dput(0x1C);
cput(0x24); //set address pointer

dput(0x1C);
cput(0xC0);
dput(0x14);
cput(0xC0);
dput(0x1C);
cput(0xC0);
dput(0x00);
cput(0xC0);
dput(0x00);
cput(0xC0);
dput(0x00);
cput(0xC0);
dput(0x00);
cput(0xC0);
dput(0x00);
cput(0xC0);

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (65 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

} //end lcd_init()

int sget(void) //get LCD display status byte


{
int lcd_status;

RDLO; //bring LCD /RD line low (read active)


WRHI; //make sure WRITE mode is inactive
CELO; //bring LCD /CE line low (chip-enable active)
CDHI; //bring LCD C/D line high (read status byte)
delay(1);
lcd_status = inp(pdata); //read LCD status byte
CEHI; //bring LCD /CE line high, disabling it
RDHI; //deactivate LCD read mode

return(lcd_status);
} //sget()

//write data byte to LCD module over par. port


void dput(int byte)
//assume PC port in data OUTPUT mode
{
//wait until display ready
do {} while ((0x03 & sget()) != 0x03);
outp(pdata, byte); //write value to data port
CDLO;
WRLO; //activate LCD's write mode
RDHI; //make sure LCD read mode is off
CELO; //pulse enable LOW > 80 ns (hah!)
delay(1);
CEHI; //return enable HIGH
WRHI; //restore Write mode to inactive
} //end dput()

void cput(int byte) //write command byte to LCD module


//assumes port is in data OUTPUT mode
{
//wait until display ready
do {} while ((0x03 & sget()) != 0x03);

outp(pdata, byte); //present data to LCD on PC's port pins

CDHI; //control/status mode


RDHI; //make sure LCD read mode is off
WRLO; //activate LCD write mode
CELO; //pulse ChipEnable LOW, > 80 ns, enables LCD I/O
delay(1);
CEHI; //disable LCD I/O
WRHI; //deactivate write mode
} //cput()

void Disp_Pic()
{
int i = 0, j = 0, k; //generic counter
int num, no;

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (66 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

int counter = 0;

lcd_clear_graph(); //fill graphics memory with 0x00


cput(0x98); // Graphics ON, Text OFF

while(1)
{
num = Gps_pic_less[counter];
if(num > 1000)
{
for(k = 1000; k < num ; k++)
{
j += 8;
if(j == 240)
{
j = 0;
i++;
if(i == 64)
break;
}
}
}
else
{
for(k = 0; k < 8; k++)
{
no = num & 0x80;
num <<= 1;
if(no == 0x80)
lcd_setpixel(j + k, i); // draw pixel on LCD screen
}
j += 8;
if(j == 240)
{
j = 0;
i++;
if(i == 64)
break;
}
}
counter++;
}
}

FILE: DISP.H

#define MAIN_MENU 0
#define POS_STA_DAT 1
#define GPS_MODES 2
#define RECEIVER_FUNC 3

#define POS_STATUS_DATA 1
#define LATTITUDE 2

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (67 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

#define LONGITUDE 3
#define HEIGHT 4
#define DATE 5
#define TIME_OF_DAY 6
#define SATELLITES 7
#define ALMANAC 8

#define GMT 1
#define TIME_MODE 2
#define LEAP_SECOND 3
#define ATMOSPHERE 4
#define SATELLITE_MASK 5

#define GPS_ID 1
#define GPS_SELFTEST 2
#define GPS_SET_DEFAULTS 3

#define POS_1 1
#define POS_2 2
#define POS_3 3
#define POS_4 4

#define GMT_POLL 1
#define GMT_CHANGE 2

#define TIME_MODE_POLL 1
#define TIME_MODE_CHANGE 2

#define ATMOSPHERE_POLL 1
#define ATMOSPHERE_CHANGE 2

#define MASK_POLL 1
#define MASK_CHANGE 2

int lines;
int chars;
int key;
long byte;

char pole[2];

char *messages[16] = { "Channel 1 Correlation Test Fail!!!",


"Channel 2 Correlation Test Fail!!!",
"Channel 3 Correlation Test Fail!!!",
"Channel 4 Correlation Test Fail!!!",
"Channel 5 Correlation Test Fail!!!",
"Channel 6 Correlation Test Fail!!!",
"Channel 7 Correlation Test Fail!!!",
"Channel 8 Correlation Test Fail!!!",
"1 kHz Presence",
"ROM Fail",
"RAM Fail",
"Ignore",
"Temperature Sensor Fail",

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (68 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

"RTC Comm & Time Fail",


"Antenna Overcurrent:",
"Antenna Undercurrent:"
};
char *channel[9] = { " - code search.",
" - code acquire.",
" - AGC set.",
" - preq acquire.",
" - bit sync detect.",
" - message sync detect.",
" - satellite time available.",
" - ephemeris acquire.",
" - available for position."
};

char *ch_status[8] = { " - parity error.",


"",
"",
" - satellite reported inaccurate(>16m).",
" - satellite reported unhealthy.",
" - satellite anti_spoof flag set.",
" - satellite momentum alert flag.",
" - using for position fix."
};

char *re_status[8] = { " - bad almanac.",


" - insufficient visible satellites(< 3).",
"",
" - acquiring satellites.",
" - 2D fix.",
" - 3D fix.",
" - poor geometry (DOP > 12)."
" - position propagate mode."
};

int nums[3][10] = { { 0, 0, 0, 1, 0, 0, 2, 0, 0, 3},


{ 0, 0, 0, 4, 0, 0, 5, 0, 0, 6},
{ 0, 0, 0, 7, 0, 0, 8, 0, 0, 9}
};

void Init_Text( int f )


{
lcd_clear_text(); //write spaces
if(f == 0)
cput(0x97); //Graphics OFF & Text ON, cursor blinking
else if(f == 1)
cput(0x94); //Graphics OFF & Text ON, cursor off
}

void Cursor_Pos(int l, int c)


{
if(l == -1)
lines--;
else if(l == 10)
lines++;

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (69 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

else
lines = l;

chars = c;

dput(chars);
dput(lines);
cput(0x21); //put cursor at (x,y) location
}

void Numbers( int f )


{
Cursor_Pos(5, 13);

lcd_xy(13,4); //first character, 5 line


lcd_print("0 1 2 3");
lcd_xy(13,5); //first character, 6 line
if(f == 0)
lcd_print("- 4 5 6");
else if(f == 1)
lcd_print("* 4 5 6");
lcd_xy(13,6); //first character, 7 line
if(f == 0)
lcd_print("+ 7 8 9");
else if(f == 1)
lcd_print(" 7 8 9");
}

int Key_Press_0()
{
while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x11B)
{
lines = 6;
break;
}
else if(key == 0x1C0D)
break;
else if(key == 0x4800)
{
if(lines > 3)
Cursor_Pos(-1, chars);
else if(lines == 3)
Cursor_Pos(5, chars);
}
else if(key == 0x5000)
{
if(lines < 5)
Cursor_Pos(10, chars);
else if(lines == 5)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (70 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Cursor_Pos(3, chars);
}
}
return (lines - 2);
}

int Key_Press_1()
{
while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x11B)
{
lines = 9;
break;
}
else if(key == 0x1C0D)
break;
else if(key == 0x4800)
{
if(lines > 0)
Cursor_Pos(-1, chars);
else if(lines == 0)
Cursor_Pos(7, chars);
}
else if(key == 0x5000)
{
if(lines < 7)
Cursor_Pos(10, chars);
else if(lines == 7)
Cursor_Pos(0, chars);
}
}
return (lines + 1);
}

int Key_Press_2()
{
while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x11B)
{
lines = 6;
break;
}
else if(key == 0x1C0D)
break;
else if(key == 0x4800)
{
if(lines > 1)
Cursor_Pos(-1, chars);
else if(lines == 1)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (71 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Cursor_Pos(5, chars);
}
else if(key == 0x5000)
{
if(lines < 5)
Cursor_Pos(10, chars);
else if(lines == 5)
Cursor_Pos(1, chars);
}
}
return lines;
}

int Key_Press_3()
{
while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x11B)
{
lines = 6;
break;
}
else if(key == 0x1C0D)
break;
else if(key == 0x4800)
{
if(lines > 1)
Cursor_Pos(-1, chars);
else if(lines == 1)
Cursor_Pos(4, chars);
}
else if(key == 0x5000)
{
if(lines < 4)
Cursor_Pos(10, chars);
else if(lines == 4)
Cursor_Pos(1, chars);
}
}
return lines;
}

int Key_Press_4()
{
while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x11B)
{
lines = 6;
break;

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (72 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

}
else if(key == 0x1C0D)
break;
else if(key == 0x4800)
{
if(lines > 3)
Cursor_Pos(-1, chars);
else if(lines == 3)
Cursor_Pos(4, chars);
}
else if(key == 0x5000)
{
if(lines < 4)
Cursor_Pos(10, chars);
else if(lines == 4)
Cursor_Pos(3, chars);
}
}
return (lines - 2);
}

char Key_Press_5()
{
char sign;

while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x11B)
{
sign = '+';
break;
}
else if(key == 0x1C0D)
break;
else if((key == 0x4800) && (chars == 13))
{
if(lines > 5)
Cursor_Pos(-1, chars);
else if(lines == 5)
Cursor_Pos(6, chars);
}
else if((key == 0x5000) && (chars == 13))
{
if(lines < 6)
Cursor_Pos(10, chars);
else if(lines == 6)
Cursor_Pos(5, chars);
}
}
if(lines == 5)
sign = '-';
else if(lines == 6)
sign = '+';

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (73 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

return sign;
}

int Key_Press_6()
{
int num = 0, i, count = 0;
int yebo[5];

while(1)
{

while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x11B)
{
num = 0;
break;
}
else if(key == 0x1C0D)
break;
else if((key == 0x4800) && (chars != 13))
{
if(lines > 4)
Cursor_Pos(-1, chars);
else if(lines == 4)
Cursor_Pos(6, chars);
}
else if((key == 0x5000) && (chars != 13))
{
if(lines < 6)
Cursor_Pos(10, chars);
else if(lines == 6)
Cursor_Pos(4, chars);
}
else if((key == 0x4800) && (chars == 13))
{
if(lines > 4)
Cursor_Pos(-1, chars);
else if(lines == 4)
Cursor_Pos(5, chars);
}
else if((key == 0x5000) && (chars == 13))
{
if(lines < 5)
Cursor_Pos(10, chars);
else if(lines == 5)
Cursor_Pos(4, chars);
}
else if((key == 0x4B00) && ((lines == 4) || (lines == 5)))
{
if(chars > 13)
Cursor_Pos(lines, chars - 3);

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (74 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

else if(chars == 13)


Cursor_Pos(lines, 22);
}
else if((key == 0x4D00) && ((lines == 4) || (lines == 5)))
{
if(chars < 22)
Cursor_Pos(lines, chars + 3);
else if(chars == 22)
Cursor_Pos(lines, 13);
}
else if((key == 0x4B00) && (lines == 6))
{
if(chars > 16)
Cursor_Pos(lines, chars - 3);
else if(chars == 16)
Cursor_Pos(lines, 22);
}
else if((key == 0x4D00) && (lines == 6))
{
if(chars < 22)
Cursor_Pos(lines, chars + 3);
else if(chars == 22)
Cursor_Pos(lines, 16);
}
}
if(key == 0x11B)
{
num = 0;
break;
}
else if(key == 0x1C0D)
{
if((lines == 5) && (chars == 13))
{
for(i = 1; i <= count; i++)
num = num + yebo[i - 1] * pow(10,count - i);
break;
}
else
{
count++;
yebo[count - 1] = nums[lines - 4][chars - 13];
lcd_xy(14 + count,2);
lcd_print_num(yebo[count - 1],0);
}
}
}
return num;
}

void Main_Menu()
{
Init_Text(0);
Cursor_Pos(3, 7);

lcd_xy(0,0); //write text from upper left corner

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (75 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcd_print("Main Menu to operate the GPS Oncore.");


lcd_xy(0,1); //first character, 2 line
lcd_print("Press ESC to quit!!");
lcd_xy(8,3); //first character, 4 line
lcd_print("POSITION/STATUS/DATA:");
lcd_xy(8,4); //first character, 5 line
lcd_print("GPS MODES:");
lcd_xy(8,5); //first character, 6 line
lcd_print("RECEIVER FUNCTIONS:");
}

void Sub_Menu1()
{
Init_Text(0);
Cursor_Pos(0, 7);

lcd_xy(8,0); //write text from upper left corner


lcd_print("POS/STATUS/DATA:");
lcd_xy(8,1); //first character, 2 line
lcd_print("LATTITUDE:");
lcd_xy(8,2); //first character, 3 line
lcd_print("LONGITUDE:");
lcd_xy(8,3); //first character, 4 line
lcd_print("HEIGHT:");
lcd_xy(8,4); //first character, 5 line
lcd_print("DATE:");
lcd_xy(8,5); //first character, 6 line
lcd_print("TIME OF DAY:");
lcd_xy(8,6); //first character, 7 line
lcd_print("VISIBLE SATELLITES:");
lcd_xy(8,7); //first character, 8 line
lcd_print("ALMANAC DATA OUTPUT:");
}

void Sub_Menu2()
{
Init_Text(0);
Cursor_Pos(1, 7);

lcd_xy(8,1); //first character, 2 line


lcd_print("GMT OFFSET:");
lcd_xy(8,2); //first character, 3 line
lcd_print("TIME MODE:");
lcd_xy(8,3); //first character, 4 line
lcd_print("LEAP SECOND PENDING STATUS:");
lcd_xy(8,4); //first character, 5 line
lcd_print("ATMOSPHERIC CORRECTION MODE:");
lcd_xy(8,5); //first character, 6 line
lcd_print("SATELLITE MASK ANGLE:");
}

void Sub_Menu3()
{
Init_Text(0);
Cursor_Pos(3, 11);

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (76 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcd_xy(12,3); //first character, 3 line


lcd_print("RECEIVER ID:");
lcd_xy(12,4); //first character, 4 line
lcd_print("GPS SELFTEST:");
lcd_xy(12,5); //first character, 5 line
lcd_print("SET TO DEFAULTS:");
}

void Pos_Menu(int flag)


{
Init_Text(0);
Cursor_Pos(1, 1);

lcd_xy(2,1); //first character, 2 line


if(flag == 0)
lcd_print("Disable Polling:");
else if(flag == 1)
lcd_print("Poll Position/Status/Data once:");
lcd_xy(2,2); //first character, 3 line
lcd_print("Poll Position once every 10 seconds:");
lcd_xy(2,3); //first character, 4 line
lcd_print("Poll Position once every 20 seconds:");
lcd_xy(2,4); //first character, 5 line
lcd_print("Poll Position once every 30 seconds:");
}

void Gmt_Menu()
{
Init_Text(0);
Cursor_Pos(3, 1);

lcd_xy(2,3); //first character, 3 line


lcd_print("Poll current GMT Offset:");
lcd_xy(2,4); //first character, 4 line
lcd_print("Change current GMT Offset:");
}

void Time_Menu()
{
Init_Text(0);
Cursor_Pos(3, 1);

lcd_xy(2,3); //first character, 3 line


lcd_print("Poll current Time Mode:");
lcd_xy(2,4); //first character, 4 line
lcd_print("Change current Time Mode:");
}

void Time_Change()
{
Init_Text(0);
Cursor_Pos(3, 1);

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (77 of 206) [30/05/2004 08:31:22 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcd_xy(2,3); //first character, 3 line


lcd_print("GPS Time:");
lcd_xy(2,4); //first character, 4 line
lcd_print("UTC Time:");
}

void Atmos_Menu()
{
Init_Text(0);
Cursor_Pos(3, 1);

lcd_xy(2,3); //first character, 4 line


lcd_print("Poll Atmosphere Correction Mode:");
lcd_xy(2,4); //first character, 4 line
lcd_print("Change Atmosphere Correction Mode:");
}

void Atmos_Sub_Menu()
{
Init_Text(0);
Cursor_Pos(1, 1);

lcd_xy(2,1); //first character, 2 line


lcd_print("Ionosperic Model disabled:");
lcd_xy(2,2); //first character, 3 line
lcd_print("Ionosperic Model only enabled:");
lcd_xy(2,3); //first character, 4 line
lcd_print("Tropospheric Model only enabled:");
lcd_xy(2,4); //first character, 5 line
lcd_print("Both Models enabled:");
}

void Mask_Menu()
{
Init_Text(0);
Cursor_Pos(3, 1);

lcd_xy(2,3); //first character, 3 line


lcd_print("Poll current Satellite Mask Angle:");
lcd_xy(2,4); //first character, 4 line
lcd_print("Change current Satellite Mask Angle:");
}

void Mask_Sub_Menu()
{
Init_Text(0);

lcd_xy(2,0); //write text from upper left corner


lcd_print("Enter angle in degrees( 0 - 89 ): ");
}

void Disp_Aa(int flag)


{

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (78 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

if(flag == 0)
{
Init_Text(1);
lcd_xy(0,3); //first character, 3 line
lcd_print("Current Time: ");
}
if(flag == 1)
{
lcd_xy(17,0);
lcd_print("/ Time: ");
}
lcd_print_num(Buffer(),1);
lcd_print(":");
lcd_print_num(Buffer(),1);
lcd_print(":");
lcd_print_num(Buffer(),1);
lcd_print(" hours");

if(flag == 0)
End();
}

void Disp_Ab()
{
Init_Text(1);

lcd_xy(0,3); //first character, 3 line


lcd_print("GMT offset: ");

byte = Buffer();
if(byte == 0)
lcd_print("+");
else
lcd_print("-");

lcd_print_num(Buffer(),0);
lcd_print(":");
lcd_print_num(Buffer(),0);
lcd_print(" hours");

End();
}

void Disp_Ac(int flag)


{
if(flag == 0)
{
Init_Text(1);
lcd_xy(0,3); //first character, 3 line
lcd_print("Current Date(dd/mm/yyyy): ");
}
else if(flag == 1)
{
lcd_xy(0,0);
lcd_print("Date: ");

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (79 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

byte = Buffer();
lcd_print_num(Buffer(),1);
lcd_print("/");
lcd_print_num(byte,1);
lcd_print("/");
lcd_print_num(Bytes(1),0);

if(flag == 0)
End();
}

void Disp_Ad(int flag)


{
long temp;
float minutes;
strcpy(pole, "N");

if(flag == 0)
{
Init_Text(1);
lcd_xy(0,1); //first character, 1 line
lcd_print("Lattitude(milliarcseconds or mas): ");
}

byte = Bytes(3);

if(flag == 0)
{
lcd_xy(5,2);
if(byte > 0)
{
lcd_print("+");
temp = byte;
}
else
{
lcd_print("-");
temp = -byte;
}
lcd_print_num(temp,0);
lcd_print("mas");

lcd_xy(0,3); //first character, 5 line


lcd_print("Lattitude(degrees/min.sec): ");
}
else if(flag == 1)
{
lcd_xy(0,1); //first character, 3 line
lcd_print("Position: ");
}
minutes = byte;
if(minutes < 0)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (80 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

minutes = -minutes;

byte = byte / 3600000;


if(byte < 0)
{
byte = -byte;
strcpy(pole, "S");
}
if(flag == 0)
lcd_xy(5,4);
lcd_print_num(byte,0);
dput(0x80); //write character(degree sign)
cput(0xc0); //increment memory ptr.
minutes = ( (minutes/3600000) - byte) * 60;
lcd_print_float(minutes);
lcd_print(" ");
lcd_print(pole);

if(flag == 0)
End();
}

void Disp_Ae(int flag)


{
long temp;
float minutes;
strcpy(pole, "E");

if(flag == 0)
{
Init_Text(1);
lcd_xy(0,1); //first character, 1 line
lcd_print("Longitude(milliarcseconds or mas): ");
}

byte = Bytes(3);

if(flag == 0)
{
lcd_xy(5,2);
if(byte > 0)
{
lcd_print("+");
temp = byte;
}
else
{
lcd_print("-");
temp = -byte;
}
lcd_print_num(temp,0);
lcd_print("mas");

lcd_xy(0,3); //first character, 5 line


lcd_print("Longitude(degrees/min.sec): ");

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (81 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

}
else if(flag == 1)
{
lcd_xy(23,1); //first character, 3 line
lcd_print("/ ");
}
minutes = byte;
if(minutes < 0)
minutes = -minutes;

byte = byte / 3600000;


if(byte < 0)
{
byte = -byte;
strcpy(pole, "W");
}
if(flag == 0)
lcd_xy(5,4);
lcd_print_num(byte,0);
dput(0x80); //write character(degree sign)
cput(0xc0); //increment memory ptr.
minutes = ( (minutes/3600000) - byte) * 60;
lcd_print_float(minutes);
lcd_print(" ");
lcd_print(pole);

if(flag == 0)
End();
}

void Disp_Af(int flag)


{
float height;

if(flag == 0)
{
Init_Text(1);

lcd_xy(0,1); //first character, 1 line


lcd_print("Height(ellipsoid height in meters): ");
lcd_xy(5,2);
}
else if(flag == 1)
{
lcd_xy(7,2); //first character, 1 line
lcd_print("Height (m): ");
}

byte = Bytes(3);
height = byte;
lcd_print_float(height/100);
lcd_print("m");

if(flag == 0)
End();

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (82 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

void Disp_Ag()
{
Init_Text(1);

lcd_xy(0,3); //first character, 1 line


lcd_print("Satellite Mask Angle(degrees): ");
lcd_print_num(Buffer(),0);
dput(0x80); //write character(degree sign)
cput(0xc0); //increment memory ptr.

End();
}

void Disp_Aq()
{
Init_Text(1);

lcd_xy(0,3);
lcd_print("Atmospheric Correction Mode: ");
byte = Buffer();
lcd_xy(2,4);
if(byte == 0)
lcd_print("'0' = Ionosphere model disabled.");
else if(byte == 1)
lcd_print("'1' = Ionosphere model only enabled.");
else if(byte == 2)
lcd_print("'2' = Troposphreric model only enabled.");
else if(byte == 3)
lcd_print("'3' = Both models enabled.");

End();
}

void Disp_Aw()
{
Init_Text(1);

lcd_xy(0,3);
lcd_print("Current Time Mode: ");
byte = Buffer();
lcd_xy(2,4);
if(byte == 0)
lcd_print("'0' = GPS Time.");
else if(byte == 1)
lcd_print("'1' = UTC Time.");

End();
}

void Disp_Bb()
{
int num, i, key;

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (83 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Init_Text(1);

lcd_xy(3,3);
lcd_print("Current Visible Satellites: ");
num = Buffer();
lcd_print_num(num,0);
lcd_xy(10,7);
lcd_print("...press enter for next page.");

while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x1C0D)
break;
}

for(i = 0; i < num; i++)


{
Init_Text(1);

lcd_xy(0,1);
lcd_print("Satellite ");
lcd_print_num(i + 1,0);
lcd_print(": PN code ID: ");
lcd_print_num(Buffer(),0);
lcd_xy(0,2);
lcd_print("Doppler freq: ");
lcd_print_num(Bytes(1),0);
lcd_print("Hz");
lcd_xy(0,3);
lcd_print("Elevation: ");
lcd_print_num(Buffer(),0);
dput(0x80); //write character(degree sign)
cput(0xc0); //increment memory ptr.
lcd_xy(0,4);
lcd_print("Azimuth: ");
lcd_print_num(Bytes(1),0);
dput(0x80); //write character(degree sign)
cput(0xc0); //increment memory ptr.

byte = Buffer();
lcd_xy(0,5);
lcd_print("Satellite is ");
if(byte == 0)
lcd_print("healthy & not removed.");
else if(byte == 1)
lcd_print("healthy & removed.");
else if(byte == 2)
lcd_print("unhealthy & not removed.");
else if(byte == 3)
lcd_print("unhealthy & removed.");

lcd_xy(35,7);

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (84 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcd_print(".....");
while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x1C0D)
break;
}
}
num = (12 - num) * 7;
for(i = 0; i < num; i++)
byte = Buffer();

End();
}

void Disp_Bj()
{
Init_Text(1);

lcd_xy(0,3);
lcd_print("Leap Second Pending Status: ");
byte = Buffer();
lcd_xy(2,4);
if(byte == 0)
lcd_print("'0' = No leap second pending.");
else if(byte == 1)
lcd_print("'1' = Addition of one second pending.");
else if(byte == 2)
lcd_print("'2' = Subtraction of one second pending.");

End();
}

void Disp_Cb()
{
int data_id, sv_id, frame, page;
int af0, af1;
int i;
float number;
char pm[2];
strcpy(pm, " ");

Init_Text(1);

frame = Buffer();
page = Buffer();
byte = Buffer();
data_id = ((byte & 0xC0) >> 6);
sv_id = (byte & 0x3F);
// cout << "\n\tData ID: " << data_id;
if( (page == 25) || (data_id == 2) || (sv_id > 32) )
{
for(i = 0; i < 23; i++)
byte = Buffer();

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (85 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

End();
}
else
{
lcd_xy(0,0);
lcd_print("SUBFRAME: ");
lcd_print_num(frame,0);
lcd_print(" / PAGE: ");
lcd_print_num(page,0);
lcd_xy(0,1);
lcd_print("SV ID: ");
lcd_print_num(sv_id,0);

number = Bytes(1) * pow(2, -21);


lcd_xy(0,2);
lcd_print("Eccentricity: ");
lcd_print_float(number);
number = Buffer() * pow(2, 12);
lcd_xy(0,3);
lcd_print("Time of Applicability (s): ");
lcd_print_float(number);

byte = Bytes(1);
if((byte >> 15) & 1 == 1)
{
number = ((~byte + 1) * pow(2, -19) * M_PI) + (0.3 * M_PI);
number = -number;
strcpy(pm, "-");
}
else
number = (byte * pow(2, -19) * M_PI) + (0.3 * M_PI);
lcd_xy(0,4);
lcd_print("Orbital Inclination(rad): ");
lcd_print(pm);
lcd_print_float(number);
strcpy(pm, " ");

byte = Bytes(1);
if((byte >> 15) & 1 == 1)
{
number = (~byte + 1) * pow(2, -38)* M_PI;
number = -number;
strcpy(pm, "-");
}
else
number = byte * pow(2, -38)* M_PI;
lcd_xy(0,5);
lcd_print("Rate of Right Ascen(r/s): ");
lcd_print(pm);
lcd_print_float(number);
strcpy(pm, " ");

lcd_xy(11,1);
lcd_print("/ Health: ");
lcd_print_num(Buffer(),0);

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (86 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

number = Bytes(2) * pow(2, -11);


lcd_xy(0,6);
lcd_print("SQRT(A) (m^1/2): ");
lcd_print_float(number);

lcd_xy(35,7);
lcd_print(".....");
while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x1C0D)
break;
}

Init_Text(1);

byte = Bytes(2);
if((byte >> 23) & 1 == 1)
{
number = (~byte + 1) * pow(2, -23)* M_PI;
number = -number;
strcpy(pm, "-");
}
else
number = byte * pow(2, -23)* M_PI;

lcd_xy(0,1);
lcd_print("Right Ascen at TOA(rad): ");
lcd_print(pm);
lcd_print_float(number);
strcpy(pm, " ");

byte = Bytes(2);
if((byte >> 23) & 1 == 1)
{
number = (~byte + 1) * pow(2, -23)* M_PI;
number = -number;
strcpy(pm, "-");
}
else
number = byte * pow(2, -23)* M_PI;

lcd_xy(0,2);
lcd_print("Argument of Perigee(rad): ");
lcd_print(pm);
lcd_print_float(number);
strcpy(pm, " ");

byte = Bytes(2);
if((byte >> 23) & 1 == 1)
{

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (87 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

number = (~byte + 1) * pow(2, -23)* M_PI;


number = -number;
strcpy(pm, "-");
}
else
number = byte * pow(2, -23)* M_PI;
lcd_xy(0,3);
lcd_print("Mean Anom(rad): ");
lcd_print(pm);
lcd_print_float(number);
strcpy(pm, " ");

af0 = Buffer(); //only get 8MSB's of Af0


af1 = Bytes(1);
byte = (af1 >> 2) & 0x0007;
af0 = ((af0 << 3) | byte);
if((af0 >> 10) & 0x01 == 1)
{
number = (~af0 + 1) * pow(2, -20);
number = -number;
strcpy(pm, "-");
}
else
number = af0 * pow(2, -20);

lcd_xy(0,4);
lcd_print("Af0 (s): ");
lcd_print(pm);
lcd_print_float(number);
strcpy(pm, " ");

af1 >>= 5;
if((af1 >> 10) & 0x01 == 1)
{
number = (~af0 + 1) * pow(2, -20);
number = -number;
strcpy(pm, "-");
}
else
number = af1 * pow(2, -38);

lcd_xy(0,5);
lcd_print("Af1 (s/s): ");
lcd_print(pm);
lcd_print_float(number);
strcpy(pm, " ");

End();

lcd_xy(35,7);
lcd_print(".....");
while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (88 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

if(key == 0x1C0D)
break;
}
}
}

void Disp_Cj()
{
int count = 0;
char array[2];
Init_Text(1);

lcd_xy(0,0);
while(bufferin != bufferout)
{
array[0] = char(Buffer());
if(count == 0)
{
if(array[0] == 0x0D)
{}
else if(array[0] == 0x0A)
{
count++;
}
}
else
{
if(array[0] == 0x0D)
{}
else if(array[0] == 0x0A)
{
if(count == 3)
{
lcd_xy(17,count - 1);
lcd_print(" / ");
count++;
}
else if(count < 3)
{
lcd_xy(0,count);
count++;
}
else
{
lcd_xy(0,count - 1);
count++;
}
}
else
lcd_print(array);
}
}

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (89 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

int Disp_Ea(int flag)


{
int i, j, num;
int count = 0;
float velocity, heading, dop;
int key;

Init_Text(1);

//data
Disp_Ac(1);
//time
Disp_Aa(1);
for(i = 0; i < 4; i++)
byte = Buffer();

//lattitude
Disp_Ad(1);
//longitude
Disp_Ae(1);
//height
Disp_Af(1);
for(i = 0; i < 4; i++)
byte = Buffer();
//velocity
velocity = Bytes(1);
lcd_xy(7,3); //first character, 1 line
lcd_print("Velocity (m/s): ");
lcd_print_float(velocity / 100);

heading = Bytes(1);
lcd_xy(7,4); //first character, 1 line
lcd_print("Current Heading: ");
lcd_print_float(heading / 100);
dput(0x80); //write character(degree sign)
cput(0xc0); //increment memory ptr.

//geometry
dop = Bytes(1);
if(dop == 0)
{
lcd_xy(6,5); //first character, 1 line
lcd_print("Current DOP not computable.");
}
else
{
lcd_xy(7,5); //first character, 1 line
lcd_print("Current DOP: ");
lcd_print_float(dop / 10);
}
byte = Buffer();
lcd_xy(4,6); //first character, 1 line
if(byte == 0)
lcd_print("DOP Type: PDOP(3D)/Antenna Ok.");

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (90 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

else if(byte == 1)
lcd_print("DOP Type: HDOP(2D)/Antenna Ok.");
else if(byte == 64)
lcd_print("DOP Type: PDOP(3D)/Antenna shorted.");
else if(byte == 65)
lcd_print("DOP Type: HDOP(3D)/Antenna shorted.");
else if(byte == 128)
lcd_print("DOP Type: PDOP(3D)/Antenna open.");
else if(byte == 129)
lcd_print("DOP Type: PDOP(3D)/Antenna open.");
else if(byte == 192)
lcd_print("DOP Type: PDOP(3D)/Antenna shorted.");
else if(byte == 193)
lcd_print("DOP Type: PDOP(3D)/Antenna shorted.");

if(flag == 1)
{
lcd_xy(35,7);
lcd_print(".....");
while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x1C0D)
break;
}

//Satellite visibility
Init_Text(1);
lcd_xy(5,2);
lcd_print("Num of visible satellites: ");
lcd_print_num(Buffer(),0);
lcd_xy(5,3);
lcd_print("Num of satellites tracked: ");
lcd_print_num(Buffer(),0);

lcd_xy(35,7);
lcd_print(".....");
while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x1C0D)
break;
}

for(i = 0; i < 8; i++)


{
Init_Text(1);
lcd_xy(3,0);
lcd_print("Channel ");
lcd_print_num(i + 1,0);
lcd_print(" / Satellite ID: ");
lcd_print_num(Buffer(),0);

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (91 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

byte = Buffer();
lcd_xy(0,1);
lcd_print("Channel Tracking Mode: ");
lcd_xy(3,2);
lcd_print(channel[byte]);

lcd_xy(0,3);
lcd_print("Carrier to Noise Density Ratio: ");
lcd_print_num(Buffer(),0);
lcd_print("dB-Hz");
byte = Buffer();

lcd_xy(0,4);
lcd_print("Channel Status Flag: ");

for(j = 0; j < 8; j++)


{
num = (byte >> j) & 0x01;
if(num == 1)
{
if(j == 1 || j == 2);

else
{
lcd_xy(1,5 + count);
lcd_print(ch_status[j]);
count++;
}
}
}
if(count == 0)
lcd_print("0");

count = 0;

while(1)
{
key = _bios_keybrd(_KEYBRD_READ);

if(key == 0x1C0D)
break;
}
}
//Receiver status flag
Init_Text(1);
lcd_xy(5,2);
lcd_print("Receiver status flag: ");
byte = Buffer();
count = 0;
for(j = 0; j < 8; j++)
{
num = (byte >> j) & 0x01;
if(num == 1 && j != 2)
{
lcd_xy(6,3 + count);

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (92 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcd_print(re_status[j]);
count++;
}
}
byte = 1;
}//end of flag == 1
else if((flag == 0) || (flag == 2))
{
for(i = 0; i < 35; i++)
byte = Buffer();
byte = 0;
}
End();
return byte;
}

void Disp_Fa()
{
int i, num, count = 0;
int bit14 = 0, bit15 = 0;

Init_Text(1);

lcd_xy(7,1); //first character, 1 line


lcd_print("GPS Selftest Results: ");
byte = Bytes(1);

for(i = 0; i < 16; i++)


{
num = (byte >> i) & 0x01;
if(num == 1)
{
lcd_xy(7,3);
lcd_print(messages[i]);
}
else if(num == 0)
count++;

if(num == 1 && i == 14)


bit14 = 1;
else if(num == 1 && i == 15)
bit15 = 1;
}
if((bit14 == 1 && bit15 == 1) || (bit14 == 1 && bit15 == 0))
{
lcd_xy(7,4);
lcd_print("Antenna causes a short!!!");
}
else if(bit14 == 0 && bit15 == 1)
{
lcd_xy(7,4);
lcd_print("Antenna not connected!!!");
}

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (93 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

if(count == 16)
{
lcd_xy(7,3);
lcd_print("Selftest Passed!!!");
}

End();
}

void Disp_Same( int f )


{
Init_Text(1);

lcd_xy(7,3); //first character, 1 line


if(f == 0)
lcd_print("GPS Receiver Reset!!!");
else if(f == 1)
lcd_print("System Power_On Failure!!!");

End();
}

FILE: PIC.H

//Picture for GPS startup (compressed)//

int Gps_pic_less[963] = {
1054, 0x1f, 0x80, 0x07, 0x80, 1025, 0x01, 0xff
0xf8, 0x03, 0xc0, 1006, 0x0f, 0xf8, 1006, 0x0f
0xf8, 1009, 0x7e, 0x00, 0x07, 0xe3, 0x7c, 1006
0x7f, 0xff, 0x00, 0x03, 0xff, 0xff, 1002, 0x7f
0xff, 1008, 0x0f, 0xc0, 0x00, 0x01, 0xfe, 0x1f
0x80, 1004, 0x01, 0xff, 0xff, 0xc0, 0x03, 0xff
0xff, 0xe0, 0x01, 0xff, 0xff, 0x80, 1007, 0x18
1003, 0x03, 0x81, 0xc0, 1004, 0x03, 0xff, 0xff
0xe0, 0x03, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff
0xc0, 1007, 0x30, 0x00, 0x0f, 0x00, 0x01, 0xc1
0xc0, 1004, 0x07, 0xf8, 0x07, 0xf0, 0x03, 0xff
0xff, 0xf8, 0x03, 0xf0, 0x0f, 0xe0, 1006, 0x01
0xe3, 0xe0, 0x3f, 0xfe, 0x00, 0x78, 0xf0, 1004
0x0f, 0xc0, 0x01, 0xf8, 0x03, 0xc0, 0x00, 0xfc
0x07, 0xc0, 0x03, 0xf0, 1006, 0x03, 0x07, 0xe0
0x7f, 0xfe, 0x00, 0x0c, 0x38, 1004, 0x1f, 1002
0xf8, 0x03, 0xc0, 0x00, 0x7c, 0x0f, 0x80, 0x00
0xf0, 1006, 0x06, 0x1f, 0xc0, 0xff, 0xfe, 0x03
0x86, 0x1c, 1004, 0x1e, 1002, 0x7c, 0x03, 0xc0
0x00, 0x3e, 0x0f, 1002, 0xf8, 1006, 0x0c, 0x1e
0x18, 0x01, 0xfe, 0x03, 0x83, 0x0e, 1004, 0x3e
1002, 0x3c, 0x03, 0xc0, 0x00, 0x1e, 0x0f, 1002
0x78, 1006, 0x18, 0x03, 0xff, 0xff, 0xff, 0xff
0xc1, 0x87, 1004, 0x3c, 1002, 0x3c, 0x03, 0xc0
0x00, 0x1e, 0x0f, 1002, 0x78, 1006, 0x30, 0x03
0xff, 0xff, 0xff, 0xff, 0xc1, 0xc3, 0x80, 1003

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (94 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

0x78, 1002, 0x18, 0x03, 0xc0, 0x00, 0x1e, 0x0f


1009, 0x60, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff
0xf1, 0x80, 1003, 0x78, 1003, 0x03, 0xc0, 0x00
0x1e, 0x0f, 0x80, 1008, 0xc0, 0x7c, 0x6f, 0xff
0xff, 0xff, 0xff, 0xf0, 0xc0, 1003, 0x78, 1003
0x03, 0xc0, 0x00, 0x1e, 0x07, 0xc0, 1007, 0x01
0xc0, 0xfc, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xf8
0xc0, 1003, 0xf0, 1003, 0x03, 0xc0, 0x00, 0x1e
0x07, 0xf8, 1007, 0x01, 0x80, 0x79, 0xc3, 0xff
0xff, 0xff, 0xff, 0xf8, 0xe0, 1003, 0xf0, 1003
0x03, 0xc0, 0x00, 0x3c, 0x03, 0xff, 0x80, 1006
0x03, 0x00, 0x31, 0xc3, 0xff, 0xff, 0xff, 0xff
0xfc, 0x60, 1003, 0xf0, 1003, 0x03, 0xc0, 0x00
0x7c, 0x01, 0xff, 0xf8, 1006, 0x02, 0x00, 0x1c
0x07, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x70, 1003
0xf0, 1003, 0x03, 0xc0, 0x01, 0xf8, 0x00, 0xff
0xff, 1006, 0x02, 0x00, 0x3f, 0x8f, 0xff, 0xff
0xff, 0xff, 0xfc, 0x30, 1003, 0xf0, 0x00, 0x7f
0xfe, 0x03, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff
0xc0, 1005, 0x02, 0x00, 0x7f, 0xff, 0xff, 0xff
0xff, 0xff, 0xfa, 0x38, 1003, 0xf0, 0x00, 0x7f
0xfe, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x03, 0xff
0xe0, 1007, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
0xf2, 0x38, 1003, 0xf0, 0x00, 0x7f, 0xfe, 0x03
0xff, 0xff, 0xc0, 1002, 0x3f, 0xf0, 1006, 0x01
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x38
1003, 0xf0, 0x00, 0x7f, 0xfe, 0x03, 0xff, 0xff
1003, 0x03, 0xf8, 1006, 0x01, 0xff, 0xff, 0xcf
0xff, 0xff, 0xff, 0xc3, 0x18, 1003, 0xf0, 1002
0x1e, 0x03, 0xc0, 1005, 0xf8, 1007, 0xff, 0xff
0xe0, 0x1f, 0xff, 0xff, 0xc1, 0x18, 1003, 0x78
1002, 0x1e, 0x03, 0xc0, 1005, 0x7c, 1007, 0xff
0xff, 0xe0, 0x0f, 0xff, 0xff, 0xc1, 0x18, 1003
0x78, 1002, 0x1e, 0x03, 0xc0, 1002, 0x1e, 1002
0x3c, 1007, 0x7f, 0xff, 0xe0, 0x0f, 0xff, 0xff
0xd9, 0x18, 1003, 0x78, 1002, 0x1e, 0x03, 0xc0
1002, 0x1e, 1002, 0x3c, 1007, 0x1f, 0xff, 0xc0
0x00, 0x3f, 0xff, 0x93, 0x18, 1003, 0x3c, 1002
0x1e, 0x03, 0xc0, 1002, 0x1f, 1002, 0x3c, 1007
0x0f, 0xff, 1002, 0x1f, 0xff, 0x03, 0x18, 1003
0x3e, 1002, 0x1e, 0x03, 0xc0, 1002, 0x0f, 1002
0x3c, 1007, 0x0f, 0xf8, 1002, 0x07, 0xfc, 0x82
0x18, 1003, 0x1e, 1002, 0x1e, 0x03, 0xc0, 1002
0x0f, 0x80, 0x00, 0x7c, 1007, 0x0f, 0xf8, 1002
0x07, 0xf1, 0x82, 0x30, 1003, 0x1f, 0x80, 0x00
0x7e, 0x03, 0xc0, 1002, 0x0f, 0xc0, 0x00, 0x78
1005, 0x02, 0x00, 0x0f, 0xf0, 1002, 0x80, 0x0f
0x06, 0x30, 1003, 0x0f, 0xc0, 0x00, 0xfe, 0x03
0xc0, 1002, 0x07, 0xe0, 0x01, 0xf8, 1005, 0x03
0x00, 0x0f, 0xf0, 0x00, 0x01, 0x81, 0x8f, 0x04
0x60, 1003, 0x07, 0xf8, 0x07, 0xfc, 0x03, 0xc0
1002, 0x03, 0xf8, 0x07, 0xf0, 1005, 0x01, 0x00
0x0f, 0xf0, 0x00, 0x01, 0x83, 0xc0, 0x0c, 0x60
1003, 0x03, 0xff, 0xff, 0xf0, 0x03, 0xc0, 1002
0x01, 0xff, 0xff, 0xe0, 1005, 0x01, 0x80, 0x0f
0xe0, 0x00, 0x01, 0x83, 0xe0, 0x18, 0xe0, 1004

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (95 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

0xff, 0xff, 0xe0, 0x03, 0xc0, 1003, 0xff, 0xff


0xc0, 1006, 0xc0, 0x07, 0x80, 1004, 0x10, 0xc0
1004, 0x7f, 0xff, 0x80, 0x03, 0xc0, 1003, 0x3f
0xff, 1007, 0xc0, 0x07, 1003, 0x60, 0x00, 0x70
0xc0, 1004, 0x07, 0xfc, 1006, 0x07, 0xfc, 1007
0x40, 1006, 0x61, 0x80, 1021, 0x60, 1006, 0xc1
0x80, 1021, 0x3f, 1003, 0x01, 0x30, 0x01, 0xc3
0x80, 1021, 0x1f, 0xf8, 1002, 0x01, 0x10, 0x03
0x1f, 1022, 0x07, 0xfc, 1004, 0x06, 0x3c, 1022
0x03, 0xff, 0xe0, 1003, 0x3c, 0x78, 1023, 0x7f
0xf0, 1003, 0x60, 0xe0, 1004, 0x3e, 1005, 0x1f
0xc0, 1002, 0x08, 1008, 0x3f, 0xf0, 1003, 0xc1
0xc0, 1004, 0x41, 1005, 0x10, 0x20, 1011, 0x1f
0xf0, 1002, 0x03, 0x83, 0x80, 1004, 0x80, 0x97
0x0e, 0x1e, 0x2c, 0xf0, 0x10, 0x23, 0xc3, 0x87
0x8a, 0x09, 0xe2, 0xc0, 1005, 0x03, 0xf8, 1002
0x1c, 0x0f, 1005, 0x80, 0x98, 0x91, 0x21, 0x31
0x08, 0x10, 0x24, 0x24, 0x48, 0x4a, 0x0a, 0x13
1005, 0x03, 0xc0, 0xff, 0x80, 0x07, 0xf0, 0x7c
1005, 0x80, 0x90, 0x90, 0x21, 0x21, 0x08, 0x10
0x24, 0x24, 0x08, 0x49, 0x12, 0x12, 1006, 0x70
0x0f, 0xff, 0xff, 0x01, 0xf0, 1005, 0x80, 0x90
0x90, 0x21, 0x21, 0xf8, 0x1f, 0xc7, 0xe4, 0x0f
0xc9, 0x13, 0xf2, 1006, 0x3f, 0xc0, 0x1f, 0x80
0x7f, 0xe0, 1005, 0x80, 0x90, 0x90, 0x21, 0x21
0x00, 0x11, 0x04, 0x04, 0x08, 0x08, 0xa2, 0x02
1006, 0x01, 0xfc, 0x00, 0x07, 0xf8, 1006, 0x80
0x90, 0x90, 0x21, 0x21, 0x00, 0x10, 0x84, 0x04
0x08, 0x08, 0xa2, 0x02, 1007, 0x3f, 0xff, 0xff
0xf0, 1006, 0x41, 0x10, 0x91, 0x21, 0x21, 0x08
0x10, 0x44, 0x24, 0x48, 0x48, 0x42, 0x12, 1008
0x0f, 1008, 0x3e, 0x10, 0x8e, 0x1e, 0x20, 0xf0
0x10, 0x23, 0xc3, 0x87, 0x88, 0x41, 0xe2, 1008
0x1f, 0xc0, 1028, 0x1f, 0xc0, 1028, 0x1f, 0xc0
1028, 0x1f, 0xc0, 1028, 0x0f, 1029, 0x7f, 0xf0
1027, 0x01, 0xff, 0xfc, 1027, 0x03, 0xff, 0xfc
1027, 0x1f, 0xff, 0xff, 0x80, 1026, 0x3f, 0xff
0xff, 0xe0, 1025, 0x01, 0xff, 0xff, 0xff, 0xfc
0x00, 0x00, 0x00 }

Appendix F
Assembly Code

The assembly code consists of only one file: 'Oncore.as'. The assembly code implements exactly the same functions as the C++ code. Only the 'Almanac' and
'Vissible Satellite' commands are ommitted.

This file is also included on the attached disc. FILE: ONCORE.H

;Data Segment
dseg at 0008h ;data segment in Ram from 03h

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (96 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

org 08h

X0 equ 08h
X1 equ 09h
X2 equ 0ah
X3 equ 0bh
Y0 equ 0ch
Y1 equ 0dh
Y2 equ 0eh
Y3 equ 0fh
Z0 equ 10h
Z1 equ 11h
Z2 equ 12h
Z3 equ 13h
Z4 equ 14h
Z5 equ 15h
Z6 equ 16h
Z7 equ 17h
PR0 equ 18h
PR1 equ 19h
PR2 equ 1ah
PR3 equ 1bh

org 0030h ;stack from 030h to 04fh


Stack: ds 0020h ;32 bytes of stack

;now the rest of the Ram from 050h to 07fh is available


org 50h

i data 50h ;vars for lcd routines


row data 52h
column data 53h
address data 54h
x data 56h
y data 58h
l data 5ah
car data 5bh
f data 5ch
lines data 5dh
chars data 5eh
flag data 5fh ;vars for main function
tag data 60h
check data 61h
count data 62h
index1 data 63h
index2 data 64h
num1 data 65h
num2 data 66h
num3 data 67h
checksum data 68h ;vars for data_to_gps function
var1 data 69h
var2 data 6ah
var3 data 6bh
fl data 6ch
fla data 6dh ;var for Numbers function

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (97 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

s data 6eh ;vars for main function


hours data 6fh
minutes data 70h
sign data 71h
time data 72h
atmos data 73h
angle data 74h
j data 75h ;var for data_to_gps function
num data 76h ;vars for Bytes function
lb data 77h
ch data 7bh
bufferin data 7ch
bufferout data 7dh
key data 7eh
univ data 7fh

ALE equ 8eh

;/////////////////////////////////
;Xdata Segment
xseg at 00h ;switch to XDATA segment at address 0

org 00h

ringbuffer:
ds 230 ;gives 230 bytes
yebo:
ds 5
array:
ds 15

aid1 xdata 0fbh


aid2 xdata 0fdh

;////////////////////////////
;Code Segment
cseg at 0000h ;code segment in Rom from 0000h

org 0000h ;on reset the PC->00h


jmp Start ;skip interrupt routines and go to main prog.

;Interrupt locations and code


;each section has 8 bytes available to it.

org 0003h ;external interrupt 0


jmp Pushbutton

org 000Bh ;timer 0 interrupt


reti

org 0013h ;external interrupt 1


reti

org 001Bh ;timer 1 interrupt

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (98 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

reti

org 0023h ;serial port interrupt


jmp serial

org 002Bh ;timer 2 interrupt


reti

;//////////////////////////////////////
;Code starts here:
org 0050h

;//////////////////////////////////////
;Interrupt service routine serial

serial:
push acc
jnb TI,serial1
clr TI ;ignore transmit interrupts
serial1:
jnb RI,serialdone ;done if no receive interrupt
mov b,SBUF
clr RI ;clear serial status bit

mov a,bufferin ;buffer[bufferin] = SBUF


add a,#ringbuffer
mov r0,a
mov a,b
movx @r0,a

inc bufferin ;bufferin++


mov a,bufferin ;if(bufferin == 230)
cjne a,#230,serialdone
mov bufferin,#0 ;bufferin = 0
serialdone:
pop acc
reti

;/////////////////////////////////////////////
;Interrupt service routine Pushbutton

Pushbutton:
lcall FindRow
mov b,a
jnc GetColumn
jmp Nothing

GetColumn:
lcall FindColumn
swap a
orl a,b
mov b,a
jnc ReportKey
jmp Nothing

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (99 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

ReportKey:
mov key,b
jmp StillKey
Nothing:
reti
StillKey:
lcall KeyRelease ;waiting for release
jc StillKey
mov P1,#0fh
clr EX0
reti

;///////////////////////////////////////////////
;Function FindRow

FindRow:
mov a,P1 ;rows in port 1
mov r0,#4 ;counter

TryNextRow:
rrc a
jnc RowFound
djnz r0,TryNextRow

setb C
ret

RowFound:
mov a,#4
subb a,r0
clr C
ret

;///////////////////////////////////////////////////
;Function FindColumn

FindColumn:
mov r0,#4
mov a,#0efh
push acc
TryNextColumn:
pop acc
mov P1,a
rl a
push acc
mov a,P1
orl a,#0f0h
cpl a
jnz ColumnFound
djnz r0,TryNextColumn
pop acc
setb C

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (100 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov P1,#0fh
ret
ColumnFound:
pop acc
mov a,#4
clr C
subb a,r0
clr C
mov P1,#0fh
ret

;/////////////////////////////////////////////////
;Function KeyRelease

KeyRelease:
mov P1,#0fh
mov a,P1
orl a,#0f0h
cpl a
jz NoKey
setb C
ret
NoKey:
clr C
ret

;///////////////////////////////////////////////
org 01a0h
Start:
using 0 ;using bank of registers 0

Initilisation:
;sets up stack pointer to 5fh as required.
mov SP,#(Stack-1)
mov IE,#00h ;disable all interrupts
mov P0,#00h ;P0: low, configured as output
;P1: columns low and rows high for keyboard routine
mov P1,#0fh
mov P2,#0f0h ;P2: low byte output

;initiate serial port


anl PCON,#7fh
mov TMOD,#20h ;set Timer 1 for auto reload - Mode 2
mov TCON,#41h ;run Timer 1 and set edge trig ints
;set Timer 1 for 9600 baud with xtal = 11.059Mhz
mov TH1,#0fdh
mov SCON,#50h ;set mode 1 and 8 data bits
mov IE,#91h ;enable ES,EX0 and global interrupt
;Disable ALE; only active during movx instruction
orl ALE,#01h

;/////////////////////////////////////////////
;Function Main: calls Gps and receives info back
;from Gps and displays it on LCD

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (101 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

main:
clr TI
clr RI
mov flag,#1
mov tag,#1
mov check,#1
mov count,#0
mov bufferin,#0
mov bufferout,#0
mov key,#0
mov num1,#0
mov num2,#0
mov num3,#0

lcall lcd_setup
lcall lcd_init
lcall Disp_Pic

DoWhile: ;do
jmp EndSwitch ;while(bufferin != bufferout)
BeginSwitch:
lcall Buffer ;index1 = Buffer()
lcall Buffer ;index2 = Buffer()
lcall Buffer ;index1 = Buffer()
mov index1,r3
lcall Buffer ;index2 = Buffer()
mov index2,r3

mov tag,#1

jmp Main_Switch ;switch(index1)

BigA: ;case 'A':


jmp Switch_A ;switch(index2)

Case_Aa: ;case 'a':


mov r4,#0
lcall Disp_Aa ;Disp_Aa(0)
jmp EndA ;break;

Case_Ab: ;case 'b':


lcall Disp_Ab ;Disp_Ab()
jmp EndA ;break

Case_Ac: ;case 'c':


mov r4,#0
lcall Disp_Ac ;Disp_Ac(0);
jmp EndA ;break
Case_Ad: ;case 'd':
mov r4,#0
lcall Disp_Ad ;Disp_Ad(0)
jmp EndA ;break

Case_Ae: ;case 'e':

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (102 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r4,#0
lcall Disp_Ae ;Disp_Ae(0)
jmp EndA ;break

Case_Af: ;case 'f':


mov r4,#0
lcall Disp_Af ;Disp_Af(0)
jmp EndA ;break

Case_Ag: ;case 'g':


lcall Disp_Ag ;Disp_Ag()
jmp EndA ;break

Case_Aq: ;case 'q':


lcall Disp_Aq ;Disp_Aq()
jmp EndA ;break

Case_Aw: ;case 'w':


lcall Disp_Aw ;Disp_Aw()
jmp EndA ;break

Switch_A:
mov a,index2
add a,#159
jz Case_Aa
dec a
jz Case_Ab
dec a
jz Case_Ac
dec a
jz Case_Ad
dec a
jz Case_Ae
dec a
jz Case_Af
dec a
jz Case_Ag
add a,#246
jz Case_Aq
add a,#250
jz Case_Aw
jmp EndA

EndA:
jmp EndSwitch ;break

BigB: ;case 'B':


jmp Switch_B ;switch(index2)

Case_Bj: ;case 'j':


lcall Disp_Bj ;Disp_Bj()
jmp EndB ;break

Switch_B:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (103 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov a,index2
add a,#150
jz Case_Bj
jmp EndB

EndB:
jmp EndSwitch ;break

BigC: ;case 'C':


jmp Switch_C ;switch(index2)

Case_Cf: ;case 'f':


mov r4,#0
lcall Disp_Same ;Disp_Same(0)
jmp EndC ;break

Switch_C:
mov a,index2
add a,#154
jz Case_Cf
jmp EndC

EndC:
jmp EndSwitch ;break

BigE: ;case 'E':


jmp Switch_E ;switch(index2)

Case_Ea: ;case 'a':


lcall Disp_Ea ;flag = Disp_Ea(flag)

jmp EndE ;break

Switch_E:
mov a,index2
add a,#159
jz Case_Ea
jmp EndE

EndE:
jmp EndSwitch ;break

BigF: ;case 'F':


jmp Switch_F ;switch(index2)

Case_Fa: ;case 'a':


lcall Disp_Fa ;Disp_Fa()
jmp EndF ;break

Switch_F:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (104 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov a,index2
add a,#159
jz Case_Fa
jmp EndF

EndF:
jmp EndSwitch ;break

BigS: ;case 'S':


jmp Switch_S ;switch(index2)

Case_Sz: ;case 'z':


mov r4,#1
lcall Disp_Same ;Disp_Same(1)
jmp EndS ;break

Switch_S:
mov a,index2
add a,#134
jz Case_Sz
jmp EndS

EndS:
jmp EndSwitch ;break

Main_Switch:
mov a,index1
add a,#191
jz F1
jmp F2
F1:
jmp BigA
F2:
dec a
jz F3
jmp F4
F3:
jmp BigB
F4:
dec a
jz BigC
add a,#254
jz BigE
dec a
jz BigF
add a,#243
jz BigS
jmp EndSwitch

EndSwitch:
mov a,bufferin
cjne a,bufferout,Back
jmp Next
Back:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (105 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jmp BeginSwitch

;////////////////////////////////////////
Next:
mov a,key
jz F5 ;if(key != 0)
jmp F6
F5:
setb EX0
jmp EndCommand
F6:
mov a,tag
cjne a,#1,Fail1 ;if(tag == 1)
mov a,key
cjne a,#23h,Fail1
mov key,#0
mov num1,#0 ;num1 = 0
mov tag,#0 ;tag = 0
jmp GoToCommands ;else if(tag == 0)

Fail1:
mov a,tag
jnz Fail2
lcall Key_Press_0 ;num1 = Key_Press_0()
mov num1,r3
setb EX0
jmp GoToCommands
Fail2:
setb EX0
mov num1,#5 ;num1 = 5 //else do nothing

GoToCommands:
jmp MainS ;switch(num1)

MainMenu: ;case 0:
lcall Main_Menu ;Main_Menu()
jmp EndCommand ;break

Pos_Sta_Dat: ;case 1:
lcall Sub_Menu1 ;Sub_Menu1()
lcall Key_Press_1 ;num2 = Key_Press_1()
mov num2,r3

mov a,check ;if((check == 0) && (num2 != 1))


jnz U1
jmp U2
U2:
mov a,num2
cjne a,#1,U3
jmp U1
U3:
jmp U4
U1:
jmp U5

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (106 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

U5:
jmp Switch_1
U4:
lcall lcd_clear_text ;lcd_clear_text()

mov r7,#148
lcall cput ;cput(0x94)

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy ;lcd_xy(0,3)

lcall lcd_print ;lcd_print()


db "Disable first polling command!!!!",0

mov num2,#10 ;num2 = 10

Switch_1: ;switch(num2)
jmp SwitchSub1

Pos_Status_Data: ;case 1:
lcall Pos_Menu ;Pos_Menu(check)

lcall Key_Press_3 ;num3 = Key_Press_3()


mov num3,r3
jmp Pos ;switch(num3)

Pos_1: ;case 1:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#1
mov r5,#1
lcall Data_To_Gps ;Data_To_Gps()

mov a,count ;if(count == 1)


cjne a,#1,U6
jmp U7
U6:
jmp U8
U7:
mov flag,#1 ;flag = 1
mov count,#0 ;count = 0

U8: ;if(flag == 0)
mov a,flag
jnz U9

mov flag,#2 ;flag = 2


mov count,#1 ;count = 1

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (107 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

U9:
mov check,#1 ;check = 1
jmp EndPos ;break

Pos_2: ;case 2:
mov var3,#0
mov var2,#0
mov var1,#10
mov fl,#1
mov r5,#1
lcall Data_To_Gps ;Data_To_Gps()
U10:
mov a,count ;if(count == 1)
cjne a,#1,U11
jmp U12
U11:
jmp U13
U12:
mov count,#0 ;count = 0

U13:
mov flag,#0 ;flag = 0
mov check,#0 ;check = 0
jmp EndPos ;break

Pos_3: ;case 3:
mov var3,#0
mov var2,#0
mov var1,#20
mov fl,#1
mov r5,#1
lcall Data_To_Gps ;Data_To_Gps()
jmp U10

Pos_4: ;case 4:
mov var3,#0
mov var2,#0
mov var1,#30
mov fl,#1
mov r5,#1
lcall Data_To_Gps ;Data_To_Gps()
jmp U10

Pos:
mov a,num3
dec a
jz F7
jmp F8
F7:
jmp Pos_1
F8:
dec a
jz Pos_2
dec a

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (108 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jz Pos_3
dec a
jz Pos_4
EndPos:
jmp EndPosition ;break

Lattitude: ;case 2:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#0
mov r5,#2
lcall Data_To_Gps ;Data_To_Gps()
jmp EndPosition ;break

Longitude: ;case 3:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#0
mov r5,#3
lcall Data_To_Gps ;Data_To_Gps()
jmp EndPosition ;break

Height: ;case 4:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#0
mov r5,#4
lcall Data_To_Gps ;Data_To_Gps()
jmp EndPosition ;break

Date: ;case 5:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#0
mov r5,#5
lcall Data_To_Gps ;Data_To_Gps()
jmp EndPosition ;break

Time_Of_Day: ;case 6:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#0
mov r5,#6
lcall Data_To_Gps ;Data_To_Gps()
jmp EndPosition ;break

SwitchSub1:
mov a,num2
dec a
jz F9

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (109 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jmp F10
F9:
jmp Pos_Status_Data
F10:
dec a
jz Lattitude
dec a
jz Longitude
dec a
jz Height
dec a
jz Date
dec a
jz Time_Of_Day
EndPosition:
jmp EndCommand ;break

Gps_Modes: ;case 2:
lcall Sub_Menu2 ;Sub_Menu2()

lcall Key_Press_2 ;num2 = Key_Press_2()


mov num2,r3

mov a,check ;if(check == 0)


jnz U18

lcall lcd_clear_text ;lcd_clear_text()

mov r7,#148
lcall cput ;cput(0x94)

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy ;lcd_xy(0,3)

lcall lcd_print ;lcd_print()


db "Disable first polling command!!!!",0

mov num2,#10 ;num2 = 10

U18: ;switch(num2)
jmp SwitchSub2

Gmt: ;case 1:
lcall Gmt_Menu ;Gmt_Menu()

lcall Key_Press_4 ;num3 = Key_Press_4()


mov num3,r3

jmp GmtFind ;switch(num3)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (110 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Gmt_Poll: ;case 1:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#0
mov r5,#7
lcall Data_To_Gps ;Data_To_Gps()
jmp EndGmt ;break

Gmt_Change: ;case 2:
lcall lcd_clear_text ;lcd_clear_text()

mov r7,#151
lcall cput ;cput(0x97)

mov r2,#high (0)


mov r3,#low (0)
mov r4,#high (4)
mov r5,#low (4)
lcall lcd_xy ;lcd_xy(4,0)

lcall lcd_print ;lcd_print()


db "Enter offset in hours(-23 .. 23):",0

mov fla,#0
lcall Numbers ;Numbers( 0 )

lcall Key_Press_5 ;s = Key_Press_5()

mov fla,#1
lcall Numbers ;Numbers( 1 )

lcall Key_Press_6 ;hours = Key_Press_6()


mov hours,r3

lcall lcd_clear_text ;lcd_clear_text()

mov r7,#151
lcall cput ;cput(0x97)

mov r2,#high (0)


mov r3,#low (0)
mov r4,#high (4)
mov r5,#low (4)
lcall lcd_xy ;lcd_xy(4,0)

lcall lcd_print ;lcd_print()


db "Enter offset in minutes(0 .. 59):",0

mov fla,#1
lcall Numbers ;Numbers( 1 )

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (111 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcall Key_Press_6 ;minutes = Key_Press_6()


mov minutes,r3

mov a,s ;if(s == '-')


cjne a,#(45),U19

mov sign,#0ffh ;sign = 0xFF

jmp U20 ;else if(s == '+')


U19:
mov a,s
cjne a,#(43),U20
clr a
mov sign,a ;sign = 0

U20:
mov var3,minutes
mov var2,hours
mov var1,sign
mov fl,#3
mov r5,#8
lcall Data_To_Gps ;Data_To_Gps()
jmp EndGmt ;break

GmtFind:
mov a,num3
dec a
jz F11
jmp F12
F11:
jmp Gmt_Poll
F12:
dec a
jz F13
jmp EndGmt
F13:
jmp Gmt_Change
EndGmt:
jmp EndModes ;break

Time_Mode: ;case 2:
lcall Time_Menu ;Time_Menu()

lcall Key_Press_4 ;num3 = Key_Press_4()


mov num3,r3

jmp TimeFind ;switch(num3)

Time_Mode_Poll: ;case 1:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#0
mov r5,#9

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (112 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcall Data_To_Gps ;Data_To_Gps()


jmp EndTime ;break

Time_Mode_Change: ;case 2:
lcall Time_Change ;Time_Change()

lcall Key_Press_4 ;time = Key_Press_4() - 1


mov a,r3
clr c
subb a,#01h
mov time,a

mov var3,#0
mov var2,#0
mov var1,time
mov fl,#1
mov r5,#10
lcall Data_To_Gps ;Data_To_Gps()
jmp EndTime ;break

TimeFind:
mov a,num3
dec a
jz Time_Mode_Poll
dec a
jz Time_Mode_Change
EndTime:
jmp EndModes ;break

Leap_Second: ;case 3:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#1
mov r5,#11
lcall Data_To_Gps ;Data_To_Gps()
jmp EndModes ;break

Atmosphere: ;case 4:
lcall Atmos_Menu ;Atmos_Menu()

lcall Key_Press_4 ;num3 = Key_Press_4()


mov num3,r3

jmp AtmosFind ;switch(num3)

Atmosphere_Poll: ;case 1:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#0
mov r5,#12
lcall Data_To_Gps ;Data_To_Gps()

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (113 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jmp EndAtmos ;break

Atmosphere_Change: ;case 2:
lcall Atmos_Sub_Menu ;Atmos_Sub_Menu()

lcall Key_Press_3 ;atmos = Key_Press_3() - 1


mov a,r3
clr c
subb a,#01h
mov atmos,a

mov var3,#0
mov var2,#0
mov var1,atmos
mov fl,#1
mov r5,#13
lcall Data_To_Gps ;Data_To_Gps()
jmp EndAtmos ;break

AtmosFind:
mov a,num3
dec a
jz Atmosphere_Poll
dec a
jz Atmosphere_Change
EndAtmos:
jmp EndModes ;break

Satellite_Mask: ;case 5:
lcall Mask_Menu ;Mask_Menu()

lcall Key_Press_4 ;num3 = Key_Press_4()


mov num3,r3

jmp Sat_Find ;switch(num3)

Mask_Poll: ;case 1:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#0
mov r5,#14
lcall Data_To_Gps ;Data_To_Gps()
jmp EndMask ;break

Mask_Change: ;case 2:
lcall Mask_Sub_Menu ;Mask_Sub_Menu()

mov fla,#1
lcall Numbers ;Numbers( 1 )

lcall Key_Press_6 ;angle = Key_Press_6()


mov angle,r3

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (114 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov var3,#0
mov var2,#0
mov var1,angle
mov fl,#1
mov r5,#15
lcall Data_To_Gps ;Data_To_Gps()
jmp EndMask ;break

Sat_Find:
mov a,num3
dec a
jz Mask_Poll
dec a
jz Mask_Change
EndMask:
jmp EndModes ;break

SwitchSub2:
mov a,num2
dec a
jz F15
jmp F16
F15:
jmp Gmt
F16:
dec a
jz F17
jmp F18
F17:
jmp Time_Mode
F18:
dec a
jz F19
jmp F20
F19:
jmp Leap_Second
F20:
dec a
jz F21
jmp F22
F21:
jmp Atmosphere
F22:
dec a
jz F23
jmp F24
F23:
jmp Satellite_Mask
F24:

EndModes:
jmp EndCommand ;break

Receiver_Func: ;case 3:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (115 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcall Sub_Menu3 ;Sub_Menu3()

lcall Key_Press_4 ;num2 = Key_Press_0()


mov num2,r3

mov a,check ;if(check == 0)


jnz U31

lcall lcd_clear_text ;lcd_clear_text()

mov r7,#148
lcall cput ;cput(0x94)

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy ;lcd_xy(0,3)

lcall lcd_print ;lcd_print()


db "Disable first polling command!!!!",0

mov num2,#10 ;num2 = 10

U31: ;switch(num2)
jmp SwitchSub3

Gps_Selftest: ;case 2:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#0
mov r5,#16
lcall Data_To_Gps ;Data_To_Gps()
jmp EndFunc ;break

Gps_Set_Defaults: ;case 3:
mov var3,#0
mov var2,#0
mov var1,#0
mov fl,#0
mov r5,#17
lcall Data_To_Gps ;Data_To_Gps()
jmp EndFunc ;break

SwitchSub3:
mov a,num2
dec a
jz Gps_Selftest
dec a
jz Gps_Set_Defaults
EndFunc:
jmp EndCommand ;break

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (116 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

MainS:
mov a,num1
jz F25
jmp F26
F25:
jmp MainMenu
F26:
dec a
jz F27
jmp F28
F27:
jmp Pos_Sta_Dat
F28:
dec a
jz F29
jmp F30
F29:
jmp Gps_Modes
F30:
dec a
jz F31
jmp F32
F31:
jmp Receiver_Func
F32:

EndCommand:
mov P1,#0fh
mov key,#0
mov a,num1
cjne a,#4,StartAgain ;while(num1 != 4)
jmp EndMain
StartAgain:
jmp DoWhile
EndMain:
mov r7,#152
lcall cput ;cput(0x98)

jmp Final

;//////////////////////////////////////////////
;Functions for Control signals

WRHI:
setb p2.0
ret
WRLO:
clr p2.0
ret
RDHI:
setb p2.1
ret
RDLO:
clr p2.1

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (117 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

ret
CEHI:
setb p2.2
ret
CELO:
clr p2.2
ret
CDHI:
setb p2.3
ret
CDLO:
clr p2.3
ret

;/////////////////////////////////////////////////
;Function lcd_clear_test

lcd_clear_text:
mov r7,#0d
lcall dput

mov r7,#0d
lcall dput

mov r7,#36d
lcall cput

clr a
mov i+0,a ;clear i
mov i+1,a
jmp Test

Loop:
mov r7,#0d
lcall dput

mov r7,#192d
lcall cput

inc i+1
mov a,i+1
jnz Bypass
inc i+0

Bypass:

Test:
mov a,i+1
add a,#low -(320)
mov a,i+0
xrl a,#80h
addc a,#(high -(320))xor 80h
jnc Loop

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (118 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

ret
;////////////////////////////////////////////////
;Function lcd_print

lcd_print:

prtLCD:
pop dph ; pop return address into dptr
pop dpl
prtNext:
clr a ; set offset = 0
movc a,@a+dptr ; get chr from code memory
cjne a,#0, chrOK ; if chr = 0 then return
sjmp retPrtLCD
chrOK:
subb a,#20h
mov r7, a
lcall wrLCDdata ; send character
inc dptr ; point at next character
ljmp prtNext ; loop till end of string
retPrtLCD:
mov a, #1h ; point to instruction after string
jmp @a+dptr ; return with a jump instruction

;////////////////////////////////////////////
lcd_print1:
clr a ; set offset = 0
movc a,@a+dptr ; get chr from code memory
mov univ,a
mov a,#1 ; set offset = 0
movc a,@a+dptr ; get chr from code memory
mov dpl,a
mov a,univ
mov dph,a

printNext:
clr a ; set offset = 0
movc a,@a+dptr ; get chr from code memory
cjne a,#0, char_is_OK ; if chr = 0 then return
sjmp returnPrtLCD
char_is_OK:
subb a,#20h
mov r7, a
lcall wrLCDdata ; send character
inc dptr ; point at next character
ljmp printNext ; loop till end of string
returnPrtLCD:
ret

;//////////////////////////////////////////////////
;Function wrLCDdata: prints out characters

wrLCDdata:
lcall dput

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (119 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r7,#192d
lcall cput

ret

;//////////////////////////////////////////////
;Function lcd_xy: place cursor at x/y position

lcd_xy:
mov y,r2 ;y == 0
mov y+1,r3

mov x,r4 ;x == 0
mov x+1,r5
mov r4,#high (40) ;Bytes_Per_Row = 40
mov r5,#low (40)
mov r2,y
mov r3,y+1

lcall mult8_8

mov a,r3
add a,x+1
mov address+1,a
mov a,r2
addc a,x
mov address,a

mov r4,address
mov r5,address+1
anl 4+0,#high (0FFh)
anl 5+0,#low (0FFh)
mov r7,1+4+0
lcall dput

mov r5,address
mov r4,#0
mov r7,1+4+0
lcall dput

mov r7,#36d
lcall cput
ret

;///////////////////////////////////////////////
;Function lcd_setup

lcd_setup:
lcall CEHI
lcall RDHI
lcall WRHI
lcall CDHI
ret

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (120 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

;////////////////////////////////////////////////
;Function lcd_init

lcd_init:
mov r7,#0d
lcall dput

mov r7,#2d
lcall dput

mov r7,#66d
lcall cput

mov r7,#40d
lcall dput

mov r7,#0d
lcall dput

mov r7,#67d
lcall cput

mov r7,#0d
lcall dput

mov r7,#0d
lcall dput

mov r7,#64d
lcall cput

mov r7,#40d
lcall dput

mov r7,#0d
lcall dput

mov r7,#65d
lcall cput

mov r7,#128d
lcall cput

mov r7,#167d
lcall cput

mov r7,#0d
lcall dput

mov r7,#0d
lcall dput

mov r7,#33d

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (121 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcall cput

;define own char(degree sign) at 80h


mov r7,#3d
lcall dput

mov r7,#0d
lcall dput

mov r7,#34d
lcall cput

mov r7,#0d
lcall dput

mov r7,#28d
lcall dput

mov r7,#36d
lcall cput

mov r7,#28d
lcall dput

mov r7,#192d
lcall cput

mov r7,#20d
lcall dput

mov r7,#192d
lcall cput

mov r7,#28d
lcall dput

mov r7,#192d
lcall cput

mov r7,#0d
lcall dput

mov r7,#192d
lcall cput

mov r7,#0d
lcall dput

mov r7,#192d
lcall cput

mov r7,#0d
lcall dput

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (122 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r7,#192d
lcall cput

mov r7,#0d
lcall dput

mov r7,#192d
lcall cput

mov r7,#0d
lcall dput

mov r7,#192d
lcall cput

;define own char(" ' " sign) at 80h


mov r7,#3d
lcall dput

mov r7,#0d
lcall dput

mov r7,#34d
lcall cput

mov r7,#08h
lcall dput

mov r7,#1ch
lcall dput

mov r7,#36d
lcall cput

mov r7,#10h
lcall dput

mov r7,#192d
lcall cput

mov r7,#10h
lcall dput

mov r7,#192d
lcall cput

mov r7,#10h
lcall dput

mov r7,#192d
lcall cput

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (123 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r7,#0
lcall dput

mov r7,#192d
lcall cput

mov r7,#0d
lcall dput

mov r7,#192d
lcall cput

mov r7,#0d
lcall dput

mov r7,#192d
lcall cput

mov r7,#0d
lcall dput

mov r7,#192d
lcall cput

mov r7,#0d
lcall dput

mov r7,#192d
lcall cput

ret

;//////////////////////////////////////////////////////
;Function sget

sget:
mov P0,#0ffh
lcall CDHI
lcall RDLO
lcall CELO
mov a,P0
lcall CEHI
lcall RDHI
ret
;/////////////////////////////////////////////////
;Function dput

dput:
lcall sget
anl a,#03h
cjne a,#03h,dput
mov P0,r7
lcall CDLO

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (124 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcall WRLO
lcall RDHI
lcall CELO
lcall CEHI
lcall WRHI
ret

;/////////////////////////////////////////////////
;Function cput

cput:
lcall sget
anl a,#03h
cjne a,#03h,cput
mov P0,r7
lcall CDHI
lcall RDHI
lcall WRLO
lcall CELO
lcall CEHI
lcall WRHI
ret

;//////////////////////////////////////////
;Function lcd_clear_graph

lcd_clear_graph:
mov r7,#0
lcall dput ; dput(0x0200%256)

mov r7,#2
lcall dput ;dput(0x0200>>8)

mov r7,#36
lcall cput ;cput(0x24)

clr a ;for (i = 0; i < 2560; i++)


mov i,a
mov i+1,a
jmp CC1
CC2:
mov r7,#0
lcall dput ;dput(0)

mov r7,#192
lcall cput ;cput(0xc0)

inc i+1
mov a,i+1
jnz CC1
inc i
CC1:
mov a,i+1
add a,#low -(2560)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (125 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov a,i
xrl a,#80h
addc a,#(high -(2560))xor 80h
jnc CC2
ret

;/////////////////////////////////////////
;Function lcd_setpixel
;param column assigned to r4 on entry
;param row assigned to r2 on entry

lcd_setpixel:
mov row,r2 ;address = 0x0200 + (row * 40) + (column / 6)
mov column,r4

mov r4,#high (40);Bytes_Per_Row = 40


mov r5,#low (40)
mov r2,#0
mov r3,row
lcall mult8_8

mov a,r3
add a,#low(512)
mov address+1,a
mov a,r2
addc a,#high(512)
mov address,a

mov X3,#0
mov X2,#0
mov X1,#0
mov X0,column
mov Y0,#6
mov Y1,#0
mov Y2,#0
mov Y3,#0
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov column,Z0

mov a,Z4
add a,address+1
mov address+1,a
mov a,Z5
addc a,address
mov address,a

mov r4,address
mov r5,address+1
anl 4+0,#high (0FFh)
anl 5+0,#low (0FFh)
mov a,r5
mov r7,a
lcall dput ;dput(addr%256)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (126 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r7,address
lcall dput ; dput(addr>>8)

mov r7,#36
lcall cput ;cput(0x24)

mov a,#05h
clr c
subb a,column
mov r7,a
orl 7,#0f8h
lcall cput ;cput(0xf8 | (5 - (column % 6)) )
ret

;//////////////////////////////////////////////
;Function Disp_Pic
;no - > index1
;num -> x
;counter -> y
;j -> time
;i -> index2
;k -> i

Disp_Pic:
mov index2,#0
mov time,#0
mov y,#0
mov y+1,#0

lcall lcd_clear_graph ;lcd_clear_graph()

mov r7,#152
lcall cput ;cput(0x98)

jmp CC3 ;while(1)


CC4:
mov a,y+1 ;num = Gps_pic_less[counter]
add a,y+1
mov r2,a
mov a,y
addc a,y
mov r3,a

lcall ADD16
clr a
movc a,@a+dptr
mov x,a
inc r2
lcall ADD16
clr a
movc a,@a+dptr
mov x+1,a

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (127 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov a,x+1 ;if(num > 1000)


add a,#low -(1001)
mov a,x
xrl a,#80h
addc a,#(high -(1001))xor 80h
jnc CC5

mov i,#high(1000) ;for(k = 1000; k < num ; k++)


mov i+1,#low(1000)
jmp CC6

CC7: ;for(k = 1000; k < num ; k++


mov a,time
add a,#08h
mov time,a ;j += 8

mov a,time ;if(j == 240)


cjne a,#240,CC8
jmp CC9
CC8:
jmp CC10
CC9:
mov time,#0 ;j = 0
inc index2 ;i++

mov a,index2 ;if(i == 64)


cjne a,#64,CC11
jmp CC12
CC11:
jmp CC10
CC12:
jmp CC13 ;break
CC10:
inc i+1
mov a,i+1
jnz CC6
inc i
CC6:
clr c
mov a,i+1
subb a,x+1
mov b,x
xrl b,#80h
mov a,i
xrl a,#80h
subb a,b
jc CC7
CC13:
jmp CC22 ;else
CC5:
mov i,#0 ;for(k = 0; k < 8; k++)
mov i+1,#0
jmp CC14
CC15:
mov a,x+1 ;no = num & 0x80

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (128 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

anl a,#080h
mov index1,a
mov r0,x ;num <<= 1
mov r1,x+1
mov a,r1
add a,r1
mov r1,a
mov a,r0
addc a,r0
mov r0,a
mov x,r0
mov x+1,r1

mov a,index1 ;if(no == 0x80)


cjne a,#128,CC16
jmp CC17
CC16:
jmp CC18
CC17:
mov r2,index2
mov a,time
add a,i+1
mov r4,a
lcall lcd_setpixel ;lcd_setpixel(j + k, i)
CC18:
inc i+1
mov a,i+1
jnz CC14
inc i
CC14:
mov a,i+1
add a,#low -(8)
mov a,i
xrl a,#80h
addc a,#(high -(8))xor 80h
jnc CC15
CC19:
mov a,time ;j += 8
add a,#08h
mov time,a
mov a,time ;if(j == 240)
cjne a,#240,CC20
jmp CC21
CC20:
jmp CC22
CC21:
mov time,#0 ;j = 0
inc index2 ;i++

mov a,index2 ;if(i == 64)


cjne a,#64,CC23
jmp CC24
CC23:
jmp CC22
CC24:
jmp CC25 ;break

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (129 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

CC22:
inc y+1 ;counter++
mov a,y+1
jnz CC3
inc y
CC3:
jmp CC4
CC25:
ret

;//////////////////////////////////////////////
;Function Init_Text

Init_Text:
lcall lcd_clear_text

mov a,f ;if(f == 0)


jnz middle ;jump to c if accumulator is not zero

mov r7,#151
lcall cput
jmp q ;jump to end of function ;else if(f == 1)

middle:
mov r7,#148
lcall cput
q:
ret

;/////////////////////////////////////////////////
;Function Cursor_Pos

Cursor_Pos:

mov a,l ;if(l == -1)


cjne a,#high (-1),aa ;jump if l != -1
jmp bb ;jump if l == -1
aa:
jmp cc
bb:
mov a,lines ;lines--
add a,#-01h
mov lines,a
jmp dd ;else if(l == 10)
cc:
mov a,l
cjne a,#10d,ee
jmp ff
ee:
jmp gg
ff:
inc lines ;lines++
jmp dd ;else

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (130 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

gg:
mov lines,l

dd:
mov chars,car

mov r7,chars
lcall dput

mov r7,lines
lcall dput

mov r7,#33
lcall cput

ret

;/////////////////////////////////////////////
;Function Main_Menu

Main_Menu:
mov f,#0
lcall Init_Text

mov car,#7
mov l,#3
lcall Cursor_Pos

mov r2,#high (0)


mov r3,#low (0)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Main Menu to operate the GPS Oncore.",0

mov r2,#high (1)


mov r3,#low (1)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Press ESC to quit!!",0

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "POSITION/STATUS/DATA:",0

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (131 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "GPS MODES:",0

mov r2,#high (5)


mov r3,#low (5)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "RECEIVER FUNCTIONS:",0
ret

;//////////////////////////////////////////////////
;Function Sub_Menu1

Sub_Menu1:
mov f,#0
lcall Init_Text

mov car,#7
mov l,#1
lcall Cursor_Pos

mov r2,#high (1)


mov r3,#low (1)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "POS/STATUS/DATA:",0

mov r2,#high (2)


mov r3,#low (2)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "LATTITUDE:",0

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (132 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcall lcd_print
db "LONGITUDE:",0

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "HEIGHT:",0

mov r2,#high (5)


mov r3,#low (5)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "DATE:",0

mov r2,#high (6)


mov r3,#low (6)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "TIME OF DAY:",0

ret

;//////////////////////////////////////////////////
;Function Sub_Menu2

Sub_Menu2:
mov f,#0
lcall Init_Text

mov car,#7
mov l,#1
lcall Cursor_Pos

mov r2,#high (1)


mov r3,#low (1)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "GMT OFFSET:",0

mov r2,#high (2)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (133 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r3,#low (2)


mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "TIME MODE:",0

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "LEAP SECOND PENDING STATUS:",0

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "ATMOSPHERE CORRECTION MODE:",0

mov r2,#high (5)


mov r3,#low (5)
mov r4,#high (8)
mov r5,#low (8)
lcall lcd_xy

lcall lcd_print
db "SATELLITE MASK ANGLE:",0

ret

;//////////////////////////////////////////////////////
;Function Sub_Menu3

Sub_Menu3:
lcall Same_XY1

lcall lcd_print
db "GPS SELFTEST:",0

lcall Same_XY2

lcall lcd_print
db "SET TO DEFAULTS:",0

ret

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (134 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

;/////////////////////////////////////////////////////
;Function Pos_Menu

Pos_Menu:
mov f,#0
lcall Init_Text

mov car,#1
mov l,#1
lcall Cursor_Pos

mov r2,#high (1)


mov r3,#low (1)
mov r4,#high (2)
mov r5,#low (2)
lcall lcd_xy

mov a,check ;if(flag == 1)


jnz yy0
lcall lcd_print
db "Disable Polling:",0
jmp yy1
yy0:
lcall lcd_print
db "Poll Position/Status/Data once:",0
yy1:
mov r2,#high (2)
mov r3,#low (2)
mov r4,#high (2)
mov r5,#low (2)
lcall lcd_xy

lcall lcd_print
db "Poll Position once every 10 seconds: ",0

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (2)
mov r5,#low (2)
lcall lcd_xy

lcall lcd_print
db "Poll Position once every 20 seconds: ",0

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (2)
mov r5,#low (2)
lcall lcd_xy

lcall lcd_print
db "Poll Position once every 30 seconds: ",0
ret

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (135 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

;////////////////////////////////////////////////////
;Function Same_XY1
Same_XY1:
mov f,#0
lcall Init_Text

mov car,#1
mov l,#3
lcall Cursor_Pos

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (2)
mov r5,#low (2)
lcall lcd_xy

ret

;//////////////////////////////////////////////////////
;Function Same_XY2
Same_XY2:
mov r2,#high (4)
mov r3,#low (4)
mov r4,#high (2)
mov r5,#low (2)
lcall lcd_xy

ret

;/////////////////////////////////////////////////////////
;Function Gmt_Menu

Gmt_Menu:
lcall Same_XY1

lcall lcd_print
db "Poll current GMT Offset:",0

lcall Same_XY2

lcall lcd_print
db "Change current GMT Offset:",0

ret

;//////////////////////////////////////////////////////
;Function Time_Menu

Time_Menu:
lcall Same_XY1

lcall lcd_print
db "Poll current Time Mode:",0

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (136 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcall Same_XY2

lcall lcd_print
db "Change current Time Mode:",0

ret

;/////////////////////////////////////////////////////
;Function Time_Change

Time_Change:
lcall Same_XY1

lcall lcd_print
db "GPS Time:",0

lcall Same_XY2

lcall lcd_print
db "UTC Time:",0

ret

;/////////////////////////////////////////////////////
;Function Atmos_Menu

Atmos_Menu:
lcall Same_XY1

lcall lcd_print
db "Poll Atmosphere Correction Mode:",0

lcall Same_XY2

lcall lcd_print
db "Change Atmosphere Correction Mode:",0

ret
;///////////////////////////////////////////////////////////
;Function Atmos_Sub_Menu

Atmos_Sub_Menu:
mov f,#0
lcall Init_Text

mov car,#1
mov l,#1
lcall Cursor_Pos

mov r2,#high (1)


mov r3,#low (1)
mov r4,#high (2)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (137 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r5,#low (2)


lcall lcd_xy

lcall lcd_print
db "Ionospheric Model disabled:",0

mov r2,#high (2)


mov r3,#low (2)
mov r4,#high (2)
mov r5,#low (2)
lcall lcd_xy

lcall lcd_print
db "Ionospheric Model only enabled:",0

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (2)
mov r5,#low (2)
lcall lcd_xy

lcall lcd_print
db "Tropospheric Model only enabled:",0

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (2)
mov r5,#low (2)
lcall lcd_xy

lcall lcd_print
db "Both Models enabled:",0

ret

;////////////////////////////////////////////////////////////
;Function Mask_Menu

Mask_Menu:
lcall Same_XY1

lcall lcd_print
db "Poll current Satellite Mask Angle:",0

lcall Same_XY2

lcall lcd_print
db "Change current Satellite Mask Angle:",0

ret

;////////////////////////////////////////////////////////
;Function Mask_Sub_Menu

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (138 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Mask_Sub_Menu:
mov f,#0
lcall Init_Text

mov r2,#high (0)


mov r3,#low (0)
mov r4,#high (2)
mov r5,#low (2)
lcall lcd_xy

lcall lcd_print
db "Enter angle in degrees( 0 - 89 ):",0

ret

;/////////////////////////////////////////////////////
; ====================================================
; subroutine mdelay - millisecond delay
; delays for 998 microseconds - 2 microseconds are
; reserved for the call to this routine.
; input : none
; output : none
; destroys : nothing - uses a
; ----------------------------------------------------
; 100h-a6h=5ah=(90)decimal
; 90 * 11 = 990
; plus 8 gives 998 microseconds
;
; microseconds (cycles)
; -----------------------

mdelay:
push acc ; 2
mov a, #0a6h ; 1

md_olp:
inc a ; 1 \
nop ; 1 |
nop ; 1 |
nop ; 1 |
nop ; 1 |
nop ; 1 |- 11 cycles
nop ; 1 |
nop ; 1 |
nop ; 1 |
jnz md_olp ; 2 /

nop ; 1
pop acc ; 2
ret ; 2

;////////////////////////////////////////////////////
;Function Gps_Chars

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (139 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Gps_Chars:

sendGPS:
pop dph ;pop return address into dptr
pop dpl
mov j,#0
sendNext:
clr a ; set offset = 0
movc a,@a+dptr ; get chr from code memory
cjne a,#0,charOK ; if chr = 0 then return
sjmp retsendGPS
charOK:
mov r0,a
lcall sendGPSdata ; send character
inc dptr ; point at next character
inc j

mov a,j
dec a
jz D1
dec a
jz D1
dec a
jz D2
jmp D3
D1:
ljmp sendNext ; loop till end of string
D2:
mov checksum,r0
ljmp sendNext ; loop till end of string

D3:
mov a,r0
xrl checksum,a
ljmp sendNext ; loop till end of string

retsendGPS:
mov a, #1h ; point to instruction after string
jmp @a+dptr ;return with a jump instruction

;////////////////////////////////////////////////////
;Function sendGPSdata: sends out characters
sendGPSdata:
clr TI
mov SBUF,r0
lcall mdelay
ret

;/////////////////////////////////////////////////
;Function Data_To_Gps

Data_To_Gps:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (140 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov a,r5
dec a
jz C1
jmp C2
C1:
jmp Possi
C2:
dec a
jz C3
jmp C4
C3:
jmp Lat
C4:
dec a
jz C5
jmp C6
C5:
jmp Lon
C6:
dec a
jz C7
jmp C8
C7:
jmp Hei
C8:
dec a
jz C9
jmp C10
C9:
jmp Datum
C10:
dec a
jz C11
jmp C12
C11:
jmp Tim
C12:
dec a
jz C13
jmp C14
C13:
jmp GmtP
C14:
dec a
jz C15
jmp C16
C15:
jmp GmtC
C16:
dec a
jz C17
jmp C18
C17:
jmp TPoll
C18:
dec a

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (141 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jz C19
jmp C20
C19:
jmp TChange
C20:
dec a
jz C21
jmp C22
C21:
jmp LeapS
C22:
dec a
jz C23
jmp C24
C23:
jmp AtmosP
C24:
dec a
jz C25
jmp C26
C25:
jmp AtmosC
C26:
dec a
jz C27
jmp C28
C27:
jmp MaskP
C28:
dec a
jz C29
jmp C30
C29:
jmp MaskC
C30:
dec a
jz C31
jmp C32
C31:
jmp Self
C32:
dec a
jz C33
jmp C34
C33:
jmp Defa
C34:
jmp lastchars

Possi:
lcall Gps_Chars
db "@@Ea",0
jmp lastchars

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (142 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Lat:
lcall Gps_Chars
db "@@Ad",99h,99h,99h,99h,0
jmp lastchars

Lon:
lcall Gps_Chars
db "@@Ae",99h,99h,99h,99h,0
jmp lastchars

Hei:
lcall Gps_Chars
db "@@Af",99h,99h,99h,99h,99h,0
jmp lastchars

Datum:
lcall Gps_Chars
db "@@Ac",0ffh,0ffh,0ffh,0ffh,0
jmp lastchars

Tim:
lcall Gps_Chars
db "@@Aa",0ffh,0ffh,0ffh,0
jmp lastchars

GmtP:
lcall Gps_Chars
db "@@Ab",0ffh,0ffh,0ffh,0
jmp lastchars

GmtC:
lcall Gps_Chars
db "@@Ab",0
jmp lastchars

TPoll:
lcall Gps_Chars
db "@@Aw",0ffh,0
jmp lastchars

TChange:
lcall Gps_Chars
db "@@Aw",0
jmp lastchars

LeapS:
lcall Gps_Chars
db "@@Bj",0
jmp lastchars

AtmosP:
lcall Gps_Chars
db "@@Aq",0ffh,0
jmp lastchars

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (143 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

AtmosC:
lcall Gps_Chars
db "@@Aq",0
jmp lastchars

MaskP:
lcall Gps_Chars
db "@@Ag",0ffh,0
jmp lastchars

MaskC:
lcall Gps_Chars
db "@@Ag",0
jmp lastchars

Self:
lcall Gps_Chars
db "@@Fa",0
jmp lastchars

Defa:
lcall Gps_Chars
db "@@Cf",0
jmp lastchars

lastchars:
mov a,var1
xrl checksum,a ;checksum ^= var1 ^ var2 ^ var3
mov a,var2
xrl checksum,a
mov a,var3
xrl checksum,a

mov a,fl ;if(fl == 1)


cjne a,#1,D4
jmp D5
D4:
jmp D6
D5:
mov r0,var1 ;SBUF = var1
lcall sendGPSdata

jmp D7 ;else if(fl == 2)


D6:
mov a,fl
cjne a,#2,D8
jmp D9
D8:
jmp D10
D9:
mov r0,var1 ;SBUF = var1
lcall sendGPSdata

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (144 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r0,var2 ;SBUF = var2


lcall sendGPSdata
jmp D7 ;else if(fl == 3)
D10:
mov a,fl
cjne a,#3,D11
jmp D12
D11:
jmp D7
D12:
mov r0,var1 ;SBUF = var1
lcall sendGPSdata
mov r0,var2 ;SBUF = var2
lcall sendGPSdata
mov r0,var3 ;SBUF = var3
lcall sendGPSdata

D7: ;SBUF = checksum


mov r0,checksum
lcall sendGPSdata
mov r0,#13 ;SBUF = 0x0D
lcall sendGPSdata
mov r0,#10 ;SBUF = 0x0A
lcall sendGPSdata
der:
ret

;////////////////////////////////////////////////////////////
;Function Buffer

Buffer:
clr EX0
mov a,bufferout ;ch = buffer[bufferout]
add a,#ringbuffer
mov r1,a
movx a,@r1
mov ch,a

mov r6,#50
loooop:
lcall mdelay ;mdelay()
djnz r6,loooop

inc bufferout ;bufferout = bufferout + 1


mov a,bufferout ;if(bufferout == 230)
cjne a,#230,D16

clr a ;bufferout = 0
mov bufferout,a
D16: ;return ch
mov r3,ch
setb EX0
ret

;///////////////////////////////////////////////////

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (145 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

;Function Bytes

Bytes:
clr a
mov lb,a
mov lb+1,a
mov lb+2,a
mov lb+3,a
mov i,a ;for(i = 0; i < num; i++)

jmp D17
D18:
mov a,i ;if(i == 0)
jnz D19

lcall Buffer ;lb = Buffer()


mov a,r3
mov lb+3,a

D19: ;lb <<= 8


mov r5,#8
mov r0,lb
mov r1,lb+1
mov r2,lb+2
mov r3,lb+3
D20:
mov a,r3
add a,r3
mov r3,a
mov a,r2
addc a,r2
mov r2,a
mov a,r1
addc a,r1
mov r1,a
mov a,r0
addc a,r0
mov r0,a
djnz r5,D20
mov lb,r0
mov lb+1,r1
mov lb+2,r2
mov lb+3,r3

lcall Buffer ;lb = lb | Buffer()


mov a,r3
mov lb+3,a

inc i
mov a,i
D17:
cjne a,num,D18

mov r2,lb ;return b


mov r3,lb+1

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (146 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r4,lb+2
mov r5,lb+3
ret

;///////////////////////////////////////////////////////
;Function EndDisps

EndDisps:
lcall Buffer ;Buffer()
lcall Buffer ;Buffer()
lcall Buffer ;Buffer()
ret

;////////////////////////////////////////////////////////
;Function Numbers

Numbers:
mov car,#13
mov l,#5
lcall Cursor_Pos

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (13)
mov r5,#low (13)
lcall lcd_xy ;lcd_xy(13,4)

lcall lcd_print ;lcd_print()


db "0 1 2 3",0

mov r2,#high (5)


mov r3,#low (5)
mov r4,#high (13)
mov r5,#low (13)
lcall lcd_xy ;lcd_xy(13,5)

mov a,fla ;if(fla == 0)


jnz ZZ1

lcall lcd_print ;lcd_print()


db "- 4 5 6",0

jmp ZZ2 ;else if(f == 1)


ZZ1:
lcall lcd_print ;lcd_print()
db "* 4 5 6",0
ZZ2:
mov r2,#high (6)
mov r3,#low (6)
mov r4,#high (13)
mov r5,#low (13)
lcall lcd_xy ;lcd_xy(13,6)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (147 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov a,fla ;if(f == 0)


jnz ZZ3

lcall lcd_print ;lcd_print()


db "+ 7 8 9",0

jmp ZZ4 ;else if(f == 1)


ZZ3:
lcall lcd_print ;lcd_print()
db " 7 8 9",0
ZZ4:
ret

;///////////////////////////////////////////////////////
;Function Key_Press_0

Key_Press_0:
M2: ;while(1)
mov a,key ;if(key == 0x03)
cjne a,#3,M3
jmp M4
M3:
jmp M5
M4:
mov lines,#6 ;lines = 6
jmp M6 ;break
;---------------------------------------
M5: ;else if(key == 0x13)
mov a,key
cjne a,#19,M7
jmp M8
M7:
jmp M9
M8:
jmp M6 ;break
;--------------------------------------------------------------------
M9: ;else if(key == 0x22)
mov a,key
cjne a,#34,M10
jmp M11
M10:
jmp M12
M11:
mov key,#0
mov a,lines ;if(lines > 3)
cjne a,#3,M13
jmp M14
M13:
mov car,chars
mov l,#-1
lcall Cursor_Pos ;Cursor_Pos(-1, chars)
jmp M15

M14: ;else if(lines == 3)


mov car,chars

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (148 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov l,#5
lcall Cursor_Pos ;Cursor_Pos(5, chars)
M15:
jmp M16
;-------------------------------------------
M12: ;else if(key == 0x32)
mov a,key
cjne a,#50,M17
jmp M18
M17:
jmp M16
M18:
mov key,#0
mov a,lines ;if(lines < 5)
cjne a,#5,M19
jmp M20

M19:
mov car,chars
mov l,#10
lcall Cursor_Pos ;Cursor_Pos(10, chars)
jmp M16
M20: ;else if(lines == 5)
mov car,chars
mov l,#3
lcall Cursor_Pos ;Cursor_Pos(3, chars)
;--------------------------------------------
M16:
setb EX0
jmp M2 ;back to while(1)

M6:
mov a,lines ;return (lines - 2)
clr c
subb a,#02h
mov r3,a
mov key,#0
setb EX0
ret

;///////////////////////////////////////////////////
;Function Key_Press_1

Key_Press_1:
N2: ;while(1)
mov a,key ;if(key == 0x03)
cjne a,#3,N3
jmp N4
N3:
jmp N5
N4:
mov lines,#10 ;lines = 6
jmp N6 ;break
;-----------------------------------------------
N5: ;else if(key == 0x13)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (149 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov a,key
cjne a,#19,N7
jmp N8
N7:
jmp N9
N8:
jmp N6 ;break
;----------------------------------------------
N9: ;else if(key == 0x22)
mov a,key
cjne a,#34,N10
jmp N11
N10:
jmp N12
N11:
mov key,#0
mov a,lines ;if(lines > 1)
cjne a,#1,N13
jmp N14
N13:
mov car,chars
mov l,#-1
lcall Cursor_Pos ;Cursor_Pos(-1, chars)
jmp N15

N14: ;else if(lines == 1)


mov car,chars
mov l,#6
lcall Cursor_Pos ;Cursor_Pos(6, chars)
N15:
jmp N16
;--------------------------------------------------
N12: ;else if(key == 0x32)
mov a,key
cjne a,#50,N17
jmp N18
N17:
jmp N16
N18:
mov key,#0
mov a,lines ;if(lines < 6)
cjne a,#6,N19
jmp N20

N19:
mov car,chars
mov l,#10
lcall Cursor_Pos ;Cursor_Pos(10, chars)
jmp N16
N20: ;else if(lines == 6)
mov car,chars
mov l,#1
lcall Cursor_Pos ;Cursor_Pos(1, chars)
;-------------------------------------------------
N16:
setb EX0

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (150 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jmp N2 ;back to while(1)

N6:
mov r3,lines ;return (lines)
mov key,#0
setb EX0
ret

;//////////////////////////////////////////////////
;Function Key_Press_2

Key_Press_2:
;while(1)
mov a,key ;if(key == 0x03)
cjne a,#3,O3
jmp O4
O3:
jmp O5
O4:
mov lines,#6 ;lines = 6
jmp O6 ;break
;----------------------------------------------
O5: ;else if(key == 0x13)
mov a,key
cjne a,#19,O7
jmp O8
O7:
jmp O9
O8:
jmp O6 ;break
;-----------------------------------------------
O9: ;else if(key == 0x22)
mov a,key
cjne a,#34,O10
jmp O11
O10:
jmp O12
O11:
mov key,#0
mov a,lines ;if(lines > 1)
cjne a,#1,O13
jmp O14
O13:
mov car,chars
mov l,#-1
lcall Cursor_Pos ;Cursor_Pos(-1, chars)
jmp O15

O14: ;else if(lines == 1)


mov car,chars
mov l,#5
lcall Cursor_Pos ;Cursor_Pos(5, chars)
O15:
jmp O16
;------------------------------------------------

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (151 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

O12: ;else if(key == 0x32)


mov a,key
cjne a,#50,O17
jmp O18
O17:
jmp O16
O18:
mov key,#0
mov a,lines ;if(lines < 5)
cjne a,#5,O19
jmp O20

O19:
mov car,chars
mov l,#10
lcall Cursor_Pos ;Cursor_Pos(10, chars)
jmp O16
O20: ;else if(lines == 5)
mov car,chars
mov l,#1
lcall Cursor_Pos ;Cursor_Pos(1, chars)
;-------------------------------------------------
O16:
setb EX0
jmp O2 ;back to while(1)

O6:
mov r3,lines ;return (lines)
mov key,#0
setb EX0
ret

;//////////////////////////////////////////////////////////
;Function Key_Press_3

Key_Press_3:
YY2: ;while(1)
mov a,key ;if(key == 0x03)
cjne a,#3,YY3
jmp YY4
YY3:
jmp YY5
YY4:
mov lines,#6 ;lines = 6
jmp Y6 ;break
;---------------------------------------------------
YY5: ;else if(key == 0x13)
mov a,key
cjne a,#19,Y7
jmp Y8
Y7:
jmp Y9
Y8:
jmp Y6 ;break
;-------------------------------------------------

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (152 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

Y9: ;else if(key == 0x22)


mov a,key
cjne a,#34,Y10
jmp Y11
Y10:
jmp Y12
Y11:
mov key,#0
mov a,lines ;if(lines > 1)
cjne a,#1,Y13
jmp Y14
Y13:
mov car,chars
mov l,#-1
lcall Cursor_Pos ;Cursor_Pos(-1, chars)
jmp Y15

Y14: ;else if(lines == 1)


mov car,chars
mov l,#4
lcall Cursor_Pos ;Cursor_Pos(4, chars)
Y15:
jmp Y16
;------------------------------------------------------
Y12: ;else if(key == 0x32)
mov a,key
cjne a,#50,Y17
jmp Y18
Y17:
jmp Y16
Y18:
mov key,#0
mov a,lines ;if(lines < 4)
cjne a,#4,Y19
jmp Y20

Y19:
mov car,chars
mov l,#10
lcall Cursor_Pos ;Cursor_Pos(10, chars)
jmp Y16
Y20: ;else if(lines == 4)
mov car,chars
mov l,#1
lcall Cursor_Pos ;Cursor_Pos(1, chars)
;------------------------------------------------
Y16:
setb EX0
jmp YY2 ;back to while(1)

Y6:
mov r3,lines ;return (lines)
mov key,#0
setb EX0
ret

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (153 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

;/////////////////////////////////////////////////////
;Function Key_Press_4

Key_Press_4:
Q2: ;while(1)
mov a,key ;if(key == 0x03)
cjne a,#3,Q3
jmp Q4
Q3:
jmp Q5
Q4:
mov lines,#6 ;lines = 6
jmp Q6 ;break
;-----------------------------------------------
Q5: ;else if(key == 0x13)
mov a,key
cjne a,#19,Q7
jmp Q8
Q7:
jmp Q9
Q8:
jmp Q6 ;break
;------------------------------------------------
Q9: ;else if(key == 0x22)
mov a,key
cjne a,#34,Q10
jmp Q11
Q10:
jmp Q12
Q11:
mov key,#0
mov a,lines ;if(lines > 3)
cjne a,#3,Q13
jmp Q14
Q13:
mov car,chars
mov l,#-1
lcall Cursor_Pos ;Cursor_Pos(-1, chars)
jmp Q15

Q14: ;else if(lines == 3)


mov car,chars
mov l,#4
lcall Cursor_Pos ;Cursor_Pos(4, chars)
Q15:
jmp Q16
;-----------------------------------------------------
Q12: ;else if(key == 0x32)
mov a,key
cjne a,#50,Q17
jmp Q18
Q17:
jmp Q16
Q18:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (154 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov key,#0
mov a,lines ;if(lines < 4)
cjne a,#4,Q19
jmp Q20

Q19:
mov car,chars
mov l,#10
lcall Cursor_Pos ;Cursor_Pos(10, chars)
jmp Q16 ;else if(lines == 4)
mov car,chars
mov l,#3
lcall Cursor_Pos ;Cursor_Pos(3, chars)
;------------------------------------------------
Q16:
setb EX0
jmp Q2 ;back to while(1)

Q6:
mov a,lines ;return (lines - 2)
clr c
subb a,#02h
mov r3,a
mov key,#0
setb EX0
ret
;///////////////////////////////////////////////
;Function Key_Press_5

Key_Press_5:
ZZ5:
mov a,key ;if(key == 0x03)
cjne a,#3,ZZ6
jmp ZZ7
ZZ6:
jmp Z8
ZZ7:
mov s,#43 ;sign = '+'
jmp Z9 ;break
;----------------------------------------------
Z8: ;else if(key == 0x13)
mov a,key
cjne a,#19,Z10
jmp Z11
Z10:
jmp Z12
Z11:
jmp Z9 ;break
;------------------------------------------------
Z12: ;else if((key == 0x22) && (chars == 13))
mov a,key
cjne a,#34,Z13
jmp Z14
Z14:
mov a,chars

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (155 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

cjne a,#13,Z13
jmp Z15
Z15:
jmp Z16
Z13:
jmp Z17
Z16:
mov key,#0
mov a,lines ;if(lines > 5)
cjne a,#5,Z18
jmp Z19
Z18:
mov car,chars
mov l,#-1
lcall Cursor_Pos ;Cursor_Pos(-1, chars)
jmp Z20
Z19: ;else if(lines == 5)
mov car,chars
mov l,#6
lcall Cursor_Pos ;Cursor_Pos(6, chars)
Z20:
jmp Z21
;-------------------------------------------------
Z17: ;else if((key == 0x32) && (chars == 13))
mov a,key
cjne a,#50,Z22
jmp Z23
Z23:
mov a,chars
cjne a,#13,Z22
jmp Z24
Z24:
jmp Z25
Z22:
jmp Z21
Z25:
mov key,#0
mov a,lines ;if(lines < 6)
cjne a,#6,Z26
jmp Z27
Z26:
mov car,chars
mov l,#10
lcall Cursor_Pos ;Cursor_Pos(10, chars)
jmp Z21
Z27: ;else if(lines == 6)
mov car,chars
mov l,#5
lcall Cursor_Pos ;Cursor_Pos(5, chars)

Z21:
setb EX0
jmp ZZ5
Z9:
mov a,lines ;if(lines == 5)
cjne a,#5,Z28

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (156 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jmp Z29
Z28:
jmp Z30
Z29:
mov s,#45 ;s = '-'
jmp Z31
Z30: ;else if(lines == 6)
mov a,lines
cjne a,#6,Z32
jmp Z33
Z32:
jmp Z31
Z33:
mov s,#43 ;s = '+'
Z31:
mov key,#0
setb EX0
ret

;/////////////////////////////////////////////////
;Function Key_Press_6
;use var1, var2, checksum

Key_Press_6:
mov var1,#0
mov var2,#0
mov checksum,#0
Z34: ;while(1)
Z35: ;while(1)
mov a,key ;if(key == 0x03)
cjne a,#3,Z36
jmp Z37
Z36:
jmp Z38
Z37:
mov var1,#0 ;var1 = 0
jmp Z39 ;break
;----------------------------------------------
Z38: ;else if(key == 0x13)
mov a,key
cjne a,#19,Z40
jmp Z41
Z40:
jmp Z42
Z41:
jmp Z39 ;break
;--------------------------------------------------
Z42: ;else if((key == 0x22) && (chars != 13))
mov a,key
cjne a,#34,Z43
jmp Z44
Z44:
mov a,chars
cjne a,#13,Z45
jmp Z43
Z45:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (157 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jmp Z46
Z43:
jmp Z47
Z46:
mov key,#0
mov a,lines ;if(lines > 4)
cjne a,#4,Z48
jmp Z49
Z48:
mov car,chars
mov l,#-1
lcall Cursor_Pos ;Cursor_Pos(-1, chars)
jmp Z50
Z49: ;else if(lines == 4)
mov car,chars
mov l,#6
lcall Cursor_Pos ;Cursor_Pos(6, chars)
Z50:
jmp Z51
;------------------------------------------------
Z47: ;else if((key == 0x32) && (chars != 13))
mov a,key
cjne a,#50,Z52
mov a,chars
cjne a,#13,Z53
jmp Z52
Z53:
jmp Z54
Z52:
jmp Z55
Z54:
mov key,#0
mov a,lines ;if(lines < 6)
cjne a,#6,Z56
jmp Z57
Z56:
mov car,chars
mov l,#10
lcall Cursor_Pos ;Cursor_Pos(10, chars)
jmp Z58
Z57: ;else if(lines == 6)
mov car,chars
mov l,#4
lcall Cursor_Pos ;Cursor_Pos(4, chars)
Z58:
jmp Z51
;-------------------------------------------------
Z55: ;else if((key == 0x22) && (chars == 13))
mov a,key
cjne a,#34,Z59
mov a,chars
cjne a,#13,Z59
jmp Z60
Z59:
jmp Z61
Z60:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (158 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov key,#0
mov a,lines ;if(lines > 4)
cjne a,#4,Z62
jmp Z63
Z62:
mov car,chars
mov l,#-1
lcall Cursor_Pos ;Cursor_Pos(-1, chars)
jmp Z64
Z63: ;else if(lines == 4)
mov car,chars
mov l,#5
lcall Cursor_Pos ;Cursor_Pos(5, chars)
Z64:
jmp Z51
;--------------------------------------------------
Z61: ;else if((key == 0x32) && (chars == 13))
mov a,key
cjne a,#50,Z65
mov a,chars
cjne a,#13,Z65
jmp Z66
Z65:
jmp Z67
Z66:
mov key,#0
mov a,lines ;if(lines < 5)
cjne a,#5,Z68
jmp Z69
Z68:
mov car,chars
mov l,#10
lcall Cursor_Pos ;Cursor_Pos(10, chars)
jmp Z70
Z69: ;else if(lines == 5)
mov car,chars
mov l,#4
lcall Cursor_Pos ;Cursor_Pos(4, chars)
Z70:
jmp Z51
;-------------------------------------------------
Z67: ;else if((key == 0x02) && ((lines == 4) || (lines == 5)))
mov a,key
cjne a,#2,Z71
mov a,lines
cjne a,#4,Z72
jmp Z73
Z72:
mov a,lines
cjne a,#5,Z71
Z73:
jmp Z74
Z71:
jmp Z75
Z74:
mov key,#0

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (159 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov a,chars ;if(chars > 13)


cjne a,#13,Z76
jmp Z77
Z76:
mov a,chars
clr c
subb a,#03h
mov car,a
mov l,lines
lcall Cursor_Pos ;Cursor_Pos(lines, chars - 3)
jmp Z78
Z77: ;else if(chars == 13)
mov car,#22
mov l,lines
lcall Cursor_Pos ;Cursor_Pos(lines, 22)
Z78:
jmp Z51
;---------------------------------------------------
Z75: ;else if((key == 0x12) && ((lines == 4) || (lines == 5)))
mov a,key
cjne a,#18,Z79
mov a,lines
cjne a,#4,Z80
jmp Z81
Z80:
mov a,lines
cjne a,#5,Z79
Z81:
jmp Z82
Z79:
jmp Z83
Z82:
mov key,#0
mov a,chars ;if(chars < 22)
cjne a,#22,Z84
jmp Z85
Z84:
mov a,chars
add a,#03h
mov car,a
mov l,lines
lcall Cursor_Pos ;Cursor_Pos(lines, chars + 3)
jmp Z86
Z85: ;else if(chars == 22)
mov car,#13
mov l,lines
lcall Cursor_Pos ;Cursor_Pos(lines, 13)

Z86:
jmp Z51
;------------------------------------------------
Z83: ;else if((key == 0x02) && (lines == 6))
mov a,key
cjne a,#2,Z87
mov a,lines
cjne a,#6,Z87

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (160 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jmp Z88
Z87:
jmp Z89
Z88:
mov key,#0
mov a,chars ;if(chars > 16)
cjne a,#16,Z90
jmp Z91
Z90:
mov a,chars
clr c
subb a,#03h
mov car,a
mov l,lines
lcall Cursor_Pos ;Cursor_Pos(lines, chars - 3)
jmp Z92
Z91: ;else if(chars == 16)
mov car,#22
mov l,lines
lcall Cursor_Pos ;Cursor_Pos(lines, 22)
Z92:
jmp Z51
;-----------------------------------------------------
Z89: ;else if((key == 0x12) && (lines == 6))
mov a,key
cjne a,#18,Z93
mov a,lines
cjne a,#6,Z93
jmp Z94
Z93:
jmp Z51
Z94:
mov key,#0
mov a,chars ;if(chars < 22)
cjne a,#22,Z96
jmp Z97
Z96:
mov a,chars
add a,#03h
mov car,a
mov l,lines
lcall Cursor_Pos ;Cursor_Pos(lines, chars + 3)
jmp Z51
Z97: ;else if(chars == 22)
mov car,#16
mov l,lines
lcall Cursor_Pos ;Cursor_Pos(lines, 16)
Z51:
setb EX0
jmp Z35
;--------------------------------------------------------
Z39:
mov a,key ;if(key == 0x03)
cjne a,#3,Z99
jmp Z100
Z99:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (161 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jmp Z101
Z100:
mov var1,a ;var1 = 0
jmp Z102 ;break
;--------------------------------------------------------
Z101: ;else if(key == 0x13)
mov a,key
cjne a,#19,Z103
jmp Z104
Z103:
jmp Z105
Z104:
mov a,lines ;if((lines == 5) && (chars == 13))
cjne a,#5,Z106
mov a,chars
cjne a,#13,Z106
jmp Z107
Z106:
jmp Z108
Z107:
mov var2,#1 ;for(i = 1; i <= count; i++)
jmp Z109
Z110: ;var1 = var1 + yebo[i - 1] * pow(10,count - i)
mov a,checksum
clr c
subb a,var2
mov r5,a
jz Z111
mov a,#1

Z111:
mov b,#10d ;pow operation (value will never be
;greater then 100)
mul ab
cjne r5,#0,Gogo1
jmp Gogo2
Gogo1:
djnz r5,Z111
Gogo2:
jz Power
mov fl,a
jmp Correct
Power:
inc a
mov fl,a
Correct:
clr c
mov a,var2
subb a,#01h
mov r3,a
mov a,#yebo
add a,r3
mov r1,a
movx a,@r1 ;r4 contains now value from array
mov 4+0,a

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (162 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov a,r4
mov b,fl
mul ab
add a,var1
mov var1,a

inc var2
Z109:
clr c
mov a,checksum
subb a,var2
add a,#1
jnz Z110
jmp Z102

Z108: ;else
inc checksum ;var3++
;yebo[count - 1] = nums[lines - 4][chars - 13]
mov a,lines
clr c
subb a,#04h
mov b,#10
mul ab
mov r2,a

clr c
mov a,chars
subb a,#0dh
add a,r2
mov r2,a

mov a,checksum
clr c
subb a,#01h
mov r1,a
mov a,#yebo
add a,r1
mov r1,a
lcall GetVal

movx @r1,a
mov fl,a

mov r2,#high (2)


mov r3,#low (2)
mov a,checksum
add a,#0Eh
mov r4,#0
mov r5,a
lcall lcd_xy ;lcd_xy(14 + count,2)

mov r1,#0
mov r2,#high (0)
mov r3,#low (0)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (163 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r4,high(fl)
mov r5,low(fl)
lcall lcd_print_num ;lcd_print_num(yebo[count - 1],0)

Z105:
setb EX0
mov key,#0
jmp Z34
Z102:
mov r3,var1 ;return var1
mov key,#0
setb EX0
ret

;////////////////////////////////////////////////
;Function GetVal

GetVal:
mov a,r2
inc a
movc a,@a+pc
ret
nums:
db 0
db 0
db 0
db 1
db 0
db 0
db 2
db 0
db 0
db 3
db 0
db 0
db 0
db 4
db 0
db 0
db 5
db 0
db 0
db 6
db 0
db 0
db 0
db 7
db 0
db 0
db 8
db 0
db 0
db 9

;////////////////////////////////////////////

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (164 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

;Function lcd_print_num
;count - num
;temp - x
;i - l
;f - car

lcd_print_num:
mov num,#0

mov y,r2 ;highest byte


mov y+1,r3
mov x,r4 ;temp = r2, r3, r4 and r5
mov x+1,r5
mov car,r1 ;save car(flag)
K1: ;while(1)
mov X3,r2 ;num % 10
mov X2,r3
mov X1,r4
mov X0,r5
mov Y0,#10
mov Y1,#0
mov Y2,#0 ;high 16 bits of Y is 0
mov Y3,#0
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov a,#array ;array[num] = Z0 + 16


add a,num
mov r1,a
mov a,Z0
add a,#16
mov Z0,a
movx @r1,a ;rem is in R4

inc num ;num++

mov r2,Z7
mov r3,Z6 ;num = num / 10
mov r4,Z5
mov r5,Z4
mov a,Z4

jnz K2 ;if(a == 0)
jmp K3 ;break
K2:
jmp K1
K3:
;if((f == 1) && (temp > 0) && (temp < 10))
mov a,car
cjne a,#1,K4
mov a,x+1
add a,#low -(1)
mov a,x
xrl a,#80h
addc a,#(high -(1))xor 80h
jnc K4

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (165 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jmp K5
K4:
jmp K6
K5:
mov a,x+1
add a,#low -(10)
mov a,x
xrl a,#80h
addc a,#(high -(10))xor 80h
jc K6
jmp K7
K6:
jmp K8
K7:
mov a,#array ;array[num] = 16
add a,num
mov r1,a
mov a,#16
movx @r1,a

inc num ;num++

K8: ;for(i = count - 1; i >= 0 ; i--)


mov a,num
clr c
subb a,#01h
mov l,a
jmp K9
K10:
mov a,l
mov r3,a
mov a,#array ;a = array[i]
add a,r3
mov r1,a
movx a,@r1

jnb acc.7, K11 ;if (a<0)


clr a ;a=0

K11:
mov r7,a
lcall dput ;dput(a)

mov r7,#192
lcall cput ;cput(0xc0)

mov a,l
clr c
subb a,#01h
mov l,a
K9:
mov a,l
add a,#1
jnz K10
ret

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (166 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

;///////////////////////////////////////////////////
;=================================================
; subroutine DIV32
; 32-Bit Unsigned Division
;=================================================
DIV32:
mov a,Y3 ;get divisor high byte
orl a,Y2
orl a,Y1
orl a,Y0 ;OR with low bytes
jnz div32_OK ;divisor OK if not 0
setb OV ;else, overflow
ret
div32_OK:
mov PR3,X3 ;store dividend
mov PR2,X2
mov PR1,X1
mov PR0,X0
mov X3,#0 ;clear partial remainder
mov X2,#0
mov X1,#0
mov X0,#0
mov r6,#0
mov r5,#0
mov r4,#0
mov r3,#0 ;clear partial quotient
mov r7,#32 ;set loop count

div32_loop:
clr C ;clear carry flag
mov a,PR0 ;shift the highest bit of the dividend...
rlc a ;... into...
mov PR0,a
mov a,PR1
rlc a
mov PR1,a
mov a,PR2
rlc a
mov PR2,a
mov a,PR3
rlc a
mov PR3,a

mov a,X0 ;... the lowest bit of the partial ...


rlc a ;... remainder
mov X0,a
mov a,X1
rlc a
mov X1,a
mov a,X2
rlc a
mov X2,a
mov a,X3

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (167 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

rlc a
mov X3,a

lcall SUB32 ;attempt to subtract to see if the...


;... partial remainder is as large or...
;... larger than the divisor.

mov C,OV ;get subtraction external barrow


cpl C ;complement external barrow
jnc div32_1
mov X3,Z3
mov X2,Z2
mov X1,Z1
mov X0,Z0
div32_1:
mov a,r3 ;add result bit to partial quotient
rlc a
mov r3,a
mov a,r4
rlc a
mov r4,a
mov a,r5
rlc a
mov r5,a
mov a,r6
rlc a
mov r6,a

djnz r7,div32_loop

mov Z7,r6 ;put quotient in Z4 - Z7


mov Z6,r5
mov Z5,r4
mov Z4,r3
mov Z0,X0 ;get remainder, saved before the...
mov Z1,X1 ;last subtraction
mov Z2,X2
mov Z3,X3
clr OV ;divisor is not 0
ret ;done

;//////////////////////////////////////////////////
;==================================================
; subroutine SUB32
; 32-Bit Unsigned subtraction
;==================================================
SUB32:
mov a,X0 ;load X low byte into accumulator
clr C ;clear carry flag
subb a,Y0 ;subract Y low byte
mov Z0,a ;put result in Z low byte
mov a,X1 ;repeat with other bytes...
subb a,Y1
mov Z1,a
mov a,X2

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (168 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

subb a,Y2
mov Z2,a
mov a,X3
subb a,Y3
mov Z3,a
mov OV,C ;set ZOV id an external barrow is produced
ret ;done

;////////////////////////////////////////////////////
;===================================================
; subroutine ADD16
; 16-Bit Unsigned Addition
;===================================================
ADD16:
mov a,#low(Gps_pic_less); load X low byte into accumulator
add a,r2 ; add Y low byte
mov dpl,a ; put result in Z low byte
mov a,#high(Gps_pic_less); load X high byte into accumulator
addc a,r3 ; add Y high byte with the carry from low ...
; ... byte operation
mov dph,a ; save result in Z high byte
mov OV,C ; set OV if external carry
ret ; done

;/////////////////////////////////////////////////
;Function mult8_8: multiplies 2 8bit numbers

mult8_8:
mov a,r5
mov b,r3
mul ab
mov r3,a
push b

mov a,r5
mov b,r2
mul ab
pop 0
add a,r0
mov r2,a
ret

;//////////////////////////////////////////////
Disp_Aa:
mov univ,r4
mov a,r4
cjne a,#0,ww

mov f,#1
lcall Init_Text

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (169 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcall lcd_xy

lcall lcd_print
db "Current Time: ",0
jmp ww1

ww:
mov r2,#high (0)
mov r3,#low (0)
mov r4,#high (17)
mov r5,#low (17)
lcall lcd_xy

lcall lcd_print
db " / Time: ",0
ww1:
lcall Buffer
mov fl,r3

mov r1,#1
mov r2,#high (0)
mov r3,#low (0)
mov r4,high(fl)
mov r5,low(fl)
lcall lcd_print_num ;lcd_print_num()

lcall lcd_print
db ":",0

lcall Buffer
mov fl,r3

mov r1,#1
mov r2,#high (0)
mov r3,#low (0)
mov r4,high(fl)
mov r5,low(fl)
lcall lcd_print_num ;lcd_print_num()

lcall lcd_print
db ":",0

lcall Buffer
mov fl,r3

mov r1,#1
mov r2,#high (0)
mov r3,#low (0)
mov r4,high(fl)
mov r5,low(fl)
lcall lcd_print_num ;lcd_print_num()

lcall lcd_print
db " hours",0

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (170 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov a,univ
cjne a,#0,ww2
lcall EndDisps
ww2:
ret

;//////////////////////////////////////////////////
Disp_Ab:
mov f,#1
lcall Init_Text

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "GMT Offset: ",0

lcall Buffer
mov a,r3

cjne a,#0,ww3
lcall lcd_print
db "+",0
jmp ww4
ww3:
lcall lcd_print
db "-",0
ww4:
lcall Buffer
mov fl,r3

mov r1,#0
mov r2,#high (0)
mov r3,#low (0)
mov r4,high(fl)
mov r5,low(fl)
lcall lcd_print_num ;lcd_print_num()

lcall lcd_print
db ":",0

lcall Buffer
mov fl,r3

mov r1,#0
mov r2,#high (0)
mov r3,#low (0)
mov r4,high(fl)
mov r5,low(fl)
lcall lcd_print_num ;lcd_print_num()

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (171 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcall lcd_print
db "hours",0

lcall EndDisps
ret

;///////////////////////////////////////////////////
Disp_Ac:
mov univ,r4
mov a,r4
cjne a,#0,ww5

mov f,#1
lcall Init_Text

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Current Date(dd/mm/yyyy): ",0
jmp ww6

ww5:
mov r2,#high (0)
mov r3,#low (0)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Date: ",0
ww6:
lcall Buffer
mov angle,r3

lcall Buffer
mov fl,r3

mov r1,#1
mov r2,#high (0)
mov r3,#low (0)
mov r4,high(fl)
mov r5,low(fl)
lcall lcd_print_num ;lcd_print_num()

lcall lcd_print
db "/",0

mov r1,#1
mov r2,#high (0)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (172 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r3,#low (0)


mov r4,high(angle)
mov r5,low(angle)
lcall lcd_print_num ;lcd_print_num()

lcall lcd_print
db "/",0

mov num,#1
lcall Bytes ;r4 contains high byte
;r5 contains low byte

mov r1,#0
mov r2,#high (0)
mov r3,#low (0)
lcall lcd_print_num ;lcd_print_num()

mov a,univ
cjne a,#0,ww7
lcall EndDisps
ww7:
ret

;////////////////////////////////////////////////////
Disp_Ad:
mov univ,r4
mov a,r4
cjne a,#0,vv1

mov f,#1
lcall Init_Text

mov r2,#high (1)


mov r3,#low (1)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Lattitude(milliarcseconds or mas): ",0

vv1:
mov num,#3
lcall Bytes ;r2 contains highest byte
;r3
;r4
;r5 contains lowest byte

mov lb,r2
mov lb+1,r3
mov lb+2,r4
mov lb+3,r5

mov a,univ

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (173 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

cjne a,#0,vv7
jmp vv8
vv7:
jmp vv2
vv8:
mov r2,#high (2)
mov r3,#low (2)
mov r4,#high (5)
mov r5,#low (5)
lcall lcd_xy

mov a,lb
anl a,#80h
cjne a,#80h,vv3 ;test if number is positive

lcall lcd_print
db "-",0

mov var1,#0

mov a,lb+3 ;lb = -lb


cpl a
add a,#01h
mov lb+3,a
mov a,lb+2
cpl a
addc a,#0
mov lb+2,a
mov a,lb+1
cpl a
addc a,#0
mov lb+1,a
mov a,lb
cpl a
addc a,#0
mov lb,a
jmp vv4

vv3:
lcall lcd_print
db "+",0

mov var1,#1

vv4:
mov r1,#0
mov r2,lb
mov r3,lb+1
mov r4,lb+2
mov r5,lb+3
lcall lcd_print_num ;lcd_print_num()

lcall lcd_print
db "mas",0

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (174 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Lattitude(degrees/min/sec): ",0

jmp vv5

vv2:
mov r2,#high (1)
mov r3,#low (1)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Position: ",0

vv5:
mov a,univ
cjne a,#0,vv6

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (5)
mov r5,#low (5)
lcall lcd_xy
vv6:
mov X3,lb ;divide milliarcseconds by 3600000
mov X2,lb+1
mov X1,lb+2
mov X0,lb+3
mov Y0,#80h
mov Y1,#0eeh
mov Y2,#36h
mov Y3,#00h
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov lb,Z3 ;get remainder


mov lb+1,Z2
mov lb+2,Z1
mov lb+3,Z0

mov r1,#0 ;print angle


mov r2,#high (0)
mov r3,#low (0)
mov r4,high(Z4)
mov r5,low(Z4)
lcall lcd_print_num ;lcd_print_num()

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (175 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r7,#80h
lcall dput ;dput(degree sign)

mov r7,#192
lcall cput

mov X3,lb ;divide remainder by 3600


mov X2,lb+1
mov X1,lb+2
mov X0,lb+3
mov Y0,#10h
mov Y1,#0eh
mov Y2,#00h
mov Y3,#00h
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov r4,#high (6)


mov r5,#low (6)
mov r2,Z5
mov r3,Z4
lcall mult8_8

mov X3,#0 ;divide by 100


mov X2,#0
mov X1,r2
mov X0,r3
mov Y0,#64h
mov Y1,#00h
mov Y2,#00h
mov Y3,#00h
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov lb,Z3 ;get remainder


mov lb+1,Z2
mov lb+2,Z1
mov lb+3,Z0

mov r1,#0 ;print minutes


mov r2,#0
mov r3,#0
mov r4,#0
mov r5,Z4
lcall lcd_print_num ;lcd_print_num()

mov r7,#81h
lcall dput

mov r7,#192
lcall cput

mov r4,#high (60)


mov r5,#low (60)
mov r2,lb+2

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (176 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r3,lb+3
lcall mult8_8

mov X3,#0 ;divide by 100


mov X2,#0
mov X1,r2
mov X0,r3
mov Y0,#64h
mov Y1,#00h
mov Y2,#00h
mov Y3,#00h
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov r1,#0 ;print seconds


mov r2,#0
mov r3,#0
mov r4,#0
mov r5,Z4
lcall lcd_print_num ;lcd_print_num()

mov r7,#02h
lcall dput

mov r7,#192
lcall cput

mov a,var1
cjne a,#0,wert
lcall lcd_print
db "S",0
jmp wert1

wert:
lcall lcd_print
db "N",0

wert1:
mov a,univ
cjne a,#0,hhhh
lcall EndDisps
hhhh:
ret

;////////////////////////////////////////////////
Disp_Ae:
mov univ,r4
mov a,r4
cjne a,#0,qq1

mov f,#1
lcall Init_Text

mov r2,#high (1)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (177 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r3,#low (1)


mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Longitude(milliarcseconds or mas): ",0

qq1:
mov num,#3
lcall Bytes ;r2 contains highest byte
;r3
;r4
;r5 contains lowest byte

mov lb,r2
mov lb+1,r3
mov lb+2,r4
mov lb+3,r5

mov a,univ
cjne a,#0,qq7
jmp qq8
qq7:
jmp qq2
qq8:
mov r2,#high (2)
mov r3,#low (2)
mov r4,#high (5)
mov r5,#low (5)
lcall lcd_xy

mov a,lb
anl a,#80h
cjne a,#80h,qq3 ;test if number is positive

lcall lcd_print
db "-",0

mov var1,#0

mov a,lb+3
cpl a
add a,#01h
mov lb+3,a
mov a,lb+2
cpl a
addc a,#0
mov lb+2,a
mov a,lb+1
cpl a
addc a,#0
mov lb+1,a
mov a,lb
cpl a

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (178 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

addc a,#0
mov lb,a
jmp ww4

qq3:
lcall lcd_print
db "+",0

mov var1,#1

qq4:
mov r1,#0 ;print angle
mov r2,lb
mov r3,lb+1
mov r4,lb+2
mov r5,lb+3
lcall lcd_print_num ;lcd_print_num()

lcall lcd_print
db "mas",0

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Longitude(degrees/min/sec): ",0

jmp qq5

qq2:
mov r2,#high (1)
mov r3,#low (1)
mov r4,#high (23)
mov r5,#low (23)
lcall lcd_xy

lcall lcd_print
db "/ ",0

qq5:
mov a,univ
cjne a,#0,qq6

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (5)
mov r5,#low (5)
lcall lcd_xy
qq6:
mov X3,lb ;divide milliarcseconds by 3600000
mov X2,lb+1

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (179 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov X1,lb+2
mov X0,lb+3
mov Y0,#80h
mov Y1,#0eeh
mov Y2,#36h
mov Y3,#00h
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov lb,Z3 ;get remainder


mov lb+1,Z2
mov lb+2,Z1
mov lb+3,Z0

mov r1,#0 ;print angle


mov r2,#high (0)
mov r3,#low (0)
mov r4,high(Z4)
mov r5,low(Z4)
lcall lcd_print_num ;lcd_print_num()

mov r7,#80h
lcall dput ;dput(degree sign)

mov r7,#192
lcall cput

mov X3,lb ;divide remainder by 3600


mov X2,lb+1
mov X1,lb+2
mov X0,lb+3
mov Y0,#10h
mov Y1,#0eh
mov Y2,#00h
mov Y3,#00h
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov r4,#high (6)


mov r5,#low (6)
mov r2,Z5
mov r3,Z4
lcall mult8_8

mov X3,#0 ;divide by 100


mov X2,#0
mov X1,r2
mov X0,r3
mov Y0,#64h
mov Y1,#00h
mov Y2,#00h
mov Y3,#00h
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov lb,Z3 ;get remainder


mov lb+1,Z2
mov lb+2,Z1

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (180 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov lb+3,Z0

mov r1,#0 ;print minutes


mov r2,#0
mov r3,#0
mov r4,#0
mov r5,Z4
lcall lcd_print_num ;lcd_print_num()

mov r7,#81h
lcall dput

mov r7,#192
lcall cput

mov r4,#high (60)


mov r5,#low (60)
mov r2,lb+2
mov r3,lb+3
lcall mult8_8

mov X3,#0 ;divide by 100


mov X2,#0
mov X1,r2
mov X0,r3
mov Y0,#64h
mov Y1,#00h
mov Y2,#00h
mov Y3,#00h
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov r1,#0 ;print seconds


mov r2,#0
mov r3,#0
mov r4,#0
mov r5,Z4
lcall lcd_print_num ;lcd_print_num()

mov r7,#02h
lcall dput

mov r7,#192
lcall cput

mov a,var1
cjne a,#0,wert2
lcall lcd_print
db "W",0
jmp wert3

wert2:
lcall lcd_print
db "E",0

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (181 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

wert3:
mov a,univ
cjne a,#0,gggg
lcall EndDisps
gggg:
ret

;/////////////////////////////////////////////////
Disp_Af:
mov univ,r4
mov a,r4
cjne a,#0,qq9

mov f,#1
lcall Init_Text

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Height(ellipsoid height in meters): ",0

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (5)
mov r5,#low (5)
lcall lcd_xy

jmp qq10

qq9:
mov r2,#high (2)
mov r3,#low (2)
mov r4,#high (7)
mov r5,#low (7)
lcall lcd_xy

lcall lcd_print
db "Height (m): ",0
qq10:
mov num,#3
lcall Bytes ;r2 contains highest byte
;r3
;r4
;r5 contains lowest byte

mov lb,r2
mov lb+1,r3
mov lb+2,r4
mov lb+3,r5

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (182 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov X3,r2 ;divide by 100


mov X2,r3
mov X1,r4
mov X0,r5
mov Y0,#64h
mov Y1,#00h
mov Y2,#00h
mov Y3,#00h
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov r1,#0 ;print minutes


mov r2,Z7
mov r3,Z6
mov r4,Z5
mov r5,Z4
lcall lcd_print_num ;lcd_print_num()

lcall lcd_print
db "m",0

mov a,univ
cjne a,#0,iiii
lcall EndDisps
iiii:
ret

;////////////////////////////////////////////////
Disp_Ag:
mov f,#1
lcall Init_Text

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Satellite Mask Angle (degrees): ",0

lcall Buffer
mov fl,r3

mov r1,#0
mov r2,#high (0)
mov r3,#low (0)
mov r4,high(fl)
mov r5,low(fl)
lcall lcd_print_num ;lcd_print_num()

mov r7,#128 ;degree sign


lcall dput

mov r7,#192

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (183 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcall cput

lcall EndDisps
ret

;///////////////////////////////////////////////
Disp_Aq:
mov f,#1
lcall Init_Text

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Atmosphere Correction Mode: ",0

lcall Buffer
mov univ,r3

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (2)
mov r5,#low (2)
lcall lcd_xy

mov a,univ
cjne a,#0,ww8
lcall lcd_print
db "'0' = Ionosphere model disabled.",0
jmp ww11
ww8:
cjne a,#1,ww9
lcall lcd_print
db "'1' = Ionosphere model only enabled.",0
jmp ww11
ww9:
cjne a,#2,ww10
lcall lcd_print
db "'2' = Tropospheric model only enabled.",0
jmp ww11
ww10:
cjne a,#3,ww11
lcall lcd_print
db "'3' = Both models enabled.",0

ww11:
lcall EndDisps
ret

;////////////////////////////////////////////////
Disp_Aw:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (184 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov f,#1
lcall Init_Text

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Current Time Mode: ",0

lcall Buffer
mov univ,r3

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (2)
mov r5,#low (2)
lcall lcd_xy

mov a,univ
cjne a,#0,ww12
lcall lcd_print
db "'0' = GPS Time.",0
jmp ww13
ww12:
cjne a,#1,ww13
lcall lcd_print
db "'1' = UTC Time.",0
ww13:
lcall EndDisps
ret

;/////////////////////////////////////////////////////
Disp_Bj:
mov f,#1
lcall Init_Text

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Leap Second Pending Status: ",0

lcall Buffer
mov univ,r3

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (2)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (185 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r5,#low (2)


lcall lcd_xy

mov a,univ
cjne a,#0,ww14
lcall lcd_print
db "'0' = No leap second pending.",0
jmp ww16
ww14:
cjne a,#1,ww15
lcall lcd_print
db "'1' = Addition of one second pending.",0
jmp ww16
ww15:
cjne a,#2,ww16
lcall lcd_print
db "'2' = Subtraction of one second pending.",0
ww16:
lcall EndDisps
ret

;////////////////////////////////////////////////
Disp_Fa:
mov var1,#0
mov row,#0
mov column,#0

mov f,#1
lcall Init_Text

mov r2,#high (1)


mov r3,#low (1)
mov r4,#high (7)
mov r5,#low (7)
lcall lcd_xy

lcall lcd_print
db "GPS Selftest Results: ",0

mov num,#1
lcall Bytes ;r4 contains high byte

mov r0,#aid1
mov a,r4
movx @r0,a
inc r0
mov a,r5
movx @r0,a

clr a
mov i,a
mov i+1,a
jmp ww19 ;for(i = 0; i < 16; i++)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (186 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

ww20:
mov r5,i+1 ;num = (byte >> i) & 0x01
mov r0,#aid1
movx a,@r0
mov r2,a
inc r0
movx a,@r0
mov r3,a
cjne r5,#0,ww21
jmp ww22
ww21:
mov a,r2
clr c
rrc a
mov r2,a
mov a,r3
rrc a
mov r3,a
djnz r5,ww21
ww22:
mov a,r3
anl a,#01h
mov r0,#aid2
inc r0
movx @r0,a
dec r0
mov a,r2
anl a,#0
movx @r0,a

mov r0,#aid2 ;if(num == 1)


inc r0
movx a,@r0
cjne a,#low (1),ww23
dec r0
movx a,@r0
cjne a,#high (1),ww23
jmp ww24
ww23:
jmp ww25
ww24:

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (7)
mov r5,#low (7)
lcall lcd_xy ;lcd_xy(7,3)

mov a,i+1
add a,i+1
mov r3,a
mov a,i
addc a,i
mov r2,a

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (187 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov a,r3
add a,#low(messages)
mov dpl,a
mov a,r2
addc a,#high(messages)
mov dph,a
lcall lcd_print1 ;lcd_print(messages[i])

jmp ww26
ww25: ;else if(num == 0)
mov r0,#aid2
inc r0
movx a,@r0
mov b,a
dec r0
movx a,@r0
orl a,b
jnz ww26

inc var1 ; count++

ww26: ;if(num == 1 && i == 14)


mov r0,#aid2
inc r0
movx a,@r0
cjne a,#low (1),ww27
dec r0
movx a,@r0
cjne a,#high (1),ww27

mov a,i+1
cjne a,#low (14),ww27
mov a,i
cjne a,#high (14),ww27
jmp ww29
ww27:
jmp ww30
ww29:
mov row,#1 ;bit14 = 1
jmp ww31
ww30: ;else if(num == 1 && i == 15)
mov r0,#aid2
inc r0
movx a,@r0
cjne a,#low (1),ww32
dec r0
movx a,@r0
cjne a,#high (1),ww32

mov a,i+1
cjne a,#low (15),ww32
mov a,i
cjne a,#high (15),ww32
jmp ww33
ww32:

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (188 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jmp ww34
ww33:
mov column,#1 ; bit15 = 1
ww34:
ww31:
inc i+1
mov a,i+1
jnz ww19
inc i
ww19:
mov a,i+1
add a,#low -(16)
mov a,i
xrl a,#80h
addc a,#(high -(16))xor 80h
jnc ww44
jmp ww35
ww44:
jmp ww20

;if((bit14 == 1 && bit15 == 1) || (bit14 == 1 && bit15 == 0))


ww35:
mov a,row
cjne a,#1,ww36
mov a,column
cjne a,#1,ww36
jmp ww37
ww36:
mov a,row
cjne a,#1,ww38
mov a,column
cjne a,#0,ww38
jmp ww37
ww38:
jmp ww41
ww37:
jmp ww40
ww40:
mov r2,#high (4)
mov r3,#low (4)
mov r4,#high (7)
mov r5,#low (7)
lcall lcd_xy ;lcd_xy(7,4)

lcall lcd_print ;lcd_print()


db "Antenna causes a short!!!",0

jmp ww42
ww41: ;else if(bit14 == 0 && bit15 == 1)
mov a,row
cjne a,#0,ww42
mov a,column
cjne a,#1,ww42

mov r2,#high (4)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (189 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r3,#low (4)


mov r4,#high (7)
mov r5,#low (7)
lcall lcd_xy ;lcd_xy(7,4)

lcall lcd_print ;lcd_print()


db "Antenna not connected!!!",0

ww42: ;if(count == 16)


mov a,var1
cjne a,#16,ww43

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (7)
mov r5,#low (7)
lcall lcd_xy ;lcd_xy(7,3)

lcall lcd_print ;lcd_print()


db "Selftest Passed!!!",0

ww43: ;End()
lcall EndDisps
ret

;////////////////////////////////////////////////
Disp_Ea:
mov key,#0
mov var3,#0

mov f,#1
lcall Init_Text

mov r4,#1
lcall Disp_Ac ;date

mov r4,#1
lcall Disp_Aa ;time

mov r0,#4
ll1:
lcall Buffer
djnz r0,ll1

mov r4,#1
lcall Disp_Ad ;lattitude
mov r4,#1
lcall Disp_Ae ;longitude
mov r4,#1
lcall Disp_Af ;height

mov r0,#4
ll2:
lcall Buffer

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (190 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

djnz r0,ll2

mov num,#1 ;get velocity


lcall Bytes ;r4 contains high byte
;r5 contains low byte

mov lb,r4
mov lb+1,r5

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (7)
mov r5,#low (7)
lcall lcd_xy

lcall lcd_print
db "Velocity (m/s): ",0

mov X3,#0 ;divide by 100


mov X2,#0
mov X1,lb
mov X0,lb+1
mov Y0,#64h
mov Y1,#00h
mov Y2,#00h
mov Y3,#00h
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov r1,#0 ;print velocity


mov r2,Z7
mov r3,Z6
mov r4,Z5
mov r5,Z4
lcall lcd_print_num ;lcd_print_num()

mov num,#1 ;get heading


lcall Bytes ;r4 contains high byte
;r5 contains low byte

mov lb,r4
mov lb+1,r5

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (7)
mov r5,#low (7)
lcall lcd_xy

lcall lcd_print
db "Current Heading: ",0

mov X3,#0 ;divide by 100


mov X2,#0
mov X1,lb

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (191 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov X0,lb+1
mov Y0,#64h
mov Y1,#00h
mov Y2,#00h
mov Y3,#00h
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov r1,#0 ;print heading


mov r2,Z7
mov r3,Z6
mov r4,Z5
mov r5,Z4
lcall lcd_print_num ;lcd_print_num()

mov r7,#80h
lcall dput

mov r7,#192
lcall cput

mov num,#1 ;get geometry


lcall Bytes ;r4 contains high byte
;r5 contains low byte

mov lb,r4
mov lb+1,r5

mov a,r5
orl a,r4
jnz ll3

mov r2,#high (5)


mov r3,#low (5)
mov r4,#high (6)
mov r5,#low (6)
lcall lcd_xy

lcall lcd_print
db "Current DOP not computable.",0
jmp hello
ll3:
mov r2,#high (5)
mov r3,#low (5)
mov r4,#high (7)
mov r5,#low (7)
lcall lcd_xy

lcall lcd_print
db "Current DOP: ",0

mov X3,#0 ;divide by 10


mov X2,#0
mov X1,lb
mov X0,lb+1

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (192 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov Y0,#0ah
mov Y1,#00h
mov Y2,#00h
mov Y3,#00h
lcall DIV32 ;Z4-Qlow - Z7-Qhigh / Z0-rem(low)

mov r1,#0 ;print dop


mov r2,Z7
mov r3,Z6
mov r4,Z5
mov r5,Z4
lcall lcd_print_num ;lcd_print_num()
hello:
mov r2,#high (6)
mov r3,#low (6)
mov r4,#high (4)
mov r5,#low (4)
lcall lcd_xy

lcall Buffer
mov a,r3

cjne a,#0,ll4
lcall lcd_print
db "DOP Type: PDOP(3D)/Antenna OK.",0
jmp ll11
ll4:
cjne a,#1,ll5
lcall lcd_print
db "DOP Type: HDOP(2D)/Antenna OK.",0
jmp ll11
ll5:
cjne a,#64,ll6
lcall lcd_print
db "DOP Type: PDOP(3D)/Antenna shorted.",0
jmp ll11
ll6:
cjne a,#65,ll7
lcall lcd_print
db "DOP Type: HDOP(2D)/Antenna shorted.",0
jmp ll11
ll7:
cjne a,#128,ll8
lcall lcd_print
db "DOP Type: PDOP(3D)/Antenna open.",0
jmp ll11
ll8:
cjne a,#129,ll9
lcall lcd_print
db "DOP Type: HDOP(2D)/Antenna open.",0
jmp ll11
ll9:
cjne a,#192,ll10
lcall lcd_print
db "DOP Type: PDOP(3D)/Antenna shorted.",0

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (193 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

jmp ll11
ll10:
cjne a,#193,ll11
lcall lcd_print
db "DOP Type: HDOP(2D)/Antenna shorted.",0
ll11:
mov a,flag ;if flag == 1
cjne a,#1,ll12
jmp ll13

ll12:
jmp ll14
ll13:
mov r2,#high (7)
mov r3,#low (7)
mov r4,#high (35)
mov r5,#low (35)
lcall lcd_xy

lcall lcd_print
db ".....",0

ll15: ;wait for key to be pressed


mov a,key
jz ll15
mov key,#0

mov f,#1
lcall Init_Text

mov r2,#high (2)


mov r3,#low (2)
mov r4,#high (5)
mov r5,#low (5)
lcall lcd_xy

lcall lcd_print
db "Num of visible satellites: ",0

lcall Buffer
mov a,r3

mov r1,#0 ;print satellites


mov r2,#0
mov r3,#0
mov r4,#0
mov r5,a
lcall lcd_print_num ;lcd_print_num()

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (5)
mov r5,#low (5)
lcall lcd_xy

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (194 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

lcall lcd_print
db "Num of satellites tracked: ",0

lcall Buffer
mov a,r3

mov r1,#0 ;print satellites


mov r2,#0
mov r3,#0
mov r4,#0
mov r5,a
lcall lcd_print_num ;lcd_print_num()

mov r2,#high (7)


mov r3,#low (7)
mov r4,#high (35)
mov r5,#low (35)
lcall lcd_xy

lcall lcd_print
db ".....",0

ll16: ;wait for key to be pressed


mov a,key
jz ll16
mov key,#0

mov var1,#0
jmp ll17
ll18:
mov f,#1
lcall Init_Text

mov r2,#high (0)


mov r3,#low (0)
mov r4,#high (3)
mov r5,#low (3)
lcall lcd_xy

lcall lcd_print
db "Channel ",0

mov a,var1
add a,#1

mov r1,#0 ;print channel no.


mov r2,#0
mov r3,#0
mov r4,#0
mov r5,a
lcall lcd_print_num ;lcd_print_num()

lcall lcd_print

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (195 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

db " / Satellite ID: ",0

lcall Buffer
mov a,r3

mov r1,#0 ;print satellite ID


mov r2,#0
mov r3,#0
mov r4,#0
mov r5,a
lcall lcd_print_num ;lcd_print_num()

mov r2,#high (1)


mov r3,#low (1)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Channel Tracking Mode: ",0

mov r2,#high (2)


mov r3,#low (2)
mov r4,#high (3)
mov r5,#low (3)
lcall lcd_xy

lcall Buffer

mov a,r3
add a,r3
mov r3,a
mov a,#0
addc a,#0
mov r2,a
mov a,r3
add a,#low(channel)
mov dpl,a
mov a,r2
addc a,#high(channel)
mov dph,a
lcall lcd_print1 ;lcd_print(channel[byte])

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Carrier to Noise Density Ratio: ",0

lcall Buffer
mov a,r3

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (196 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r1,#0 ;print carrier to noise density ratio


mov r2,#0
mov r3,#0
mov r4,#0
mov r5,a
lcall lcd_print_num ;lcd_print_num()

lcall lcd_print
db "dB-Hz",0

mov r2,#high (4)


mov r3,#low (4)
mov r4,#high (0)
mov r5,#low (0)
lcall lcd_xy

lcall lcd_print
db "Channel Status Flag: ",0

lcall Buffer
mov lb,r3

mov var2,#0
jmp ll19
ll20:
mov r5,var2 ;num = (byte >> i) & 0x01
mov r0,#0
mov r1,lb
cjne r5,#0,ll21
jmp ll22
ll21:
mov a,r0
clr c
rrc a
mov r0,a
mov a,r1
rrc a
mov r1,a
djnz r5,ll21
ll22:
mov a,r1
anl a,#01h

cjne a,#1,ll23
jmp ll24
ll23:
jmp ll25
ll24:
mov a,var2
cjne a,#1,ll26
jmp ll25
ll26:
cjne a,#2,ll27
jmp ll25

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (197 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

ll27:
mov a,#5
add a,var3

mov r2,#0
mov r3,a
mov r4,#high (1)
mov r5,#low (1)
lcall lcd_xy ;lcd_xy(7,3)

mov a,var2
add a,var2
mov r3,a
mov a,#0
addc a,#0
mov r2,a
mov a,r3
add a,#low(ch_status)
mov dpl,a
mov a,r2
addc a,#high(ch_status)
mov dph,a
lcall lcd_print1 ;lcd_print(ch_status[var2])

inc var3
ll25:
inc var2
ll19:
mov a,var2
cjne a,#8,ll20

mov a,var3
cjne a,#0,ll28
lcall lcd_print
db "0",0
ll28:
mov var3,#0

ll29: ;wait for key to be pressed


mov a,key
jz ll29
mov key,#0
inc var1
ll17:
mov a,var1
cjne a,#8,ll44
jmp ll45
ll44:
jmp ll18
ll45:
mov f,#1
lcall Init_Text

mov r2,#high (2)


mov r3,#low (2)

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (198 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov r4,#high (5)


mov r5,#low (5)
lcall lcd_xy

lcall lcd_print
db "Receiver status flag: ",0

lcall Buffer
mov lb,r3

mov var2,#0
jmp ll30
ll31:
mov r5,var2 ;num = (byte >> i) & 0x01
mov r0,#0
mov r1,lb
cjne r5,#0,ll32
jmp ll33
ll32:
mov a,r0
clr c
rrc a
mov r0,a
mov a,r1
rrc a
mov r1,a
djnz r5,ll32
ll33:
mov a,r1
anl a,#01h

cjne a,#1,ll34 ;if(num == 1) && var2!=2


mov a,var2
cjne a,#2,ll36
ll34:
jmp ll35
ll36:
mov a,#3
add a,var3

mov r2,#0
mov r3,a
mov r4,#high (6)
mov r5,#low (6)
lcall lcd_xy ;lcd_xy(7,3)

mov a,var2
add a,var2
mov r3,a
mov a,#0
addc a,#0
mov r2,a
mov a,r3
add a,#low(re_status)
mov dpl,a

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (199 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

mov a,r2
addc a,#high(re_status)
mov dph,a
lcall lcd_print1 ;lcd_print(re_status[var2])

inc var3
ll35:
inc var2
ll30:
mov a,var2
cjne a,#8,ll31

mov flag,#1 ;return value//flag


jmp ll41
ll14: ;end of flag == 1
mov r0,#35
ll40:
inc bufferout ;bufferout = bufferout + 1
mov a,bufferout ;if(bufferout == 230)
cjne a,#230,wieder
clr a ;bufferout = 0
mov bufferout,a
wieder:
djnz r0,ll40
mov flag,#0

ll41:
lcall EndDisps
ret

;////////////////////////////////////////////////////
Disp_Same:
mov univ,r4

mov f,#1
lcall Init_Text

mov r2,#high (3)


mov r3,#low (3)
mov r4,#high (7)
mov r5,#low (7)
lcall lcd_xy

mov a,univ
cjne a,#0,ww17
lcall lcd_print
db "GPS Receiver Reset!!!",0
jmp ww18
ww17:
cjne a,#1,ww18
lcall lcd_print
db "System Power_On Failure!!!",0
ww18:
lcall EndDisps
ret

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (200 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

;//////////////////////////////////////////////
messages:
dw 0+kk1
dw 0+kk2
dw 0+kk3
dw 0+kk4
dw 0+kk5
dw 0+kk6
dw 0+kk7
dw 0+kk8
dw 0+kk9
dw 0+kk10
dw 0+kk11
dw 0+kk12
dw 0+kk13
dw 0+kk14
dw 0+kk15
dw 0+kk16

kk16:
db "Antenna Undercurrent:",0
kk15:
db "Antenna Overcurrent:",0
kk14:
db "RTC Comm & Time Fail",0
kk13:
db "Temperature Sensor Fail",0
kk12:
db "Ignore",0
kk11:
db "RAM Fail",0
kk10:
db "ROM Fail",0
kk9:
db "1 kHz Presence",0
kk8:
db "Channel 8 Correlation Test Fail!!!",0
kk7:
db "Channel 7 Correlation Test Fail!!!",0
kk6:
db "Channel 6 Correlation Test Fail!!!",0
kk5:
db "Channel 5 Correlation Test Fail!!!",0
kk4:
db "Channel 4 Correlation Test Fail!!!",0
kk3:
db "Channel 3 Correlation Test Fail!!!",0
kk2:
db "Channel 2 Correlation Test Fail!!!",0
kk1:
db "Channel 1 Correlation Test Fail!!!",0

;/////////////////////////////////////////////////

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (201 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

channel:
dw 0+tt1
dw 0+tt2
dw 0+tt3
dw 0+tt4
dw 0+tt5
dw 0+tt6
dw 0+tt7
dw 0+tt8
dw 0+tt9

tt9:
db " - available for position.",0
tt8:
db " - ephemeris acquire.",0
tt7:
db " - satellite time available.",0
tt6:
db " - message sync detect.",0
tt5:
db " - bit sync detect.",0
tt4:
db " - preg acquire.",0
tt3:
db " - AGC set.",0
tt2:
db " - code acquire.",0
tt1:
db " - code search.",0

;///////////////////////////////////////////////////
ch_status:
dw 0+tt10
dw 0+tt11
dw 0+tt12
dw 0+tt13
dw 0+tt14
dw 0+tt15
dw 0+tt16
dw 0+tt17

tt17:
db " - using for position fix.",0
tt16:
db " - satellite momentum alert flag.",0
tt15:
db " - satellite anti-spoof flag set.",0
tt14:
db " - satellite reported unhealthy.",0
tt13:
db " - satellite reported inaccurate(>16m).",0
tt12:
db "",0
tt11:
db "",0

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (202 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

tt10:
db " - parity error.",0

;//////////////////////////////////////////////////
re_status:
dw 0+tt18
dw 0+tt19
dw 0+tt20
dw 0+tt21
dw 0+tt22
dw 0+tt23
dw 0+tt24
dw 0+tt25

tt25:
db " - position propagate mode.",0
tt24:
db " - poor geometry (DOP > 12).",0
tt23:
db " - 3d fix.",0
tt22:
db " - 2d fix.",0
tt21:
db " - acquring satellites.",0
tt20:
db "",0
tt19:
db " - insufficient visible satellites(< 3).",0
tt18:
db " - bad almanac.",0

;/////////////////////////////////////////////////
;Picture for GPS startup (compressed)
Gps_pic_less:
dw 1054, 01fh, 080h, 007h, 080h, 1025, 001h, 0ffh
dw 0f8h, 003h, 0c0h, 1006, 00fh, 0f8h, 1006
dw 00fh, 0f8h, 1009, 07eh, 000h, 007h, 0e3h, 07ch
dw 1006, 07fh, 0ffh, 000h, 003h, 0ffh, 0ffh
dw 1002, 07fh, 0ffh, 1008, 00fh, 0c0h, 000h, 001h
dw 0feh, 01fh, 080h, 1004, 001h, 0ffh, 0ffh
dw 0c0h, 003h, 0ffh, 0ffh, 0e0h, 001h, 0ffh, 0ffh
dw 080h, 1007, 018h, 1003, 003h, 081h, 0c0h
dw 1004, 003h, 0ffh, 0ffh, 0e0h, 003h, 0ffh, 0ffh
dw 0f0h, 003h, 0ffh, 0ffh, 0c0h, 1007, 030h
dw 000h, 00fh, 000h, 001h, 0c1h, 0c0h, 1004, 007h
dw 0f8h, 007h, 0f0h, 003h, 0ffh, 0ffh, 0f8h
dw 003h, 0f0h, 00fh, 0e0h, 1006, 001h, 0e3h, 0e0h
dw 03fh, 0feh, 000h, 078h, 0f0h, 1004, 00fh
dw 0c0h, 001h, 0f8h, 003h, 0c0h, 000h, 0fch, 007h
dw 0c0h, 003h, 0f0h, 1006, 003h, 007h, 0e0h
dw 07fh, 0feh, 000h, 00ch, 038h, 1004, 01fh, 1002
dw 0f8h, 003h, 0c0h, 000h, 07ch, 00fh, 080h
dw 000h, 0f0h, 1006, 006h, 01fh, 0c0h, 0ffh, 0feh
dw 003h, 086h, 01ch, 1004, 01eh, 1002, 07ch
dw 003h, 0c0h, 000h, 03eh, 00fh, 1002, 0f8h, 1006

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (203 of 206) [30/05/2004 08:31:23 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

dw 00ch, 01eh, 018h, 001h, 0feh, 003h, 083h


dw 00eh, 1004, 03eh, 1002, 03ch, 003h, 0c0h, 000h
dw 01eh, 00fh, 1002, 078h, 1006, 018h, 003h
dw 0ffh, 0ffh, 0ffh, 0ffh, 0c1h, 087h, 1004, 03ch
dw 1002, 03ch, 003h, 0c0h, 000h, 01eh, 00fh
dw 1002, 078h, 1006, 030h, 003h, 0ffh, 0ffh, 0ffh
dw 0ffh, 0c1h, 0c3h, 080h, 1003, 078h, 1002
dw 018h, 003h, 0c0h, 000h, 01eh, 00fh, 1009, 060h
dw 03fh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0f1h
dw 080h, 1003, 078h, 1003, 003h, 0c0h, 000h, 01eh
dw 00fh, 080h, 1008, 0c0h, 07ch, 06fh, 0ffh
dw 0ffh, 0ffh, 0ffh, 0f0h, 0c0h, 1003, 078h, 1003
dw 003h, 0c0h, 000h, 01eh, 007h, 0c0h, 1007
dw 001h, 0c0h, 0fch, 0e7h, 0ffh, 0ffh, 0ffh, 0ffh
dw 0f8h, 0c0h, 1003, 0f0h, 1003, 003h, 0c0h
dw 000h, 01eh, 007h, 0f8h, 1007, 001h, 080h, 079h
dw 0c3h, 0ffh, 0ffh, 0ffh, 0ffh, 0f8h, 0e0h
dw 1003, 0f0h, 1003, 003h, 0c0h, 000h, 03ch, 003h
dw 0ffh, 080h, 1006, 003h, 000h, 031h, 0c3h
dw 0ffh, 0ffh, 0ffh, 0ffh, 0fch, 060h, 1003, 0f0h
dw 1003, 003h, 0c0h, 000h, 07ch, 001h, 0ffh
dw 0f8h, 1006, 002h, 000h, 01ch, 007h, 0ffh, 0ffh
dw 0ffh, 0ffh, 0fch, 070h, 1003, 0f0h, 1003
dw 003h, 0c0h, 001h, 0f8h, 000h, 0ffh, 0ffh, 1006
dw 002h, 000h, 03fh, 08fh, 0ffh, 0ffh, 0ffh
dw 0ffh, 0fch, 030h, 1003, 0f0h, 000h, 07fh, 0feh
dw 003h, 0ffh, 0ffh, 0f8h, 000h, 01fh, 0ffh
dw 0c0h, 1005, 002h, 000h, 07fh, 0ffh, 0ffh, 0ffh
dw 0ffh, 0ffh, 0fah, 038h, 1003, 0f0h, 000h
dw 07fh, 0feh, 003h, 0ffh, 0ffh, 0f0h, 000h, 003h
dw 0ffh, 0e0h, 1007, 0ffh, 0ffh, 0ffh, 0ffh
dw 0ffh, 0ffh, 0f2h, 038h, 1003, 0f0h, 000h, 07fh
dw 0feh, 003h, 0ffh, 0ffh, 0c0h, 1002, 03fh
dw 0f0h, 1006, 001h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
dw 0ffh, 0f3h, 038h, 1003, 0f0h, 000h, 07fh
dw 0feh, 003h, 0ffh, 0ffh, 1003, 003h, 0f8h, 1006
dw 001h, 0ffh, 0ffh, 0cfh, 0ffh, 0ffh, 0ffh
dw 0c3h, 018h, 1003, 0f0h, 1002, 01eh, 003h, 0c0h
dw 1005, 0f8h, 1007, 0ffh, 0ffh, 0e0h, 01fh
dw 0ffh, 0ffh, 0c1h, 018h, 1003, 078h, 1002, 01eh
dw 003h, 0c0h, 1005, 07ch, 1007, 0ffh, 0ffh
dw 0e0h, 00fh, 0ffh, 0ffh, 0c1h, 018h, 1003, 078h
dw 1002, 01eh, 003h, 0c0h, 1002, 01eh, 1002
dw 03ch, 1007, 07fh, 0ffh, 0e0h, 00fh, 0ffh, 0ffh
dw 0d9h, 018h, 1003, 078h, 1002, 01eh, 003h
dw 0c0h, 1002, 01eh, 1002, 03ch, 1007, 01fh, 0ffh
dw 0c0h, 000h, 00fh, 093h, 018h, 1003
dw 03ch, 1002, 01eh, 003h, 0c0h, 1002, 01fh, 1002
dw 03ch, 1007, 00fh, 0ffh, 1002, 01fh, 0ffh
dw 003h, 018h, 1003, 03eh, 1002, 01eh, 003h, 0c0h
dw 1002, 00fh, 1002, 03ch, 1007, 00fh, 0f8h
dw 1002, 007h, 0fch, 082h, 018h, 1003, 01eh, 1002
dw 01eh, 003h, 0c0h, 1002, 00fh, 080h, 000h
dw 07ch, 1007, 00fh, 0f8h, 1002, 007h, 0f1h, 082h
dw 030h, 1003, 01fh, 080h, 000h, 07eh, 003h
dw 0c0h, 1002, 00fh, 0c0h, 000h, 078h, 1005, 002h

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (204 of 206) [30/05/2004 08:31:24 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

dw 000h, 00fh, 0f0h, 1002, 080h, 00fh, 006h


dw 030h, 1003, 00fh, 0c0h, 000h, 0feh, 003h, 0c0h
dw 1002, 007h, 0e0h, 001h, 0f8h, 1005, 003h
dw 000h, 00fh, 0f0h, 000h, 001h, 081h, 08fh, 004h
dw 060h, 1003, 007h, 0f8h, 007h, 0fch, 003h
dw 0c0h, 1002, 003h, 0f8h, 007h, 0f0h, 1005, 001h
dw 000h, 00fh, 0f0h, 000h, 001h, 083h, 0c0h
dw 00ch, 060h, 1003, 003h, 0ffh, 0ffh, 0f0h, 003h
dw 0c0h, 1002, 001h, 0ffh, 0ffh, 0e0h, 1005
dw 001h, 080h, 00fh, 0e0h, 000h, 001h, 083h, 0e0h
dw 018h, 0e0h, 1004, 0ffh, 0ffh, 0e0h, 003h
dw 0c0h, 1003, 0ffh, 0ffh, 0c0h, 1006, 0c0h, 007h
dw 080h, 1004, 010h, 0c0h, 1004, 07fh, 0ffh
dw 080h, 003h, 0c0h, 1003, 03fh, 0ffh, 1007, 0c0h
dw 007h, 1003, 060h, 000h, 070h, 0c0h, 1004
dw 007h, 0fch, 1006, 007h, 0fch, 1007, 040h, 1006
dw 061h, 080h, 1021, 060h, 1006, 0c1h, 080h
dw 1021, 03fh, 1003, 001h, 030h, 001h, 0c3h, 080h
dw 1021, 01fh, 0f8h, 1002, 001h, 010h, 003h
dw 01fh, 1022, 007h, 0fch, 1004, 006h, 03ch, 1022
dw 003h, 0ffh, 0e0h, 1003, 03ch, 078h, 1023
dw 07fh, 0f0h, 1003, 060h, 0e0h, 1004, 03eh, 1005
dw 01fh, 0c0h, 1002, 008h, 1008, 03fh, 0f0h
dw 1003, 0c1h, 0c0h, 1004, 041h, 1005, 010h, 020h
dw 1011, 01fh, 0f0h, 1002, 003h, 083h, 080h
dw 1004, 080h, 097h, 00eh, 01eh, 02ch, 0f0h, 010h
dw 023h, 0c3h, 087h, 08ah, 009h, 0e2h, 0c0h
dw 1005, 003h, 0f8h, 1002, 01ch, 00fh, 1005, 080h
dw 098h, 091h, 021h, 031h, 008h, 010h, 024h
dw 024h, 048h, 04ah, 00ah, 013h, 1005, 003h, 0c0h
dw 0ffh, 080h, 007h, 0f0h, 07ch, 1005, 080h
dw 090h, 090h, 021h, 021h, 008h, 010h, 024h, 024h
dw 008h, 049h, 012h, 012h, 1006, 070h, 00fh
dw 0ffh, 0ffh, 001h, 0f0h, 1005, 080h, 090h, 090h
dw 021h, 021h, 0f8h, 01fh, 0c7h, 0e4h, 00fh
dw 0c9h, 013h, 0f2h, 1006, 03fh, 0c0h, 01fh, 080h
dw 07fh, 0e0h, 1005, 080h, 090h, 090h, 021h
dw 021h, 000h, 011h, 004h, 004h, 008h, 008h, 0a2h
dw 002h, 1006, 001h, 0fch, 000h, 007h, 0f8h
dw 1006, 080h, 090h, 090h, 021h, 021h, 000h, 010h
dw 084h, 004h, 008h, 008h, 0a2h, 002h, 1007
dw 03fh, 0ffh, 0ffh, 0f0h, 1006, 041h, 010h, 091h
dw 021h, 021h, 008h, 010h, 044h, 024h, 048h
dw 048h, 042h, 012h, 1008, 00fh, 1008, 03eh, 010h
dw 08eh, 01eh, 020h, 0f0h, 010h, 023h, 0c3h
dw 087h, 088h, 041h, 0e2h, 1008, 01fh, 0c0h, 1028
dw 01fh, 0c0h, 1028, 01fh, 0c0h, 1028, 01fh
dw 0c0h, 1028, 00fh, 1029, 07fh, 0f0h, 1027, 001h
dw 0ffh, 0fch, 1027, 003h, 0ffh, 0fch, 1027
dw 01fh, 0ffh, 0ffh, 080h, 1026, 03fh, 0ffh, 0ffh
dw 0e0h, 1025, 001h, 0ffh, 0ffh, 0ffh, 0fch
dw 000h, 000h, 000h

;///////////////////////////////////////////////////
Final:
jmp Final

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (205 of 206) [30/05/2004 08:31:24 a.m.]


Interfacing a GPS to an LCD using a Microcontroller

end

Appendix G
Included Disc

This disc contains 3 directories:

gpscomp:
This directory contains C++ files to interface the GPS via the serial port to the PC. All information is displayed on the PC.
gpslcd:
This directory contains C++ files to interface the GPS via the serial port to the PC and the LCD via the parallel port to the PC.
asem:
This directory contains the assembly program file and a cross-assembler.

File translated from TEX by TTH, version 2.00.


On 31 May 1999, 11:49.

http://www.dip.ee.uct.ac.za/~ahenric/oncorhtm.html (206 of 206) [30/05/2004 08:31:24 a.m.]

You might also like