IOT

ATtiny85 SPI protocol – Master and Slave mode tutorial

Serial communication protocols enable microcontrollers to connect with external hardware, peripherals, and other microcontrollers. In the embedded environment, USART, SPI, and I2C are prominent serial communication protocols. The ATtiny85 microcontroller features a Universal Serial Interface USI module to simplify serial communication. This USI module is compatible with I2C and SPI protocols. This article describes how to operate an ATtiny85 in SPI master and slave mode.

SPI protocol or Three-wire Synchronous data transfer mode:

SPI is a type of serial communication that transfers data using three pins. In SPI communication, master and slave roles are assumed by the communicating devices. To synchronize the communication, it is the master device’s responsibility to generate the clock pulse. DO (PB1), DI (PB0), and USCK are the three required SPI communication pins in ATtiny85 (PB2). Additionally, if numerous slave devices are engaged in the communication, the Slave Select (SS) pin can be specified in the code. Learn about SPI communication in-depth on this page.

Timing diagram of SPI protocol in ATtiny85:

The following timing diagram provides an overview of SPI communication in ATtiny85. USCK is the clock cycle used to synchronize device communication. It could be either external or interior ( generated by the master device ). The length of the data register associated with SPI communication is 8 bits. DO represents the data that leaves the sender device, beginning with MSB. The data indicated by the DI displayed above is received by the receiver device beginning with the MSB.

Data that must be sent must be placed in the USIDR (USI data register) at least a half-clock prior to the generation of the USCK clock and the beginning of sampling, as indicated by the intersection of points A and B in the picture above. Also, during data reception, the MSB should be held in the DI pin for half a clock cycle prior to USCK sampling. This ensures that data bits are sent and received in synchronization with the clock pulse. Each clock pulse will be sampled at the clock’s rising and falling edges. A 16-bit counter that increments with every sample ( rising and falling edges of clock pulse ).

The data bits 6, 5, 4,… will be transmitted and received in synchronization with the trailing clock pulses. At the conclusion of the eighth clock pulse (point E in the picture above), all eight bits will have been transmitted or received, and the counter will have reached its maximum value. Once it reaches its maximum value The counter overflow flag is set to indicate that the data transfer is complete and that the next byte may be transmitted or received via the data lines.

Slave select in ATtiny85:

Slave select is the SPI function utilized when a single master must connect with many slaves. For the purpose of slave selection, a specific master device pin must be assigned. If a master has to communicate with two slave devices, it must allocate two slaves choose pins. When a master device wishes to send or receive data from a slave-1 device, it will pull the slave choose pin corresponding to the slave-1 device low. The master and slave-1 can now converse with one another.

There is no specific slave select pin on the ATtiny85. It must be set up via software, meaning that if your device is a slave, you must assign an IO pin as an input and activate the SPI communication when the input goes low. To establish communication with a slave device, you must assign an IO pin as output and pull it low if your device is a master.

USICR ( USI Control Register )

The bits USIWM1 and USIWM0 in the USICR register are used to configure the USI module to operate via the SPI or I2C protocols. The table below displays the bit settings for selecting SPI communication.

USIWM1 and USIWM0 must be set to 0 and 1 respectively for our USI module to operate in SPI mode.

The USICS0, USICS1, and USICLK bits are utilized to select the clock for SPI communication. The table below illustrates the various clock sources that can be used for our SPI communication and clock to power a 4-bit counter, which is responsible for keeping track of sent and received data ( explained below ).

Possible clock sources include a software-generated clock via the USICLK bit, an external clock to the USCK or PB2 pin, and a Timer/ Counter0 compare match. This article will demonstrate the use of Software to create a clock strobe ( USICLK ).

When the USICLK bit is set to 1, an internal single clock transition is generated to power SPI communication. This permits the USIDR register to transmit or receive a single bit of data. In order to send or receive a byte of data, a bit must be written high 16 times.

USITC is a bit responsible for creating clock pulse if our microcontroller is acting as the master to generate clock pulse. Writing this bit toggles the logic state of the USCK pin between 0 and 1 and 0 and 0. This facilitates the generation of clock pulses and the synchronization of data transfer with slave devices.

USIDR ( USI Data register ):

This is the real register that stores the data that must be transmitted and the data received from other devices. The user must write 8-bit data into this register before transmitting it by triggering clock pulses to synchronize the transfer. In a similar fashion, when the ATtiny85 gets the data, each bit is stored in the USIDR register. When a byte transfer is complete, the contents of the USIDR register will be copied to the USIBR register.

USIBR ( USI Buffer register ):

It is comparable to the USI data registry. When the data transfer is complete, the contents of USIDR will be copied to USI Buffer. This allows the user time to read the data during time-sensitive data transfers.

USISR ( USI status register ):

