Файл: The quintessential PIC microcontroller (S. Katzen, 2000).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 15.06.2025

Просмотров: 5280

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

12. One Bit at a Time 339

movlw

K

;

; K is the delay const

BAUD_LOOP addlw

-1

;

; Decrement

btfss

STATUS,Z ;

((K-1)+2)˜ ; until zero

goto

BAUD_LOOP;

2(K-1)˜

which gives a total of 4K cycles delay, where each cycle is 4/XTAL microseconds. This can be increased by padding with nop instructions, each adding K cycles to the total.

For any given baud rate we require

106

microseconds for a

1

bit

2×BAUD

2

period delay; so to evaluate the value of K we need to calculate the total

number N of 4/XTAL cycles.

4

106

N × XTAL =

2

×

BAUD

N

=

106 × XTAL

8

×

BAUD

In the macro of Program 12.10 N has been defined accordingly. To determine the constant to be loaded into W at the beginning of the loop this value is divided by the total delay cycles in the loop. For example, if XTAL is greater than 12 MHz then the five extra nop instructions bring the total delay to nine cycles, hence the initial constant K is N/9. Actually the value of K is can be reduced by around 2% to compensate for the instructions outside the macro; hence the use of 980,000 in Program 12.10 in the definition of N rather than 1,000,000 (106).

Notice the use of the local directive to qualify a label inside a macro; in this case BAUD_LOOP. This ensures that when the macro is used several times, the assembler will not object to the same named label appearing more than once in the one program.

With our delay macro in situ, the basic input/output subroutines of Program 12.11 are similar to our bit banging SPI subroutines. The PUTCHAR subroutine simply brings the TX pin low for two Baud_delay periods and then toggles the pin eight times mirroring the data in DATA_OUT least-significant bit first – the opposite order to SPI/I2C. Finally TX is held high for the same period to give the Stop/Idle condition.

The input GETCHAR counterpart is more complex. After an Idle state a low-going voltage at pin RX will be treated as a Start bit. However, if the data stream is subsequentially sampled at intervals of one bit period (two evocations of Baud_delay) then as this is just at the transition point of the transmitter, any drift in the two clock rates may cause errors. To avoid this, a half bit period is evoked and then the state of RX checked to ensure that the Start bit is still present. If it is, then subsequent samples are taken at two Baud_delay periods, which is approximately at the bit center point. Better noise rejection could be obtained by sampling at a


340 The Quintessential PIC Microcontroller

Program 12.11 Asynchronous formatted input and output subroutines.

;*************************************************************

;* FUNCTION: Transmits one 8-bit byte in asynchronous format *

;* FUNCTION: Baud rate can be 1200 - 9600 for XTAL 1 -- 20MHz*

; *

RESOURCE:

Macro

Baud_delay giving a

0.5

bit delay; COUNT

*

;

*

ENTRY

:

8-bit

datum

in DATA_OUT, XTAL

& BAUD predefined *

;

*

EXIT

:

Contents of

DATA_OUT 00h,

byte TXed

*

; *************************************************************

PUTCHAR

movlw

8

; Eight data bits

movwf

COUNT

bcf

PORTA,TX

; Start bit

Baud_delay

; 2x0.5 bit delay

Baud_delay

; Now shift out data, LSB first

PUTCHAR_LOOP rrf

DATA_OUT,f

; Rotate right into Carry

btfss

STATUS,C

; Test Carry bit

goto

ITS_A_0

; IF 0 THEN output a 0

bsf

PORTA,TX

; ELSE output a 1

goto

PUTCHAR_NEXT

; and continue

ITS_A_0

bcf

PORTA,TX

; Output a 0

PUTCHAR_NEXT

Baud_delay

; One-bit duration

Baud_delay

decfsz

COUNT,f

; Repeat eight times

goto

PUTCHAR_LOOP

bsf

PORTA,TX

; Stop bit

Baud_delay

Baud_delay return

; *************************************************************

; * FUNCTION:

Receives one 8-bit byte in asynchronous format

*

; * FUNCTION:

Baud rate can be 1200 - 9600 for XTAL 1 -- 20MHz*

; * RESOURCE:

Macro BAUD_DELAY giving a 0.5 bit delay; COUNT

*

; * ENTRY

:

XTAL & BAUD predefined

*

; * EXIT

:

DATA_IN holds the received byte.

