I'm trying to implement an SPI protocol with multiple slaves. I'm currently working with only two slaves and a master. Each slave has their own button which the user can press. What I want to do is this: When the user presses a button, the respective slave will send an acknowledgement to the master and master will blink an LED indicating it has receives acknowledgement from that particular slave.
Here's my code so far:
Code for master:
#define F_CPU 1e6 #include <avr/io.h> #include <util/delay.h> #define ACK_Slave1 0x7D #define ACK_Slave2 0x7E #define MOSI_PIN DDB5 #define SCK_PIN DDB7 #define SLAVE_SELECT1 DDB4 #define SLAVE_SELECT2 DDB3 /** * set SPI enable (SPE), set MC as master (MSTR) * set serial clock freqeuncy (prescalar) = f_osc / 16 ; (SPR1 and SPI2X being 0 , f_osc --> internal clock/crystal frequency) * MOSI, SCK & Slave Select as output * We have to set SS as output for master */ void SPI_Master_Init(void){ DDRB |= (1 << MOSI_PIN) | (1 << SCK_PIN) | (1 << SLAVE_SELECT1) | (1 << SLAVE_SELECT2); PORTB &= ~(1 << SLAVE_SELECT1); PORTB &= ~(1 << SLAVE_SELECT2); SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0); } /** * Load data in the buffer (SPI data register / shift register) * Wait until data transmission is complete * return received data */ unsigned char SPI_Transceiver(unsigned char data){ SPDR = data; while(!(SPSR & (1 << SPIF))); return SPDR; } int main(void){ SPI_Master_Init(); DDRD |= (1 << DDD0) | (1 << DDD1); PORTD &= 0x00; // clear output unsigned char data; while (1) { data = 0x00; data = SPI_Transceiver('1'); if(data == ACK_Slave1){ PORTD |= (1 << DDD0); _delay_ms(1000); PORTD &= ~(1 << DDD0); _delay_ms(1000); } if(data == ACK_Slave2){ PORTD |= (1 << DDD1); _delay_ms(1000); PORTD &= ~(1 << DDD1); _delay_ms(1000); } } _delay_ms(500); }
Code for slaves:
#define F_CPU 1e6 #include <avr/io.h> #include <util/delay.h> #define ACK_Slave1 0x7D #define ACK_Slave2 0x7E #define MISO_PIN DDB6 #define SLAVE_SELECT DDB4 /** * MISO as output * enable SPI enable * */ void SPI_Slave_init(void){ DDRB |= (1 << MISO_PIN); SPCR = (1 << SPE); } /** * Load data in the buffer (SPI data register / shift register) * Wait until data transmission is complete * return received data */ unsigned char SPI_Transceiver(unsigned char data){ SPDR = data; while(!(SPSR & (1 << SPIF))); return SPDR; } int main(void){ SPI_Slave_init(); DDRA &= ~(1 << DDA0); PINA &= 0x00; unsigned char data; while (1) { data = 0x00; if(PINA & (1 << DDA0)){ data = SPI_Transceiver(ACK_Slave1); // will be changed to ACK_Slave2 for another slave } } }
The problem is the LED connected at PD0 doesn't blink at all and when I press the button , the LED at PD1 blinks an extra time i.e , if I press it one time, it blinks twice. I've attached a pin diagram of my configuration. Please point out any error in the code or in the diagram. Any help would be appreciated.