Adding a Second MCP23S17 Port Expander —
Adding a second MCP23S17 adds 16 additional pins and is not difficult to accomplish. The second (or more) chip just has to have +V and Ground connections for power, each IC chip pin 18 (Reset) needs to have the 10K resistor to +V, each of the A0, A1, and A2 pins must be either Ground or +V, the CS pin and the three SPI pins (SCK, SI, and SO) must be connected together between chips to the Arduino CS ,CLK, MOSI, and MISO pins. You now have 16 or more additional pins.
Since that was easy, we will skip ahead to building a quad MCP23S17 Port Expander backpack for the Arduino. Four MCP23S17 chips were added to a backpack expander board that fits on both an Uno and Mega 2560 Arduino. SPI on the Arduino uses 3 SPI pins (Uno pins D11, D12, D13, or on Mega 2560 pins D50, D51, D52). SPI also requires a CS pin which is used to select which SPI device is active at any given time. The default Arduino CS pin is D10 on Uno and D53 on Mega 2560. The SPI pins are connected to the Arduino ICSP pins, so with careful construction adding an ICSP 6-pin jack, the backpack will automatically work with either the Uno or Mega. The only requirement is to connect the CS pin which is not part of the ICSP configuration. Pin D10 was used for CS with this backpack. The ICSP does provide +V and Ground connections, which would allow the port expander board to be mounted separately from the Arduino, while using a 6-wire ICSP jumper for power and SPI. The 6th ICSP wire is for Reset which is not used in this application, so a 7th wire would be required for the CS connection. The Arduino pins just pass through the backpack board so that other backpacks could be placed on top. Only the SPI and CS pins, and V+ and Ground, make a connection between the boards.
Pictures: The finished backpack mounted on a Mega 2560 uses the ICSP for SPI and D10 for CS. Each MCP digital pin is brought out to an 8-pin header (Port A pins [0...7] and Port B pins [8...15]). The MCP23S17 interrupt pins (INTA and INTB x 4 chips = 8) were brought out to a separate header where they could be used for processing interrupts. The backside of the port expander backpack is a tangle of wires required to make all of the necessary connections. An etched and drilled circuit board would have made this much easier.
MultiTest Sketch --
The following MCP23S17_MultiTest_01.ino sketch code is lengthy but it provides several different examples of using the Majenko library with the quad port expander. Each example can be turned off by commenting out the function calls in loop(). The code instantiates the 4 MCP23S17 chips on the quad backpack, various combinations of input and output pins are set, pins are read and written, 8-pin ports are read and written, and long 16-pin (Port A & Port B) words are read and written. Then, 16 pins are sequentially set and cleared with counts displayed to Serial Monitor in decimal, hex, and binary. This process is conducted for each of the four chips. The code demonstrates how to do each of these functions so they can be used in other applications.
This code does not conduct any interrupt processing. Interrupts will be covered in detail in future parts of this series.
/* * MCP23S17_MultiTest_01.ino * Library Ref: github.com/MajenkoLibraries/MCP23S17 * * Lowell Bahner * 2016-12-11 * * Hardware: Arduino UNO / Mega2560 * IDE: Arduino 1.6.5 * * Useful SPI Ref: gammon.com.au/spi * * Wire the SPI Interface common lines (Mega2560 SPI pins shown in [ ]): * Arduino SPI_MOSI pin 11 [51] <-> SI MCP23S17 pin 13 * Arduino SPI_MISO pin 12 [50] <-> SO MCP23S17 pin 14 * Arduino SPI_CLOCK pin 13 [52]<-> SCK MCP23S17 pin 12 * Arduino SPI_CS pin 10 [53] <-> SS MCP23S17 pin 11 * MCP23S17 VDD pin 9 to +5V * MCP23S17 VSS pin 10 to Gnd * MCP23S17 Reset pin 18 to +5V * MCP23S17 Interrupt pins 19-20 * MCP23S17 A0,A1,A2 pins connect to Gnd or +5V (000 = Address 0, 100 = Address 1, 010 = Address 2, etc) * MCP23S17 Port A pins are chip pins 21-28 * MCP23S17 Port B pins are chip pins 1-8 * * This sketch runs a series of functions to demonstrate library capabilities. * This sketch does not demonstrate interrupt functionality. * * This sketch instantiates 4 MCP23S17 chips. * Bank1 (MCP23S17 address 1) pins are set as INPUT or INPUT_PULLUP. * Normally HIGH, use switch to set a pin LOW. * Bank0 (MCP23S17 address 0) pins are set as OUTPUT. * MCP23S17 outputs will power LEDs up to 25ma through 1000ohm resistor to ground. * * Bank3 (MCP23S17 address 3) pins are set as INPUT or INPUT_PULLUP. * Normally HIGH, use switch to set a pin LOW. * Bank2 (MCP23S17 address 2) pins are set as OUTPUT. * MCP23S17 outputs will power LEDs up to 25ma through 1000ohm resistor to ground. * * Majenko MCP23S17 library functions (see .h,.cpp files for details): * * bank.pinMode(uint8_t pin, uint8_t mode) * where modes are: * OUTPUT - sets pin HIGH * INPUT - sets pin LOW for sensing change to HIGH +V * INPUT_PULLUP - sets pin HIGH for sensing change to LOW 0V * * bank.digitalWrite(uint8_t pin, uint8_t value) * if mode=OUTPUT, pin value = LOW (0) or HIGH (1) * if mode=INPUT, value LOW disables pullup on pin, value HIGH enables pullup on pin * * uint8_t value = bank.digitalRead(uint8_t pin) * read the state of the pin * * uint8_t value = bank.readPort(uint8_t port) * read entire 8-bit port of all INPUT pins on Port A (port=0) or Port B (port>=1) * * uint16_t longValue = bank.readPort() * read both ports as 16-bit combined * * bank.writePort(uint8_t port, uint8_t val) * write val (0 or 1, hex example 0x55) to all OUTPUT pins on Port A (port=0) or Port B (port>=1) * * bank.writePort(uint16_t val) * write val (hex example 0x55AA) to all OUTPUT pins on Port A and Port B * * Also, interrupt functions are defined: * enableInterrupt(uint8_t pin, uint8_t type); * void disableInterrupt(uint8_t pin); * void setMirror(boolean m); * uint16_t getInterruptPins(); * uint16_t getInterruptValue(); * void setInterruptLevel(uint8_t level); * void setInterruptOD(boolean openDrain); * * * * Run Sketch: Serial Monitor Output -- RWpins() -- Bank1: Switch i15: 1 (Push button switch not pushed, Bank1 INPUT pin 15 is HIGH +5V) Bank0: Output j4: 1 (Bank0 OUTPUT pin 4 is HIGH. Arduino pin 7 is set HIGH. LED on pin 4 is ON. LED on pin 7 is ON.) Bank1: Switch i15: 0 (Push button switch pushed, grounds Bank1 INPUT pin 15) Bank0: Output j4: 0 (Bank0 OUTPUT pin 4 switches to LOW. Arduino pin 7 is set LOW. LED on pin 4 is OFF. LED on pin 7 is OFF.) -- RWport() -- Bank0: Port A BIN: 00000000 Bank0: Port B BIN: 00000000 Bank0: Port A BIN: 11110100 DEC: 244 Bank0: Port B BIN: 00001011 DEC: 11 -- RWlongPortValue() -- Bank0: Port A & B BIN: 0000101111110100 HEX: 0x0BF4 DEC: 3060 -- RWlongPort() -- Bank0: Port A & B BIN: 1011100101000010 HEX: 0xB942 DEC: 47426 -- CyclePins() -- Bank0: Port A & B BIN: 0000000000000000 HEX: 0x0000 DEC: 0 Bank0: Port A & B BIN: 0000000000000001 HEX: 0x0001 DEC: 1 Bank0: Port A & B BIN: 0000000000000011 HEX: 0x0003 DEC: 3 Bank0: Port A & B BIN: 0000000000000111 HEX: 0x0007 DEC: 7 Bank0: Port A & B BIN: 0000000000001111 HEX: 0x000F DEC: 15 Bank0: Port A & B BIN: 0000000000011111 HEX: 0x001F DEC: 31 Bank0: Port A & B BIN: 0000000000111111 HEX: 0x003F DEC: 63 Bank0: Port A & B BIN: 0000000001111111 HEX: 0x007F DEC: 127 Bank0: Port A & B BIN: 0000000011111111 HEX: 0x00FF DEC: 255 Bank0: Port A & B BIN: 0000000111111111 HEX: 0x01FF DEC: 511 Bank0: Port A & B BIN: 0000001111111111 HEX: 0x03FF DEC: 1023 Bank0: Port A & B BIN: 0000011111111111 HEX: 0x07FF DEC: 2047 Bank0: Port A & B BIN: 0000111111111111 HEX: 0x0FFF DEC: 4095 Bank0: Port A & B BIN: 0001111111111111 HEX: 0x1FFF DEC: 8191 Bank0: Port A & B BIN: 0011111111111111 HEX: 0x3FFF DEC: 16383 Bank0: Port A & B BIN: 0111111111111111 HEX: 0x7FFF DEC: 32767 Bank0: Port A & B BIN: 1111111111111111 HEX: 0xFFFF DEC: 65535 Bank0: Port A & B BIN: 1111111111111111 HEX: 0xFFFF DEC: 65535 Bank0: Port A & B BIN: 0111111111111111 HEX: 0x7FFF DEC: 32767 Bank0: Port A & B BIN: 0011111111111111 HEX: 0x3FFF DEC: 16383 Bank0: Port A & B BIN: 0001111111111111 HEX: 0x1FFF DEC: 8191 Bank0: Port A & B BIN: 0000111111111111 HEX: 0x0FFF DEC: 4095 Bank0: Port A & B BIN: 0000011111111111 HEX: 0x07FF DEC: 2047 Bank0: Port A & B BIN: 0000001111111111 HEX: 0x03FF DEC: 1023 Bank0: Port A & B BIN: 0000000111111111 HEX: 0x01FF DEC: 511 Bank0: Port A & B BIN: 0000000011111111 HEX: 0x00FF DEC: 255 Bank0: Port A & B BIN: 0000000001111111 HEX: 0x007F DEC: 127 Bank0: Port A & B BIN: 0000000000111111 HEX: 0x003F DEC: 63 Bank0: Port A & B BIN: 0000000000011111 HEX: 0x001F DEC: 31 Bank0: Port A & B BIN: 0000000000001111 HEX: 0x000F DEC: 15 Bank0: Port A & B BIN: 0000000000000111 HEX: 0x0007 DEC: 7 Bank0: Port A & B BIN: 0000000000000011 HEX: 0x0003 DEC: 3 Bank0: Port A & B BIN: 0000000000000001 HEX: 0x0001 DEC: 1 Bank0: Port A & B BIN: 0000000000000000 HEX: 0x0000 DEC: 0 * * * */ // Majenko MCP23S17 Library (revised 2017-Jan-23) #include <MCP23S17.h> // Arduino Library SPI.h #include <SPI.h> // SPI CS/SS chipselect pin can be changed by user as desired const uint8_t chipSelect = 10; // use for Uno or Mega // example Arduino board pin uint8_t pin7 = 7; // Create an object for each chip // Bank0 is address 0. Pins A0,A1,A2 grounded. // Bank1 is address 1. Pin A0=+5V, A1,A2 grounded. MCP23S17 Bank0(&SPI, chipSelect, 0); MCP23S17 Bank1(&SPI, chipSelect, 1); MCP23S17 Bank2(&SPI, chipSelect, 2); MCP23S17 Bank3(&SPI, chipSelect, 3); void setup() { // Slow down the master a bit if desired // SPI.setClockDivider(SPI_CLOCK_DIV8); Serial.begin(9600); Bank0.begin(); Bank1.begin(); Bank2.begin(); Bank3.begin(); // LED connected to Arduino pin 7 to test inter-device communication pinMode(pin7, OUTPUT); // // Set MCP23S17 pin modes: // example set one pin: chip.pinMode(0, OUTPUT); // sets chip pin 0 (Port A 0) to OUTPUT mode // setChipPins(); // use loop to set individual pins // or, since this library does not have a setPortPinMode, do 8 pin loops //setPortPins(); // example: set pins on each Port on each chip to different modes. // } // Set all Chip pins to desired mode void setChipPins() { // Example usage // Set all Bank0 pins to be OUTPUT for (uint8_t i = 0; i <= 15; i++) Bank0.pinMode(i, OUTPUT); // Set all Bank1 pins to be INPUT_PULLUP for (uint8_t i = 0; i <= 15; i++) //Bank1.pinMode(i, INPUT); // unswitched pin voltages about +0.1V, switch must pull pin to +5V Bank1.pinMode(i, INPUT_PULLUP); // unswitched pin voltages about +4.9V, switch must ground pin // Set all Bank2 pins to be OUTPUT for (uint8_t i = 0; i <= 15; i++) Bank2.pinMode(i, OUTPUT); // Set all Bank3 pins to be INPUT_PULLUP for (uint8_t i = 0; i <= 15; i++) //Bank3.pinMode(i, INPUT); // unswitched pin voltages about +0.1V, switch must pull pin to +5V Bank3.pinMode(i, INPUT_PULLUP); // unswitched pin voltages about +4.9V, switch must ground pin } // Set all Chip pins to OUTPUT mode void setAllPins() { // Example usage // Set all Bank0 pins to be OUTPUT for (uint8_t i = 0; i <= 15; i++) Bank0.pinMode(i, OUTPUT); // Set all Bank1 pins to be OUTPUT for (uint8_t i = 0; i <= 15; i++) Bank1.pinMode(i, OUTPUT); // Set all Bank2 pins to be OUTPUT for (uint8_t i = 0; i <= 15; i++) Bank2.pinMode(i, OUTPUT); // Set all Bank3 pins to be OUTPUT for (uint8_t i = 0; i <= 15; i++) Bank3.pinMode(i, OUTPUT); } // Set Port pins to desired mode void setPortPins() { // Example usage // Set all Bank0 Port A pins to OUTPUT for (uint8_t i = 0; i <= 7; i++) Bank0.pinMode(i, OUTPUT); // Set all Bank0 Port B pins to OUTPUT for (uint8_t i = 8; i <= 15; i++) Bank0.pinMode(i, OUTPUT); // Set all Bank1 Port A pins to be INPUT_PULLUP for (uint8_t i = 0; i <= 7; i++) Bank1.pinMode(i, INPUT_PULLUP); // Set all Bank1 Port B pins to be INPUT_PULLUP for (uint8_t i = 8; i <= 15; i++) Bank1.pinMode(i, INPUT_PULLUP); // Set all Bank2 Port A pins to OUTPUT for (uint8_t i = 0; i <= 7; i++) Bank2.pinMode(i, OUTPUT); // Set all Bank2 Port B pins to OUTPUT for (uint8_t i = 8; i <= 15; i++) Bank2.pinMode(i, OUTPUT); // Set all Bank3 Port A pins to be INPUT_PULLUP for (uint8_t i = 0; i <= 7; i++) Bank3.pinMode(i, INPUT_PULLUP); // Set all Bank3 Port B pins to be INPUT_PULLUP for (uint8_t i = 8; i <= 15; i++) Bank3.pinMode(i, INPUT_PULLUP); } // // Change LED On/Off with button push // 1) Switch an INPUT_PULLUP pin to ground // 2) Read the pin value // 3) Write the value to an OUTPUT pin // 4) Turn LED On/Off // Use functions digitalRead(pin) and digitalWrite(pin,value) // void RWpins01() { setChipPins(); Serial.print("\n -- RWpins01() --"); Serial.println(""); uint8_t b15 = 0; // Bank1 input pin value (0 push LOW, 1 normally open HIGH) with push button switch to gnd uint8_t i = 15; // Bank1 pin number uint8_t a4 = 0; // Bank0 output pin value uint8_t j = 4; // Bank0 pin number // read the switch value into b15 b15 = Bank1.digitalRead(i); Serial.print("\nBank1: Switch i"); Serial.print(i); Serial.print(": "); Serial.println(b15); // write the switch pin i, value b15, to the output pin j Bank0.digitalWrite(j, b15); a4 = Bank0.digitalRead(j); Serial.print("Bank0: Output j"); Serial.print(j); Serial.print(": "); Serial.println(a4); // Turn on/off LED connected to Arduino pin 7 through resistor to ground digitalWrite(pin7, a4); } void RWpins23() { setChipPins(); Serial.print("\n -- RWpins23() --"); Serial.println(""); uint8_t b15 = 0; // Bank1 input pin value (0 push LOW, 1 normally open HIGH) with push button switch to gnd uint8_t i = 15; // Bank1 pin number uint8_t a4 = 0; // Bank0 output pin value uint8_t j = 4; // Bank0 pin number // read the switch value into b15 b15 = Bank3.digitalRead(i); Serial.print("\nBank3: Switch i"); Serial.print(i); Serial.print(": "); Serial.println(b15); // write the switch pin i, value b15, to the output pin j Bank2.digitalWrite(j, b15); a4 = Bank2.digitalRead(j); Serial.print("Bank2: Output j"); Serial.print(j); Serial.print(": "); Serial.println(a4); // Turn on/off LED connected to Arduino pin 7 through resistor to ground digitalWrite(pin7, a4); } // // Read and Write Port values // void RWport0() { Serial.print("\n -- RWport0() --"); Serial.println(""); // set the port pin modes setAllPins(); // all Bank0 pins are OUTPUT but set as Ports // clear the port pin values to 0 uint8_t port = 0; // Port A uint8_t val = 0x00; // set to 0000 0000 Bank0.writePort(port, val); port = 1; // Port B Bank0.writePort(port, val); // set to 0000 0000 // read the port pin values uint8_t valueA = Bank0.readPort(0); Serial.print("\nBank0: Port A BIN: "); print8Bits(valueA); Serial.println(""); uint8_t valueB = Bank0.readPort(1); Serial.print("Bank0: Port B BIN: "); print8Bits(valueB); Serial.println(""); // set the port pin values port = 0; // Port A val = 0xF4; // set to 1111 0100 Bank0.writePort(port, val); port = 1; // Port B val = 0x0B; // set to 0000 1011 //val = 0xB0; // set to 1011 0000 Bank0.writePort(port, val); // read the port pin values valueA = Bank0.readPort(0); Serial.print("\nBank0: Port A BIN: "); print8Bits(valueA); Serial.print(" DEC: "); Serial.println(valueA, DEC); valueB = Bank0.readPort(1); Serial.print("Bank0: Port B BIN: "); print8Bits(valueB); Serial.print(" DEC: "); Serial.println(valueB, DEC); } void RWport1() { Serial.print("\n -- RWport1() --"); Serial.println(""); // set the port pin modes setAllPins(); // all Bank0 pins are OUTPUT but set as Ports // clear the port pin values to 0 uint8_t port = 0; // Port A uint8_t val = 0x00; // set to 0000 0000 Bank1.writePort(port, val); port = 1; // Port B Bank1.writePort(port, val); // set to 0000 0000 // read the port pin values uint8_t valueA = Bank1.readPort(0); Serial.print("\nBank1: Port A BIN: "); print8Bits(valueA); Serial.println(""); uint8_t valueB = Bank1.readPort(1); Serial.print("Bank1: Port B BIN: "); print8Bits(valueB); Serial.println(""); // set the port pin values port = 0; // Port A val = 0xF4; // set to 1111 0100 Bank1.writePort(port, val); port = 1; // Port B val = 0x0B; // set to 0000 1011 //val = 0xB0; // set to 1011 0000 Bank1.writePort(port, val); // read the port pin values valueA = Bank1.readPort(0); Serial.print("\nBank1: Port A BIN: "); print8Bits(valueA); Serial.print(" DEC: "); Serial.println(valueA, DEC); valueB = Bank1.readPort(1); Serial.print("Bank1: Port B BIN: "); print8Bits(valueB); Serial.print(" DEC: "); Serial.println(valueB, DEC); } void RWport2() { Serial.print("\n -- RWport2() --"); Serial.println(""); // set the port pin modes setAllPins(); // all Bank2 pins are OUTPUT but set as Ports // clear the port pin values to 0 uint8_t port = 0; // Port A uint8_t val = 0x00; // set to 0000 0000 Bank2.writePort(port, val); port = 1; // Port B Bank2.writePort(port, val); // set to 0000 0000 // read the port pin values uint8_t valueA = Bank2.readPort(0); Serial.print("\nBank2: Port A BIN: "); print8Bits(valueA); Serial.println(""); uint8_t valueB = Bank2.readPort(1); Serial.print("Bank2: Port B BIN: "); print8Bits(valueB); Serial.println(""); // set the port pin values port = 0; // Port A val = 0xF4; // set to 1111 0100 Bank2.writePort(port, val); port = 1; // Port B val = 0x0B; // set to 0000 1011 //val = 0xB0; // set to 1011 0000 Bank2.writePort(port, val); // read the port pin values valueA = Bank2.readPort(0); Serial.print("\nBank2: Port A BIN: "); print8Bits(valueA); Serial.print(" DEC: "); Serial.println(valueA, DEC); valueB = Bank2.readPort(1); Serial.print("Bank2: Port B BIN: "); print8Bits(valueB); Serial.print(" DEC: "); Serial.println(valueB, DEC); } void RWport3() { Serial.print("\n -- RWport3() --"); Serial.println(""); // set the port pin modes setAllPins(); // all Bank3 pins are OUTPUT but set as Ports // clear the port pin values to 0 uint8_t port = 0; // Port A uint8_t val = 0x00; // set to 0000 0000 Bank3.writePort(port, val); port = 1; // Port B Bank3.writePort(port, val); // set to 0000 0000 // read the port pin values uint8_t valueA = Bank3.readPort(0); Serial.print("\nBank3: Port A BIN: "); print8Bits(valueA); Serial.println(""); uint8_t valueB = Bank3.readPort(1); Serial.print("Bank3: Port B BIN: "); print8Bits(valueB); Serial.println(""); // set the port pin values port = 0; // Port A val = 0xF4; // set to 1111 0100 Bank3.writePort(port, val); port = 1; // Port B val = 0x0B; // set to 0000 1011 //val = 0xB0; // set to 1011 0000 Bank3.writePort(port, val); // read the port pin values valueA = Bank3.readPort(0); Serial.print("\nBank3: Port A BIN: "); print8Bits(valueA); Serial.print(" DEC: "); Serial.println(valueA, DEC); valueB = Bank3.readPort(1); Serial.print("Bank3: Port B BIN: "); print8Bits(valueB); Serial.print(" DEC: "); Serial.println(valueB, DEC); } void RWlongPortValue0() { Serial.print("\n -- RWlongPortValue0() --"); Serial.println(""); // Read the Bank0 Port pin values as a combined long value uint16_t valueLong = Bank0.readPort(); Serial.print("\nBank0: Port A & B BIN: "); print16Bits(valueLong); Serial.print(" HEX: "); crPrintHEX(valueLong, 4); Serial.print(" DEC: "); Serial.println(valueLong, DEC); } void RWlongPortValue1() { Serial.print("\n -- RWlongPortValue1() --"); Serial.println(""); // Read the Bank1 Port pin values as a combined long value uint16_t valueLong = Bank1.readPort(); Serial.print("\nBank1: Port A & B BIN: "); print16Bits(valueLong); Serial.print(" HEX: "); crPrintHEX(valueLong, 4); Serial.print(" DEC: "); Serial.println(valueLong, DEC); } void RWlongPortValue2() { Serial.print("\n -- RWlongPortValue2() --"); Serial.println(""); // Read the Bank2 Port pin values as a combined long value uint16_t valueLong = Bank2.readPort(); Serial.print("\nBank2: Port A & B BIN: "); print16Bits(valueLong); Serial.print(" HEX: "); crPrintHEX(valueLong, 4); Serial.print(" DEC: "); Serial.println(valueLong, DEC); } void RWlongPortValue3() { Serial.print("\n -- RWlongPortValue3() --"); Serial.println(""); // Read the Bank3 Port pin values as a combined long value uint16_t valueLong = Bank3.readPort(); Serial.print("\nBank3: Port A & B BIN: "); print16Bits(valueLong); Serial.print(" HEX: "); crPrintHEX(valueLong, 4); Serial.print(" DEC: "); Serial.println(valueLong, DEC); } void RWlongPort0() { Serial.print("\n -- RWlongPort0() --"); Serial.println(""); // Write the Bank0 Port pin values as a combined long value uint16_t valueLong = 0xB942; Bank0.writePort(valueLong); // Read the Bank0 Port pin values as a combined long value uint16_t valueLongIn = Bank0.readPort(); Serial.print("\nBank0: Port A & B BIN: "); print16Bits(valueLongIn); Serial.print(" HEX: "); crPrintHEX(valueLongIn, 4); Serial.print(" DEC: "); Serial.println(valueLongIn, DEC); } void RWlongPort1() { Serial.print("\n -- RWlongPort1() --"); Serial.println(""); // Write the Bank1 Port pin values as a combined long value uint16_t valueLong = 0xB942; Bank1.writePort(valueLong); // Read the Bank1 Port pin values as a combined long value uint16_t valueLongIn = Bank1.readPort(); Serial.print("\nBank1: Port A & B BIN: "); print16Bits(valueLongIn); Serial.print(" HEX: "); crPrintHEX(valueLongIn, 4); Serial.print(" DEC: "); Serial.println(valueLongIn, DEC); } void RWlongPort2() { Serial.print("\n -- RWlongPort2() --"); Serial.println(""); // Write the Bank2 Port pin values as a combined long value uint16_t valueLong = 0xB942; Bank2.writePort(valueLong); // Read the Bank2 Port pin values as a combined long value uint16_t valueLongIn = Bank2.readPort(); Serial.print("\nBank2: Port A & B BIN: "); print16Bits(valueLongIn); Serial.print(" HEX: "); crPrintHEX(valueLongIn, 4); Serial.print(" DEC: "); Serial.println(valueLongIn, DEC); } void RWlongPort3() { Serial.print("\n -- RWlongPort3() --"); Serial.println(""); // Write the Bank3 Port pin values as a combined long value uint16_t valueLong = 0xB942; Bank3.writePort(valueLong); // Read the Bank3 Port pin values as a combined long value uint16_t valueLongIn = Bank3.readPort(); Serial.print("\nBank3: Port A & B BIN: "); print16Bits(valueLongIn); Serial.print(" HEX: "); crPrintHEX(valueLongIn, 4); Serial.print(" DEC: "); Serial.println(valueLongIn, DEC); } // // Cycle through OUTPUT pins with count-up count-down // void CyclePins0() { Serial.print("\n -- CyclePins0() --"); Serial.println("\n"); // Set all Bank0 pins to be OUTPUT for (uint8_t i = 0; i <= 15; i++) Bank0.pinMode(i, OUTPUT); // clear Bank0 using writePort uint16_t valueLong = 0x0000; Bank0.writePort(valueLong); // Read the Bank0 Port pin values as a combined long value for (int8_t i = -1; i <= 15; i++) { if (i >= 0) Bank0.digitalWrite(i, 1); // i=-1 allows print of 0 data valueLong = Bank0.readPort(); // read 16 bits Serial.print("Bank0: Port A & B BIN: "); print16Bits(valueLong); Serial.print(" HEX: "); crPrintHEX(valueLong, 4); Serial.print(" DEC: "); Serial.println(valueLong, DEC); } Serial.println(""); for (int8_t i = 15; i >= -1; i--) { // i=-1 allows print of 0 data // decrement after the read while reading down the values valueLong = Bank0.readPort(); // read 16 bits Serial.print("Bank0: Port A & B BIN: "); print16Bits(valueLong); Serial.print(" HEX: "); crPrintHEX(valueLong, 4); Serial.print(" DEC: "); Serial.println(valueLong, DEC); Bank0.digitalWrite(i, 0); } } void CyclePins1() { Serial.print("\n -- CyclePins1() --"); Serial.println("\n"); // Set all Bank1 pins to be OUTPUT for (uint8_t i = 0; i <= 15; i++) Bank1.pinMode(i, OUTPUT); // clear Bank1 using writePort uint16_t valueLong = 0x0000; Bank1.writePort(valueLong); // Read the Bank1 Port pin values as a combined long value for (int8_t i = -1; i <= 15; i++) { if (i >= 0) Bank1.digitalWrite(i, 1); // i=-1 allows print of 0 data valueLong = Bank1.readPort(); // read 16 bits Serial.print("Bank1: Port A & B BIN: "); print16Bits(valueLong); Serial.print(" HEX: "); crPrintHEX(valueLong, 4); Serial.print(" DEC: "); Serial.println(valueLong, DEC); } Serial.println(""); for (int8_t i = 15; i >= -1; i--) { // i=-1 allows print of 0 data // decrement after the read while reading down the values valueLong = Bank1.readPort(); // read 16 bits Serial.print("Bank1: Port A & B BIN: "); print16Bits(valueLong); Serial.print(" HEX: "); crPrintHEX(valueLong, 4); Serial.print(" DEC: "); Serial.println(valueLong, DEC); Bank1.digitalWrite(i, 0); } } void CyclePins2() { Serial.print("\n -- CyclePins2() --"); Serial.println("\n"); // Set all Bank2 pins to be OUTPUT for (uint8_t i = 0; i <= 15; i++) Bank2.pinMode(i, OUTPUT); // clear Bank2 using writePort uint16_t valueLong = 0x0000; Bank2.writePort(valueLong); // Read the Bank2 Port pin values as a combined long value for (int8_t i = -1; i <= 15; i++) { if (i >= 0) Bank2.digitalWrite(i, 1); // i=-1 allows print of 0 data valueLong = Bank2.readPort(); // read 16 bits Serial.print("Bank2: Port A & B BIN: "); print16Bits(valueLong); Serial.print(" HEX: "); crPrintHEX(valueLong, 4); Serial.print(" DEC: "); Serial.println(valueLong, DEC); } Serial.println(""); for (int8_t i = 15; i >= -1; i--) { // i=-1 allows print of 0 data // decrement after the read while reading down the values valueLong = Bank2.readPort(); // read 16 bits Serial.print("Bank2: Port A & B BIN: "); print16Bits(valueLong); Serial.print(" HEX: "); crPrintHEX(valueLong, 4); Serial.print(" DEC: "); Serial.println(valueLong, DEC); Bank2.digitalWrite(i, 0); } } void CyclePins3() { Serial.print("\n -- CyclePins3() --"); Serial.println("\n"); // Set all Bank3 pins to be OUTPUT for (uint8_t i = 0; i <= 15; i++) Bank3.pinMode(i, OUTPUT); // clear Bank3 using writePort uint16_t valueLong = 0x0000; Bank3.writePort(valueLong); // Read the Bank3 Port pin values as a combined long value for (int8_t i = -1; i <= 15; i++) { if (i >= 0) Bank3.digitalWrite(i, 1); // i=-1 allows print of 0 data valueLong = Bank3.readPort(); // read 16 bits Serial.print("Bank3: Port A & B BIN: "); print16Bits(valueLong); Serial.print(" HEX: "); crPrintHEX(valueLong, 4); Serial.print(" DEC: "); Serial.println(valueLong, DEC); } Serial.println(""); for (int8_t i = 15; i >= -1; i--) { // i=-1 allows print of 0 data // decrement after the read while reading down the values valueLong = Bank3.readPort(); // read 16 bits Serial.print("Bank3: Port A & B BIN: "); print16Bits(valueLong); Serial.print(" HEX: "); crPrintHEX(valueLong, 4); Serial.print(" DEC: "); Serial.println(valueLong, DEC); Bank3.digitalWrite(i, 0); } } void loop() { // Change LED On/Off with button push RWpins01(); RWpins23(); // Read and Write Port pins as a group RWport0(); RWport1(); RWport2(); RWport3(); // Read the Bank0 Port pin values as a combined long value RWlongPortValue0(); RWlongPortValue1(); RWlongPortValue2(); RWlongPortValue3(); // Read and Write Chip 16 pins as a group RWlongPort0(); RWlongPort1(); RWlongPort2(); RWlongPort3(); // Cycle through OUTPUT pins with count-up count-down CyclePins0(); CyclePins1(); CyclePins2(); CyclePins3(); delay(1000); } // print 8-bit byte as 8 bit binary string void print8Bits(uint8_t myByte) { for (byte mask = 0x80; mask; mask >>= 1) { if (mask & myByte) Serial.print('1'); else Serial.print('0'); } } // print 16-bit word as 16 bit binary string void print16Bits(uint16_t myWord) { for (uint16_t mask = 0x8000; mask; mask >>= 1) { if (mask & myWord) Serial.print('1'); else Serial.print('0'); } } //--------------------------------------------------------------------------------- // crPrintHEX print value as hex with specified number of digits //--------------------------------------------------------------------------------- void crPrintHEX(unsigned long DATA, unsigned char numChars) { unsigned long mask = 0x0000000F; mask = mask << 4 * (numChars - 1); Serial.print("0x"); for (unsigned int i = numChars; i > 0; --i) { Serial.print(((DATA & mask) >> (i - 1) * 4), HEX); mask = mask >> 4; } Serial.print(" "); }
Useful references -
No comments:
Post a Comment