*

; * EXIT

:

Err is 00 if no Framing error ELSE -1

*

; *************************************************************

GETCHAR

movlw

8

; Eight data bits

movwf

COUNT

clrf

ERR

; Zero Error byte

GETCHAR_START

btfsc

PORTA,RX

; Poll for 0

goto

GETCHAR_START

Baud_delay

; Hang around for 0.5 bit time

btfsc

PORTA,RX

; Check; is it still low?

goto

GETCHAR_START

Baud_delay

; IF yes THEN hang around

Baud_delay

GETCHAR_LOOP bcf

STATUS,C

; Clear Carry

rrf

DATA_IN,f

; Shift 0 into datum

btfsc

PORTA,RX

; Check; is input high?

bsf

DATA_IN,7

; IF yes THEN set bit in datum

Baud_delay

Baud_delay

decfsz

COUNT,f

; Do eight times

goto

GETCHAR_LOOP

btfss

PORTA,RX

; Look for a Stop bit (High)

decf

ERR,f

; IF low THEN signal an error

return


12. One Bit at a Time 341

higher rate and then taking a majority decision regarding the logic state of the incoming voltage.

After the eight data bits have been shifted into DATA_IN, the Stop bit is checked for 1. If Stop is 0 then a Framing error has occurred. This is signalled by returning a value of −1 in ERR. Other more elaborate schemes may return a variety of error types. For example, where parity is used then a Parity error can be returned.

As an example, if we wish to transmit the three characters PIC then the following code fragment would implement our task. For convenience the assembler allows the programmer to represent ASCII codes in delimited single quotes to represent their ASCII equivalent, as described on page 223.

movlw

’P’

; ASCII for P is 50h

movwf

DATA_OUT

; Put in store

call

PUTCHAR

; Send it out

movlw

’I’

; ASCII for I is 49h

movwf

DATA_OUT

; Put in store

call

PUTCHAR

; Send it out

movlw

’C’

; ASCII for C is 43h

movwf

DATA_OUT

; Put in store

call

PUTCHAR

; Send it out

Handling serial communications this way is only really satisfactory for very simple situations. For example, if the RX pin is not continually monitored a transmission can be missed or synchronization lost. Also it is di cult to implement a full-duplex link. In addition the procedure is software intensive with most of the processing power being wasted in delay loops. The situation can be improved somewhat by using an internal timer to generate the baud delay and by using interrupt-driven techniques. However, the majority of 28+pin PICs have an integral communications port to automatically deal with asynchronous transmission.

One of the first applications of the then new LSI fabrication techniques in the late 1960s, was the implementation of a dedicated hardware asynchronous serial port known as the Universal Asynchronous Receiver Transmitter. The UART12 was already in production by the time microprocessors were developed. Most PCs, even in the 1970s, had a serial port implemented by a UART, as do current systems. As well as dealing with shifting, error checking and interrupt handling, most UARTs also have an integral baud-rate generator which can be set up in software to give the correct bit frequency.

Figure 12.19 shows a simplified model of the basic PIC USART – Universal Synchronous-Asynchronous Receiver Transmitter as the port has a synchronous mode (SYNC = 1) which will not be discussed here. The core of the USART is the Transmit and Receive registers and their

12Sometimes known as the Asynchronous Communication Interface Adapter or ACIA.


342 The Quintessential PIC Microcontroller

Serial Port

Baud Rate Generator

SPBRG File 99h

X f/4

Fosc/64(X+1) 0

TranSmit STAtus

7

Transmit 6

X

data length

TX9

(R/W 0)

(R/W 0)

Serial 7

ReCeive 6

Port

data length

ENable

SPEN

RX9

(R/W 0)

(R/W 0)

Clock

Transmit

shift

register

Serial

data

out

RC6/TX

TranSmit

data

REGister

File 19h

TXREG

Receive

shift

register

Serial

data

in

RC7/RX

ReCeive

data

REGister

File 1Ah

RCREG

h

and

control register

File 0C PIR1

Transmit 5

4

3

Baud Rate2

TRansMiT 1

TX Data 0

ENable

0

----

Generator

shift reg

bit 9

File 98h

4

High speed

empty

bufferTX

