Data transmission with the USART

The 690 has an Enhanced Universal Synchronous Asynchronous Receiver Transmitter, or USART for short. We use this to take a byte of data and transmit it serially (that is, one bit at a time) to the USART of another PIC. The second USART receives the serial data bit by bit and assembles it into a byte that can be read from a register. Transmission can be by a single wire (if the 0V line is common to both PICs) or by a radio link.

The output from the USART is at RB7 (pin 10) and the input at RB5 (pin 12). The USART can operate in both synchronous and asynchronous modes but we describe only the asynchronous mode. In this mode, one USART waits for an indefinite period to receive the data signal from the other USART.

As a transmitter, the USART is controlled by the TXSTA register, in Bank 1. The settings we use are:

<7> = 0, not applicable for asynchronous mode. <6> = 0, 8-bit transmission.

<5> = 1, enable tranmission.

<4> = 0, asynchronous mode.

<3> = 0, disable Break Character bit.

<2> = 0, low speed.

<1> this bit is '1' if transmit shift register is empty and '0' if it is full.

<0> = 0, the ninth bit, when used.

All we have to do to transmit a byte is to place it in the data register TXREG and set bit

<5> of TXSTA. There is no need to set the Baud Rate Control register (BAUDCTL), as we

use the default asynchronous mode.

After a short delay to allow data (usually only a single byte) to be transmitted, the data is

read from RCREG in the other PIC. To set up the USART as a receiver, the RCSTA

register is loaded as follows:

<7> = 1, enables serial port.

<6> = 0, 8-bit reception.

<5> = 0, not applicable.

<4> = 1, enables receiver.

<3:0> = 0, not applicable.

The following is a routine for configuring the USART:

bsf status, 5

Bank 1.

bsf trisb, 7

RB7 as input (automatically changed

to output).

bsf trisb, 5

RB5 as input.

clrf txsta

Set up, but not enable transmitter.

bcf status, 5

Back to Bank 0.

bsf rcsta, 7

Set up but not enable receiver.

The USART is now ready for action except that it is not enabled. Immediately or

whenever we want to use it we switch it on by:

bsf status, 5

Bank 1.

bsf txsta, 5

Enable transmitter.

bcf status, 5

Bank 0.

A subroutine for transmitting a byte is:

movlw XXh

XX is the byte, in w.


btfss piri, 4

If register clear for use.

goto transmit

movwf txreg

To send the byte.


This assumes that the transmitting PIC knows that the other PIC is ready to receive. It

may previously have sent a 'ready to

receive' byte.

To receive a byte, the code is:


bcf status, z

Reset zero flag.

btfss piri, 5

New data received?


No, try later.

btfss rcsta, 2

Test for framing error.

goto noferr

No framing error.

movf rcreg, w

Byte to w.

bcf status, z

Zero flag clear - error.

goto orerr

to check overrun flag.


movf rcreg, w

Byte to w.

bsf status, z

Set zero flag to show valid byte.

orerr btfss rcsta, i

Test for overrun error.


No overrun error.

bcf rcsta, 4

Clear continuous receive.

bsf rcsta, 4

Enable it (clears overrun flag).


The subroutine returns with z = 1 if there is a new valid byte in w. Call the above

subroutine, check z, and either use the byte that is in w, or call again until a valid byte is


The routines given above show you how to set up the USART, how to send and how to

receive data. The other thing to think about is how to write these routines into a program

so that data can be exchanged with another controller while the program continues to


Data memory

The 16F690 has 256 bytes of EEPROM data memory that can be written to for long-term

storage of data. Unlike the ordinary SRAM used as temporary storage, the data in this

memory remains for 40 years or more or until it is overwritten.

Most important is the fact that it is not lost when the power is switched off. For this reason

it is useful in robots that can be taught or in other ways can learn their best responses to

given situations. They do not forget what they have learnt. They can carry their acquired

knowledge over from one session to the next.

The data memory is addressed

in the range 0 to 0FFh. Reading data is simpler than

writing it. A routine for reading data from EEPROM is as follows:

bsf status, 6

Bank 2.

bcf status, 5

movlw address-to-read

movwf eeadr

Address to eeadr register.

bsf status, 5

Bank 3

bcf eeconi, 7

Access data memory.

bcf eeconi, 0

Read data.

bcf status, 6

Bank 2.

movf eedat, w

Data to w.

bcf status, 5

Bank 0.

Writing data includes a sequence of instructions that must be followed exactly:

bsf status, 6 ;

Bank 2.

bcf status, 5

movlw address-to-write-to

movwf eeadr ;

Address to eeadr register.

movlw data-to-write

movwf eedat ;

Data to eedat register.

bsf status, 5 ;

Bank 3.

bcf eeconi, 7 ;

Access data memory.

bsf eeconi, 2 ;

Enable writing.

bcf intcon, 7 ;

Disable interrupts. Required code begins here.

movlw 055h

movwf eecon2 movlw 0aah movfw eecon2 bsf eeconl, 1

Write 55h.

Write aah.

Write data. Required code ends here.

writing btfsc eeconl, 1 goto writing bcf eeconl, 2 bcf status, 5 bcf status, 6

Becomes 0 when data is completely written. Until data written. Disable writing. Bank 0.

Was this article helpful?

0 0

Post a comment