Hello to the group. I am new to Arduino. My electronics knowledge is rusty, I’ve been away from electronic design and programming for about 20 years.
I will be posting my progress with the SPI interface. The novice should be able to follow along, hence I will try to explain everything in full detail. I also would like the feedback from the experienced on this group as to the correctness and anything I post, or that is felt should be mentioned that I may have missed. I am an NOT AN EXPERT or experienced so your comments and questions will be welcome. Hoping to reduce my learning curve by input from others, and allow others inexperienced with SPI interface, to discover its’ power.
I was going to require more then the 14 Input/Output (I/O) pins available for my project. At first I was going to use the 74HC595 & 74HC165 shift registers for my I/O requirements and just bit bang away for my requirements, but after investigation, I discovered the Microchip MCP23S17 SPI chip. Upon realizing the power of this chip, I decided it was worth the extra time it would take it would take to learn how to use it. Because of its versatility, it will be my first preference for any future I/O expansion requirements. First thing I discovered, there are many postings on the internet with people having problems with implementation using the MCP23S17. Many aspects of using this chip are not so obvious. Many solutions provided code, but no explanation as to WHY the steps were required. Others skip relevant information; such as the defaults may have met their project needs. Hopefully this document with your help, will become an all encompassing “how to” document.
First recognize the MCP23S17 provides enhancements over the suggested SPI protocol. Therefore a little extra programming maybe required for SPI implementation into your project.
MCP23S17 Overview spec sheet
• SPI pin support
o SI - Serial In
o SO - Serial Out
o SCK – Clock – speeds up to 10 MHz
o CS (active low) – chip select (SS Slave Select from master)
• (2) - 8 bit General Purpose I/O (GPIO) registers, GPA0-7, GPB0-7
• (3) – hardware addressing pins A0, A1, A2 – allows addressing of up to 8 devices (0 through 7)
• (2) –Interrupts, INTA, INTB
• (1)-RESET (active low) - sets chip to a known state on power up
• (1) – VDD – supply voltage - range -0.3 V to 5.5V DC
Definition: active low means you take the pin to a LOW state, it normally sits at a HIGH, indicated with a solid line above the pin name
My reasons for choosing MCP23S17:
-
Almost any I/O pin expansion requirement can be provided which is the power of using this chip
a. (16) I/O ports is higher density then the 74C1595 or 74HC165 - 8 I/O, in about the same space
b. One chip can support both Input and Output requirements at the same time
c. Same chip family MCP23017 also provides I2C support
d. full duplex operation
e. synchronous data transfer, clock is provided by Master SPI device
f. Using internal functionality of chip can reduce component count that would be required to implement the same functions outside of the chip
g. 8 or 16 bit operation -
16 I/O ports per chip
a. Each port programmable as to behaviour, Input or Output
b. Programmable Bit inversion on Input, this is useful when using Active Low to represent a 1
c. Programmable biasing using an internal 100K on Outputs
d. 25mA source/sink capability per I/O pin (limitation all 16 Output pins cannot simultaneously source 25mA)
e. Programmable Open drain for each Output pin -
Hardware Address Pins
a. Multiple SPI devices can share one buss (with hardware addressing enabled the MCP23S17 can support up to 8 devices) -
Interrupts
a. Monitor input(s) on single port or multiple ports
b. Interrupt on change from last state of pin
c. Interrupt on change from reference state
d. 2 interrupts available, monitoring A and B register ports independently
e. Internal ORing of INTA and INTB
f. INTA and INTB outputs can be set for
i. active LOW\active HI
ii. Open Drain – useful for “wired OR”, “implied AND” -
Speed (not sure yet how much faster then an I2C interface, but many sites mention this)
-
Ease of use (once you get past learning the initial set-up of the chip)
a. Arduino has a built in library
b. Only program 3 steps required to write/read information with SPI
Definitions:
Full duplex - this allows the Ardunio to write to SPI device while simultaneously reading from the SPI device, half duplex you have to write, then read as two separate steps
Open Drain – allows you to connect several open drain pins together with one biasing resistor, forming a “wired OR” / “Implied AND”. Operation is active LOW. Any input that changes the output to LOW, creates a LOW on the shared Open Drain connection.
Synchronous: data is transferred using a Clock provided by the Master SPI device, this clock is used by the slave devices, (asynchronous – data is transferred by each device using its own internal clock, because the 2 devices clocks are not synchronized together, data could be transferred incorrectly because of clock edges drifting apart)
To date, I have received my Arduino Uno, and I am in the process of learnign programming and ordering the electronic components required for the SPI setup. I should be ready to post in about 4 weeks, with my first experimentation. The first setup will be learning basic operation, just using the default settings were we can.:
• Arduino SPCR and SPSR register settings
• MCP23S17 Logical Address 0 (or 4) with Hardware Addressing disabled, i.e. HAEN=0
• setting I/O ports for Input or Output
• Read/Write operation
Definition
Logical Address – I differentiate hardware and logical addresses. Logical addresses are used by software to access a device. e.g. when HAEN is disabled, the MCP23S17 has one of 1 of 2 possible logical addresses, 0 or 4 (will discuss why later). When HAEN is enabled, the logical address of device becomes the hardware address set on pins A0-A1-A2.
My first ask is, does anyone have some good bookmarked sites explaining the use of the SPI MCP23S17 with Arduino? I have so far found the following sites to have the most useful information:
http://www.gammon.com.au/forum/?id=10892&page=999 Site just posted, good SPI overview
Using Serial Peripheral Interface (SPI) Master and Slave with Atmel AVR Microcontroller | ermicroblog Arduino control register explanation
http://www.myamicus.co.uk/content.php?246-Port-Expansion-using-SPI
http://jimsmindtank.com/atmega168-and-master-spi/ Arduino conrol register
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1279796536 Arduin Forum, relay shield
Reference documents
Arduino Atmel AVR
http://www.atmel.com/dyn/resources/prod_documents/doc8025.pdf Amtel AVR
SPI - Arduino Reference Aeduino SPI Library
Arduino Playground - Spi Arduino SPI library
http://arduino.cc/playground/uploads/Main/arduino_notebook_v1-1.pdf Notebook by B Evans
http://www.atmel.com/dyn/resources/prod_documents/doc2585.pdf Atmel App note : AVR151 Setup and Use of SPI
http://www.atmel.com/dyn/resources/prod_documents/doc2582.pdf Atmel App note: AVR319 SPI with USI module
www.atmel.com/dyn/resources/prod_documents/doc1108.pdf Atmel App Note: AVR320 SPI Master
Microchip MCP23X17
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en023500 MCP2XS17 website
http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf MCP23X17 Data Sheet
http://ww1.microchip.com/downloads/en/DeviceDoc/80311a.pdf MCP23X17 Errata (A2 = 1 and HAEN = 0)
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en027237 MCP23S17 Unique Features
My project? A model railroad turntable self indexing drive system. By using an optical rotary encoder with 1024 steps and an index step, for absolute rotation control, when attached to the axle of turntable, any position can be programmed to within 0.3 degrees. There are simpler setups, but I wanted to be able to anticipate approaching the final destination, and start to slow the drive motor speed down in steps before reaching the destination. Also, the logic will determine if it is faster to go clockwise or counter-clockwise to get to the desired exit track. Why 1024 steps? I could not find an encoder with 256 or 512 steps that supported an index step. The 1024 steps required 10 bits to implement, and an11th bit for flipping the table 180 degrees. The MCP23S17 will interrupt based on one of the 11 bits changing from 1, and will also invert the input bits received. Three requirements met with 1 chip, handling 11 bits, interrupt and bit inversion. It doesn’t get much better then that. Turntables run infrequently on the layout, I’ll use an interrupt so I will not be constantly polling the registers for a change, I maybe will be able to use the same processor to run another planned railroad project. That project will require the MCP23017 I2C 2-wire operation.
I hope the forum is an appropriate spot to post for now. Once everything is checked out, I'll move the relevant information to the playground.