Status register is used to identify the status of the USI peripheral. The bits USICNT0, USICNT1, USICNT2, and USICNT3 are dedicated counter bits that keep count of the data transfer. It does that by incrementing by one per raising and falling edge of the clock pulse. 4 bits are dedicated for this counter, so the count data will overflow after counting to 16, that is this counter will overflow after transmission of every byte.

In this register, USIOIF bit is an overflow flag bit that will overflow when the above counter overflows after reaching the 16 value. This flag will be read as one after a data byte transfer is completed.

Circuit diagram – ATtiny85 MCUs as Master and Slave:

attiny85-spi-protocol-master-slave-device

In this setup, U1 acts like the Master, and U2 will be the slave. U1 generates a clock pulse to synchronize this SPI protocol communication.

Steps to configure ATtiny85 and send data as master using SPI protocol:

  1. Set the output, input, and input states of pins DO (PB0), DI (PB1), and USCK (PB2) using the data direction register DDRB.
  2. Using the USIWM1 and USIWM0 bits in the USICR register, the three-wire mode, or SPI, is selected.
  3. Place the data byte to be transmitted to the slave in the USIDR register.
  4. The bits USICS1, USICS0, and USICLK are used to time the data transfer. In this lesson, the Software strobe will serve as the clock, thus these three bits will be expressed as 001.
  5. Set the USITC bit to 1 to toggle the USICLK pin, which will function as the slave’s clock source.
  6. Repeat steps 4 and 5 until the USIOIF flag is raised to conclude the transfer of one byte of data.
  7. Write the following byte to the USID register
  8. Repetition of steps 4 and 5

Sample Code for ATtiny85 as SPI master device:

#include<avr/io.h>String tosend=”Test”;
void spi_setup(){ DDRB=(1<<PB1)|(1<<PB2); //Setting direction of PB1 and PB2 as output USICR=(1<<USI#include<avr/io.h>
String tosend=”Test”;

void spi_setup()
{
DDRB=(1<<PB1)|(1<<PB2); //Setting direction of PB1 and PB2 as output
USICR=(1<<USIWM0); //Choosing SPI aka three wire mode
}

int main()
{
short int i=0;
spi_setup();
for(i=0;i<=3;i++)
{
USIDR=tosend[i]; //Writing data bytes in Data register
while(USIOIF==0) //Checking USI data counter overflow flag to detect the end of transmission every byte
{
USICR|=(1<<USICLK)|(1<<USITC); //Enabling clock for transmission and generating clock for slave device
}
USISR|=(1<<USIOIF); //Clearing counter overflow flag
}
}
WM0); //Choosing SPI aka three wire mode}

int main(){ short int i=0; spi_setup(); for(i=0;i<=3;i++) { USIDR=tosend[i]; //Writing data bytes in Data register while(USIOIF==0) //Checking USI data counter overflow flag to detect the end of transmission every byte { USICR|=(1<<USICLK)|(1<<USITC); //Enabling clock for transmission and generating clock for slave device } USISR|=(1<<USIOIF); //Clearing counter overflow flag }}

ATtiny85 as SPI slave:

To configure SPI as a slave device, its USICS0, USICS1, and USCLK bits must be configured to accept external clock pulses from the master device. USCK or PB2 must receive the input clock signal from the master device. The DDRB register must be used to set this pin’s orientation to input.

Steps to configure ATtiny85 to receive data as SPI slave:

  1. Set the output, input, and input states of pins DO (PB0), DI (PB1), and USCK (PB2) using the data direction register DDRB.
  2. Using the USIWM1 and USIWM0 bits in the USICR register, the three-wire mode, or SPI, is selected.
  3. Choose the External positive edge and external edges as the clock source for a 4-bit counter.
  4. Wait until the USIOIF flag becomes high, indicating that one byte has been received.
  5. Copy the USIBR register data for processing.
  6. Repeat step four.

Sample Code for ATtiny85 as SPI slave device:


#include<avr/io.h>
String received[200];

void spi_setup()
{
DDRB=(1<<PB1); //Setting direction of PB1
USICR=(1<<USIWM0); //Choosing SPI aka three wire mode
}

int main()
{
int i=0;
spi_setup();
while(1)
{
if((USISR&(1 << USIOIF))==1) //Checking USI data counter overflow flag to detect the end of transmission every byte
{
received[i]=USIBR; //Reading received byte from USIBR buffer register
if(i<200)
i=i+9;
else
i=0;
USISR|=(1<<USIOIF); //Clearing counter overflow flag
}
}
}

Try this out:

  • Configure two ATtiny85 devices, one as the master and the other as the slave. Write code for both Master and slave devices with slave select capability.
  • The Master device should send “Welcome” and the Slave should answer “Ok” when data is successfully received.

Conclusion

I hope all of you got an idea of the ATtiny85 SPI protocol – Master and Slave mode tutorial. Hope all of you find this article informative. For more queries, contact our online store-MATHA ELECTRONICS

Leave a Reply

Your email address will not be published.