Sei sulla pagina 1di 4

1

18. SPI communication


Some sensors implement SPI (Serial Peripheral Interface) protocol for data transfer. An example
of communication between a microcontroller and an accelerometer sensor using the SPI interface
willbedemonstratedinthisexample.
TheSPIprotocolbasicallydefinesabuswith
four wires (four signals) and a common
ground.Thereisonemasterdevicecontrolling
the activity on the bus, and one slave device.
The slave is active only when one of the
signals, Slave Select (SS) enables it. This signal
isalwaysprovidedbythemaster.Therecanbe
morethanoneslaveconnectedtotheSPIbus,
but each slave requires its own Slave Select
signal, see Fig. 1. The data gets transferred
serially bitbybit. There are basically two
signals to carry information, one from master
to slave (MOSI, Master Output Slave Input,
driven by master), and one for the opposite direction (MISO, Master Input Slave Output, driven by
slave).ThelastsignalSCLK(SerialCLocK)assuresthetimesynchronizationbetweenmasterandslave,
andisalwaysdrivenbymaster.TherearestreamlinedversionsoftheSPIbususingonlyonesignalto
transferdata,butthedirectionofdatamustbereversedonrequest;wewillnotusethiskindofdata
transfer.
ThespeedofdatatransferishigherthanwithI
2
Cbus,sincetheslaveisselectedusingahardware
signal and there is no need to transfer the address of the slave. However, this results in multiple
Slave Select signals where more than one slave is connected to the bus. The speed of transfer is
typicallyhigheralsoduetotheoutputswhichshouldbeabletoforcesignalsloworhigh,contraryto
the opendrain outputs used at I
2
C which can force signals low only. The logic levels are defined by
thepowersupplyofthedevicesconnectedtotheSPIbus,andare3.5Vinourcase.Theactualspeed
oftransmissionconformstotheslowestdeviceonthebus,aswithI
2
Cbus.
TheSPIprotocolisfarlessstrictthattheI2Cprotocolalsoduetothefactthatitwasimplemented
first by several different companies and standardized only later. Variants of clock polarities, edge
synchronizations, and even number of bits per transfer are used, and the designer should adopt its
hardwaretotheSPIdevicesused.Themicrocontrollerusedherecanimplementonlysomepossible
variantsofthestandard,andthevariantimplementedintheaccelerometerusedisnotoneofthem.
Toavoidtheproblemasimplebitbangingfunctioncombiningwritingtoandreadingfromaslave
Fig.1:TheSPIbuscanbeusedtotransferdata
betweenthemasterandaslaveusingfourwires.
MASTER
SLAVE 1
SLAVE 2
SCK
MOSI
MISO
SS1
SS2
PlayingwithSTM32F407testboardSPICommunication
2

will be prepared to implement SPI communication as understood by the accelerometer. The


accelerometerLIS3LV02DLisused.
ThetimingdiagramoftherequiredsignalsisgiveninFig.2,thewritingbeingshownintheupper
half. Slave select signal must first be forced low by the master, then a series of 2 times eight clock
pulses are issued by the master at the SCK signal. After this the signal SCK is first returned high,
followed by the signal slave select SS. The value of the signal MOSI is clocked into the slave on
positive edge of the clock signal SCK, and the MOSI signal can change either before or after the
clockingedge,seeslavedevicedatasheetforsetupandholdtimes.Thefirsteightbitsstartwithabit
todefineeitherwritingtoslave(low)orreadingfromslave(high);thisbitislowinourcase.Thenext
bitisfixedtozero,followedbysixbitsofaddress.Thisistheaddresstobeusedbytheslavedevice
toselectoneoftheinternallocationsforwriting,nottheaddressoftheslaveonthebus,aswithI
2
C
bus.Here,withSPIbus,thedeviceisselectedusingtheSlaveSelectsignal!Nexteightbitsaresimply
the byte as it is supposed to be written into the slave. In the diagram address 20
h
is selected for
writing, and value 40
h
is written. The signal MISO is not important during the writing, and is not
shown.
The timing diagram for reading is given in the same figure, bottom half. The Slave Select signal
andthe16risingedgesoftheclockarethesameasforwriting,signalsMOSIandMISOaredifferent.
The master first sends a command to read from the slave by forcing the first bit of the first byte at
MOSI signal high, and then pulling the same signal low during the second bit. Next come six bits of
address within the slave, here 28
h
. After the first byte the MOSI signal is not important anymore. It
canbeleftfloatingasshowninthefigure,butitcanalsohaveanyotherlogicvalue;thavaluewillbe
ignoredbytheslave.However,clockpulsesarestillcoming,andtheslavenowdrivestheMISOsignal
returning the byte to be read, shown as AC
h
. This sequence should be read by the microcontroller
andcombinedintoabyte.
Both sequences for writing and reading are equal with respect to Slave Select and clock signals,
and similar with respect of first byte sent over the MOSI signal. It seems rational to prepare one
single function for sending and receiving a byte, and to interpret return values of this function in a
proper way. When writing to slave we can ignore the value returned over the MISO signal, when

