Link here

Chapter 12 - The User Interface: LCD Display, Keypad, and Serial Ports


The QED Board is designed to communicate with users via LCD display, keypad, and dual serial communications links. The "Getting Started with the QED Board" booklet provides an excellent introduction to these interfaces. This chapter builds on the information presented there and describes the useful display, keypad and serial device drivers that are built into QED-Forth.

 

Connecting the Display and Keypad

Mosaic Industries provides a ribbon cable that connects a 4 by 5 keypad and 4 by 20 LCD display to the QED Board. The onboard keypad/display interface connector is the 34 pin dual-row header next to the QED-Forth Kernel PROM socket. A 34 pin female ribbon connector plugs into this header. Two female single row connectors terminate the ribbon cable: one for the display, and one for the keypad.

The display connector is a 17 pin single-row female connector. The lower 14 pins connect directly to the display, and the upper three pins are the potentiometer connections (Vcc, Vcontrast, and GND). These three connections allow the addition of an optional potentiometer to facilitate contrast control of the potentiometer from a front panel or other accessible location. The default contrast adjustment potentiometer is on the QED Board next to the QED-Forth Kernel PROM. In the "standard orientation", the display connector is at the top of the display, and the display has 4 lines and 20 characters per line.

The keypad connector is a 10 pin single-row female connector (the tenth pin is extra). Pin 1 of this single-row header should be connected to the pin marked "F" on the 4 by 5 key keypad. In the "standard orientation" of the keypad, the keypad connector is at the "bottom" of the keypad. The keypad has 4 rows and 5 columns in the standard orientation. In the QED Product Design Kit the front panel keypad is in the standard orientation.

 

Connecting the Serial Cable

The onboard serial interface connector is the 10 pin dual-row header next to the 6-position DIP switch on the QED Board. Mosaic Industries provides a serial cable that plugs into this header and brings out the dual serial ports to two female 25-pin D connectors with a standard IBM PC compatible pinout.

 

LCD Display Driver Routines

The QED Board includes a built-in interface for a liquid crystal display (LCD) up to 4 lines by 20 characters in size. A ribbon cable connects the board to the display. The display's contrast can be adjusted by changing the setting of an onboard potentiometer next to the QED-Forth Kernel PROM.

The software necessary to control the display is included in the QED-Forth kernel ROM. The display is automatically initialized and blanked upon each reset or restart, so it is ready to use at startup. The driver software is conceptually simple: a 4 line by 20 character buffer is maintained in RAM, and the UPDATE.DISPLAY function transfers the contents of this buffer to the LCD display. Thus the programmer controls the display by writing ascii characters or strings to the buffer in RAM and executing UPDATE.DISPLAY to make the contents visible on the LCD display.

QED-Forth maintains an 80 character buffer whose base xaddress is returned by the word

DISPLAY.BUFFER ( -- xaddr )

The offset from the start of this buffer to a specified line and character position is returned by the routine

