Вы находитесь на странице: 1из 16

Transmisie octet pe interfata SPI

// transmit byte serially, MSB first


void send_8bit_serial_data(unsigned char data)
{
int i;
// select device
output_high(SD_CS);
// send bits 7..0
for (i = 0; i < 8; i++)
{
// consider leftmost bit
// set line high if bit is 1, low if bit is 0
if (data & 0x80)
output_high(SD_DI);
else
output_low(SD_DI);
// pulse clock to indicate that bit value should be read
output_low(SD_CLK);
output_high(SD_CLK);
// shift byte left so next bit will be leftmost
data <<= 1;
}

// deselect device
output_low(SD_CS);

Manipulare biti in C
bit_fld =variabila de 8 biti

Setarea unui bit :


Stergerea unui bit:
Inversarea unui bit:
Testare unui bit :

bit_fld |= (1 << n) (bitul n este pus pe 1)


bit_fld &= ~(1 << n)(bitul n e pus pe 0)
bit_fld ^= (1 << n) (bitul n este inversat)
bit_fld & (1 << n) (bitul n este testat )

Serial Communication is one of the most widely used methods of


communications is microcontrollers. It provides a low cost solution for
interfacing with the PC. Most of the micro controllers have one UART port, some
have two UART ports but some lower end microcontrollers do not have a single
UART port. Serial communication is also used for interfacing modules like GSM
modems, GPS modules, RFID reader etc so what if you are using 8051 based
controller and has just one UART port and want to serially interface more
than one device to the same controller?
You can use a method called as BIT BANGING. Bit Banging basically uses
Software for communication instead of a dedicated hardware. In this method
Transmitting is done by alternating the Transmit Pin after specific interval, this
time interval depends on the Baud rate for serial communication. In same way
Receive function is performed by sampling the pin at regular interval. This is
quite a tedious process and puts too much load the Micro controller processing.
Over here I will be explaining how to send and receive a byte using this
method. This polling interval is decided by the communication Baud rate e.g. if
the baud rate is 9600 bps then the polling interval will be 1/9600 seconds
i.e.104S.

Figure 1
Figure 1 shows the basic Frame for serial communication. You can see the basic
frame consists of Start Bit which is followed by the Data and end of
transmission is indicated by a Stop Bit.

ALGORITHM for Sending Byte:1.

Start.

2.

Make Tx pin Low (Stop Bit).

3.

Wait for duration corresponding to baud rate.

4.

Send data bit.

5.

Wait for duration corresponding to baud rate.

6.

Go to 4 till all eight data bits havent been sent.

7.

Send Stop Bit

8.

Wait for duration corresponding to baud rate.

9.

Make Tx pin High

10.

Stop

Receiving a byte is more difficult than sending it. Since it is not possible to
continuously poll the Rx pin we will be using external interrupt function for
detecting the START bit of serial communication. Once this START bit has been
detected we poll the Rx pin at regular interval.
We will be using P3.2 (INT0) as the Rx pin so that we can use the External
Interrupt 0 to detect the Start Bit. Normally the Rx pin is high so when the pin
becomes low i.e. Start Bit is received an interrupt is generated. The controller
then deactivates the External Interrupts and starts polling the Rx pin at regular
interval after getting next eight bits we confirm the receiving of the Stop bit
and the External Interrupt 0 is activated again for receiving the next byte.

ALGORITHM for Receiving Byte:1.

Start.

2.

Turn ON External Interrupt 0.

3.

Wait for External Interrupt 0.

4.

Confirm Rx Pin is Low (Start Bit).

5.

Wait for duration corresponding to baud rate.

6.

Get Rx pins status.

7.

Go to 5 till eight bits havent been read.

8.

Wait for duration corresponding to baud rate.

9.

Check for stop bit.

10.

Stop

I2C is a MULTI MASTER SERIAL BUS i.e. more than one


device capable of controlling the bus can be connected to it. It
was invented by PHILIPS & stands for Inter-Integrated Circuit.
In I2C only two bi-directional lines Serial Data (SDA) & Serial
Clock (SCL) are required to carry information between the
devices connected to the bus. Each I2C device is recognized by a
unique 7-bit address. The device that initiates the
communication is called MASTER. The master controls the clock
signal. Whereas the device being addressed by the Master is
called as SLAVE.Generation of clock signals on the I2C-bus is
always the responsibility of master devices; each master
generates its own clock signals when transferring data on the
bus.
Data on the I2C bus can be transferred in three modes:
1) Standard Mode: 100kbps.
2) Fast Mode: 400kbps
3) High Speed Mode: 3.4Mbps.
The maximum number of nodes is obviously limited by the address space, and also by the total bus capacitance of 400 pf.

