SPI programing

Okay I have been doing a bit of reading about SPI and how it is used on the Arduino. If I understand correctly, the SPI.h file is ONLY for use with one device who's SS pin is 10. Now as I understand SPI, I should be able to put several devices on the SPI bus as long as I have enough digital pins to act as SSs. The SD shield that I have from Seed Studio uses 10. I am trying to use a 3208 to get more analog inputs and a greater resolution. Can I still use SPI.h, or will I have to program the control/interface to the 3208 myself? I think I can figure that out from other sources, just trying to see if SPI.h, can handle more than one device at a time.

Bob

Use any pin for chip_select... but pin 10 MUST be defined as output..

It will handle more than one SPI device. In addition to knut_ny, insure they have separate slave select pins and the SPI settings (mode, speed and bit order) are the same. If the settings are not the same, you must switch those settings to access the other device, then switch them back.

knut_ny:
Use any pin for chip_select... but pin 10 MUST be defined as output..

According to this:

MOSI (Master out slave in) is pin 11. This is what I would call output. Am I missing something?

Also where can I find a more detailed reference for the SPI.h library?

Bob

start here: SPI - Arduino Reference

parrst:

knut_ny:
Use any pin for chip_select... but pin 10 MUST be defined as output..

According to this:

SD Card Shield V3.0 | Seeed Studio Wiki

MOSI (Master out slave in) is pin 11. This is what I would call output. Am I missing something?

Also where can I find a more detailed reference for the SPI.h library?

Bob

Correct the MOSI is an output as is the CLK the MISO is an input but as the other have said to get the chip to work in SPI mode you MUST have the default pin 10 set as an output. The SD card is SPI and if you use an external one the you can use any pin. aside from the MOSI,MISO and CLK pins. Remember however that you can only have ONE SS pin active at any time they are mutually exclusive.

The SPI register is basically a shift register as you toggle the CLK is shift out from the high bit onto the MOSI and shifts into the low bit the level on the MISO.

Cheers Pete.

Pin 10 set to output for the SPI master. If left as input, an external device pulling the pin low will put the Arduino into SP slave mode.
Here's the part of loop I used to read the channels of an MCP3208 every 5mS and send the data out over the serial port:

 // Elapsed time check for ADC and Switch reading
  if (millis()>=previousMillis){

    previousMillis = previousMillis + 5; // set for next 5 mS interval

    // read ADC with 3 byte transfer
    PORTB = PORTB & B11111011;  // ADC_SS, LOW
    // ADCaddress = 0x0600, 640, 680, 6C0, 700, 740, 780, 7C0
    dummyADC = SPI.transfer (highByte(ADCaddress));  // 0x06, 0x07 out, read in dummy data
    highADC = SPI.transfer (lowByte(ADCaddress));    // 0x00, 0x40, 0x80, 0xC0, read in upper 4 bits
    lowADC = SPI.transfer (0);              // dummy 0 byte out , read in lower 8 bits
    PORTB = PORTB | B00000100; // ADC_SS, HIGH

    // send the data out
    // this is a synchronization byte, there were other serial messages going out as well.
    Serial.write (ADCsyncbyte);      // syncbyte = B00110011
    Serial.write (address_count);    // 
    Serial.write (highADC & 0x0F);   // send it out
    Serial.write (lowADC);           // send it out
    
    // prep address_count for next pass. Used to create ADC select, DAC select
    address_count = address_count +1;  // 0 to 7, pass to Rx for DAC sync
    if (address_count == 8){ 
      address_count = 0;
    }  // reset if hit all 8

    ADCaddress = baseADCaddress + (address_count * 0x40); // update for next ADC pass

  } // end 5mS test

knut_ny:
start here: SPI - Arduino Reference

I was looking for more details. But if I go to the link on begin() it tells me that only on the duo can I select the slave select pin. From further reading, it looks like I can use any SS pin, I want, I will just need to take it low or high manually. Is that normally required? It also says the begin function sets the SS high. Do any of the other functions set the SS pin state? that is, does the transfer() function take the SS pin the uno thinks I am using low then transfer then take the SS high again?

Again the duo has an SS pin parameter. does the duo handle the SS number in it's function but the uno, I have to handle it?

I used direct port manipulation to set/clear PORTB bit 2, which is D10.
pinMode (D10, OUTPUT); was used earlier to set the mode.
Or you can use digitalWrite.
The actual ADC reading is just sending out the address and read in the data. SPI sends out 8 bits on MOSI while reading in 8 bits on MISO at the same time. The address bits (channel select) going out are spread over 2 bytes, so some of the code just puts those bits in the correct place for them to be recognized by the MCP3208:

dummyADC = SPI.transfer (highByte(ADCaddress));  // 0x06, 0x07 out, read in dummy data
    highADC = SPI.transfer (lowByte(ADCaddress));    // 0x00, 0x40, 0x80, 0xC0, read in upper 4 bits
    lowADC = SPI.transfer (0);              // dummy 0 byte out , read in lower 8 bits

Again the duo has an SS pin parameter. does the duo handle the SS number in it's function but the uno, I have to handle it?

How did "duo" (did you mean the Due?) jump in here?
Any code you write for SPI needs to have the SS pin controlled. Maybe you use a library that does it, like the SD card library. Maybe you have to write your own control of it like I did.
Maybe you use D10, maybe you use another pin, and D10 is used for another output function.

CrossRoads:

Again the duo has an SS pin parameter. does the duo handle the SS number in it's function but the uno, I have to handle it?

How did "duo" (did you mean the Due?) jump in here?
Any code you write for SPI needs to have the SS pin controlled. Maybe you use a library that does it, like the SD card library. Maybe you have to write your own control of it like I did.
Maybe you use D10, maybe you use another pin, and D10 is used for another output function.

On the following page it shows that for the duo, the begin() function take an SS parameter, but the uno version does not. I am assuming that means the duo version will handle taking the SS pin low before transferring and back high when done. but on the uno, I will have to take the SS of whatever device I am communicating with Low myself before the transfer and back high myself after. Just trying to make sure I understand completely what I am doing.

Also on the data sheet for the 3208 it shows it can be run in mode 0,0 and 1,1. How is that determined? by the SetDataMode function that I program on the uno?

Also do I have to set the data mode, bit order and clock divider manually or does the begin() function set defaults?

Default SPI modes are Mode 0, clock at 4 MHz, MSB first.
Those would be changed in setup After the SPI.begin call if needed:

  // Open SPI interface
  SPI.begin (); // leave blank, we are master

For MCP3208, the default settings are fine.