Hi Guys,
I am trying to use the example from AVR151 for the SPI between two Atmega168's (one master and one slave). Both are using an 8MHz crystal. Here is the master code:
//This is master code; the master has a button input which when pressed on the master side, tells the slave to light LED //Use internal oscillator for both master and slave //SPI configured in mode 0 with MSB transmitted first //SPI mode is polling the interrupt flags #include#include #include #include char* TextStringToSend = "AVR communicating with SPI"+0x00; char* PtrToStrChar; // Pointer to certain Character in String void master_init() { volatile char Data; //Make SS,MOSI and SCK as outputs DDRB = (1<<PB2)|(1<<PB3)|(1<<PB5); //SPI control register //SPIE: SPI interrupt enable needed to poll the interrupt flag //SPE: Enable SPI //Set SPI in master mode //SPR0 sets SCK frequency to SCK/16 SPCR = (1<<SPIE)|(1<<SPE)|(1<<MSTR)|(1<<SPR0); Data = SPSR; Data = SPDR; sei(); } void Master_Send (void) { PtrToStrChar = TextStringToSend; // Set Pointer to beginning of String while (*PtrToStrChar != 0) // if not end of String { SPDR = *PtrToStrChar; // send Character while (!(SPSR & (1<<SPIF))); // wait until Char is sent PtrToStrChar++; // Point to next char in String } } int main() { unsigned char KeyPressed; //Switch will be on port C DDRC = 0x00; //LED will be on Port D //PORT D0 will be output DDRD = 0xFF; DDRB = 0xFF; master_init(); PORTD = (1 << PD2);//this is to check if AVR is working while(1) { if(PINC != 0xFF) { if(KeyPressed == 0x00) { KeyPressed = 0x01; PORTD ^= (1 << PD0); //led will just show that key has been pressed Master_Send(); } } else KeyPressed = 0x00; } //the LED will toggle only after the switch is released and pressed again }
Here is the slave code:
//Slave code to communicate with M168 Master //use internal oscillator //Master sends string to slave; slave compares it with stored string //If string matches, then slave turns on LED on Port D #include#include #include #include #define ERROR 0x01 #define SUCCESS 0x02 char TransmitStatus = 0x00; char* ReceivedString = "AVR communicating via the SPI"+0x00; void init_slave() { volatile char slave_data; //Set MISO (PB4) as output DDRB = (1 << PB4); //Set Slave with clk/(default value for M168) //Clear the SPSR and SPDR registers by reading them slave_data = SPSR; slave_data = SPDR; DDRD = (1 << PORTD0) | (1 << PORTD1) | (1 << PORTD2); } void slave_receive() { while ((*ReceivedString !=0 && TransmitStatus != ERROR)) { while (!(SPSR & (1 << SPIF))); if (SPDR != *ReceivedString) //will check one byte at a time till end of string reached { TransmitStatus = ERROR; } ReceivedString++; } if(TransmitStatus == ERROR) { PORTD = (1 << PORTD1); //portd1 (pin 3) LED on = transmission error } else PORTD = (1 << PORTD0); //Port D0 (pin 2) LED on = success while(1); } int main() { init_slave(); slave_receive(); }
What is missing here?
The LED on PD2 on my master lights just fine indicating that the AVR master side is working.
Port C5 is connected to VCC through a 10K resistor by default and has a capacitor to GND. The switch is connected between port C5 and GND.
I have connected the following:
1. MOSI of master to MOSI of slave
2. MISO of slave to MISO of slave
3. SCK of master to SCK of slave
4. Master /SS is connected to VCC
5. Slave SS is connected to GND
Appreciate any help.