hi..
i have connected arduino uno to mcp23s08(spi expander) arduino as master and mcp23s08 as slave where 10 th pin as slave select pin..it worked..
now i need to connect another mcp23s08 to arduino uno ..which pin can be used as slave select pin..i have tried with 9 th pin but it did not work..(when i connect to 10th pin it is working and when connected to 9th it is not working)
which pins on arduino can be used inorder to select multiple slaves...
please help me ..thanks in advance..
/*
Code to test MCP23S08 SPI B-bit I/O expander
See:
<http://code.rancidbacon.com/LearningAboutArduinoMCP23S08>
<http://www.arduino.cc/en/Tutorial/SPIEEPROM>
Current features:
* Read input pins
* Set output pins
* Write output pins
* Gratuitous LED fiddling
* Terrible hacked-together code
*/
// Define SPI-related pins
#define PIN_DATA_OUT 11 // MOSI (Master Out / Slave In)
#define PIN_DATA_IN 12 // MISO (Master In / Slave Out)
#define PIN_SPI_CLOCK 13 // SCK (Serial Clock)
#define PIN_SLAVE_SELECT 10 // SS (Slave Select)
byte deviceOpcodeRead = 0;
byte deviceOpcodeWrite = 0; // TODO: handle this better?
byte pinState = B00000000;
unsigned long clk = 0;
void setup () {
Serial.begin(9600);
Serial.println("Setup enter...");
Serial.print("SPCR: "); Serial.println(SPCR, BIN);
// Configure SPI
// Configure I/O pins
pinMode(PIN_DATA_OUT, OUTPUT);
pinMode(PIN_DATA_IN, INPUT);
pinMode(PIN_SPI_CLOCK, OUTPUT);
pinMode(PIN_SLAVE_SELECT, OUTPUT);
digitalWrite(PIN_SLAVE_SELECT, HIGH); // Disable slave
// Configure SPI Control Register (SPCR) (All values initially 0)
// Bit Description
// 7 SPI Interrupt Enable -- disable (SPIE --> 0)
// 6 SPI Enable -- enable (SPE --> 1)
// 5 Data Order -- MSB 1st (DORD --> 0) (Slave specific)
// 4 Master/Slave Select -- master (MSTR --> 1)
// 3 Clock Polarity -- (CPOL --> 0) (Slave specific) ("Mode")
// 2 Clock Phase -- (CPHA --> 0) (Slave specific)
// 1 SPI Clock Rate Select 1 -- } (SPR1 --> 0)
// 0 SPI Clock Rate Select 0 -- } fOSC/4 (SPR0 --> 0) ("Fastest" but see SPI2X in SPSR)
SPCR = (1<<SPE)| (1<<MSTR);
Serial.print("SPCR: "); Serial.println(SPCR, BIN);
// Clear previous data and status (TODO: Determine if necessary/better way.)
// (Based on Playground SPI example.)
byte dummy;
dummy = SPSR;
dummy = SPDR;
delay(10);
// Serial.println((1 << SPIF), BIN);
# define SLAVE_ADDRESS_BASE (B01000 << 3)
# define SLAVE_ADDRESS_BIT_A1 (0 << 2) // TODO: Allow non-zero and define constants
# define SLAVE_ADDRESS_BIT_A0 (0 << 1) // TODO: Allow non-zero and define constants
# define SLAVE_ADDRESS (SLAVE_ADDRESS_BASE|SLAVE_ADDRESS_BIT_A1|SLAVE_ADDRESS_BIT_A0)
# define CONTROL_BIT_READ 1
# define CONTROL_BIT_WRITE 0
# define REG_IODIR 0x00
# define REG_IOPOL 0x01
# define REG_GPIO 0x09
// byte deviceOpcode = 0;
//TODO: Reset slave?
deviceOpcodeRead = (SLAVE_ADDRESS | CONTROL_BIT_READ);
deviceOpcodeWrite = (SLAVE_ADDRESS | CONTROL_BIT_WRITE);
Serial.print("Device opcode (read): ");
Serial.println(deviceOpcodeRead, BIN);
Serial.print("Device opcode (write): ");
Serial.println(deviceOpcodeWrite, BIN);
/*
digitalWrite(PIN_SLAVE_SELECT, LOW); // Enable slave
spi_transfer(deviceOpcode);
// spi_transfer(REG_IODIR); // The register we want to read
// spi_transfer(REG_IOPOL); // The register we want to read
spi_transfer(REG_GPIO); // The register we want to read
// int data; // Correct type?
byte data; // Correct type?
//unsigned long data; // Correct type?
data = spi_transfer(0xFF); // Transfer dummy byte to get response
digitalWrite(PIN_SLAVE_SELECT, HIGH); // Disable slave
*/
byte iodirVal = 0;
Serial.print("IODIR response: ");
iodirVal = getRegister(deviceOpcodeRead, REG_IODIR);
Serial.println(iodirVal, BIN);
byte newVal = 0;
// newVal = iodirVal & B01111111;
// newVal = B01111111;
newVal = B00001111;
Serial.print("newVal: ");
Serial.println(newVal, BIN);
setRegister(deviceOpcodeWrite, REG_IODIR, newVal);
Serial.print("IODIR response: ");
iodirVal = getRegister(deviceOpcodeRead, REG_IODIR);
Serial.println(iodirVal, BIN);
//setRegister(deviceOpcodeWrite, REG_GPIO, B10000000); // on
//setRegister(deviceOpcodeWrite, REG_GPIO, B00000000); // off
setRegister(deviceOpcodeWrite, REG_GPIO, pinState);
Serial.print("Initial GPIO response: ");
Serial.println(getRegister(deviceOpcodeRead, REG_GPIO), BIN);
Serial.println("Setup exit...");
clk = millis();
}
byte getRegister(byte targetDeviceOpcode, byte registerAddress) {
digitalWrite(PIN_SLAVE_SELECT, LOW); // Enable slave
spi_transfer(targetDeviceOpcode);
spi_transfer(registerAddress); // The register we want to read
byte data; // Correct type?
data = spi_transfer(0xFF); // Transfer dummy byte to get response
digitalWrite(PIN_SLAVE_SELECT, HIGH); // Disable slave
return data;
}
void setRegister(byte targetDeviceOpcode, byte registerAddress, byte value) {
// TODO: Do Better?
digitalWrite(PIN_SLAVE_SELECT, LOW); // Enable slave
spi_transfer(targetDeviceOpcode);
spi_transfer(registerAddress); // The register we want to write
spi_transfer(value);
digitalWrite(PIN_SLAVE_SELECT, HIGH); // Disable slave
}
// From Playground
char spi_transfer(volatile char data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait for the end of the transmission
{
};
return SPDR; // return the received byte
}
byte buttonState = 0;
void loop() {
if (pinState && ((millis() - clk) > 750)) {
// pinState = B00000000;
pinState = (pinState >> 1) & B11110000;
setRegister(deviceOpcodeWrite, REG_GPIO, pinState);
clk = millis() - 500;
}
// Serial.println(getRegister(deviceOpcodeRead, REG_GPIO), BIN);
buttonState = (getRegister(deviceOpcodeRead, REG_GPIO) & B00000001);
// Serial.println(buttonState, BIN);
//if (buttonState && !pinState) { // TODO: mask off pin(s) we're interested in & do better.
if (buttonState) {
// pinState = B10000000;
// pinState = B11110000; // Note: You need to set as outputs remember!
if (!(pinState & B10000000)) { // Compare to top-most output bit
pinState = (pinState << 1) | B00010000; // Add bottom-most output bit
}
setRegister(deviceOpcodeWrite, REG_GPIO, pinState);
delay(75);
clk = millis();
} /*
else if (!buttonState && pinState) {
pinState = B00000000;
setRegister(deviceOpcodeWrite, REG_GPIO, pinState);
}
*/
delay(50);