COMMUNICATION
The master begins the communication by issuing the START condition followed by 7- bit unique address/Control Byte of the
device it wants to access.The eighth bit after the start specifies if the slave is now to receive (0) or to transmit (1). After
reciving the address all IC's on the I2C bus will compare with their own address & if the address does not match, it will wait
till a STOP is received. If address matches a ACKNOWLEDGE signal is generated by the Slave.

Following receipt of the slaves address acknowledgment, the master continues with the data transfer. If a write
operationhas been ordered, the master transmits the remaining data, with the slave acknowledging receipt of each byte. If
the master has ordered a read operation, it releases the data line and clocks in data sent by the slave. After each byte is
received, the master generates an acknowledge condition on the bus. The acknowledge is omitted following receipt of the
last byte. The master terminates all operations by generating a stop condition on the bus. The master may also abort a data
transfer at any time by generating a stop condition.

BUS CHARACTERISTIC

1. BUS NOT BUSY


BOTH Data & Clock lines remain high.
2. START CONDITION
A HIGH to LOW transition of SDA line while the SCL is high.
3. STOP CONDITION
A LOW to HIGH transition of SDA line while the SCL is high.
4. DATA VALID
During Data transfer, the data on must be changed during the LOW period of the
clock signal i.e. the data line must remain stable whenever the clock line is HIGH.
Any change in data line while clock is HIGH will be interpreted as START or STOP
condition.
5. ACKNOWLEDGE
Each device when addressed to has to generate an acknowledge signal after the
reception of each byte. The master generated an extra clock pulse which is
associated with the ACKNOWLEDGE bit. The device that acknowledges pulls down

the SDA line during the acknowledge clock pulse.


Pseudocodul pentru I2C
// Hardware-specific support functions that MUST be customized:
#define I2CSPEED 100
void I2C_delay() { volatile int v; int i; for (i=0; i < I2CSPEED/2; i++) v; }
bool read_SCL(void); // Set SCL as input and return current level of line, 0 or 1
bool read_SDA(void); // Set SDA as input and return current level of line, 0 or 1
void clear_SCL(void); // Actively drive SCL signal low
void clear_SDA(void); // Actively drive SDA signal low
void arbitration_lost(void);
bool started = false; // global data
void i2c_start_cond(void) {
if (started) { // if started, do a restart cond
// set SDA to 1
read_SDA();
I2C_delay();
while (read_SCL() == 0) { // Clock stretching
// You should add timeout to this loop
}
// Repeated start setup time, minimum 4.7us
I2C_delay();
}
if (read_SDA() == 0) {
arbitration_lost();
}
// SCL is high, set SDA from 1 to 0.
clear_SDA();
I2C_delay();
clear_SCL();
started = true;
}
void i2c_stop_cond(void){
// set SDA to 0
clear_SDA();
I2C_delay();
// Clock stretching
while (read_SCL() == 0) {
// add timeout to this loop.
}
// Stop bit setup time, minimum 4us
I2C_delay();
// SCL is high, set SDA from 0 to 1
if (read_SDA() == 0) {
arbitration_lost();
}
I2C_delay();
started = false;
}
// Write a bit to I2C bus
void i2c_write_bit(bool bit) {
if (bit) {
read_SDA();
} else {
clear_SDA();
}
I2C_delay();
while (read_SCL() == 0) { // Clock stretching
// You should add timeout to this loop
}
// SCL is high, now data is valid
// If SDA is high, check that nobody else is driving SDA
if (bit && read_SDA() == 0) {
arbitration_lost();
}
I2C_delay();
clear_SCL();

}
// Read a bit from I2C bus
bool i2c_read_bit(void) {
bool bit;
// Let the slave drive data
read_SDA();
I2C_delay();
while (read_SCL() == 0) { // Clock stretching
// You should add timeout to this loop
}
// SCL is high, now data is valid
bit = read_SDA();
I2C_delay();
clear_SCL();
return bit;
}
// Write a byte to I2C bus. Return 0 if ack by the slave.
bool i2c_write_byte(bool send_start,
bool send_stop,
unsigned char byte) {
unsigned bit;
bool nack;
if (send_start) {
i2c_start_cond();
}
for (bit = 0; bit < 8; bit++) {
i2c_write_bit((byte & 0x80) != 0);
byte <<= 1;
}
nack = i2c_read_bit();
if (send_stop) {
i2c_stop_cond();
}
return nack;
}
// Read a byte from I2C bus
unsigned char i2c_read_byte(bool nack, bool send_stop) {
unsigned char byte = 0;
unsigned bit;
for (bit = 0; bit < 8; bit++) {
byte = (byte << 1) | i2c_read_bit();
}
i2c_write_bit(nack);
if (send_stop) {
i2c_stop_cond();
}
return byte;
}