Figure2:SPIbussignalsduringthewritingintotheslave(top),andreadingfromtheslave(bottom)
D
3
1 0
A
4
D
2
0
D
5
A
1
0 0
SCK
1 0
D
4
A
0
0 0 MOSI
A
3
A
5
D
1
D
7
0 0 0
A
2
0
D
0
D
6
0
R
W
0
SS
M
S
A
5
A
1
D
2
D
7
R
W
1
D
1
D
5
1
A
0
1 X
D
3
SS
0
D
0
A
3
SCK
0 0
A
4
D
6
0
M
S
MOSI
A
2
D
4
D
6
0
D
1
1 0
D
7
D
5
MISO
D
2
D
4
1 1 1 0
D
0
0
D
3
0
1
WRITE FROM MASTER TO SLAVE
READ FROM SLAVE TO MASTER
PlayingwithSTM32F407testboardSPICommunication
3

readingfromslavewecansendadummyvalueinsteadofeightdatabitsovertheMOSIsignal.The
completelistingofthefunctionisgiveninFig.3.
The combined 16 bits to be sent over the MOSI signal are the argument AandD of the function.
The function returns a char value as received over the MISO signal during the transmission. The
function starts with some definitions of bits and the declaration and initialization of a local variable
Ret.NexttheSlaveSelectsignalispulsedlowandkeptassuchuntiltheendofthefunction.
Sixteenclockpulsesareneededtotransmitorreceiveabyte,sothefunctioncontinuesbyafor
loop to be repeated 16 times. In the loop the bit 15 of the argument is first checked, and then the
signal MOSI is set to the value of this bit. Next the value of the argument is shifted left for one bit
preparingtheargumentforthenextloop,andtheclockpulseisgeneratedbypullingthesignalSCK
firstlow,andthenhighagain.Somedelayisaddedtoadapttothespeedoftheslavedevice.Thelast
thing to do within the loop is to read the value of the signal MISO and shiftaccumulate bits in the
variableRet.
In order to write to the slave device the above function should be called, and the combined
addressanddatabytesaretobepassedastheargument.ThelistingofthefunctionSPIwritetodo
thisisshowninFig.4,top.OnlysixbitsofargumentAdrareused(thisassuresthefirsttwoofthe
string of 16 bits bits are low), they are shifted eight bits to the left, and then byte of data is added.
Thereturnvalueisignored.
Inordertoreadfromtheslavedevicetheabovefunctioniscalledinasimilarway(SPIread)but
most significant of the 16 bits is set to high by adding 8000
h
. This causes reading from the slave, so
thereturnedvalueisusedhereandreturnedtothecallingprogram.
char SPI t r ansact i on ( i nt AandD) { / / about 7us
#def i ne MOSI 0x8000
#def i ne MI SO 0x4000
#def i ne SCK 0x2000
#def i ne SEL 0x1000
i nt Ret = 0;
GPI OB- >ODR &= ~SEL; / / SPI sel ect
f or ( char k = 0; k<16; k++) { / / f or 16 bi t s
i f ( AandD & 0x8000) GPI OB- >ODR | = MOSI ; / / send addr ess & dat a
el se GPI OB- >ODR &= ~MOSI ; / /
AandD <<= 1; / / next bi t of addr ess & dat a
GPI OB- >ODR &= ~SCK; / / SCL l o
f or ( i nt i = 0; i <10; i ++) {}; / / wast e 150ns
Ret <<= 1; / / shi f t bi t s r ead r i ght
GPI OB- >ODR | = SCK; / / SCL hi
i f ( GPI OB- >I DR & MI SO) Ret ++; / / r ead bi t and add t o st r i ng
};
GPI OB- >ODR | = SEL; / / SPI done
r et ur n ( ( char ) ( Ret & 0xf f ) ) ; / / r et ur n r esul t
}
Figure3:AlistingofthefunctiontowriteorreadabyteofdatausingSPIbus
voi d SPI wr i t e( i nt Adr , i nt Dat a) {
SPI t r ansact i on( ( ( Adr & 0x3f ) << 8) + Dat a) ; / / pr epar e 16 bi t s
}

