318 The Quintessential PIC Microcontroller
tal the SCK/RC3 shift rate can be selected as 5, 1.25 MHz and 312.5 kHz (200, 800 ns and 3.2 µs). The final selection gives the shift rate as half the frequency generated by Timer 2 overflowing – see Fig. 13.8 on page 379. This option is used where very slow shift rates are required.
As well as programmable frequency selection the idle polarity of the SCK may be set with the CKP bit at SSPCON[4]. With CKP = 0 the clock will idle low with valid data being made available on the \ for an external shift register, as shown in Fig. 12.11.4
The two SSPMode combinations 0110b and 0101b (see Table 12.1) place the SSP in the Slave mode. As opposed to the Master mode, shifting is done using an external clock, usually generated from a remote Master device. In addition, when in Slave mode 0100b the PIC can become a listener only if its SS (Slave Select) pin is high. This disconnects SDO and allows another Slave in a multidrop network to do the talking — see Fig. 12.12.
|
|
|
|
|
SSPSTAT |
|
File 94h |
|
|
|
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Synchronous |
Serial |
|
|
|
|
|
|
|
|
|
|
BF |
|
|
|
|
|
|
|
|
|
Port STATus |
|
|
|
(R 0) |
(R 0) |
(R 0) |
(R 0) |
(R 0) |
(R 0) |
(R 0) |
(R 0) |
|
|
|
|
|
|
|
|
|
|
|
|
read Buffer Full |
|
|
|
|
|
|
SSPCON |
|
|
|
|
|
|
|
|
|
|
File 14h |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Synchronous |
Serial |
|
|
WCOL |
|
SSPEN |
CKP |
SSPM3 |
SSPM2 |
SSPM1 |
SSPM0 |
|
|
Port CONtrol |
|
|
(R/W 0) |
(R/W 0) |
(R/W 0) |
(R/W 0) |
(R/W 0) |
(R/W 0) |
(R/W 0) |
(R/W 0) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SSP Mode
00: Clock = Fosc /4
01: Clock = Fosc/16
10: Clock = Fosc/64
11: Clock = Timer 2/2
ClocK Polarity
0:ClocK Polarity TX on, idle low
1:ClocK Polarity TX on, idle high
SSP ENable
Write COLlision detect
SSPBUF is written while still transmitting
R = Read
W = Write
( ) = Reset condition
Fig. 12.10 The SSP CONtrol and STATus registers as appropriate to the SPI mode.
4A more advanced SSP port, such as used in the PIC16C774/F874, can control both active edge and idle polarity separately as well as input sampling time.
12. One Bit at a Time 319
Figure 12.10 shows the SSP CONtrol register at File 14h and the associated SSPSTATus register in Bank 1 at File 94h. The SSP port is enabled for whatever protocol when SSPEN (SSP ENable) in SSPCON[5] is 1. As SSPEN resets to zero, the SSP is disabled by default. In the disabled state the relevant Port C pins can be used as normal parallel I/O lines. If they are to be used as SSP lines then RC5:3 must be set via TRISC to be input or output as appropriate to their SSP function. Similarly, if the SS control is to be used, RA5 must be set to input.
Bits SSPCON[3:0] are the Mode control bits which set the communication protocol and various Master/Slave options as listed in Table 12.1. Of interest to us is the internal clock source in the SPI Master mode and the use of the SS pin when in the SPI Slave mode.
Finally, SSPCON[7] is the Write COLlision (WCOL) status bit – not in SSPSTAT due to lack of space. This is set to 1 if the software writes to SSPBUF before the transmission of the previous byte has been completed. If set, it should be cleared by software to reset this warning mechanism.
Using Figs. 12.9 and 12.10 as a programmer’s model we can now deduce the hardware-software interaction in order to action a transmission of a byte and/or receive a new byte:
1.Configure SSP module.
•Set up SCK/RC3, SDO/RC5 as outputs and SDI/RC4 as an input (TRISC[5:3])
•Set up Master/Slave mode with appropriate clock source (SSPCON[3:0])
•Choose active TX clock edge with CKP (SSPCON[4])
•Enable the SSP by setting SSPEN (SSPCON[5])
2.Move datum to SSPBUF to initiate transmission.
3.IF WCOL = 1 THEN reset WCOL and go to item 2
4.Poll BF for 1 (SSPSTAT[0])
5.Move RX data from SSPBUF, which also resets BF
To illustrate this process, consider a subroutine SPI_IN_OUT which combines the function of SPI_READ and SPI_WRITE; that is it transmits the datum in file register DATA_OUT whilst at the same time returning the consequential received byte to DATA_IN.
Table 12.1: The SSP Mode bits.
SSPM[3:0]: Synchronous Port Mode select bits
0000 SPI Master mode with SCK = Fosc/4 0001 SPI Master mode with SCK = Fosc/16 0010 SPI Master mode with SCK = Fosc/64
0011 SPI Master mode with SCK = TMR2 output/2
0100 SPI Slave mode. SS pin control enabled
0101 SPI Slave mode. SS pin control disabled 0110 I2C Slave mode, 7-bit address
0111 I2C Slave mode, 10-bit address
1011 I2C Start & Stop bit interrupts enabled, Slave idle
1110 I2C Slave mode, 7-bit address with Start & Stop interrupts enabled 1111 I2C Slave mode, 10-bit address with Start & Stop interrupts enabled
320 The Quintessential PIC Microcontroller
The implementation of this subroutine depends on setting up the SSP during the initialization phase of the main software after Reset. In the following code fragment we are using the Fosc/4 clock rate Master mode:
.include "p16c74.inc" |
|
MAIN bsf |
STATUS,RP0 |
; Change to Bank |
1 |
movlw |
b’11010111’ |
; RC5/SDO, RC3/SCK outputs |
movwf TRISC |
; RC4/SDI input |
|
..... ..... |
|
|
bcf |
STATUS,RP0 |
; Return to Bank |
0 |
movlw |
b’00100000’ |
; Enable SSP, TX |
clock on -ve edge |
movwf |
SSPCON |
; SPI Master, Fosc/4 rate |
|
|
|
|
The coding shown in Program 12.4 follows the task list exactly. Data to be transmitted is moved from the designated file register to SSPBUF and status bit WCOL checked to see that it got there. If there was a transmission in progress then the datum is not stored in SSPBUF and WCOL is set. If this subroutine is the only code to access the SSP then this should rarely be the case and in most instances this check is omitted, but its inclusion makes the system more robust.
Once the transmit datum is in situ, the transmit sequence is immediately initiated, as shown in Fig. 12.11 and progresses to its conclusion. Once the Bu er Full status flag BF is set, the received datum can be moved out of SSPBUF to its ordained location. This automatically resets BF.
Program 12.4 Using the SSP for SPI data input and output.
;************************************************************
;* FUNCTION: Transmits and simultaneously receives one byte *
; * |
FUNCTION: |
from the SSP using the |
SPI protocol |
* |
; |
* |
ENTRY |
: |
Data |
to be transmitted |
is in DATA_OUT |
* |
; |
* |
EXIT |
: |
Data |
received is in DATA_IN |
* |
; ************************************************************
SPI_IN_OUT |
|
|
movf |
DATA_OUT,w |
; Get datum for transmission |
movwf |
SSPBUF |
; Put into SSPBUF |
SSP_IN_OUT_LOOP |
|
btfss |
SSPCON,WCOL |
; Did it make it? |
goto |
SPI_IN_OUT_CONT |
; IF so THEN continue |
bcf |
SSPCON,WCOL |
; ELSE reset WCOL and try again |
goto |
SSP_IN_OUT_LOOP |
|
SPI_IN_OUT_CONT |
|
bsf |
STATUS,RP0 |
; Change to Bank0 |
btfss |
SSPSTAT,BF |
; Check for Buffer Full |
goto |
SPI_IN_OUT_CONT |
; IF not then poll again |
bcf |
STATUS,RP0 |
; Back to Bank 1 |
movf |
SSPBUF,w |
; ELSE get the received datum |
movwf |
DATA_IN |
; Put away |
return |
|
|
|
|
|
12. One Bit at a Time 321
Apart from a slight reduction in the code length, the advantage of using this hardware is the increase in speed. The actual transmit/receive takes eight SCK cycles, which in our case is eight instruction cycles. With
an Fosc of 20 MHz the clocking rate is 5 MHz (that is a bit rate of 5 million bits per second, commonly written as 5 Mbit/s or 5 Mbps), giving a total
time of 1.6 µs per byte.
If speed is of the essence then the SSP can be interrupt driven, as the SSPIF in the PIR1 register is set at the same time as BF. If the SSPIE mask bit in the PIE1 register is set, together with the overall mask bits GIE and PEIE in INTCON, then an interrupt will be generated when the outgoing byte has been transmitted and the new incoming byte is ready and waiting in SSPBUF. The function of these bits are shown in Fig. 14.10 on page 408. This interrupt can be used to awaken the PIC when in its Sleep mode.
Figure 12.11 shows the SPI mode timing for our subroutine. As we have cleared CKP then SCK is idling low. As soon as SSPBUF is written to, SCK goes high and the MSB of the TX datum appears at SDO. On the following edge, the MSB of the received datum is read in at SDI.
With this chosen polarity there is plenty of time for data from the external serial input port to present data to the PIC assuming that (as is
usual) the its shift register is |
|
|
/ |
|
triggered. This data is then sampled by |
|
|
|
the PIC on the following |
|
|
|
|
of SCK, as indicated the the ↓ sample/shift |
\ |
|
|
|
|
|
|
|
|
|
points in Fig. 12.11. However, as we see, data that the PIC places on its SDO pin is placed on the / of SCK ready and stable for the following active \ . This means that the serial output port must be negative-edge triggered to ensure that it shifts in stable data. To get around this problem an inverter should be inserted at the peripheral’s input shift register
|
SSPBUF to Write
|
Sample/shift
|
Sample/shift
|
Sample/shift
|
Sample/shift
|
Sample/shift
|
Sample/shift
|
Sample/shift
|
Sample/shift
|
CKP = 0 |
|
|
|
|
|
|
|
|
SCK |
1 |
|
|
|
|
|
|
8 |
SDO |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
SDI |
d7 |
d6 |
d5 |
d4 |
d3 |
d2 |
d1 |
d0 |
BF/SSPIF |
|
Outgoing data is stable now |
|
|
|
Incoming data must be stable now |
|
To serial peripheral
From serial peripheral
Fig. 12.11 SSP SPI-mode master waveforms.
322 The Quintessential PIC Microcontroller
clock, e ectively converting it to a negative-edge triggered shift register. Some more advanced SSP modules, such as included in the PIC16F87X line, allow the input sample time to be shifted to remove the need for this additional hardware.
One use of serial transmission is to connect a number of PICs (or indeed other MCUs) together in one multiprocessor network. For example, a robot arm may have a MCU controlling each joint, communicating with a master processor. A simple multidrop circuit of one Master and two slave processors is shown in Fig. 12.12.
Master |
|
|
|
|
|
|
|
|
|
PIC |
|
|
|
|
|
|
|
|
|
RA1 |
|
|
|
|
|
|
|
|
|
RA0 |
|
|
|
|
|
|
|
|
|
SCK |
|
|
|
|
|
|
|
|
|
SDO |
|
|
|
|
|
|
|
|
|
SDI |
|
|
|
|
|
|
|
|
|
|
Slave PIC 1
|
SDI
|
SDO
|
SCK
|
SS
|
Slave PIC 2
|
SDI
|
SDO
|
SCK
|
SS
|
Fig. 12.12 A multidrop SPI communications network.
In this configuration the Master PIC externally drives the SCK of both Slaves, thus controlling when and how fast transmission occurs across the network. Both Slaves are configured in Mode 6 (SSPM[3 : 0] = 0110) so that the Slave Select inputs are enabled. Thus, if the Master wishes to read a datum from Slave 2 the the latter’s SS is brought low and the Master clocks the eight bits from Slave 2’s SSPBUF/SSPSR, into its own SSPBUF/SSPSR. At the same time any data transmitted by the Master will be received by the Slave. Slaves can rest in Sleep mode while all this is going on and the resulting interrupt used to awaken it after the transaction has completed provided that the PEIE and SSPIE mask bits are set.
SPI transactions may be coded in C either by mimicking the assemblelevel code and setting/reading the appropriate registers, or by using builtin functions specific to the task. For example, for the CCS compiler constructions like:
spi_write(DATA_OUT); DATA_IN = spi_read();
e ectively mimic our SPI_IN_OUT subroutine.