Using the I2C Bus

Using the I2C Bus


Judging from my emails, it is quite clear that the I2C bus can be very confusing for the newcomer. I have lots of examples on using the I2C bus on the website, but many of
these are using high level controllers and do not show the detail of what is actually happening on the bus. This short article therefore tries to de-mystify the I2C bus, I hope it
doesn't have the opposite effect!

The physical I2C bus


This is just two wires, called SCL and SDA. SCL is the clock line. It is used to synchronize all data transfers over the I2C bus. SDA is the data line. The SCL & SDA lines are
connected to all devices on the I2C bus. There needs to be a third wire which is just the ground or 0 volts. There may also be a 5volt wire is power is being distributed to the
devices. Both SCL and SDA lines are "open drain" drivers. What this means is that the chip can drive its output low, but it cannot drive it high. For the line to be able to go
high you must provide pull-up resistors to the 5v supply. There should be a resistor from the SCL line to the 5v line and another from the SDA line to the 5v line. You only
need one set of pull-up resistors for the whole I2C bus, not for each device, as illustrated below:

The value of the resistors is not critical. I have seen anything from 1k8 (1800 ohms) to 47k (47000 ohms) used. 1k8, 4k7 and 10k are common values, but anything in this
range should work OK. I recommend 1k8 as this gives you the best performance. If the resistors are missing, the SCL and SDA lines will always be low - nearly 0 volts - and
the I2C bus will not work.

Masters and Slaves


The devices on the I2C bus are either masters or slaves. The master is always the device that drives the SCL clock line. The slaves are the devices that respond to the
master. A slave cannot initiate a transfer over the I2C bus, only a master can do that. There can be, and usually are, multiple slaves on the I2C bus, however there is normally
only one master. It is possible to have multiple masters, but it is unusual and not covered here. On your robot, the master will be your controller and the slaves will be our
modules such as the SRF08 or CMPS03. Slaves will never initiate a transfer. Both master and slave can transfer data over the I2C bus, but that transfer is always controlled
by the master.

The I2C Physical Protocol


When the master (your controller) wishes to talk to a slave (our CMPS03 for example) it begins by issuing a start sequence on the I2C bus. A start sequence is one of two
special sequences defined for the I2C bus, the other being the stop sequence. The start sequence and stop sequence are special in that these are the only places where the
SDA (data line) is allowed to change while the SCL (clock line) is high. When data is being transferred, SDA must remain stable and not change whilst SCL is high. The start
and stop sequences mark the beginning and end of a transaction with the slave device.

Data is transferred in sequences of 8 bits. The bits are placed on the SDA line starting with the MSB (Most Significant Bit). The SCL line is then pulsed high, then low.
Remember that the chip cannot really drive the line high, it simply "lets go" of it and the resistor actually pulls it high. For every 8 bits transferred, the device receiving the data
sends back an acknowledge bit, so there are actually 9 SCL clock pulses to transfer each 8 bit byte of data. If the receiving device sends back a low ACK bit, then it has
received the data and is ready to accept another byte. If it sends back a high then it is indicating it cannot accept any further data and the master should terminate the
transfer by sending a stop sequence.

How fast?
The standard clock (SCL) speed for I2C up to 100KHz. Philips do define faster speeds: Fast mode, which is up to 400KHz and High Speed mode which is up to 3.4MHz. All
of our modules are designed to work at up to 100KHz. We have tested our modules up to 1MHz but this needs a small delay of a few uS between each byte transferred. In
practical robots, we have never had any need to use high SCL speeds. Keep SCL at or below 100KHz and then forget about it.

I2C Device Addressing


All I2C addresses are either 7 bits or 10 bits. The use of 10 bit addresses is rare and is not covered here. All of our modules and the common chips you will use will have 7 bit
addresses. This means that you can have up to 128 devices on the I2C bus, since a 7bit number can be from 0 to 127. When sending out the 7 bit address, we still always
send 8 bits. The extra bit is used to inform the slave if the master is writing to it or reading from it. If the bit is zero the master is writing to the slave. If the bit is 1 the master is
reading from the slave. The 7 bit address is placed in the upper 7 bits of the byte and the Read/Write (R/W) bit is in the LSB (Least Significant Bit).