char SPI r ead( i nt Adr ) {
char Ret = SPI t r ansact i on( ( ( Adr & 0x3f ) << 8) + 0x8000) ; / / 16 bi t s
r et ur n ( Ret ) ; / / r et ur n r esul t
}
Figure4:Alistingoffunctions toutilizetheabovefunctionforwritingandreading
PlayingwithSTM32F407testboardSPICommunication
4

The complete program to read data from the accelerometer, two axess, is given in Fig. 5. The
program starts with the initialization of ports where the slave device is connected, and continues
with the initialization of the slave device and the LCD screen. Then the execution of the program
enters the endless loop, where the two bytes representing the readout from each axis of the
accelerometerarecombined(seedatasheetontheaccelerometerfordetailsandregisters)intoa16
bit result and sent to the screen. Some delay is added to ease the reading of results from the LCD
screen.
Astheinitializationisconcerned,theSPIbusisavailableattheconnectorK485.Thisisconnected
toportB(MOSIsignalatbit15,MISOsignalatbit14,SCKsignalatbit13,andSSsignalatbit12).This
portmustfirstbeactivatedbyenablingtheclockforportB,thenbits15,13,and12mustbedefined
asoutputs.Thisisdobeintwosteps;onresetofthemicrocontrollerthebit15isdefinedasalternate
function for programming purposes, and this must be disabled by clearing MS bit of the register
MODE,thenallthreebitsoftheportcanbemadeoutputs.Thefinalstepoftheinitilizationistoset
SlaveSelectandclocksignaltohighinitially.
As the initialization of the accelerometer chip is concerned, the relevan info is available in the
datasheetoftheaccelerometer.Hereweonlystatethattheaccelerometerchipmustbepoweredup
bywritingC7
h
toaddres20
h
,andthentheinternalupdatingofresultsshouldbedefinedbywritingto
address21
h
,aswellasfilteringdisabledbywritingtoaddress22
h
forthepurposeofthisexperiment.
Otherrequirementsmaybesuitableforotherpurposes.

#i ncl ude " st m32f 4xx. h"


#i ncl ude " LCD2x16. c"

voi d mai n ( ) {

/ / por t s i ni t : 15- MOSI , 14- MI SO, 13- SCK, 12- SEL
RCC- >AHB1ENR | = 0x00000002; / / Enabl e cl ock f or GPI OB
GPI OB- >MODER &= ~0x80000000; / / PB 15 => i nput pi n, no AF!
GPI OB- >MODER | = 0x45000000; / / PB 15, 13, 12 => out put s
GPI OB- >ODR | = 0xc000; / / SEL & SCK - > hi

/ / I ni t accel er omet er chi p
SPI wr i t e( 0x20, 0xc7) ; / / CR1: power - up, al l axes
SPI wr i t e( 0x21, 0x40) ; / / CR2: Bl ock dat a updat e & 12 bi t mode
SPI wr i t e( 0x22, 0x00) ; / / CR3: no f i l t er i ng

/ / I ni t LCD & pr epar e di spl ay
LCD_i ni t ( ) ; / / I ni t LCD
LCD_st r i ng( " x= mg" , 0x00) ; / / pr epar e 1st r ow
LCD_st r i ng( " y= mg" , 0x40) ; / / pr epar e 2nd r ow

/ / endl ess l oop
whi l e ( 1) {
shor t r et X = SPI r ead( 0x28) + ( SPI r ead( 0x29) << 8) ; / / x axi s, bot h byt es
LCD_sI nt 16( r et X, 0x02, 1) ; / / di spl ay r esul t
shor t r et Y = SPI r ead( 0x2a) + ( SPI r ead( 0x2b) << 8) ; / / y axi s, bot h byt es
LCD_sI nt 16( r et Y, 0x42, 1) ; / / di spl ay r esul t
f or ( i nt i =0; i <1000000; i ++) {}; / / wast e t i me, ~30ms
};
}
Figure5:AlistingoftheprogramtoreaddatafromsensorusingtheSPIbus

Potrebbero piacerti anche