In this post I’m going to show how to build a SPI receiver with Arduino. Basically I want to configure Arduino with the same SPI settings that DDS I used in the previous post has. After configure SPI in Arduino I’m going to connect it with Bus Pirate, as master device, and using it I’m going to send data, that Arduino has to show using serial port.

From Atmega reference we see that a SPI mode 2 is needed to emulate SPI mode in DDS. The following figure shows the format this working mode:

SPI Transfer Format with CPHA = 0

Taking a look to this diagram is easy to realize the way how to setup the SPI mode.

  • Select Clock Phase (CPHA) as 0
  • Select Clock Polarity (CPOL) as 1
  • Select bit Order as MSB (DORD=0)
  • Select Slave Mode (MSTR=0)

In any slave mode, the data rate is not important to setup, because the SPI Master device is the one in charge of clock generation. Doesn’t matter if the slave device is sending data to the Master throght the MISO line: the data will be provided synchronized with SCK pulses.

Let’s code!

/*
 *******************************************************
 *  Name:            SPI Slave Test    
 *
 *  Author:        Joan Martínez
 *
 *  Start Date:         1 ago 2012        
 *
 *  Version Date:       
 *
 *  Description:    Use of SPI Mode in ATmega as Slave
 *                      SCK: PB5(D13), MISO: PB4(D12),
 *                      MOSI: PB3(D11), SS: PB2(D10).
 *  Platform:           Arduino UNO, 2009,...
 *
 *******************************************************/

uint8_t c;

void setup(){
  Serial.begin(9600);
  SPI_SlaveInit(); 
  Serial.println("Ready!!");
}

void loop(){
  c=SPI_SlaveReceive();  
  Serial.print("[0x");
  Serial.print(c,HEX);
  Serial.println("]");
}

void SPI_SlaveInit(void){
 /* Enable SPI, Slave set clock and Mode */
 SPCR &= ~((1<<CPHA) | (1<<MSTR) | (1<<DORD)) ;  
 SPCR |= (1<<SPE) | (1<<CPOL);
}

uint8_t SPI_SlaveReceive(void){
  while(!(SPSR & (1<<SPIF)))
  ;
  return SPDR;
}

The code is bassically the same that can be seen in Atmega reference.

In SPI_SlaveInit we can see that there’s no setup for SS, CLK or MOSI pins. All these are input by default. Just in case we need to send data from Slave to Master we should place the following line inside the code:

 /* Set MISO output, all others input by default*/
 DDRB |= (1<<MISO);

The SPI_SlaveReceive code just waits for a 8 bit data complete in SPDR register and return this data. But also implies that SS line is hold in a low level while receiving data, because once this line raises a high level resets the SPDR registers, avoiding bad data. This is an automatic process that simplifies coding.

Using Bus Pirate lets check how it works.

Bus Pirate connected to Arduino

Sending data with Bus Pirate, we can see this data received in Arduino using the Serial Monitor.

Sending data with Bus Pirate using moserial, and receiving with Arduino

Anuncios