If all you need is a quick serial communications implementation for your project, Program 8.1 (from the microEngineering Labs Web site) gives all the code you need to read and write to the USART. Combine the single character code in a loop to read and write more than one character (in other words, create strings).
Program 8.1 RS232 Communications (Program to communicate with a computer)
; This microEngineering Labs program can be found on their Web
; site. Use the latest version.
CLEAR ; read and write hardware usart
DEFINE OSC 4 ; osc speed
B1 VAR BYTE ; initialize usart
TRISC = %10111111 ; set TX (PORTC.6) to out, rest in
SPBRG = 25 ; set baud rate to 2400
RCSTA = %10010000 ; enable serial port and continuous receive
TXSTA = %00100000 ; enable transmit and asynchronous mode
;
; echo received characters in infinite loop
LOOP: ;
GOSUB CHARIN ; get a character from serial input, if any
IF B1 = 0 THEN LOOP; no character yet
GOSUB CHAROUT ; send character to serial output
GOTO LOOP ; do it forever
;
CHARIN: ; sub to get a character; from usart receiver
B1 = 0 ; preset to no character received
IF PIR1.5 = 1 THEN; if receive flag then…
B1 = RCREG ; get received character to b1
ENDIF ;
RETURN ; go back to caller
; subroutine to send a character
CHAROUT: ; to usart transmitter
IF PIR1.4 = 0 THEN CHAROUT ; wait for transmit register empty
TXREG = B1 ; send character to transmit
; register
RETURN ; go back to caller
END ; end program
On the other hand, if you need a greater understanding of what is going on, read on.
The LAB-X1 lets us experiment with two types of serial communications. The board comes with hardware for the RS232 standard on board and an empty socket that can be configured with the RS485 protocol (a line driver IC must be added). Only one type of communications can be active at any one time, and the chip that is not being used must be removed from the board. The RS232 communications are routed to the DB-9 female connector on the board, and there are PC board holes for a three-pin connector at J10 for RS485 communications. The IC required by the RS485 is the SN175176A or equivalent line driver.
The two standards are similar and, simply stated, using RS485 allows you to go longer distances and the communication is more noise tolerant. (This is related to the capacitance of the lines used and stronger drivers being employed. The discussion of the why and how of this is beyond the scope of this book.)
The compiler supports communications to both standards and the specified compiler commands should be used whenever possible. Writing your own sequences for controlling serial communications is counterproductive, even though it might be instructive. The compiler uses the same commands to access both standards, and the hardware you put in place determines how the signals are sent out and received. (Take a minute to look at Figures 8-1 and 8-2 to see what the complications are.)
Communications are timed according to the specification of the oscillator. For the proper timing to be achieved, the OSC command has to be set to the actual oscillator frequency in use. If the frequencies are not matched, communications will be sped up or slowed down (in speed) based on the extent of the mismatch. If you are actually using a 4 MHz oscillator and specify OSC 20 in your program, the communications will slow down to one-fifth the specified speed because the system is actually running at one-fifth the 20 MHz speed.
In order to experiment with communications, we need to be able to communicate with an external device. The easiest device to use is a personal computer set up with a dumb terminal program. The various versions of Microsoft Office Works software all contain a terminal program that you can access and use.
A dumb terminal may be set up by following these instructions:
Go to the Start menu in your PC command trough, then select
Programs
Communications
HyperTerminal
If for some reason HyperTerminal does not show up here, go to HELP under the Start menu, search for “HyperTerminal,” and then click “Finding in 2000.” This will give you a window with a link to HyperTerminal. Downloads are free.
Set up the HyperTerminal for
8 bits
No parity
I stop bit
2400 baud
This is what the system defaults to with the PICBASIC PRO Compiler. We will use these settings for all our experiments. Set it up and save your terminal to the desktop for easy access.
Connect the serial cable between the computer and the MCU. Since this same cable is also used for programming the MCU, if you have only one serial port, you must disconnect it from the serial programmer after every programming session when using a serial programmer. It’s just one more reason for opting for the USB programmer. The wiring for the connector to the serial port is shown in Figure 8.1
Figure 8.1 RS232 Communications wiring. (Wiring diagram for the RS 232 standard –There are actually two RS232 drivers on the MAX232CPE. The unconnected I/O lines belong to the second driver on this chip.)
Once set up properly, whatever is sent out by the LAB-X1 will show up on the HyperTerminal screen, and whatever is typed in at the computer keyboard will show up on the LAB-X1 LCD and the HyperTerminal screen.
We will be using the hardware serial output command HSEROUT, which applies to the first COM port on the LAB-X1. (The LAB-X1 has only one port, so HERSOUT2 is not applicable for use with this MCU. The most obvious use is for data collection and conversion with useful filtering where the data comes in on one port [or from an instrument], is translated and filtered, and then goes out on the other port.)
Let’s write a simple program (see Program 8.2), with no safety or error correction interlocks, to send a series of 75 uppercase “A”s to the computer one “A” at a time with no delay between transmissions. Seventy-five characters will fit on one line with the carriage return. This will keep the LAB-X1 busy for about 0.25 seconds every time you press the reset pushbutton while adjusting the terminal settings, if necessary.
Program 8.2 RS232 Communications (Program to send information to the computer)
CLEAR ; Clear the Ram
DEFINE OSC 4 ; Define the oscillator speed
DEFINE HSER_RXSTA 90h ; ]setting up the communications
DEFINE HSER_TXSTA 20h ; ]variables and baud rate
DEFINE HSER_BAUD 2400 ; ]see PBP manual for details
DEFINE HSER_SPBRG 25 ; ]
HSEROUT [$D, $A, $A] ; a carriage return and two line feeds
ALPHA VAR BYTE ; set counter variable
FOR ALPHA =1 TO 75 ;
HSEROUT [“A”] ; loop to send out the 75 ‘A’ characters
NEXT ALPHA ;
END ; end program
For the communications protocol, we will match the settings of the HyperTerminal. As indicated in the compiler manual, this is done with the arguments in the HSEROUT command and by the protocol related DEFINEs in the program. This is what is implemented in Program 8.2. Before you go any further, the preceding program must be made operational.
Next, we need to receive information from the computer and display it on the two lines of the LCD. We will set it up so the LCD will be cleared after every 20 characters received, so we don’t run out of space on line 1 of the display. The operant command to receive data is:
HSERIN {ParityLabel, }{Timeout, Label,}[Item{,…}]
The DEFINEs in the first program segment define the variables being used. “Timeout” and “Label” are optional and are used to allow the program to continue if characters are not received in a timely manner. Timeout is specified in milliseconds. See the more detailed discussion in the compiler manual. In our case, the timeout means that the program will jump to the sending routine whenever there is nothing in the receiver buffer. The receiver buffer has preference as set up. However, you need to keep in mind that the receive buffer is only 2 bytes long, so we cannot linger on the send side too long before checking on the receive buffer again.
Things to keep in mind when receiving information:
Even though certain control characters do not show up onscreen, they will still be counted as characters unless they are filtered out.
Some characters may not be implemented at all depending on the character set recognized by the software in the two processors. This means that the filters you design have to be carefully designed to take care of all possibilities.
The receiving buffer is only two characters long. This is a very important consideration.
We have not taken any precautions for transmission/reception errors, and so on, and that can get more complicated than we need to cover at this level of our expertise. Meaning that we will assume there are no hardware errors to disturb what we are doing.
We can write a short program (see Program 8.3) to receive and display information on the LAB-X1. Since the information will be displayed on the LCD, we have to include all the usual code for the LCD in our program.
Program 8.3 RS232 Communications (Program to receive and display information from the computer)
CLEAR ; clear memory
DEFINE OSC 4 ; osc
DEFINE LCD_DREG PORTD ; define LCD registers and bits
DEFINE LCD_DBIT 4 ;
DEFINE LCD_RSREG PORTE ;
DEFINE LCD_RSBIT 0 ;
DEFINE LCD_EREG PORTE ;
DEFINE LCD_EBIT 1 ;
;
CHAR VAR BYTE ; variables used in the routine
; storage for serial character
COL VAR BYTE ; keypad column
ROW VAR BYTE ; keypad row
KEY VAR BYTE ; key value
LASTKEY VAR BYTE ; last key storage
;
ADCON1 = %00000111 ; set PORTA and PORTE to digital
LOW PORTE.2 ; LCD R/W line low (W)
PAUSE 500 ; wait for LCD to startup
OPTION_REG.7 = 0 ; enable PORTB pullups ;
KEY = 0 ; initialize vars
LASTKEY = 0 ;
;
LCDOUT $FE, 1 ; initialize and clear display
;
LOOP: ;
HSERIN 1, TLABEL, [CHAR] ; get a char from serial port
LCDOUT CHAR ; send char to display
;
TLABEL: ;
GOSUB GETKEY ; get a keypress if any
IF (KEY != 0) AND (KEY != LASTKEY) THEN ;
HSEROUT [KEY] ; send key out serial port
ENDIF ;
LASTKEY = KEY ; save last key value
GOTO LOOP ; do it all over again
;
GETKEY: ; subroutine to get a key from keypad
KEY = 0 ; preset to no key
FOR COL = 0 TO 3
PORTB = 0 ; all output pins low
TRISB = (DCD COL) ˆ $FF ; set one column pin to output
ROW = PORTB >> 4 ; read row
IF ROW != %00001111 THEN GOTKEY ;
NEXT COL ;
RETURN ; no key pressed
GOTKEY: ; change row and col to ASCII numb
KEY = (COL * 4) + (NCD (ROW ˆ $F)) + “0” ;
RETURN ; subroutine over
END ; end of program
Next, we combine the send and receive programs to give us full communications between the LAB-X1 and the HyperTerminal program in the computer. (This is left to you. At this stage, you should have no problem with implementing this; however, a couple of hints are provided.)
The HyperTerminal software takes care of receiving, displaying, and sending characters, without need for any further modification by us.
The LAB-X1 software must receive characters from the terminal program and display them on the LCD. It also has to read the keyboard and send what it sees to the terminal. The receiving and sending must be in the same main loop.
Figure 8.2 RS485 communications wiring. (Wiring diagram for the RS 485 standard.)
In order to use the RS485 serial communications standard (see Figure 8.2), pins must be installed in JP4 to enable the ground connections and allow J10 to carry the communications. As mentioned earlier, the RS232 IC in U9 must be removed. After these changes, the operations will be similar to the RS-323C standard.