Ein einfaches Beispiel wie ein SPI-Master von einem SPI-Slave Daten anfragen kann ist hier zu finden: spi_slavetest.zip
In der Datei ist auch das passende Simulide File vorhanden
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
#define SET_BIT(BYTE, BIT) ((BYTE) |= (1 << (BIT)))
#define CLR_BIT(BYTE, BIT) ((BYTE) &= ~(1 << (BIT)))
#define SLAVE_REQUEST 0x11 // The value can be changed
void SPI_MasterTransmit(uint8_t data);
int main()
{ // Set the following Pins as output
DDRB = (1<<DDB2) // - !SS
|(1<<DDB3) // - MOSI
|(1<<DDB4) // - MOSI
|(1<<DDB5); // - SCK
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); // Enable SPI, Master mode, clock rate fck/16
DDRD = 0xFF; // Set PORTD as output
while(1) {
SPI_MasterTransmit(SLAVE_REQUEST); // Send request to slave
uint8_t dataFromSlave = SPDR; // Receive the answer from the slave
PORTD = dataFromSlave^0xFF; // Output the answer on PORTC, but all Bits inverted
}
}
void SPI_MasterTransmit(uint8_t data)
{
CLR_BIT(PORTB, PORTB2); // clear !SS to activate Slave
SPDR = data; // Start transmission
while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
SET_BIT(PORTB, PORTB2); // Set !SS to deactivate Slave
}
#include <avr/io.h>
#include <avr/interrupt.h>
#define SLAVE_REQUEST 0x11 // The value can be changed
volatile uint8_t dataToMaster = 0x00;
volatile uint8_t dataFromMaster = 0x00;
int main() {
DDRB = (1<<DDB4); // MISO as output
PORTD = 0xFF; // Activate all pull-up resistors for PIND, to read switch states correctly
SPCR = (1<<SPE)|(1<<SPIE); // Enable SPI and SPI interrupt
sei(); // Enable global interrupts
while(1)
{
// Main application code
}
}
ISR(SPI_STC_vect) {
dataFromMaster = SPDR;
if (dataFromMaster == SLAVE_REQUEST)
{
dataToMaster=PIND;
SPDR = dataToMaster; // Load data into the buffer
}
}