The placement of the 7 bit address in the upper 7 bits of the byte is a source of confusion for the newcomer. It means that to write to address 21, you must actually send out
42 which is 21 moved over by 1 bit. It is probably easier to think of the I2C bus addresses as 8 bit addresses, with even addresses as write only, and the odd addresses as
the read address for the same device. To take our CMPS03 for example, this is at address 0xC0 ($C0). You would uses 0xC0 to write to the CMPS03 and 0xC1 to read from
it. So the read/write bit just makes it an odd/even address.

The I2C Software Protocol


The first thing that will happen is that the master will send out a start sequence. This will alert all the slave devices on the bus that a transaction is starting and they should
listen in incase it is for them. Next the master will send out the device address. The slave that matches this address will continue with the transaction, any others will ignore
the rest of this transaction and wait for the next. Having addressed the slave device the master must now send out the internal location or register number inside the slave
that it wishes to write to or read from. This number is obviously dependant on what the slave actually is and how many internal registers it has. Some very simple devices do
not have any, but most do, including all of our modules. Our CMPS03 has 16 locations numbered 0-15. The SRF08 has 36. Having sent the I2C address and the internal
register address the master can now send the data byte (or bytes, it doesn't have to be just one). The master can continue to send data bytes to the slave and these will
normally be placed in the following registers because the slave will automatically increment the internal register address after each byte. When the master has finished writing
all data to the slave, it sends a stop sequence which completes the transaction. So to write to a slave device:
1. Send a start sequence
2. Send the I2C address of the slave with the R/W bit low (even address)
3. Send the internal register number you want to write to
4. Send the data byte
5. [Optionally, send any further data bytes]
6. Send the stop sequence.

As an example, you have an SRF08 at the factory default address of 0xE0. To start the SRF08 ranging you would write 0x51 to the command register at 0x00 like this:
1. Send a start sequence
2. Send 0xE0 ( I2C address of the SRF08 with the R/W bit low (even address)
3. Send 0x00 (Internal address of the command register)
4. Send 0x51 (The command to start the SRF08 ranging)
5. Send the stop sequence.

Reading from the Slave


This is a little more complicated - but not too much more. Before reading data from the slave device, you must tell it which of its internal addresses you want to read. So a
read of the slave actually starts off by writing to it. This is the same as when you want to write to it: You send the start sequence, the I2C address of the slave with the R/W bit
low (even address) and the internal register number you want to write to. Now you send another start sequence (sometimes called a restart) and the I2C address again - this
time with the read bit set. You then read as many data bytes as you wish and terminate the transaction with a stop sequence. So to read the compass bearing as a byte from
the CMPS03 module:
1. Send a start sequence
2. Send 0xC0 ( I2C address of the CMPS03 with the R/W bit low (even address)
3. Send 0x01 (Internal address of the bearing register)
4. Send a start sequence again (repeated start)
5. Send 0xC1 ( I2C address of the CMPS03 with the R/W bit high (odd address)
6. Read data byte from CMPS03
7. Send the stop sequence.

The bit sequence will look like this:

Wait a moment
That's almost it for simple I2C communications, but there is one more complication. When the master is reading from the slave, its the slave that places the data on the SDA
line, but its the master that controls the clock. What if the slave is not ready to send the data! With devices such as EEPROMs this is not a problem, but when the slave
device is actually a microprocessor with other things to do, it can be a problem. The microprocessor on the slave device will need to go to an interrupt routine, save its
working registers, find out what address the master wants to read from, get the data and place it in its transmission register. This can take many uS to happen, meanwhile the
master is blissfully sending out clock pulses on the SCL line that the slave cannot respond to. The I2C protocol provides a solution to this: the slave is allowed to hold the SCL
line low! This is called clock stretching. When the slave gets the read command from the master it holds the clock line low. The microprocessor then gets the requested data,
places it in the transmission register and releases the clock line allowing the pull-up resistor to finally pull it high. From the masters point of view, it will issue the first clock
pulse of the read by making SCL high and then check to see if it really has gone high. If its still low then its the slave that holding it low and the master should wait until it goes
high before continuing. Luckily the hardware I2C ports on most microprocessors will handle this automatically.

Sometimes however, the master I2C is just a collection of subroutines and there are a few implementations out there that completely ignore clock stretching. They work with
things like EEPROM's but not with microprocessor slaves that use clock stretching. The result is that erroneous data is read from the slave. Beware!

Example Master Code


This example shows how to implement a software I2C master, including clock stretching. It is written in C for the PIC processor, but should be applicable to most processors
with minor changes to the I/O pin definitions. It is suitable for controlling all of our I2C based robot modules. Since the SCL and SDA lines are open drain type, we use the
tristate control register to control the output, keeping the output register low. The port pins still need to be read though, so they're defined as SCL_IN and SDA_IN. This
definition and the initialization is probably all you'll need to change for a different processor.

#define
#define
#define
#define

SCL
TRISB4 // I2C bus
SDA
TRISB1 //
SCL_IN RB4 //
SDA_IN RB1 //

To initialize the ports set the output resisters to 0 and the tristate registers to 1 which disables the outputs and allows them to be pulled high by the resistors.
SDA = SCL = 1;
SCL_IN = SDA_IN = 0;
We use a small delay routine between SDA and SCL changes to give a clear sequence on the I2C bus. This is nothing more than a subroutine call and return.
void i2c_dly(void)
{
}

The following 4 functions provide the primitive start, stop, read and write sequences. All I2C transactions can be built up from these.
void i2c_start(void)
{
SDA = 1;
// i2c start bit sequence
i2c_dly();
SCL = 1;
i2c_dly();
SDA = 0;
i2c_dly();
SCL = 0;
i2c_dly();
}
void i2c_stop(void)
{
SDA = 0;
// i2c stop bit sequence
i2c_dly();
SCL = 1;
i2c_dly();
SDA = 1;
i2c_dly();

unsigned char i2c_rx(char ack)


{
char x, d=0;
SDA = 1;
for(x=0; x<8; x++) {
d <<= 1;
do {
SCL = 1;
}
while(SCL_IN==0); // wait for any SCL clock stretching
i2c_dly();
if(SDA_IN) d |= 1;
SCL = 0;
}
if(ack) SDA = 0;
else SDA = 1;
SCL = 1;
i2c_dly();
// send (N)ACK bit
SCL = 0;
SDA = 1;
return d;
}

bit i2c_tx(unsigned char d)


{
char x;
static bit b;
for(x=8; x; x--) {
if(d&0x80) SDA = 1;
else SDA = 0;
SCL = 1;
d <<= 1;
SCL = 0;
}
SDA = 1;
SCL = 1;
i2c_dly();
b = SDA_IN;
// possible ACK bit
SCL = 0;
return b;
}
The 4 primitive functions above can easily be put together to form complete I2C transactions. Here's and example to start an SRF08 ranging in cm:

i2c_start();
i2c_tx(0xE0);
i2c_tx(0x00);
i2c_tx(0x51);
i2c_stop();

// send start sequence


// SRF08 I2C address with R/W bit clear
// SRF08 command register address
// command to start ranging in cm
// send stop sequence

Now after waiting 65mS for the ranging to complete (I've left that to you) the following example shows how to read the light sensor value from register 1 and the range result
from registers 2 & 3.
i2c_start();
// send start sequence
i2c_tx(0xE0);
// SRF08 I2C address with R/W bit clear
i2c_tx(0x01);
// SRF08 light sensor register address
i2c_start();
// send a restart sequence
i2c_tx(0xE1);
// SRF08 I2C address with R/W bit set
lightsensor = i2c_rx(1); // get light sensor and send acknowledge. Internal register address will increment automatically.
rangehigh = i2c_rx(1); // get the high byte of the range and send acknowledge.
rangelow = i2c_rx(0);
// get low byte of the range - note we don't acknowledge the last byte.
i2c_stop();
// send stop sequence

Easy isn't it?

The definitive specs on the I2C bus can be found on the Philips website. It currently here but if its moved you'll find it easily be googleing on "i2c bus specification".

O alta implementare in C pentru I2C


1.

#define SDA P0_0

2.

#define SCL P0_1

3.
4.

void I2CInit(){

5.

SDA = 1;

6.

SCL = 1;

7.

8.
9.

void I2CStart(){

10.

SCL = 1;

11.

SDA = 0;

12.

SCL = 0;

13.

14.
15.

void I2CRestart(){

16.

SDA = 1;

17.

SCL = 1;

18.

SDA = 0;

19.

20.
21.

void I2CStop(){

22.

SDA = 0;

23.

SCL = 1;

24.

SDA = 1;

25.

26.
27.

void I2CAck(){

28.

SDA = 0;

29.

SCL = 1;

30.

SCL = 0;

31.

32.
33.

void I2CNak(){

34.

SDA = 1;

35.

SCL = 1;

36.

SCL = 0;

37.

38.
39.

unsigned char I2CSend(unsigned char Data){

40.

unsigned char i, ack_bit;

41.

for(i=0;i<8;i++){

42.

SCL = 0;

43.

if ((Data & 0x80) == 0)

44.

SDA = 0;

45.

else

46.

SDA = 1;

47.

SCL = 1;

48.

Data<<=1;

49.

50.

SCL = 0;

51.

ack_bit = SDA;

52.

SCL = 1;

53.

SCL = 0;

54.

return !ack_bit;

55.

56.
57.

unsigned char I2CRead(){

58.

unsigned char i, Data=0;

59.

for(i=0;i<8;i++){

60.

SCL = 0;

61.

SCL = 1;

62.

if(SDA)

63.

Data |=1;

64.

if(i<7)

65.

Data<<=1;

66.

67.

SCL = 0;

68.

SDA = 1;

69.

return Data;

70.

71.

Implementare cu Arduino si Wire


Master :
#include <Wire.h>
#define LED_PIN 13
byte x = 0;
void setup()
{
Wire.begin(); // Start I2C Bus as Master
pinMode(LED_PIN, OUTPUT);

digitalWrite(LED_PIN, LOW);
}
void loop()
{
Wire.beginTransmission(9); // transmit to device #9
Wire.send(x);
// sends x
Wire.endTransmission();
// stop transmitting
x++;
if (x > 5) x=0;
delay(450);
}

SLAVE: (la slave apare adresa de SLAVE in Wire.begin(slave_adress))


#include <Wire.h>
#define LED_PIN 13
#define LED_1 12
#define LED_2 11
int x;
void setup() {
Wire.begin(9);
// Start I2C Bus as a Slave (Device Number 9)
Wire.onReceive(receiveEvent); // register event
pinMode(LED_PIN, OUTPUT);
pinMode(LED_1, OUTPUT);
pinMode(LED_2, OUTPUT);
digitalWrite(LED_PIN, LOW);
digitalWrite(LED_1, LOW);
digitalWrite(LED_2, LOW);
}

x = 0;

void loop() {
//If value received is 0 blink LED 1
if (x == 0) {
digitalWrite(LED_1, HIGH);
delay(200);
digitalWrite(LED_1, LOW);
delay(200);
}
//If value received is 1 blink LED 2
if (x == 1) {
digitalWrite(LED_2, HIGH);
delay(200);
digitalWrite(LED_2, LOW);
delay(200);
}
}

void receiveEvent(int howMany) {


x = Wire.receive();
// receive byte as an integer
}

Serial Peripheral Interface or SPI bus is a synchronous serial bus standard


established by MOTOROLA. It is a 4 wire MASTER-SLAVE serial interface that
operates in Full Duplex. The SPI bus can support up to 10Mbps.
SPI Specifies four Signals:
1) Clock: SCK/SCLK : Serial Clock (Output by Master).
2) Chip Select/Slave Select: CS/SS (active low output from Master).
3) Serial Data IN/Master Output, Slave Input: SDI/MOSI.
4) Serial Data Out/Master Input, Slave Output: SDO/MISO.

SPI Signals

The SPI bus can operate with a single master device and with one or more slave devices. If the devices on the SPI bus have a chip-select signal
it is possible to connect many ICs to the same SPI bus in parallel. With multiple slave devices, an independent SS signal is required from the
master for each slave device. Devices have tri-state outputs that become high impedance ("disconnected") when the device is not selected, so
that it does not interfere with the currently activated devices. When cascading several SPI devices, they are treated as one slave and therefore
connected to the same chip select. Only one slave may talk to the master at any time, and only its SS may be activated by pulling the Slave
Select LOW.

cascading of several SPI devices


During each SPI clock cycle, a full duplex data transmission occurs:

Master sends a bit on the MOSI line; the slave reads it from that same line.

Slave sends a bit on the MISO line; the master reads it from that same line.

DISADVANTAGE OF SPI
1)Every IC connected to bus needs its own chip-select signal line. Thus, when 10 devices are on the bus, 10 chip-select lines, in addition to the
shared clock and data lines, are needed to select the appropriate device.
2)SPI does not have an acknowledgement mechanism to confirm receipt of data. If the SPI device is of output type then the SPI master may
have no knowledge of whether a slave even exists. Basically SPI offers no hardware flow control.

Вам также может понравиться