BUFFER.POSITION ( line#\char# -- buffer.offset )

The user can write ascii characters into this buffer using standard operators such as C! or CMOVE, or with the assistance of the handy utility routine

$>DISPLAY ( x$addr\line#\char# -- )

which is pronounced "string-to-display" (in Forth, $ is often used to represent a string). $>DISPLAY moves the string starting at x$addr to the buffer starting at the specified line number (0, 1, 2, or 3) and character position (0 through 19) in the display buffer. This routine moves only as many characters as will fit on the specified line. Executing $>DISPLAY modifies the contents of the buffer but does not alter the display.

Placing the appropriate line number (0, 1, 2, or 3) on the stack and executing

UPDATE.DISPLAY.LINE ( line# -- )

transfers the specified line's contents from the buffer to the display.

Executing

UPDATE.DISPLAY ( -- )

transfers all of the lines in the display buffer to the display.

Let's try an example. Type in the following definition:

: SHOW.MESSAGE    ( -- )
    CLEAR.DISPLAY
    " My favorite color is"      0 0 $>DISPLAY
    " purple."          1 0 $>DISPLAY
    UPDATE.DISPLAY
;

SHOW.MESSAGE first executes CLEAR.DISPLAY which clears the display and fills the DISPLAY.BUFFER with ascii blanks. The next two lines in the definition specify the contents of the top two lines of the display. The characters between the quotation marks specify a string to be moved to the display buffer, and the two numbers immediately preceding $>DISPLAY are the line number (numbered 0 through 3) and the character position (numbered 0 through 19) to which the string is moved. If you execute

SHOW.MESSAGE

the message will appear on the display.

To modify only the line reporting the color "purple" without changing the rest of the display, we can execute

DISPLAY.BUFFER 1 0 BUFFER.POSITION XN+ 20 BLANK
" blue." 1 0 $>DISPLAY
1 UPDATE.DISPLAY.LINE

The first command blanks line#1 in the display, eliminating the prior contents. BUFFER.POSITION calculates the offset to the start of line 1, and XN+ adds this offset to the DISPLAY.BUFFER base address to yield the start address of line# 1 in the buffer. BLANK then blanks the 20 characters on the line in the buffer. The following command line moves the string "blue." to the display buffer, and UPDATE.DISPLAY.LINE writes the new contents of line 1 to the display. Note that the top line of the display is unchanged.

We could have avoided the need for the BLANK command by making the new "color" string as long or longer than the original string on line 1. For example, the following two commands have the same effect as three commands above:

" blue. " 1 0 $>DISPLAY
1 UPDATE.DISPLAY.LINE

The extra trailing spaces ensure that none of the prior string remains in the buffer.

To clear the display, fill the display buffer with blanks, and home the cursor to the upper left corner of the display, simply type

CLEAR.DISPLAY

and of course executing SHOW.MESSAGE again replaces the original message on the display.

The routine

INIT.DISPLAY ( -- )

initializes the peripheral interface adapter (PIA) to ensure that it is compatible with the keypad/display interface, and initializes the display so that it is ready to accept characters, homes the cursor to the upper left position, and blanks the screen, cursor, and display buffer. This routine is executed upon every processor reset or restart. INIT.DISPLAY also initializes the system variable LINES/DISPLAY to 4 and the system variable CHARS/DISPLAY.LINE to 20. The values of these variables may be modified by the programmer to accommodate different sized displays up to a maximum of 80 characters. For example, to interface a 2 line by 16 character display, execute

DECIMAL 2 LINES/DISPLAY ! 16 CHARS/DISPLAY.LINE !

Throughout the above examples you probably noticed that no cursor was visible on the display. This is because INIT.DISPLAY turns the cursor off. You have full control over the cursor, however. The routine

DISPLAY.OPTIONS ( display.on?\cursor.on?\cursor.blinking? -- )

sets the cursor and display state based on the three flags passed to it on the stack. The first flag, called display.on?, specifies whether the display is enabled or disabled. This feature can be used to flash the display by rapidly enabling and disabling the display via successive calls to DISPLAY.OPTIONS. The second flag, called cursor.on?, specifies whether the cursor is visible as an underbar at the current cursor position. The top flag on the stack, called cursor.blinking?, specifies whether the cursor is visible as a blinking box obscuring the current character position. The default condition is:

display enabled, cursor off, cursor not blinking

This condition applies after a reset, restart, or execution of INIT.DISPLAY. Try passing different flag combinations to DISPLAY.OPTIONS to see what the results are.

Several lower level utilities are available to the programmer. For example, the routine

PUT.CURSOR ( line#\character# -- )

places the cursor at the specified location on the display. Note that whether or not the cursor is visible depends on the configuration set by DISPLAY.OPTIONS. Once the cursor has been placed, each succeeding character written to the display appears at the cursor location and causes the cursor position to be incremented by 1. Please note, however, that in many displays the cursor does not advance smoothly as one might expect from the end of one line to the start of the following line! Please test your routines carefully when using these low level utilities to control the display.

To send a single character to the display at the current cursor position, execute

CHAR>DISPLAY ( char -- )

This automatically increments the cursor position (but note that the cursor may skip to the start of an unexpected line after the end of a line is reached). CHAR>DISPLAY does not update the contents of the DISPLAY.BUFFER.

To send a command character to the display, execute

COMMAND>DISPLAY ( byte -- )

Consult the display data sheet appendix in the QED Hardware Manual to determine the numerical value associated with each valid command. For example, the command byte that clears the display is 01.

The multitasking resource variable associated with the keypad/display interface is called KEYPAD/DISPLAY.RESOURCE. All QED-Forth words that access the display execute

KEYPAD/DISPLAY.RESOURCE GET

before the access and

KEYPAD/DISPLAY.RESOURCE RELEASE

after the access is complete. This ensures that all of the routines work properly in a multitasking environment. In addition, the driver routines have been carefully coded to avoid corruption of port PPB which is shared by the keypad, display, and 12-bit A/D interfaces. All read/modify/write operations to PPB are coded as uninterruptable sequences (by disabling interrupts for short periods of time) to ensure that they are robust in interrupt-driven and multitasking environments. Please consult Chapter 10 for additional information about multitasking.

 

Keypad Driver

The QED Board includes a built-in interface for a keypad with up to 20 keys arranged as a 4 by 5 matrix. A ribbon cable connects the board to the keypad, and two simple high level words scan the keypad to detect a keypress.

With the keypad in the standard orientation as described at the beginning of this chapter, the QED-Forth software assigns key#0 to the lower right key, and key#1 is directly above key#0. The key directly to the left of key#0 is key#4. In other words, key numbers increase as we progress upward and to the left. The highest key number is key#19 in the upper left corner of the keypad. Thus in the standard orientation the keys are numbered as follows:

19 15 11 7 3
18 14 10 6 2
17 13 9 5 1
16 12 8 4 0

The routine

?KEYPAD ( [key#\TRUE] or [FALSE] -- )

scans the keypad looking for a depressed key. If no key is being depressed, a false flag is returned. If a key is being depressed, the routine "de-bounces" the keypad by waiting until the key is released (calling PAUSE while waiting so that other tasks may run) and returns the key number under a true flag. De-bouncing prevents a single keystroke from being interpreted as multiple keystrokes.

The routine

?KEYPRESS ( [key#\TRUE] or [FALSE] -- )

is identical to ?KEYPAD except that it does not de-bounce the keypad. Rather than waiting for a key to be released, it returns immediately. The advantage is that the program or task is not stuck waiting for the key release. When using ?KEYPRESS, make sure that your program does not misinterpret a single keystroke as multiple entries from the keypad.

The routine

KEYPAD ( -- key# )

scans the keypad and waits for a key to be depressed. While waiting, it calls PAUSE to give other tasks a chance to run. Once a keypress is detected, the routine "de-bounces" the keypad by waiting until the key is released (again calling PAUSE while waiting) and then returns the key number on the data stack.

All of these routines GET and RELEASE the resource variable called KEYPAD/DISPLAY.RESOURCE to ensure proper operation in multitasking environments.

The key numbers returned by ?KEYPAD and KEYPAD may be easily passed to QED-Forth words that perform some required action. For example, the following simple routine writes the key number to the LCD display:

: TEST.KEYPAD    ( -- )
    INIT.DISPLAY    \ initialize PIA and display
    BEGIN
        PAUSE.ON.KEY    \ type a CR to bail out of loop
        " You pressed key#:" 0 0 $>DISPLAY    \ write to buffer
        KEYPAD    ( -- key# )
        S>D <# # # #> DROP 1XN-    ( -- x$addr ) \ convert key# to string
        1 0 $>DISPLAY    ( -- ) \ write key# to buffer
        UPDATE.DISPLAY    \ write to display
    AGAIN
    ;

After executing TEST.KEYPAD, the identifier of each key that you press is displayed as a 2-digit number on the LCD display. Type a carriage return at the terminal and press one final key on the keypad to exit the routine.

 

Serial I/O Drivers

The QED Board has two serial communications ports: the primary serial port called serial1 and the secondary serial port called serial2. During program development, the primary serial port is used to communicate with the QED Board. To learn how to set up a terminal for reliable communications with the QED Board, consult the section titled "Terminal Configurations for Smooth Downloads" in Chapter 3 of this manual, or Appendix A in the "Getting Started with the QED Board" booklet.

The serial1 port is implemented with the 68HC11's on-chip hardware UART. Serial2 is implemented by a software UART in the QED-Forth kernel that controls two PortA pins. Pin 3 of PortA is the serial2 input, and pin 4 of PortA is the serial2 output.

A UART is a "Universal Asynchronous Receiver/Transmitter"; it controls the serial-to-parallel and parallel-to-serial conversion and performs all of the timing functions necessary for asynchronous serial communications. The communications is "asynchronous" because no synchronizing clock is transmitted along with the data. Rather, the UART must deduce the correct time to sample the incoming signal based on the characters (such as start bits and stop bits) in the signal itself. The QED Board also supports fast synchronous serial communications via the SPI (serial peripheral interface) as described in the QED Hardware Manual.

The serial1 port can be configured for either RS232 or RS485 communications. The serial2 port is configured for RS232 communications. RS232 is a full duplex protocol, meaning that both parties can be transmitting and receiving at the same time. The specified signal levels of approximately +/- 9 Volts are derived from the QED Board's +5 Volt supply by a dual RS232 driver chip that has a built-in charge pump.

RS485 is a half duplex protocol, meaning that data can flow in only one direction at a time. At any given time, a communicator can be transmitting or receiving but not both. The RS485 protocol uses differential data signals for improved noise immunity which allows communications at greater distance than RS232. RS485 can be implemented as a multi-drop protocol with many computers communicating on a single set of wires. An RS485 transceiver is present on the QED Board, and its data direction is controlled by pin 4 of port PPC of the peripheral interface adapter (PIA).

When shipped from the factory, the QED Board is configured to communicate via RS232 on the serial1 port. Before attempting to use a different serial configuration, make sure that the onboard hardware is properly set up:

A 3-post jumper on the QED Board between the RAM/ROM socket and the 40 pin address/data bus connector selects either RS232 or RS485 for the serial1 port. To select RS232 (the default), the jumper should connect the center post to the post nearest to the crystal oscillator. To select RS485, the jumper should connect the center post to the post nearest to the power connector.

Onboard DIP switch #4 must be in the ON position to communicate using the serial2 port. If switch #4 is in the OFF position, port pin PA3 is disconnected from the RS232 receiver chip and can thus be used as a general purpose digital input or output.

QED-Forth provides routines to initialize the serial ports, transmit and receive characters, set baud rates and specify which serial port is used by QED-Forth upon startup or restart. These are described in detail below.

 

Transmitting and Receiving Characters

The generic Forth interface to a serial port is very simple. It consists of only three routines called ?KEY, KEY, and EMIT. ?KEY looks at the serial port and returns a true flag if a character has been received. KEY waits until the next character is received by the serial port and leaves the ascii value of the character on the data stack. EMIT takes an ascii character from the stack and transmits it via the serial port. Higher level routines that input and output strings are written in terms of the three fundamental serial routines.

In QED-Forth, the actions of ?KEY, KEY and EMIT are "revectorable". This means that the actions of the routines can be modified by storing the extended code field addresses (xcfa's) of the desired actions in the user variables named U?KEY, UKEY, and UEMIT, respectively. This provides a ready means of changing the serial port that is used by the QED-Forth interpreter and compiler.

The kernel includes pre-coded routines that implement the ?KEY, KEY, and EMIT functions for the primary and secondary serial ports. The routines are called ?KEY1, KEY1, and EMIT1 for the serial1 port, and ?KEY2, KEY2, and EMIT2 for the serial2 port.

When you first receive your QED Board (or after you invoke the special cleanup mode), QED-Forth uses the primary serial port which is associated with the 68HC11's hardware UART. In other words, the ?KEY automatically calls ?KEY1, KEY calls KEY1, and EMIT calls EMIT1. The xcfa's of ?KEY1, KEY1, and EMIT1 are installed in U?KEY, UKEY, and UEMIT respectively.

If you want the QED-Forth interpreter to use the serial2 port, simply set the baud rate by executing the BAUD2 routine, and then execute USE.SERIAL2 which initializes the serial2 port and revectors ?KEY, KEY, and EMIT to call the serial2 routines. For example, to use the serial2 port at 2400 baud, execute

DECIMAL
2400 BAUD2
USE.SERIAL2

At this point QED-Forth starts communicating via the serial2 port, so you'll need to have a terminal connected to the serial2 connector to keep communicating with QED-Forth. To revert to the primary serial port at the prior baud rate, simply execute

USE.SERIAL1

Another way to restore communications at 9600 baud via the primary serial port is to invoke the special cleanup mode by resetting the processor when DIP switch #5 is in the ON position. This returns the board to the "pristine" condition it was in when it was shipped from the Mosaic Industries.

 

Specifying the Baud Rate of the Primary Serial Channel

The baud rate is the serial bit transfer rate in units of bits per second. While the primary serial port serial1 can run at rates up to 131,000 baud, the maximum "standard" baud rate is 9600 baud with an 8 MHz crystal, or 19,200 baud with a 16 MHz crystal. These rates are summarized in Table 9-2 of the Motorola 68HC11F1 manual.

Setting the baud rate of the primary serial channel serial1 is accomplished by writing to the BAUD register at address 802BH in the 68HC11. The table in Figure 12.1 relates the register contents to some commonly used baud rates.

Desired Baud Rate (decimal)BAUD contents (hex) 8 MHz crystal BAUD contents (hex) 16 MHz crystal
19200 N/A 30
9600 30 31
4800 31 32
2400 32 33
1200 33 34
600 34 35
300 35 36

Figure 12.1. Contents of the BAUD register in the 68HC11 required to achieve standard baud rates.

For example, if your board is clocked by an 8 MHz crystal and you want to immediately change the serial1 baud rate to 1200 baud, execute

HEX 33 802B 0 C!

to set the contents of the BAUD register to 33H.

The default baud rate for the serial1 channel is 9600 baud, but you may require a different baud rate to be in effect each time the QED Board starts up. The INSTALL.REGISTER.INITS routine described in Chapter 11 may be used to automatically initialize the BAUD register to a specified value every time the processor is powered up or reset. This routine specifies startup values for the OPTION, TMSK2, BPROT, and BAUD registers in the 68HC11. For reference, the default register initialization values are summarized in Figure 12.2.

Register Name Register Address Default Value @ 8 MHz Default Value @ 16 MHz
OPTION 8039H 33H 33H
TMSK2 8024H 01H02H
BPROT 8035H 10H 10H
BAUD 802BH 30H 31H

Figure 12.2. Default values of the registers initialized by INSTALL.REGISTER.INITS. These are the values that take effect after DEFAULT.REGISTER.INITS has been executed.

Let's assume that we want standard initialization values to be used for the OPTION, TMSK2, and BPROT registers, but we want to automatically establish a baud rate of 1200 baud after every power up and reset. Using the information from Figure 12.2 and assuming an 8 MHz crystal frequency, we specify the default values for the OPTION, TMSK2, and BPROT registers, and from Figure 12.1, we specify a BAUD value of 33H to set the baud rate. Thus executing

HEX
33    \ default contents of OPTION register
01    \ default contents of TMSK2 at 8 MHz crystal (use 02H at 16 MHz)
10    \ default contents of BPROT register
33    \ BAUD contents for 1200 baud at 8 MHz (use 34H at 16 MHz)
INSTALL.REGISTER.INITS

sets the baud rate to 1200 upon each subsequent reset or restart. To revert to 9600 baud, execute DEFAULT.REGISTER.INITS or use the switch-selectable special cleanup mode described at the end of this chapter.

 

Specifying the Baud Rate of the Secondary Serial Channel

Specifying the baud rate of the secondary serial channel is easy. Just place an integer on the data stack and invoke BAUD2 to immediately change the baud rate. BAUD2 works whether the crystal frequency is 8 MHz or 16 Mhz. Be careful not to specify a baud rate higher than the software UART can support. The maximum baud rate of the secondary serial port is limited by the time required to execute the software UART routines. With an 8 MHz crystal, the maximum sustainable file transfer rate is 2400 baud, and of course this rate doubles to 4800 baud with a 16 MHz crystal:

Maximum File Transfer Rate of Serial2 Port
@ 8 MHz crystal @ 16 MHz crystal
2400 Baud 4800 Baud

You can also use the SERIAL2.AT.STARTUP command to specify a default baud rate for the serial2 channel that is automatically installed when the QED Board is powered up or reset.

 

Specifying Serial2 as the Startup Serial Channel

Either one of the serial channels can be specified as the default that will be initialized and used upon each reset or restart. To specify serial2 as the startup serial port, execute

SERIAL2.AT.STARTUP ( u -- | u = baud.rate )

This routine expects a baud rate on the data stack. The specified baud rate must be a power of 2 times 75 baud. The allowed baud rate choices are 75, 150, 300, 600, 1200, 2400, 4800, and 9600 baud. For example, to specify the serial2 port as the default at 1200 baud, execute

DECIMAL 1200 SERIAL2.AT.STARTUP
For experts and the curious:
The SERIAL2.AT.STARTUP command causes a byte to be stored in the reserved area at the start of EEPROM. The QED-Forth operating system checks this byte upon every startup, and initializes the serial2 port at the specified baud rate as the default if the EEPROM byte is properly set. The byte that is stored in EEPROM equals the specified baud rate divided by 75. The startup routine selects serial2 as the default serial port if this EEPROM byte is an exact power of two. The startup routine revectors KEY, ?KEY, and EMIT to call KEY2, ?KEY2, and EMIT2, respectively. It also globally enables interrupts so that the serial2 port can begin to operate immediately.

Another way to ensure that the QED Board starts up using the serial2 port is to define an AUTOSTART or PRIORITY.AUTOSTART routine that initializes the serial2 port. This can be accomplished by calling INIT.SERIAL2 or USE.SERIAL2 from within the autostart routine.

INIT.SERIAL2 installs the required interrupt handlers and initializes the hardware registers associated with serial2; it does not revector KEY, ?KEY, and EMIT, and it does not globally enable interrupts. USE.SERIAL2 calls INIT.SERIAL2 and then proceeds to revector KEY, ?KEY, and EMIT, and globally enables interrupts.

After executing USE.SERIAL2, the secondary serial port is immediately active. After executing INIT.SERIAL2, however, the serial2 port does not become active until interrupts are globally enabled by ENABLE.INTERRUPTS or some other command (such as a call to START.TIMESLICER, or execution of the CLI command in assembly code).

In many applications it is important that all interrupt service routines be properly initialized before globally enabling interrupts. In these cases it is not wise to use the SERIAL2.AT.STARTUP to specify the serial2 port as the startup port. SERIAL2.AT.STARTUP causes interrupts to be globally enabled by the operating system before the application gets a chance to initialize other interrupt service routines. It may be better to initialize all of the required interrupt service routines, and then execute USE.SERIAL2, or INIT.SERIAL2 followed by ENABLE.INTERRUPTS.

 

Specifying Serial1 as the Startup Serial Channel

The primary serial port serial1 is the default serial port at startup unless SERIAL2.AT.STARTUP has been executed. The command

SERIAL1.AT.STARTUP ( -- )

undoes the effect of SERIAL2.AT.STARTUP. (For experts and the curious: It stores a value into the EEPROM byte that is not a power of two.) Consequently, the QED-Forth operating system selects the serial1 port on subsequent resets or restarts. The section above titled "Specifying the Baud Rate of the Primary Serial Channel" details how to set a default baud rate that becomes effective upon each power up or reset.

 

Using the Secondary Serial Port

The serial2 port has some interesting features including queued input and output and an optional parity bit.

The data format of the serial2 port is as follows:

  • 1 start bit
  • 8 data bits
  • optional parity bit (can also implement an extra stop bit or 9th data bit)
  • 1 stop bit

The start bit is sent as a logical 0 (also known as a "space") at the PA4 output pin and is received as a logical 0 at the PA3 input pin. The data bits are transmitted or received one at a time starting with the least significant bit. If the system variable PARITY is ON, the logical level of the optional parity bit output is specified by the system variable PARITY.OUT, and the logical level of the latest incoming parity bit is stored in the variable PARITY.IN. The stop bit is a logical 1 (also known as a "mark"). An idle transmission line is maintained in the "marking" or high state. Note that the RS232 drivers and receivers invert the signal levels, so a logical 1 at the processor corresponds to a negative voltage on the transmission wires between the driver and receiver. Likewise a logical 0 at the processor corresponds to a positive voltage on the transmission wires.

The variable PARITY contains a flag. If true, a parity bit is transmitted and received after the final data bit. If PARITY is ON, the level of the outgoing parity bit is set by the flag in the PARITY.OUT variable, and the level of the last received incoming parity bit is stored in the variable PARITY.IN. Implementing odd or even parity requires calculations by the user's programs; the software UART does not perform parity calculations. Mark or space parity is easy to implement, however. For example, to implement space parity, execute

PARITY ON
PARITY.OUT OFF

This specifies that the software UART outputs a logical 0 (space) after the eighth data bit has been transmitted. The user's program could check the contents of PARITY.IN after each received bit to make sure that the received parity bit is a logical 0, but this is not required.

If no parity is required but an extra stop bit is needed, execute

PARITY ON
PARITY.OUT ON

This specifies that the software UART outputs a logical 1 (mark) after the eighth data bit has been transmitted, and this exactly replicates the effect of an extra stop bit.

The output of the serial2 port is buffered by an 80 character queue. This can greatly reduce the time required to service the serial port. The application program can write an entire line to the circular output buffer using the EMIT2 routine, and the interrupt-driven software UART will then automatically transmit all of the characters. If EMIT has been revectored (for example, by USE.SERIAL2 or SERIAL2.AT.STARTUP) to execute EMIT2, then the printing routines such as ." and TYPE can be used to emit an entire line or string via the secondary serial port. The ." or TYPE command will execute very quickly, and transmission of characters will take place "in the background" under the control of the interrupt-driven serial2 transmission routine.

The routine

#OUTPUT.CHARS ( -- n )

returns the number of characters remaining in the queue waiting to be sent out. The application program can use this information to check on the progress of the transmission. The variable TRANSMITTING is also available for this purpose. It contains a flag that is true while characters are being transmitted and false when the buffer is empty and no character is being transmitted.

The input of the serial2 port is also buffered by an 80 character queue. Up to 80 characters can be received by the interrupt-driven software UART input routine before service from the application is required. The application program removes the characters from the input buffer with the KEY2 routine. The status of the input buffer may be checked with the routine

#INPUT.CHARS ( -- n )

which returns the number of characters that have been received and stored in the input buffer but which have not been removed by KEY2.

If KEY has been revectored to execute KEY2, then EXPECT can be used to remove a line of characters from the input queue and place the text at a specified buffer address.

 

Using RS485

The primary serial port can be configured to communicate using the RS485 protocol. An RS485 driver/receiver chip is on the board. Before using RS485, make sure that the onboard hardware is properly configured:

A 3-post jumper on the QED Board between the RAM/ROM socket and the 40 pin address/data bus connector selects either RS232 or RS485 for the serial1 port. To select RS485, the jumper should connect the center post to the post nearest to the power connector. This connects the RS485 received signal to the 68HC11's serial input pin.

The data direction of the RS485 transceiver is controlled by pin 4 of the PPC port on the PIA. If PPC4 is high, the QED Board is configured to transmit RS485 data, and if PPC4 is low, the QED Board is configured to receive RS485 data. The QED-Forth routine

INIT.RS485 ( -- )

sets the direction of the upper PPC port as output to ensure compatibility with control of the RS485 transceiver; see its glossary entry for a detailed description of its operation. The routine

RS485.TRANSMIT ( -- )

sets PPC4 high to put the transceiver in transmit mode, and

RS485.RECEIVE ( -- )

clears PPC4 low to put the transceiver in receive mode. Both of these routines use uninterruptable bit set and bit clear operations for maximum robustness in multitasking environments (see the "Multitasking" chapter).

Because there are many possible RS485 protocols, QED-Forth does not specifically implement a software protocol for managing communications on a multi-drop RS485 network.

The secondary serial port provides a convenient way of debugging the RS485 serial link. You can use the primary serial port for RS485 communications while maintaining communications with the QED-Forth development environment via the secondary serial port.

 
This page is about: Programming User Interface, LCD Display, Keypad, Serial Ports – The QED Board is designed to communicate with users via LCD display, keypad, and dual serial communications links. The Getting Started with QED Board booklet provides an excellent introduction to these interfaces. This chapter builds on information …
 
 
Navigation