empty TXIF 0)(R/W

TXSTA

TXEN

SYNC

BRGH

TRMT

TX9D

(R/W

0)

(R/W 0)

(R 0)

(R/W 0)

(R 1)

(R/W 0)

5

Empty RCIF 0)(R/W

5

4

3

Framing

2

Overflow

1

RX Data

0

bufferRX

Continuous

X

Receive

----

ERRor

ERRor

bit 9

File 18h

ENable

RCSTA

CREN

FERR

OERR

RX9D

(R/W

0)

(R/W 0)

(R 0)

(R 0)

(R 0)

(R X)

ReCeive STAtus and control register

Fig. 12.19 The PIC USART configured for asynchronous communication.

associated bu ers and Status registers. To enable the overall USART the

Serial Port ENable (SPEN) bit in the ReCeive STAtus register (RCSTA[7]) at File 18h must be set.

Transmission

The transmitter logic is enabled when the TranSmit ENable (TXEN) bit in the TranSmit STAtus register (TXSTA[5]) at File 98h is set. To send a character the datum must be moved to the TranSmit data REGister (TXREG) at File 19h, whence it will be transferred to the Transmit shift register and shifted out of pin TX, which is shared with RC6. If a 9- bit format is required the TX9 bit in TXSTA[6] must be set to 1 and the ninth bit placed in bit 0 of the same register before moving the lower eight bits into TXREG. If the Transmit shift register is not empty; that is it is in the process of shifting out a previous datum, then the new datum will remain in the TXREG bu er register awaiting the completion of transmission before being transferred.

Bit 1 of the TranSmit STAtus register reflects the state of the Transmit shift register whilst the TranSmit Interrupt Flag (TXIF) in bit 4 of the Peripheral Interrupt Register 1 (PIR1) is automatically set when the TXREG bu er is empty and ready for reloading. If an interrupt on TX bu er is empty is required, the corresponding TXIE mask bit in the Peripheral


12. One Bit at a Time 343

Enable Register 1 (PIE1[4]) must be set – see Fig. 14.10 on page 408. TXIF is automatically cleared whenever a datum is written into the TXREG.

Reception

Once a Start bit is detected at pin RX then the succeeding eight or nine bits are shifted into the 2-deep ReCeive data REGister (RCREG) at File 1Ah pipeline irrespective of what is going on at the transmitter section. If a 9-bit receive protocol has been selected with RX9 set to 1 in RCSTA[6] then the ninth bit can be read in the RX9D bit of the same status register.

When a datum has been received, it is automatically stored in the top RCREG bu er whence it moves to the lower bu er, provided that no datum is still waiting to be read. ReCeiver Interrupt Flag (RCIF) is automatically set whenever a datum is waiting for collection and this can be used to generate an interrupt if the RCIE mask bit is set; as well as the GIE and PEIE global masks. RCIF is cleared whenever a datum is read. If a datum is waiting in the top bu er, then RCIF is immediately set again showing that there is another datum ready for collection.

If a third character has been received and the 2-deep receive pipeline is full then the Overflow ERRor (OERR) bit at RCSTA[1] will be set and this newly received datum will be lost. The RCREG can still be read twice to retrieve the two bu ered bytes. However, to clear OERR the receive logic must be reset by clearing the Continuous Receive ENable (CREN) bit in RCSTA[4] and then setting it again.

The Framing ERRor (FERR) bit in RCSTA[2] will be updated by reading the RCREG on the next received datum. Both FERR and any ninth received bit are double bu ered in the same way as the received data and so should be read/checked first before the main datum is read as this will empty the pipeline and therefore change these auxiliary bits.

Serial Port Baud-Rate Generator, SPBRG

This is basically a programmable 8-bit counter followed by a switchable frequency ÷4 flip flop chain which can be set up to give the appropriate sampling and shifting rates for the desired baud rate, based on the PIC’s crystal frequency XTAL giving:

Baud rate

XTAL

64×(X+1)

Baud rate

XTAL

16×(X+1)

Low-speed

High-speed

where X is an 8-bit datum written into SPBRG at File 99h who’s value

is XTAL×106 − 1. For example, if we require a baud rate of 4800 on a

64×BAUD

20 MHz device, then a value X = 64 will give a baud rate of 4808, an error of +0.161%. At 20 MHz the maximum baud rate is 312,500 whilst the lowest rate is 1221. A baud rate of 1.25 Mbaud is obtainable at 20 MHz in the high-speed mode with SPBRG = 1, but Microchip do not advise this