1

For a project I am trying to understand SPI.

The final project I will use this in, is for reading the SPI from a car radio.

That Radio writes to address 0x80 of a DDRAM LCD display. MY intent is to read for a write to this address and if the bits are correct replace waht is being written.

IE Radio says write the letter E to 0x80, using a mega2560 read this and then interject a different letter then write to the radio screen. So the radio is a master with the Mega and LCD as daisy chained slaves.

I'm using the base code from for writing to the screen. This was written to fully replac ethe radio so i'm trying to mimic the radio using an UNO as Master and the screen using a Uno as a slave.

I've got the demo working from circuits4you.com

I'm trying to modify it to use the same STI settings as seen in the base radio replacement code i'll be modifying for my final project. I know this code writes correctly to the screen. The problem is that the code uses SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3)); as its designed to replace the radio functions.

I'm trying to get that line to work on the 2 UNO's im bench testing with so I can make the mega a slave in the final project.

SPI MASTER Code



void setup (void) {
   Serial.begin(9600); //set baud rate to 115200 for usart
   digitalWrite(SS, HIGH); // disable Slave Select
   SPI.begin ();

}

void loop (void) {
    SPI.beginTransaction(SPISettings(9600, MSBFIRST, SPI_MODE3)); 

   char c;
   digitalWrite(SS, LOW); // enable Slave Select
   // send test string
   for (const char * p = "Hello, world!\r" ; c = *p; p++) 
   {
      SPI.transfer (c);
      Serial.println(c);
   }
   digitalWrite(SS, HIGH); // disable Slave Select
   delay(2000);
   SPI.endTransaction();
}

The problem seems to arise from the SPI.attachInterrupt() not being compatible with the SPI.beginTransaction is this correct and is there a way around it?

SPI SLAVE Code

include <SPI.h>
char buff [50];
volatile byte indx;
volatile boolean process;


void setup (void) {
   Serial.begin (9600);
   pinMode(MISO, OUTPUT); // have to send on master in so it set as output
   SPCR |= _BV(SPE); // turn on SPI in slave mode
   indx = 0; // buffer empty
   process = false;
   SPI.attachInterrupt(); // turn on interrupt

}

ISR (SPI_STC_vect) // SPI interrupt routine 
{ 
   byte c = SPDR; // read byte from SPI Data Register
   if (indx < sizeof buff) {
      buff [indx++] = c; // save data in the next index in the array buff
      if (c == '\r') //check for the end of the word
      process = true;
   }
}

void loop (void) {


   if (process) {
      process = false; //reset the process
      Serial.println (buff); //print the array on serial monitor
      indx= 0; //reset button to zero
   }

}
1
  • Please show your modification (use and position) of SPI.setDataMode() in your code above.
    – KG1
    Commented Jan 24, 2021 at 20:49

1 Answer 1

1

Okay so I have got this working now. It seems that it was the Slave not understanding the data mode. I found the SPI.setDataMode() it is listed as Do not use in the reference guide on Arduino.com but its worked spot on for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.