https://obrazki.elektroda.pl/5502422400_1590145798_thumb.jpg Witajcie moi drodzy Chciałbym zaprezentować tutaj drugą wersję mojego Arduino VGA Shield (nakładki na Arduino UNO generującej jednokolorowy obraz VGA i czarno-biały PAL/NTSC) - tym razem wykonaną za pomocą elementów SMD, i z dodatkowymi układami na pokładzie (expander portów MCP23016 oraz dwie kości EEPROM AT24CM02). Opis pierwszej wersji tego shielda znajdziecie tutaj: https://www.elektroda.pl/rtvforum/viewtopic.php?p=18496229#18496229 Co to za Arduino Shield? W dużym skrócie mój shield jest nakładką na Arduino UNO która pozwala bardzo łatwo generować jednokolorowy obraz na monitor VGA oraz obsługiwać klawiaturę PS/2. Opcjonalnie też dostępne jest wyjście sygnału PAL/NTSC dla telewizorów. Shield korzysta z biblioteki 'ASCII Video Terminal' dla PIC32MX250F128B autorstwa geoffg. Arduino UNO komunikuje się z tym shieldem poprzez UART na wybranych przez nas za pomocą lutowanej zworki pinach. Dodatkowo na pokładzie (nowość w tej wersji!) znajduje się: - expander portów MCP23016, dzięki czemu zyskujemy aż 16 dodatkowych IO! - dwie kości EEPROM AT24CM02, dzięki którym zyskujemy aż 512KB pamięci nieulotnej do własnych projektów! Obie nowości znajdują się na magistrali I2C od Arduino. Poniżej szczegółowo opiszę cały projekt, umieszczę proste przykłady użycia nowości na płytce a na koniec dam bardziej zaawansowane demka korzystające z poszczególnych funkcjonalności shielda. Projekt Arduino VGA Shield SMD Niniejszy projekt jest zasadniczo aktualizacją jego poprzedniej wersji która była wykonana w THT (montaż przewlekany): https://obrazki.elektroda.pl/2294289300_1588796118_thumb.jpg W obecnej wersji większość elementów jest w obudowach SMD, dodatkowo dzięki zaoszczędzonemu miejscu udało mi się na płytkę dodać: - złącze USB od PIC32 (do aktualizacji softu poprzez bootloader; może to dać też w przyszłości możliwość łatwego użycia tego shielda bez Arduino, ale na razie brakuje na PCB w tym celu regulatora 3.3V) - dwie kości pamięci EEPROM AT24CM02 na magistralę I2C od Arduino (standardowo piny 4 i 5) - 16-bitowy expander portów MCP23016 na magistralę I2C od Arduino (jak wyżej; piny 4 i 5) - rezystory pull-up na piny 4 i 5 (jak wyżej; magistrala I2C Arduino) W ten sposób obecna wersja wyszła tak: https://obrazki.elektroda.pl/8546300900_1588796382_thumb.jpg Całość open hardware i do pobrania poniżej. Schemat płytki w PDF: 1030456 Schemat płytki w PNG: 1030457 Pełny projekt płytki w Eagle (.sch + .brd): 1030455 Pliki Gerber które wyeksportowałem z Eagle (te same, których użyłem przy zleceniu wykonania gołego PCB płytkarni): 1030453 Tym razem obyło się bez żadnych błędów na płytce. Płytki standardowo zamówiłem w Chinach (10 sztuk - ktoś chętny na kilka?) a jak przybyły to wziąłem się do lutowania. Lutowanie Arduino VGA Shield w wersji SMD Opiszę tutaj szczegółowo jak zlutowałem tę płytkę w warunkach domowych. Na początek przygotowałem wszystkie elementy: https://obrazki.elektroda.pl/8220448100_1588804224_thumb.jpg https://obrazki.elektroda.pl/6139364300_1588804228_thumb.jpg I tym razem nawet nie używałem złącza VGA (DSUB25) z starej płyty głównej od komputera, tylko miałem zakupione przez internet. Do lutowania użyłem mojej wiernej najtańszej lutownicy kolbowej i na tę okazję zmieniłem jej grot na grot ścięty (choć pewnie lepszy byłby grot ścięty typu minifala, ten z wyżłobionym 'zbiorniczkiem' na cynę): https://obrazki.elektroda.pl/4748971600_1588804324_thumb.jpg Zacząłem lutowanie od najmniejszych elementów: https://obrazki.elektroda.pl/3753769700_1588804437_thumb.jpg Dałem też wtedy cynową zworkę na sygnał "B" (Blue) koło złącza VGA, czyli wybrałem niebieski kolor czcionki. Szybko przyszła pora na złącza: https://obrazki.elektroda.pl/8356330500_1588804501_thumb.jpg https://obrazki.elektroda.pl/6638436500_1588804722_thumb.jpg Złącze DSUB25 czyli VGA oraz MDC6 (aka 'mini din') czyli PS/2: https://obrazki.elektroda.pl/6815685300_1588804785_thumb.jpg Na zdjęciu można zobaczyć, że wciąż nie przylutowałem EEPROMów - to dlatego, że dopiero czekałem na paczkę z nimi. Jak przyszły to uzupełniłem ubytek: https://obrazki.elektroda.pl/3204394600_1588804882_thumb.jpg https://obrazki.elektroda.pl/1382751400_1588804914_thumb.jpg Potem jeszcze uzupełniłem ubytek złącza RCA (od sygnału PALNTSC); nie miałem takiego na składzie więc wylutowałem z jakiegoś fragmentu urządzenia elektronicznego, to chyba był odtwarzacz kaset VHS: https://obrazki.elektroda.pl/7021071000_1588805047_thumb.jpg https://obrazki.elektroda.pl/9088830900_1588805043_thumb.jpg https://obrazki.elektroda.pl/5706716800_1588805051_thumb.jpg Złącze RCA: https://obrazki.elektroda.pl/4076050200_1588805209_thumb.jpg I oto końcowy efekt (już po wyczyszczeniu z nadmiaru topnika): https://obrazki.elektroda.pl/1416338600_1588846009_thumb.jpg https://obrazki.elektroda.pl/6408921300_1588846191_thumb.jpg Warto jeszcze pamiętać, że przed użyciem należy zrobić ze spoiwa lutowniczego następujące zworki: - zworka pinu RX shielda z Arduino - zworka pinu TX shielda z Arduino - zworka pinu RESET z Shielda (łączy RESET od PIC32 z RESET od Arduino) - zworka wyboru koloru VGA z Shielda - dwie zworki na magistrali I2C dla EEPROMów Przed użyciem shielda trzeba oczywiście też wgrać mu firmware na PIC32MX250F128B za pomocą PICKIT3 (lub innego programatora) poprzez złącze ICSP dostępne na płytce. Test generowanego sygnału VGA z różnymi monitorami i telewizorem W temacie dotyczącym poprzedniej wersji mojego shielda (tutaj: https://www.elektroda.pl/rtvforum/viewtopic.php?p=18496229#18496229 ) pojawiła się uwaga, że nie działa on z częścią monitorów. Postanowiłem to zweryfikować. Użyłem do tego: - telewizora LG42LE4500 - monitora DELL 1703FP - monitora ASUS VH196S - monitora HP L1706 - monitora SyncMaster 740N Zapraszam do obejrzenia zdjęć z testów. Test 1 - monitor DELL 1703FP: https://obrazki.elektroda.pl/9890789800_1588852185_thumb.jpg https://obrazki.elektroda.pl/5803001300_1588852224_thumb.jpg Tabliczka znamionowa użytego monitora: https://obrazki.elektroda.pl/2073302500_1588783980_thumb.jpg Test 2 - telewizor LG42LE4500: https://obrazki.elektroda.pl/5747425500_1588852640_thumb.jpg https://obrazki.elektroda.pl/7081934500_1588852638_thumb.jpg Tabliczka znamionowa użytego telewizora: https://obrazki.elektroda.pl/7031910900_1588783997_thumb.jpg Test 3 - monitor ASUS VH196S: https://obrazki.elektroda.pl/2275459400_1588854942_thumb.jpg https://obrazki.elektroda.pl/3360872300_1588854987_thumb.jpg Tabliczka znamionowa użytego monitora: https://obrazki.elektroda.pl/5879373100_1588854839_thumb.jpg Test 4 - HP L1706. https://obrazki.elektroda.pl/7060437300_1588855274_thumb.jpg https://obrazki.elektroda.pl/2953685300_1588855274_thumb.jpg Tabliczka znamionowa użytego monitora: https://obrazki.elektroda.pl/6106436200_1588855202_thumb.jpg Test 5 - SyncMaster 740N. Ten monitor naprawiałem tutaj: https://www.elektroda.pl/rtvforum/topic3688191.html , wymieniłem w nim kondensatory elektrolityczne. Dzięki temu może dalej działać i brać udział w testach mojego shielda: https://obrazki.elektroda.pl/4246636900_1588855412_thumb.jpg https://obrazki.elektroda.pl/2066575900_1588855446_thumb.jpg Tabliczka znamionowa użytego monitora: https://obrazki.elektroda.pl/1258439900_1588855496_thumb.jpg Podsumowując, shield VGA przetestowałem z czterema monitorami i jednym telewizorem i w każdym przypadku obraz był poprawnie wyświetlany. Sygnał widziany jest przez wszystkie urządzenia jako 640x480, mimo iż w dokumentacje użytej biblioteki jest podana nieco inna rozdzielczość. Po prostu shield w sprytny sposób sobie z tym radzi zostawiając puste marginesy wokół obrazu (co zresztą widać na większości zdjęć z jego działania). Nie znalazłem ani jednego urządzenia przez którego sygnał VGA z mojego shielda nie był wspierany, a jego timingi (31.5kHz i 60Hz) są zgodne z tym, co jest w kodzie: https://obrazki.elektroda.pl/8567581200_1590314726_thumb.jpg Test generowanego sygnału PAL Generowanie czarno-białego obrazu PAL (oraz NTSC - też jest wspierany) może się przydać gdy chcemy obsłużyć jakiś starszy telewizor, pewnie jeszcze CRT, który nie posiada złącza VGA. Może to być podyktowane chociażby sentymentem - niektórzy lubią korzystać ze starszego sprzętu nawet dla samej satysfakcji korzystania z niego. Z tego powodu przetestowałem też jak shield radzi sobie z generowaniem sygnału PAL. Sygnał PAL ze shielda podłącza się za pomocą przewodu RCA: https://obrazki.elektroda.pl/9451123200_1590143186_thumb.jpg Wystarczy pojedynczy sygnał video, audio nie jest oferowane przez ten shield. Test PAL 1 - telewizor LG42LE4500: Podłączenie: https://obrazki.elektroda.pl/2258585600_1590146184_thumb.jpg https://obrazki.elektroda.pl/9368920000_1590146199_thumb.jpg https://obrazki.elektroda.pl/3942760900_1590146205_thumb.jpg Obraz na ekranie: https://obrazki.elektroda.pl/9427440500_1590146322_thumb.jpg Obraz generowany przez shield jest tutaj rzecz jasna czarno-biały; zworka od koloru (wybór R/G/B) jest tylko dla VGA. Test PAL 2 - stary telewizor CRT TX-21AT1P: Ten pierwszy test PAL z nowym, płaskim telewizorem LG42LE4500 poniekąd mija się z celem, bo użyty tam telewizor ma złącze VGA (i to nie jedno!) więc nic nie stoi na przeszkodzie, by go podłączyć normalnie. Z tego powodu też przetestowałem tryb PAL z telewizorem który jest o wiele bardziej z tym trybem związanym - ze starym, ciężkim telewizorem kineskopowym, dokładniej 'Panasonic Colour TV' model TX-21AT1P: https://obrazki.elektroda.pl/8911258000_1590161461_thumb.jpg Tabliczka znamionowa tego telewizora: https://obrazki.elektroda.pl/8935412200_1590161531_thumb.jpg https://obrazki.elektroda.pl/7483420000_1590161541_thumb.jpg Sygnał PAL podłączyłem z przodu telewizora do złącz RCA: https://obrazki.elektroda.pl/9148315700_1590161702_thumb.jpg Warto tu wspomnieć, że nawet jeśli telewizor nie ma złącz RCA to sygnał PAL można też podać poprzez SCART - w przewodzie SCART jest jeden pin odpowiedzialny za wejście 'composite video'. Sygnał PAL oczywiście tutaj nie jest modulowany i odbieramy go w trybie AV: https://obrazki.elektroda.pl/6474478000_1590161796_thumb.jpg (Aczkolwiek jakby się postarać i użyć np. modulatora ze starego odtwarzacza VHS to można by prosto odbierać sygnał ze shielda poprzez złącze antenowe; choć wtedy jest ryzyko, że będziemy 'siać' sygnał po okolicy; do tej pory pamiętam jak kilkanaście lub więcej lat temu odbierałem przez przypadek na telewizorze obraz z konsoli do gier sąsiada). Na telewizorze uruchomiłem demko, które opisane jest nieco niżej w tekście. Rezultat: https://obrazki.elektroda.pl/3756502800_1590162046_thumb.jpg Uwaga - co jeśli monitor pokazuje 'nieobsługiwany format VGA'? Chciałbym tu tylko jeszcze przypomnieć, że shield w celu obsługi zarówno standardu PAL jak i VGA musi w sprytny sposób między nimi przełączać. Nie generuje dwóch sygnałów naraz. Shield przy starcie (po sygnale RESET lub podaniu zasilania) sam określa, czy monitor VGA jest podłączony i jeśli nie, to przechodzi w tryb PAL. Określa to poprzez badanie stanu na pinie RA4. Więc jeśli podłączymy monitor VGA w trakcie do shielda to powinniśmy wcisnąć przycisk RESET na Arduino lub wyłączyć i włączyć zasilanie - w przeciwnym razie shield będzie już 'nastawiony na PAL' i monitor VGA nic nie wyświetli. RESET z Arduino jest połączony z RESET (aka MCLR) z PIC32 z płytki shielda, ale należy pamiętać by na płytce shielda dać tam zworkę by oba układy resetowały się razem. (O tym, że mam wspomnieć o tym problemie przypomniał mi Bartek, który odkupił ode mnie jedno PCB poprzedniej wersji shielda - za przetestowanie układu i zwrócenie uwagi tu dziękuję) Test magistrali I2C - skan dostępnych urządzeń Na samym początku na mojej płytce uruchomiłem prosty program całkowicie niezwiązany z VGA - skaner I2C. Program ten pochodzi z oficjalnej strony Arduino: https://playground.arduino.cc/Main/I2cScanner/ i po prostu wykrywa wszystkie urządzenia podłączone na magistralę I2C, czyli w przypadku użytego przeze mnie Arduino UNO na jego piny 4 i 5. Program drukuje adresy I2C znalezionych urządzeń na port szeregowy/terminal Arduino. #include <Wire.h> //include Wire.h library void setup() { Wire.begin(); // Wire communication begin Serial.begin(9600); // The baudrate of Serial monitor is set in 9600 while (!Serial); // Waiting for Serial Monitor Serial.println("\nI2C Scanner"); } void loop() { byte error, address; //variable for error and I2C address int nDevices; Serial.println("Scanning..."); nDevices = 0; for (address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address < 16) Serial.print("0"); Serial.print(address, HEX); Serial.println(" !"); nDevices++; } else if (error == 4) { Serial.print("Unknown error at address 0x"); if (address < 16) Serial.print("0"); Serial.println(address, HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(5000); // wait 5 seconds for the next I2C scan } Program skompilowałem i wgrałem na Arduino z założonym moim shieldem. Rezultat sketchu: https://obrazki.elektroda.pl/8259841700_1588789861_thumb.jpg Widzimy, że skan I2C znalazł aż 9 urządzeń! Ale czy na pewno? Na powyższym zrzucie ekranu: - adres 0x20 to port expander MCP23016 - adresy 0x50, 0x51, 0x52, 0x53 to pierwszy AT24CM02 (przypominam: w adresie urządzenia AT24CM02 dwa bity odpowiadają za jego 'wewnętrzny adres' pamięci; dwa bity dają nam 4 możliwe adresy) - adresy 0x54, 0x55, 0x56, 0x57 to drugi AT24CM02 Czyli wszystko jest okej - dwie pamięci EEPROM i jeden expander portów. Poniżej zaprezentuję już jak można ich użyć. Lutowanie przejściówki do expandera portów (dla płytki stykowej) Na płytce znajduje się 16-pinowe złącze 2.54mm (2 rzędy po 8 pinów) od MCP23016: https://obrazki.elektroda.pl/3189098400_1588846402_thumb.jpg Oferuje ono dodatkowe 16 pinów IO którymi możemy sterować przez I2C. Polecam używać go w połączeniu z takim przewodem (najlepiej też zakupić odpowiednie gniazdo pod ten przewód by nie dało się go wsadzić odwrotnie, ale ja takiego pod ręką nie miałem): https://obrazki.elektroda.pl/1013751400_1588799286_thumb.jpg https://obrazki.elektroda.pl/6126385500_1588799285_thumb.jpg Do tego sugeruję zlutować sobie przejściówkę z tego przewodu do płytki stykowej/prototypowej. Płytka stykowa ma rozstaw pól 2.54mm pasujący do goldpinów, za wyjątkiem środkowego przedziałka płytki który ma akurat 5.08mm, czyli tyle ile wąski rozstaw pinów z obudowy DIP. Aż prosi się to wykorzystać. Opiszę tutaj jak - na początek trzeba przygotować goldpiny 1x8 (dwie sztuki) i 2x8 (jedna sztuka) oraz płytkę wierconą: https://obrazki.elektroda.pl/8689529400_1588799587_thumb.jpg https://obrazki.elektroda.pl/3694746900_1588799587_thumb.jpg Następnie warto dodać topnik na płytkę, by się lepiej lutowało: https://obrazki.elektroda.pl/4560970200_1588799647_thumb.jpg Dalej umieścić na naszej płytce pierwszy rząd goldpinów (on będzie wchodzić w płytkę stykową), ale odwrotnie niż zazwyczaj: https://obrazki.elektroda.pl/3611174500_1588799703_thumb.jpg Teraz trzeba ją przylutować - najwygodniej bardzo cienką końcówką. Przy lutowaniu pilnować, by goldpiny były prostopadle do płytki: https://obrazki.elektroda.pl/8970239000_1588799870_thumb.jpg Pierwszy lut gotowy: https://obrazki.elektroda.pl/5596099700_1588799906_thumb.jpg Następnie trzeba dokończyć wszystkie luty i można od drugiej strony płytki dać złącze 2x8 2.54mm goldpin i zacząć łączyć odpowiednie piny: https://obrazki.elektroda.pl/1829572700_1588799984_thumb.jpg Dalej polecam delikatnie przylutować drugi pojedynczy rząd goldpinów który wejdzie w płytkę stykową: https://obrazki.elektroda.pl/6292228500_1588800085_thumb.jpg https://obrazki.elektroda.pl/3709848100_1588800087_thumb.jpg Następnie wystarczy zmostkować odpowiednie piny za pomocą lutownicy. Jeszcze tylko trzeba odciąć zbędny fragment PCB: https://obrazki.elektroda.pl/8851617300_1588800172_thumb.jpg Przejściówka gotowa: https://obrazki.elektroda.pl/5095248300_1588800212_thumb.jpg Idealnie pasuje do wybranego przeze mnie przewodu (choć ponownie tu Wam polecam użyć nie zwykłych goldpinów 2x8, lecz złącza pod ten konkretny kabelek; wtedy unikniecie ryzyka podłączenia go odwrotnie): https://obrazki.elektroda.pl/1732464200_1588800500_thumb.jpg Przejściówka expandera portów gotowa. Tak wygląda razem z Shieldem i Arduino: https://obrazki.elektroda.pl/3922228300_1588800544_thumb.jpg Następne cztery akapity przedstawią testy MCP23016 w oparciu o te połączenie. Test expandera portu - MCP23016 - użyta biblioteka Na początku do obsługi expandera portów MCP23016 sterowanego poprzez I2C próbowałem użyć tej biblioteki od Adafruit (mimo iż jest ona dla MCP23017 - liczyłem na podobieństwo układów): https://obrazki.elektroda.pl/9380545400_1588790023_thumb.jpg Ale nie zadziałała, więc ostatecznie użyłem biblioteki CyMCP23016 autorstwa Chris Brunner aka cyrusbuilt, stąd: https://github.com/cyrusbuilt/CyMCP23016 Kopia zapasowa repozytorium (na czas pisania tematu): 1030477 Bibliotekę dodałem do Arduino poprzez Sketch->Include Library->Add .ZIP Library. Test expandera portu - MCP23016 - układ testowy Do przygotowania układu testowego MCP23016 użyłem płytki stykowej i wcześniej opisanej przejściówki i kabelka, do tego kilka rezystorów: https://obrazki.elektroda.pl/7024523100_1588802931_thumb.jpg https://obrazki.elektroda.pl/2680579400_1588802952_thumb.jpg Do tego oczywiście trzeba osobno podpiąć masę (i zasilanie, jeśli go potrzebujemy) https://obrazki.elektroda.pl/4391025300_1588803055_thumb.jpg Test expandera portu - MCP23016 - blink LED Pierwszym przykładem użycia MCP23016 jaki przygotowałem jest proste miganie jedną diodą poprzez ten expander portów, poprzez I2C. Wybrałem pin GP0.0, w tej bibliotece oznaczany MCP23016_PIN_GPIO0_0. Kod prawie w całości pochodzi z przykładu biblioteki z Githuba: /** * Basic input/output test for MCP23016 expander. */ #include <Arduino.h> #include "CyMCP23016.h" CyMCP23016 mcp; void setup() { Serial.begin(9600); Serial.println(("start")); // Init MCP23016 at the default address. This assumes we are running on // an ATmel AVR-based arduino, like the Arduino Uno. mcp.begin(); Serial.println(("begin")); // Set Pin 0 on Port 0 as an output. mcp.pinMode(MCP23016_PIN_GPIO0_0, OUTPUT); Serial.println(("pm")); } void loop() { delay(1000); // Set the pin HIGH and read back the state. mcp.digitalWrite(MCP23016_PIN_GPIO0_0, HIGH); uint8_t val = mcp.digitalRead(MCP23016_PIN_GPIO0_0); Serial.print(F("Pin 0.0 is ")); Serial.println(val == HIGH ? "HIGH" : "LOW"); delay(1000); // Set the pin LOW and read back the state. mcp.digitalWrite(MCP23016_PIN_GPIO0_0, LOW); val = mcp.digitalRead(MCP23016_PIN_GPIO0_0); Serial.print(F("Pin 0.0 is ")); Serial.println(val == HIGH ? "HIGH" : "LOW"); } Kod tylko przełącza stan na pierwszym pinie expandera i dodatkowo wysyła jego stan na UART. Rezultat w Serial Monitor: https://obrazki.elektroda.pl/7086169000_1588791010_thumb.jpg Rezultat na filmie: https://filmy.elektroda.pl/92_1588794181.mp4 W taki sam sposób możemy sterować wszystkimi 16 pinami od MCP23016. Test expandera portu - MCP23016 - prosty licznik binarny Drugim, bardziej zaawansowanym przykładem użycia MCP23016 jaki tu zaprezentuję jest prosty licznik binarny zrealizowany na 8 diodach LED (czyli 8-bitowy). Do tego użyłem całego portu GP0: https://obrazki.elektroda.pl/6748085500_1588798418_thumb.jpg Odpowiednio zmodyfikowałem też kod przykładu. Do ustawienia odpowiednich diod LED użyłem pętli for oraz operatorów bitowych, całość sketchu jest do wglądu poniżej: /** * Basic input/output test for MCP23016 expander. */ #include <Arduino.h> #include "CyMCP23016.h" CyMCP23016 mcp; int counter = 0; void setup() { Serial.begin(9600); Serial.println(("start")); mcp.begin(); Serial.println(("begin")); // Set Pin 0 on Port 0 as an output. for(int i = 0; i < 8; i++) { mcp.pinMode(i, OUTPUT); mcp.digitalWrite(i, LOW); } delay(1000); Serial.println(("pm")); } void loop() { delay(250); for(int i = 0; i < 8; i++) { mcp.digitalWrite(i, counter & (1<<(i))); } counter++; } Powyższy kod powinien być zrozumiały nawet dla początkujących z Arduino, jedyną z pozoru trudną rzeczą w nim jest 'wyłuskanie' bitu za pomocą counter & (1<<(i)). Ta linijka po prostu sprawdza, czy i-ty bit zmiennej counter jest zapalony. Rezultat na filmie: https://filmy.elektroda.pl/15_1588793680.mp4 Wszystko działa poprawnie. Można by jeszcze sprawdzić czy wszystko jest okej z drugim portem od MCP23016, ale uznałem, że to już jest zbędne. Test pamięci EEPROM - AT24CM02 - użyta biblioteka Do obsługi pamięci EEPROM a dokładniej dwóch kości AT24CM02 użyłem biblioteki autorstwa Rushikesh Patel aka luffykesh z Githuba, tej: https://github.com/luffykesh/AT24Cx Kopia zapasowa/snapshot repo na czas pisania artykułu: 1030460 Bibliotekę dodałem do Arduino poprzez Sketch->Include Library->Add .ZIP Library. Test pamięci EEPROM - AT24CM02 - test zapisu i odczytu Na początek sprawdziłem czy w ogóle komunikacja z AT24CM02 działa poprawnie. W tym celu użyłem przykładowego kodu z wybranej biblioteki, jedynie tylko zmodyfikowałem go by korzystał z konkretnie AT24CM02 (z pierwszego na PCB, o adresie 0x50): /* * * Read and write demo of the AT24CX library * Written by Christian Paul, 2014-11-24 * * */ // include libraries #include <Wire.h> #include <AT24CX.h> // EEPROM object AT24CM02 mem; // setup void setup() { // serial init Serial.begin(9600); Serial.println("AT24CX read/write demo"); Serial.println("----------------------"); } // main loop void loop() { // read and write byte Serial.println("Write 42 to address 12"); mem.write(12, 42); Serial.println("Read byte from address 12 ..."); byte b = mem.read(12); Serial.print("... read: "); Serial.println(b, DEC); Serial.println(); // read and write integer Serial.println("Write 65000 to address 15"); mem.writeInt(15, 65000); Serial.println("Read integer from address 15 ..."); unsigned int i = mem.readInt(15); Serial.print("... read: "); Serial.println(i, DEC); Serial.println(); // read and write long Serial.println("Write 3293732729 to address 20"); mem.writeLong(20, 3293732729UL); Serial.println("Read long from address 20 ..."); unsigned long l = mem.readLong(20); Serial.print("... read: "); Serial.println(l, DEC); Serial.println(); // read and write long Serial.println("Write 1111111111 to address 31"); mem.writeLong(31, 1111111111); Serial.println("Read long from address 31 ..."); unsigned long l2 = mem.readLong(31); Serial.print("... read: "); Serial.println(l2, DEC); Serial.println(); // read and write float Serial.println("Write 3.14 to address 40"); mem.writeFloat(40, 3.14); Serial.println("Read float from address 40 ..."); float f = mem.readFloat(40); Serial.print("... read: "); Serial.println(f, DEC); Serial.println(); // read and write double Serial.println("Write 3.14159265359 to address 50"); mem.writeDouble(50, 3.14159265359); Serial.println("Read double from address 50 ..."); double d = mem.readDouble(50); Serial.print("... read: "); Serial.println(d, DEC); Serial.println(); // read and write char Serial.print("Write chars: '"); char msg = "This is a message"; Serial.print(msg); Serial.println("' to address 200"); mem.writeChars(200, msg, sizeof(msg)); Serial.println("Read chars from address 200 ..."); char msg2; mem.readChars(200, msg2, sizeof(msg2)); Serial.print("... read: '"); Serial.print(msg2); Serial.println("'"); Serial.println(); // write array of bytes Serial.println("Write array of 80 bytes at address 1000"); byte xy = {0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9, // 10 x 3 = 30 10,11,12,13,14,15,16,17,18,19, // 10 120,121,122,123,124,125,126,127,128,129, // 10 130,131,132,133,134,135,136,137,138,139, // 10 200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219}; // 20 mem.write(1000, (byte*)xy, sizeof(xy)); // read bytes with multiple steps Serial.println("Read 80 single bytes starting at address 1000"); for (int i=0; i<sizeof(xy); i++) { byte sb = mem.read(1000+i); Serial.print(" = "); Serial.println(sb); } Serial.println(); // read bytes with one step Serial.println("Read 80 bytes with one operation at address 1000"); byte z; memset(&z, 32, sizeof(z)); mem.read(1000, z, sizeof(z)); for (int i=0; i<sizeof(z); i++) { Serial.print(" = "); Serial.println(z); } // stop while (1==1) {delay(1000);} } https://obrazki.elektroda.pl/7951808100_1588847183_thumb.jpg Następnie zmodyfikowałem ten kod tak, by przetestować użycie dwóch EEPROM jednocześnie. W celu weryfikacji czy na pewno kod korzysta z dwóch różnych kości postanowiłem zapisać na ten sam adres różne wartości (dla pierwszej kości: 42, dla drugiej: 15) i potem je odczytać i sprawdzić czy są zachowywane. /* * * Read and write demo of the AT24CX library * Written by Christian Paul, 2014-11-24 * * */ // include libraries #include <Wire.h> #include <AT24CX.h> // EEPROM object AT24CM02 mem0(0); AT24CM02 mem1(1); // setup void setup() { // serial init Serial.begin(9600); Serial.println("AT24CX read/write demo"); Serial.println("----------------------"); } // main loop void loop() { // read and write byte Serial.println(" Write 42 to address 12"); mem0.write(12, 42); Serial.println(" Write 15 to address 12"); mem1.write(12, 15); Serial.println(" Read byte from address 12 ..."); byte b0 = mem0.read(12); Serial.print(" ... read: "); Serial.println(b0, DEC); Serial.println(" Read byte from address 12 ..."); byte b1 = mem1.read(12); Serial.print(" ... read: "); Serial.println(b1, DEC); // stop while (1==1) {delay(1000);} } Rezultat sketchu: https://obrazki.elektroda.pl/9200007400_1588847521_thumb.jpg Jak widać obie pamięci EEPROM działają poprawnie. W ten sposób zyskujemy całe dodatkowe 512KB (dwie kości po 256KB) pamięci! Małe demko - drukowanie kodów klawiszy na ekranie Teraz przedstawię proste demko już bezpośrednio związane z głównymi atutami mojej nakładki, czyli generowaniem obrazu VGA i obsługą klawiatury PS/2. Poniższe demko odbiera klawisze wciśnięte na klawiaturze i wyświetla ich kody na ekranie - za wyjątkiem strzałek, które są kodowane jako kilka kolejnych wartości i trzeba je w specjalny sposób wykrywać. Każda wciśnięcie jednej ze strzałek daje na UART następujące kody: * Up Arrow - 27 91 65 * Down Arrow - 27 91 66 * Right Arrow 27 91 67 * Left Arrow 27 91 68 Strzałki w poniższym demku są wykrywane poprawne i informacje o ich wciśnięciu są wyświetlane jako tekst. UWAGA: Poniższe demko poprawnie obsługuje Caps Lock i wpisywanie znaków z Shift, ale tego nie ma w kodzie na Arduino, gdyż dzieje się to w samym shieldzie i na klawiaturze. Pełny kod demka: /* * Up Arrow - 27 91 65 * Down Arrow - 27 91 66 * Right Arrow 27 91 67 * Left Arrow 27 91 68 * */ #if 0 #define USE_ARDUINO_RXTX #endif #ifdef USE_ARDUINO_RXTX #define vgaSerial Serial #else #include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3); // RX, TX #define vgaSerial mySerial #endif void SCR_Reset() { vgaSerial.print((char)27); vgaSerial.print("c"); } void SCR_PrintLn(const char *s) { vgaSerial.println(s); } void SCR_Print(const char *s) { vgaSerial.print(s); } void SCR_ClearScreen() { vgaSerial.print((char)27); vgaSerial.print("[2J"); } void SCR_SetPos(int x, int y) { vgaSerial.print((char)27); vgaSerial.print("["); vgaSerial.print(x); vgaSerial.print(";"); vgaSerial.print(y); vgaSerial.print("H"); } void setup() { // Open serial communications and wait for port to open: Serial.begin(57600); while (!Serial) { ; // wait for serial port to connect. Needed for Native USB only } Serial.println("started vga"); #ifndef USE_ARDUINO_RXTX //mySerial.begin(1200); // mySerial.begin(57600); // mySerial.begin(38400); mySerial.begin(19200); //mySerial.begin(115200); mySerial.listen(); #endif delay(10); SCR_Reset(); SCR_ClearScreen(); // put your setup code here, to run once: SCR_PrintLn("Arduino VGA Shield Key Code Tester"); //SCR_SetPos(5,5); //SCR_Print("A"); } char buffer ; //whatever void OnPress_ArrowDown() { sprintf (buffer, "Pressed DOWN ARROW"); SCR_PrintLn(buffer); } void OnPress_ArrowRight() { sprintf (buffer, "Pressed RIGHT ARROW"); SCR_PrintLn(buffer); } void OnPress_ArrowLeft() { sprintf (buffer, "Pressed LEFT ARROW"); SCR_PrintLn(buffer); } void OnPress_ArrowUp() { sprintf (buffer, "Pressed UP ARROW"); SCR_PrintLn(buffer); } void OnPress_Key(char inByte) { sprintf (buffer, "Pressed code %i (visual %c)", (int)inByte, inByte); SCR_PrintLn(buffer); } void loop() { // put your main code here, to run repeatedly: while (vgaSerial.available() > 0) { char inByte = vgaSerial.read(); if(inByte == 27) { while (vgaSerial.available() == 0) { } vgaSerial.read(); while (vgaSerial.available() == 0) { } char inByte2 = vgaSerial.read(); if(inByte2 == 65) { OnPress_ArrowUp(); } if(inByte2 == 66) { OnPress_ArrowDown(); } if(inByte2 == 68) { OnPress_ArrowLeft(); } if(inByte2 == 67) { OnPress_ArrowRight(); } } else { OnPress_Key(inByte); } } } Rezultat działania: https://obrazki.elektroda.pl/9093480600_1589293381_thumb.jpg Shift i Caps-Lock są poprawnie obsługiwane, a same klawisze są bezbłędnie odbierane (za wyjątkiem pewnej sytuacji - ale o tym w następnym akapicie). Dlaczego lepiej korzystać z baud 19200 a nie np. z 1200? Tutaj chciałbym zwrócić uwagę na to jak duże znaczenie ma świadomy wybór odpowiedniego baud komunikacji UART ze shieldem. Nie można wybrać zbyt dużego baud, bo ogranicza nas zdolność SoftwareSerial z Arduino. Przy około 38400 mogą się zacząć problemy. To raczej wiadomo, podobne informacje powtarzają się na forum Arduino: https://forum.arduino.cc/index.php?topic=528912.0 Ale nie można też wybrać zbyt małego baud, bo wtedy będziemy gubić znaki lub co gorsza otrzymywać błędne dane. Łatwo to pokazać uruchamiając demo 'test klawiszy' i wciskając (trzymając cały czas) klawisz strzałki, który wysyłany jest przez UART jako trzy znaki. Zdjęcie demka 'odbiór klawiszy' przy baud 1200: https://obrazki.elektroda.pl/9787153500_1589293837_thumb.jpg Zdjęcie demka 'odbiór klawiszy' przy baud 19200: https://obrazki.elektroda.pl/2876768200_1589293876_thumb.jpg Widzicie różnicę? Wniosek: nieodpowiednio dobrany baud może naprawdę namieszać, również gdy wybierzemy jego zbyt małą wartość. Na zdjęciu widać, że raz nawet wysłała się wartość '109' która odpowiada klawiszowi 'm', co z pewnością mogłoby mieć niepożądany skutek jeśli byśmy w naszym programie korzystali zarówno ze strzałek jak i z tego klawisza. Zaawansowane edytor tekstu Teraz zaprezentuję nieco bardziej zaawansowane demko oparte o mojego shielda, a mianowicie prosty edytor tekstu. Edytor tekstu będzie oferować: - obsługa klawisza Shift - obsługa klawisza Caps Lock - obsługa klawisza Delete (usuwanie znaku po kursorze) - obsługa klawisza Backspace (usuwanie znaku przed kursorem) - obsługa klawisza Enter (dodawanie nowej linii) Część tej funkcjonalności jest po stronie Arduino, a część na shieldzie. Rzeczy takie jak poruszanie kursorem, obsługa bufora tekstu, dodawanie znaków, usuwanie ich itp. są po stronie Arduino. Zdjęcia z działania dema-edytora tekstu na monitorze VGA i klawiaturze PS2: https://obrazki.elektroda.pl/5248090800_1589747497_thumb.jpg https://obrazki.elektroda.pl/5745421400_1589747497_thumb.jpg https://obrazki.elektroda.pl/5153392700_1589747496_thumb.jpg https://obrazki.elektroda.pl/5951234900_1589747502_thumb.jpg https://obrazki.elektroda.pl/5538928900_1589747504_thumb.jpg Edytor tekstu można by znacznie ulepszyć, ograniczyć bardziej zbędne odświeżanie pełnego ekranu lub po prostu przenieść w większej części na PICa. Skecz Arduino do pobrania: 1030452 Test edytora tekstu na starym telewizorze CRT TX-21AT1P W ramach uzupełnienia poprzedniego akapitu przedstawiam tu filmik z działania edytora tekstu w trybie PAL na telewizorze kineskopowym: https://filmy.elektroda.pl/13_1590143145.mp4 Zbędne 'pełne odświeżenie' ekranu w trakcie dodawania nowej linii do tekstu można by usunąć w kodzie programu, ale nie to było celem tego demka. Zaawansowane demko - system plików na EEPROM Przedstawione tutaj demko opracowałem w celu dokładniejszego przetestowania obu pamięci EEPROM znajdujących się na płytce (te pamięci pozwalają nam zapisać dane które nie utracą się nawet po całkowitym odłączeniu zasilania od Arduino). Demko to stanowi podstawową wersję systemu plików, który wspiera podstawowe operacje na plikach i katalogach (tworzenie ich, usuwanie, dodawanie danych, przeglądanie, czyszczenie), pozwala też zagnieżdżać katalogi/pliki w innych katalogach tworząc strukturę drzewa. System oczywiście też jest na różne sposoby ograniczony - brakuje dynamicznej alokacji pamięci dla danych pliku, choć jest ona dostępna dla samych katalogów i plików (używane są ponownie zwolnione sloty). Demko obsługuje się poprzez Serial Monitor od Arduino który pełni dla niego funkcję linii komend i wspiera następujące polecenia: - dirls - wyświetla zawartość bieżącego katalogu - mkdir - tworzy katalog o danej nazwie - rmdir - usuwa katalog z zawartością - resetfs - resetuje EEPROMy do pustego systemu plików - resetfile - resetuje plik do stanu pustego (tj. ustawia jego długość na zero) - rmfile - usuwa plik - cd - przechodzi do danego folderu - mkfile - tworzy pusty plik o danej nazwie - append - dodaje do danego pliku dany ciąg znaków - show - pokazuje dany plik w konsoli Poniżej umieszczam zrzuty ekranu z testów powyższego systemu plików; myślę, że ich zawartość nie wymaga komentarza. Testy komend mkdir, ls, mkfile, append, ls: https://obrazki.elektroda.pl/9208051700_1589744617_thumb.jpg Testy komend: cd, mkdir, mkfile: https://obrazki.elektroda.pl/5551405800_1589744899_thumb.jpg Testy komend: rmdir, rmfile, resetfs: https://obrazki.elektroda.pl/7737634500_1589744985_thumb.jpg Testy komend: show, mkfile, append: https://obrazki.elektroda.pl/9026338300_1589745050_thumb.jpg Demko do pobrania: 1030449 Kompilacja wsadu z kodu źródłowego Jeśli tylko chcecie złożyć i używać tego shielda z Arduino to nie musicie samodzielnie kompilować kodu na PICa, potrzebny dla niego .hex załączam tutaj: 1030451 Ale jeśli ktoś chce zmodyfikować samo działanie shielda, to kod można łatwo skompilować w środowisku MPLAB X IDE v5.20: https://obrazki.elektroda.pl/1438991700_1590314916_thumb.jpg Przy użyciu kompilatora XC32 (v2.20): https://obrazki.elektroda.pl/6079210300_1590315087_thumb.jpg Dodatkowo do kompilacji wymagana jest biblioteka PIC32 Peripheral Library (słynne plib.h wraz z innymi nagłówkami), którą ściąga się osobno ze strony Microchipa: https://www.microchip.com/SWLibraryWeb/product.aspx?product=PIC32%20Peripheral%20Library Gdy już ją zainstalujemy, to wszystko poprawnie się kompiluje: https://obrazki.elektroda.pl/2965134100_1590410028_thumb.jpg Kompilować wsad można w dwóch trybach: - tryb dla bootloadera (do wgrania wsadu przez USB za pomocą PIC32UBL.exe) - wtedy w projekcie załączamy 32MX250F128B.ld - tryb bez bootloadera (do wgrania wsadu przez ICSP) - wtedy w projekcie wykluczamy plik 32MX250F128B.ld Więcej informacji na ten temat znajdziecie w oryginalnej paczce z kodem źródłowym: 1030459 Dalszy rozwój projektu - dalsza minimalizacja? Obecna wersja pozostawia jeszcze pole do popisu i możliwość ulepszenia, m.in. dlatego że np. użyty PIC32 jest w wersji PIC32MX250F128B-50I/SO, czyli obudowa SOIC: https://obrazki.elektroda.pl/7523413500_1588796498_thumb.jpg A ten sam mikrokontroler jest jeszcze dostępny w obudowach SSOP (PIC32MX250F128B-50I/SS): https://obrazki.elektroda.pl/9127079900_1588796563_thumb.jpg ... oraz w QFN (PIC32MX250F128B-50I/ML): https://obrazki.elektroda.pl/2453157800_1588796599_thumb.jpg Wszystkie obudowy naszego PICa (kolejno: QFN, SSOP, SOIC i SPDIP) umieściłem na obrazku poniżej: https://obrazki.elektroda.pl/2428852500_1588857711_thumb.jpg Dalszy rozwój projektu - co można by lepiej zrobić? Projekt (i też jego wykonanie - luty) nie jest idealny i dużo można by jeszcze ulepszyć. - można by dać slot na kartę microSD na płytce (podłączony do SPI od Arduino) - można by (jak wspomniałem wyżej) użyć mniejszych obudów elementów i zyskać w ten sposób miejsce na coś więcej na płytce - można by zastąpić MCP23016 (wymagający zewnętrznego rezystora i kondensatora na pinie CLK) poprzez nieco lepszy MCP23017 (który nie wymaga tych dwóch elementów) - można by też dać tam mocniejszego PICa i/lub iść w stronę kolorowego VGA - umieszczone tu przykłady możny by ulepszyć i zoptymalizować, lecz nie to było ich celem (to tylko demonstracja możliwości shielda, nie miała być wydajna) Możliwe zatem, że za jakiś czas zrobię trzecią wersję shielda. Tabela załączników Dla wygody czytelników umieszczam tutaj raz jeszcze odnośniki do załączników które pojawiły się w temacie: NazwaOpisZałącznik Źródła Eagle projektuPliki .sch i .brd które można edytować w Eagle. Użyjcie tego, jeśli chcecie zrobić własną, zmodyfikowaną wersję tego shielda. 1030455 Pliki Gerber projektuTe pliki wysyłamy płytkarni jeśli chcemy by nam wyprodukowali PCB pod ten projekt. Nie polecam ich edytować. 1030453 Arduino skecz - demo edytora tekstuPełny kod edytora tekstu zrealizowanego na tym shieldzie dla Arduino w formacie .ino. Wymaga podłączonej klawiatury i monitora/telewizora do działania. 1030452 Arduino skecz - demo klawiszyPełny kod testera klawiszy PS/2 z obsługą strzałek zrealizowanego na tym shieldzie dla Arduino w formacie .ino. Wymaga podłączonej klawiatury i monitora/telewizora do działania. 1030450 Arduino skecz - demo system plików na EEPROMPełny kod prostego systemu plików na dwóch kościach EEPROM na magistrali I2C Arduino wraz z linią komend na UART. Ten projekt nie korzysta wcale z VGA i nie korzysta z klawiatury PS/2. Kod w formacie .ino 1030449 Skompilowane firmware dla PICa z ShieldaNiezbędny wsad do jednorazowego wgrania na PIC32MX250F128B znajdującego się na pokładzie shielda. Można go wgrać np. za pomocą PICKIT3. 1030451 Kod źródłowy shieldaKod C firmware shielda na PIC32MX250F128B dla MPLAB. Projekt autorstwa geoffg. 1030459 Datasheet AT24CM02Dla dociekliwych - nota katalogowa użytej kości pamięci 1030458 Datasheet MCP23016Dla dociekliwych - nota katalogowa użytego expandera portów 1030454 Biblioteka AT24CXBiblioteka AT24CX z Githuba - kopia zapasowa, wersja ta którą przetestowałem i wykorzystałem do tego projektu. Tę paczkę .ZIP można łatwo dodać do Arduino poprzez 'Add .ZIP Library...'. 1030460 Biblioteka CyMCP23016Biblioteka CyMCP23016 z Githuba - kopia zapasowa, wersja ta którą przetestowałem i wykorzystałem do tego projektu. Tę paczkę .ZIP można łatwo dodać do Arduino poprzez 'Add .ZIP Library...'. 1030477 Podsumowanie Jestem bardzo zadowolony z drugiej wersji mojego shielda. Przejście z montażu przewlekanego na powierzchniowy pozwoliło mi zmieścić na nim nieco więcej niż w pierwszej wersji. Dzięki oparciu o Arduino UNO całość jest wygodna i prosta w użyciu nawet dla początkujących. Umieszczone dodatkowo na płytce układy (MCP23016 i AT24CM02) też posiadają gotowe biblioteki dla Arduino dostępne w sieci, co sprawia, że obsługa mojego shielda sprowadza się do składania programów niemalże jak z klocków, a użycie klawiatury PS/2 oraz możliwość wyświetlania jednokolorowego obrazu VGA oraz czarno-białego obrazu PAL/NTSC nadaje całości nieco 'oldschoolowy' klimat.
MCP23016
16-Bit I2C™ I/O Expander
Features
Package Types
• 16-bit remote bidirectional I/O port
- 16 I/O pins default to 16 inputs
• Fast I2C™ bus clock frequency (0 - 400 kbits/s)
• Three hardware address pins allow use of up to
eight devices
• High-current drive capability per I/O: ±25 mA
• Open-drain interrupt output on input change
• Interrupt port capture register
• Internal Power-On Reset (POR)
• Polarity inversion register to configure the polarity
of the input port data
• Compatible with most microcontrollers
• Available temperature range:
- Industrial (I): -40°C to +85°C
PDIP, SOIC, SSOP
QFN
GP1.2
GP1.3
INT
GP1.4
VSS
CLK
TP
CMOS Technology
• Operating Supply Voltage: 2.0V to 5.5V
• Low standby current
GP0.7
GP0.6
GP0.5
GP0.4
GP0.3
GP0.2
GP0.1
GP0.0
VDD
VSS
A2
A1
A0
SDA
28
27
26
25
24
23
22
21
20
19
18
17
16
15
GP1.1
GP1.0
Vss
GP0.7
GP0.6
GP0.5
GP0.4
•1
2
3
4
5
6
7
8
9
10
11
12
13
14
MCP23016
Vss
GP1.0
GP1.1
GP1.2
GP1.3
INT
GP1.4
VSS
CLK
TP
GP1.5
GP1.6
GP1.7
SCL
28 27 26 2524 23 22
21
20
19
MCP23016 18
17
16
15
8 9 10 11 121314
GP0.3
GP0.2
GP0.1
GP0.0
VDD
VSS
A2
GP1.5
GP1.6
GP1.7
SCL
SDA
A0
A1
Packages
1
2
3
4
5
6
7
• 28-pin PDIP, 300 mil; 28-pin SOIC, 300 mil
• 28-pin SSOP, 209 mil; 28-pin QFN, 6x6 mm
Block Diagram
Low Pass
Filter
Interrupt
Logic
INT
SDA
CLKIN
TP
VDD
I2C™ Bus
Interface/
Protocol
Handler
Address
Decoder
I2C™ Bus
Control
IARES
16 Bits
Clock
Gen
VSS
© 2007 Microchip Technology Inc.
GP1.0 to GP1.7
Write pulse
Power-on
Reset
8-Bit
GP0.0 to GP0.7
I/O
Port
Control
SCL
Serializer/
Deserializer
A0
A1
A2
Read pulse
Configuration
Registers
Control
DS20090C-page 1
MCP23016
NOTES:
DS20090C-page 2
© 2007 Microchip Technology Inc.
MCP23016
1.0
DEVICE OVERVIEW
The MCP23016 device provides 16-bit, general
purpose, parallel I/O expansion for I2C bus
applications.
This device includes high-current drive capability, low
supply current and individual I/O configuration. I/O
expanders provide a simple solution when additional
I/Os are needed for ACPI, power switches, sensors,
push buttons, LEDs and so on.
The MCP23016 consists of multiple 8-bit configuration
registers for input, output and polarity selection. The
system master can enable the I/Os as either inputs or
outputs by writing the I/O configuration bits. The data
for each input or output is kept in the corresponding
1.1
input or output register. The polarity of the read register
can be inverted with the polarity inversion register (see
Section 1.7.3, “Input Polarity Registers”). All
registers can be read by the system master.
The open-drain interrupt output is activated when any
input state differs from its corresponding input port
register state. This is used to indicate to the system
master that an input state has changed. The interrupt
capture register captures port value at this time. The
Power-on Reset sets the registers to their default values and initializes the device state machine.
Three device inputs (A0 - A2) determine the I2C
address and allow up to eight I/O expander devices to
share the same I2C bus.
Pin Descriptions
TABLE 1-1:
Pin Name
PINOUT DESCRIPTION
PDIP,
SOIC,
SSOP
Pin No.
QFN
Pin No.
I/O/P
Type
Buffer
Type
Description
CLK
9
6
I
ST
Clock source input
TP
10
7
O
—
Test Pin (This pin must be left floating)
GP1.0
2
27
I/O
TTL
D0 digital input/output for GP1
GP1.1
3
28
I/O
TTL
D1 digital input/output for GP1
GP1.2
4
1
I/O
TTL
D2 digital input/output for GP1
GP1.3
5
2
I/O
TTL
D3 digital input/output for GP1
GP1.4
7
4
I/O
TTL
D4 digital input/output for GP1
GP1.5
11
8
I/O
ST
D5 digital input/output for GP1
GP1.6
12
9
I/O
ST
D6 digital input/output for GP1
GP1.7
13
10
I/O
ST
D7 digital input/output for GP1
GP0.0
21
18
I/O
TTL
D0 digital input/output for GP0
GP0.1
22
19
I/O
TTL
D1 digital input/output for GP0
GP0.2
23
20
I/O
TTL
D2 digital input/output for GP0
GP0.3
24
21
I/O
TTL
D3 digital input/output for GP0
GP0.4
25
22
I/O
TTL
D4 digital input/output for GP0
GP0.5
26
23
I/O
TTL
D5 digital input/output for GP0
GP0.6
27
24
I/O
TTL
D6 digital input/output for GP0
GP0.7
28
25
I/O
TTL
D7 digital input/output for GP0
SCL
14
11
I
ST
Serial clock input
SDA
15
12
I/O
ST
Serial data I/O
INT
6
3
O
OD
Interrupt output
A0
16
13
I
ST
Address input 1
A1
17
14
I
ST
Address input 2
A2
18
15
I
ST
Address input 3
VSS
1, 8, 19
5, 16, 26
P
—
Ground reference for logic and I/O pins
VDD
20
17
P
—
Positive supply for logic and I/O pins
© 2007 Microchip Technology Inc.
DS20090C-page 3
MCP23016
1.2
Power-on Reset (POR)
The on-chip POR circuit holds the chip in RESET until
VDD has reached a high enough level to deactivate the
POR circuit (i.e., release RESET). A maximum rise
time for VDD is specified in the electrical specifications.
When the device starts normal operation (exits the
RESET condition), device operating parameters
(voltage, frequency, temperature) must be met to
ensure proper operation.
A 1 MHz (typ.) internal clock is needed for the device to
function properly. The internal clock can be measured
on the TP pin. Recommended REXT and CEXT values
are shown in Table 1-2.
Note:
Set IARES = 1 to measure the clock
output on TP.
TABLE 1-2:
RECOMMENDED VALUES
Power-up Timer (PWRT)
The Power-up Timer provides a 72 ms nominal timeout on power-up, keeping the device in RESET and
allowing VDD to rise to an acceptable level.
The power-up time delay will vary from chip-to-chip due
to VDD, temperature and process variation. See
Table 2-4 for details (TPWRT, parameter 3).
1.5
CEXT
3.9 kΩ
1.3
REXT
33 pF
I2C Bus Interface/ Protocol
Handler
This block manages the functionality of the I2C bus
interface and protocol handling. The MCP23016
supports the following commands:
TABLE 1-3:
1.4
Clock Generator
The MCP23016 uses an external RC circuit to
determine the internal clock speed. The user must
connect R and C to the MCP23016, as shown in
Figure 1-1.
COMMAND BYTE TO
REGISTER RELATIONSHIP
Command Byte
Result
1h
Access to INTCAP1 (Read-Only)
Access to IOCON0
Bh
1.6
Access to INTCAP0 (Read-Only)
Ah
MCP23016
Access to IODIR1
9h
VSS
Access to IODIR0
8h
CEXT
Access to IPOL1
7h
CLK
Access to IPOL0
6h
Internal Clock
Access to OLAT1
5h
REXT
Access to OLAT0
4h
VDD
Access to GP1
3h
CLOCK CONFIGURATION
Access to GP0
2h
FIGURE 1-1:
0h
Access to IOCON1
Address Decoder
The last three LSb of the 7-bit address are user-defined
(see Table 1-4). Three hardware pins ( & lt; A2:A0 & gt; ) define
these bits.
TABLE 1-4:
0
DS20090C-page 4
1
DEVICE ADDRESS
0
0
A2
A1
A0
© 2007 Microchip Technology Inc.
MCP23016
1.7
Register Block
The register block contains the Configuration and Port registers, as shown in Table 1-5.
TABLE 1-5:
Name
REGISTER SUMMARY
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
Value on
POR
Port Registers
GP0
GP0.7
GP0.6
GP0.5
GP0.4
GP0.3
GP0.2
GP0.1
GP0.0
0000 0000
GP1
GP1.7
GP1.6
GP1.5
GP1.4
GP1.3
GP1.2
GP1.1
GP0.0
0000 0000
OLAT0
OL0.7
OL0.6
OL0.5
OL0.4
OL0.3
OL0.2
OL0.1
OL0.0
0000 0000
OLAT1
OL1.7
OL1.6
OL1.5
OL1.4
OL1.3
OL1.2
OL1.1
OL1.0
0000 0000
IGP0.2
IGP0.1
IGP0.0
0000 0000
Configuration Registers
IPOL0
IGP0.7
IGP0.6
IGP0.5
IGP0.4
IGP0.3
IPOL1
IGP1.7
IGP1.6
IGP1.5
IGP1.4
IGP1.3
IGP1.2
IGP1.1
IGP1.0
0000 0000
IODIR0
IOD0.7
IOD0.6
IOD0.5
IOD0.4
IOD0.3
IOD0.2
IOD0.1
IOD0.0
1111 1111
IODIR1
IOD1.7
IOD1.6
IOD1.5
IOD1.4
IOD1.3
IOD1.2
IOD1.1
IOD1.0
1111 1111
INTCAP0
ICP0.7
ICP0.6
ICP0.5
ICP0.4
ICP0.3
ICP0.2
ICP0.1
ICP0.0
xxxx xxxx
INTCAP1
ICP1.7
ICP1.6
ICP1.5
ICP1.4
ICP1.3
ICP1.2
ICP1.1
ICP1.0
xxxx xxxx
IOCON0
—
—
—
—
—
—
—
IARES
---- ---0
IOCON1
—
—
—
—
—
—
—
IARES
---- ---0
Legend: ‘1’ bit is set, ‘0’ bit is cleared, x = unknown, — = unimplemented.
© 2007 Microchip Technology Inc.
DS20090C-page 5
MCP23016
1.7.1
DATA PORT REGISTERS
Two registers provide access to the two GPIO ports:
• GP0 (provides access to data port GP0)
• GP1 (provides access to data port GP1)
A read from this register provides status on pins of
these ports. A write to these registers will modify the
output latch registers (OLAT0, OLAT1) and data output.
REGISTER 1-1:
GP0 - GENERAL PURPOSE I/O PORT REGISTER 0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
GP0.7
GP0.6
GP0.5
GP0.4
GP0.3
GP0.2
GP0.1
GP0.0
bit 7
bit 7-0
bit 0
GP0.0:GP0.7: Reflects the logic level on the pins.
1 = Logic ‘1’
0 = Logic ‘0’
Legend:
R = Readable bit
W = Writable bit
U = Unimplemented bit, read as ‘0’
- n = Value at POR
‘1’ = Bit is set
‘0’ = Bit is cleared
REGISTER 1-2:
x = Bit is unknown
GP1 - GENERAL PURPOSE I/O PORT REGISTER 1
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
GP1.7
GP1.6
GP1.5
GP1.4
GP1.3
GP1.2
GP1.1
GP1.0
bit 7
bit 7-0
bit 0
GP1.0:GP1.7: Reflects the logic level on the pins.
1 = Logic ‘1’
0 = Logic ‘0’
Legend:
R = Readable bit
W = Writable bit
U = Unimplemented bit, read as ‘0’
- n = Value at POR
‘1’ = Bit is set
‘0’ = Bit is cleared
DS20090C-page 6
x = Bit is unknown
© 2007 Microchip Technology Inc.
MCP23016
1.7.2
OUTPUT LATCH REGISTERS
Two registers provide access to the two port output
latches:
• OLAT0 (provides access to the output latch for
port GP0)
• OLAT1 (provides access to the output latch for
port GP1)
A read from these registers results in a read of the latch
that controls the output and not the actual port. A write
to these registers updates the output latch that controls
the output.
REGISTER 1-3:
OLAT0 - OUTPUT LATCH REGISTER 0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
OL0.7
OL0.6
OL0.5
OL0.4
OL0.3
OL0.2
OL0.1
OL0.0
bit 7
bit 7-0
bit 0
OL0.0:O0.7: Reflects the logic level on the output latch.
1 = Logic ‘1’
0 = Logic ‘0’
Legend:
R = Readable bit
W = Writable bit
U = Unimplemented bit, read as ‘0’
- n = Value at POR
‘1’ = Bit is set
‘0’ = Bit is cleared
REGISTER 1-4:
x = Bit is unknown
OLAT1 - OUTPUT LATCH REGISTER 1
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
OL1.7
OL1.6
OL1.5
OL1.4
OL1.3
OL1.2
OL1.1
OL1.0
bit 7
bit 7-0
bit 0
OL1.0:O1.7: Reflects the logic level on the output latch.
1 = Logic ‘1’
0 = Logic ‘0’
Legend:
R = Readable bit
W = Writable bit
U = Unimplemented bit, read as ‘0’
- n = Value at POR
‘1’ = Bit is set
‘0’ = Bit is cleared
© 2007 Microchip Technology Inc.
x = Bit is unknown
DS20090C-page 7
MCP23016
1.7.3
INPUT POLARITY REGISTERS
These registers allow the user to configure the polarity
of the input port data (GP0 and GP1). If a bit in this register is set, the corresponding input port (GPn) data bit
polarity will be inverted.
• IPOL0 (controls the polarity of GP0)
• IPOL1 (controls the polarity of GP1)
REGISTER 1-5:
IPOL0 - INPUT POLARITY PORT REGISTER 0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
IGP0.7
IGP0.6
IGP0.5
IGP0.4
IGP0.3
IGP0.2
IGP0.1
IGP0.0
bit 7
bit 7-0
bit 0
IGP0.0:IGP0.7: Controls the polarity inversion for the input pins
1 = Corresponding GP0 bit is inverted
0 = Corresponding GP0 bit is not inverted
Legend:
R = Readable bit
W = Writable bit
U = Unimplemented bit, read as ‘0’
- n = Value at POR
‘1’ = Bit is set
‘0’ = Bit is cleared
REGISTER 1-6:
x = Bit is unknown
IPOL1 - INPUT POLARITY PORT REGISTER 1
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
R/W-0
IGP1.7
IGP1.6
IGP1.6
IGP1.4
IGP1.3
IGP1.2
IGP1.1
IGP1.0
bit 7
bit 7-0
bit 0
IGP1.0:IGP1.7: Controls the polarity inversion for the input pins
1 = Corresponding GP1 bit is inverted
0 = Corresponding GP1 bit is not inverted
Legend:
R = Readable bit
W = Writable bit
U = Unimplemented bit, read as ‘0’
- n = Value at POR
‘1’ = Bit is set
‘0’ = Bit is cleared
DS20090C-page 8
x = Bit is unknown
© 2007 Microchip Technology Inc.
MCP23016
1.7.4
I/O DIRECTION REGISTERS
Two registers control the direction of data I/O:
• IODIR0 (controls GP0)
• IODIR1 (controls GP1)
When a bit in these registers is set, the corresponding
pin becomes an input. Otherwise, it becomes an
output. At Power-on Reset, the device ports are
configured as inputs.
REGISTER 1-7:
IODIR0 - I/O DIRECTION REGISTER 0
R/W-1
R/W-1
R/W-1
R/W-1
R/W-1
R/W-1
R/W-1
R/W-1
IOD0.7
IOD0.6
IOD0.5
IOD0.4
IOD0.3
IOD0.2
IOD0.1
IOD0.0
bit 7
bit 7-0
bit 0
IOD0.0:IO0.7: Controls the direction of data I/O
1 = Input
0 = Output
Legend:
R = Readable bit
W = Writable bit
U = Unimplemented bit, read as ‘0’
- n = Value at POR
‘1’ = Bit is set
‘0’ = Bit is cleared
REGISTER 1-8:
x = Bit is unknown
IODIR1 - I/O DIRECTION REGISTER 1
R/W-1
R/W-1
R/W-1
R/W-1
R/W-1
R/W-1
R/W-1
R/W-1
IOD1.7
IOD1.6
IOD1.5
IOD1.4
IOD1.3
IOD1.2
IOD1.1
IOD1.0
bit 7
bit 7-0
bit 0
IOD1.0:IO1.7: Controls the direction of data I/O
1 = Input
0 = Output
Legend:
R = Readable bit
W = Writable bit
U = Unimplemented bit, read as ‘0’
- n = Value at POR
‘1’ = Bit is set
‘0’ = Bit is cleared
© 2007 Microchip Technology Inc.
x = Bit is unknown
DS20090C-page 9
MCP23016
1.7.5
INTERRUPT CAPTURE REGISTERS
Two registers contain the value of the port that
generated the interrupt:
• INTCAP0 contains the value of GP0 at time of
GP0 change interrupt
• INTCAP1 contains the value of GP1 at time of
GP1 change interrupt
These registers are ‘read-only’ registers (A write to
these registers is ignored).
REGISTER 1-9:
INTCAP0 - INTERRUPT CAPTURED VALUE FOR PORT REGISTER 0
R-x
R-x
R-x
R-x
R-x
R-x
R-x
R-x
ICP0.7
ICP0.6
ICP0.5
ICP0.4
ICP0.3
ICP0.2
ICP0.1
ICP0.0
bit 7
bit 7-0
bit 0
ICP0.0:ICP0.7: Reflects the logic level on the GP0 pins at the time of interrupt due to pin
change
1 = Logic ‘1’
0 = Logic ‘0’
Legend:
R = Readable bit
W = Writable bit
U = Unimplemented bit, read as ‘0’
- n = Value at POR
‘1’ = Bit is set
‘0’ = Bit is cleared
REGISTER 1-10:
x = Bit is unknown
INTCAP1 - INTERRUPT CAPTURED VALUE FOR PORT REGISTER 1
R-x
R-x
R-x
R-x
R-x
R-x
R-x
R-x
ICP1.7
ICP1.6
ICP1.5
ICP1.4
ICP1.3
ICP1.2
ICP1.1
ICP1.0
bit 7
bit 7-0
bit 0
ICP1.0:ICP1.7: Reflects the logic level on the GP1 pins at the time of interrupt due to pin
change
1 = Logic ‘1’
0 = Logic ‘0’
Legend:
R = Readable bit
W = Writable bit
U = Unimplemented bit, read as ‘0’
- n = Value at POR
‘1’ = Bit is set
‘0’ = Bit is cleared
DS20090C-page 10
x = Bit is unknown
© 2007 Microchip Technology Inc.
MCP23016
1.7.6
I/O EXPANDER CONTROL
REGISTER
• IOCON0 controls the functionality of the
MCP23016.
The IARES (Interrupt Activity Resolution) bit controls
the sampling frequency of the GP port pins. The higher
the sampling frequency, the higher the device current
requirements. If this bit is ‘0’ (default), the maximum
time to detect the activity on the port is 32 ms (max.),
which results in lower standby current. If this bit is ‘1’,
the maximum time to detect activity on the port is
200 µsec. (max.) and results in higher standby current.
REGISTER 1-11:
IOCON0 - I/0 EXPANDER CONTROL REGISTER
U-0
U-0
U-0
U-0
U-0
U-0
U-0
R/W-0
—
—
—
—
—
—
—
IARES
bit 7
bit 0
bit 1-7
Unimplemented bit: Read as ‘0’
bit 0
IARES: Interrupt Activity Resolution
1 = Fast sample rate
0 = Normal sample rate
Legend:
R = Readable bit
W = Writable bit
U = Unimplemented bit, read as ‘0’
- n = Value at POR
‘1’ = Bit is set
‘0’ = Bit is cleared
x = Bit is unknown
IOCON1 is a shadow register for IOCON0. Access to IOCON1 results in access to IOCON0.
© 2007 Microchip Technology Inc.
DS20090C-page 11
MCP23016
1.8
The Serializer/Deserializer block converts
transfers data between the I2C bus and GPIO.
1.9
1.9.1
Serializer/Deserializer
and
Interrupt Logic
The MCP23016 asserts the open-drain interrupt output
(INT) low when one of the port pins changes state. Only
those pins that are configured as an input can cause an
interrupt. Pins defined as an output have no effect on
INT. The interrupt will remain active until a read from
either the port (GPn) on which the interrupt occurred or
the INTCAPn register is performed. If the input returns
to its previous state before a read operation, it will reset
the interrupt and the INT pin output will tri-state. Each
8-bit port is read separately, so reading GP0 or
INTCAP0 will not clear the interrupt generated by GP1
or INTCAP1, and vice versa.
Input change activity on each port will generate an
interrupt and the value of the particular port will be
captured and copied into INTCAP0/INTCAP1. The
INTCAPn registers are only updated when an interrupt
occurs on INT. These values will stay unchanged until
the user clears the interrupt by reading the port or the
INTCAPn register.
INTERRUPT EVENT DETECTION
The IARES bit controls the resolution for detecting an
interrupt-on-change event. If this bit is ‘0’ (default), the
maximum time for detecting a change of event is high,
which results in lower standby current. If this bit is ‘1’, it
takes less time for scanning the activity on the port and
results in higher standby current.
FIGURE 1-2:
GPx
READING PORTX AFTER
INTERRUPT EVENT
PORT X
PORT X
INT
Port value
is captured
and written to
INTCAPn
Read GPx
or INTCAPn
Port value
is captured
and written to
INTCAPn
If the input port value changes back to normal before a
user-read, the INT output will be reset. However, the
INTCAP0/INTCAP1 will still contain the value of the
port at the interrupt change. If the port value changes
again, it will re-activate the interrupt and the new value
will be captured.
The first interrupt on change event following an
interrupt RESET will result in a capture event. Any further change event that occurs before the interrupt is
reset will not result in a capture event.
DS20090C-page 12
© 2007 Microchip Technology Inc.
MCP23016
FIGURE 1-3:
WRITE TO CONFIGURATION
REGISTERS (CASE 1)
2
9
8
7
6
5
4
3
2
1
9
8
7
6
5
4
SCL held low until
data is processed
3
2
1
9
8
7
6
5
4
3
2
1
D7 D6 D5 D4 D3 D2 D1 D0
ACK
5
6
7
8
ACK
A2 A1 A0
0
2
1
S
1
0
0
R/W=0
Address
9
D7 D6 D5 D4 D3 D2 D1 D0 ACK
Data 2
ACK
The bus must remain free until after the
ninth clock pulse for a minimum of 12 µs
(see Table 2-5 and Figure 2-4).
Command Byte
Note:
D7 D6 D5 D4 D3 D2 D1 D0
There is no limitation on the number of data bytes in
one write transmission. Figure 1-4 shows the case of
multiple byte writes in one write operation. In this case,
the multiple writes are made to the same data pair.
Data 1
The MCP23016 has twelve 8-bit registers. They are
configured to operate as six 16-bit register pairs,
supporting the device’s 16-bit port. These pairs are
formed based on their functions (e.g., GP0 and GP1
are grouped together). The I2C commands apply to one
register pair to provide faster access. The first data byte
following a command byte is written into the register
pointed to by the command byte, while the second data
is written into another register in the same pair. For
example, if the first byte is sent to OLAT1 (command
byte 03h), the next data byte will be written into the second register of that pair, OLAT0. If the first byte is written to OLAT0 (command byte 02h), the second byte
will be written to OLAT1.
P
To write to a MCP23016 register, the Master I C device
needs to follow the requirements, as illustrated in
Figure 1-3. First, the device is selected by sending the
slave address and setting the R/W bit to logic ‘0’. The
command byte is sent after the address and
determines which register will be written. Table 1-3
shows the relationship of the command byte and
register.
4
WRITING THE REGISTERS
3
1.9.2
© 2007 Microchip Technology Inc.
DS20090C-page 13
0
DS20090C-page 14
Data on GP1
2
1
4
3
0
4
0
Address
3
0
6
5
6
7
8
8
R/W=0
7
A2 A1 A0
5
A2 A1 A0
1
2
4
5
Command Byte
3
6
7
9
1
2
3
4
5
6
7
1
2
ACK
9
7
8
9
1
2
Data 2
3
4
5
6
7
3
Data 1
4
5
6
7
8
9
1
2
3
4
5
6
7
9
t GPV0
8
D7 D6 D5 D4 D3 D2 D1 D0 ACK
2
4
5
6
Data 2
SCL held low until
data is processed
3
7
1
2
3
4
5
7
8
9
9
ACK
8
t GPV1
DATA VALID
6
D7 D6 D5 D4 D3 D2 D1 D0
2
8
P
1
6
1
5
VALID
DATA
P
9
D7 D6 D5 D4 D3 D2 D1 D0 ACK
D7 D6 D5 D4 D3 D2 D1 D0 ACK
4
ACK
Data 2
D7 D6 D5 D4 D3 D2 D1 D0 ACK
Data 1
3
D7 D6 D5 D4 D3 D2 D1 D0
SCL held low until
data is processed
8
9
ACK
SCL held low until
data is processed
8
D7 D6 D5 D4 D3 D2 D1 D0
ACK D7 D6 D5 D4 D3 D2 D1 D0
9
ACK
Data 1
FIGURE 1-5:
Data on GP0
1
2
0
Command Byte
WRITE TO CONFIGURATION
REGISTERS (CASE 2)
SCL S
1
1
R/W=0
FIGURE 1-4:
SDA
S
0
Address
MCP23016
WRITE TO OUTPUT PORTS
© 2007 Microchip Technology Inc.
MCP23016
FIGURE 1-6:
READ FROM
CONFIGURATION
REGISTER
© 2007 Microchip Technology Inc.
9
8
7
6
5
4
3
2
1
SCL held low until
data is processed
9
8
7
6
5
4
3
2
1
ACK
7
6
5
4
3
2
1
A1
A2
0
1
0
0
2
1
SCL S
S
A0
8
9
Data from LSB or
MSB of register
SCL held low until
data is processed
D7 D6 D5 D4 D3 D2 D1 D0
9
8
7
6
5
4
3
2
1
9
8
7
6
5
4
A0
1
0
SDA
0
0
A2
A1
R/W=0
Address
3
The bus must remain free until after the
ninth clock pulse for a minimum of 12 µs
(see Table 2-5 and Figure 2-4).
ACK
Note:
Command Byte
There is no limitation on the number of data bytes in
one read transmission. Figure 1-8 shows the case of
multiple byte read in one read operation. In this case,
the multiple writes are made to the same data pair.
D7 D6 D5 D4 D3 D2 D1 D0
ACK
The MCP23016 holds the clock low after the falling
edge of the ninth clock pulse. The configuration
registers (or port control registers) are read and the
value is stored. Finally, the clock is released to enable
the next transmission.
ACK
The falling edge of the ninth clock initiates the register
read action. The SCL clock will be held low while the
data is read from the register and is transferred to the
I2C bus control block by the Serializer/Deserializer
block.
D7 D6 D5 D4 D3 D2 D1 D0 ACK
Data from MSB or
LSB of register
P
To read a MCP23016 register, the Master needs to
follow the requirements shown in Figure 1-6. First, the
device is selected by sending the slave address and
setting the R/W bit to logic ‘0’. The command byte is
sent after the address and determines which register
will be read. A restart condition is generated and the
device address is sent again with the R/W bit set to
logic ‘1’. The data register defined by the command
byte will be sent first, followed by the other register in
the register pair. The logic for register selection is the
same as explained in Write mode (Section 1.9.2,
“Writing the Registers”).
R/W=0
READING THE REGISTERS
Address
1.9.3
DS20090C-page 15
0
SCL S
DS20090C-page 16
3
0
4
0
Data in GP0
2
1
5
Note:
tIsd
7
8
9
ACK
Data from LSB or
MSB of register
2
tIcd0
tRDd0
1
3
4
5
6
7
8
D7 D6 D5 D4 D3 D2 D1 D0
It is assumed that command byte is already set to ‘00’.
INT
Read signal (Internal) for GP1
Data in GP1
6
A2 A1 A0
R/W=0
1
tIcd1
tRDd1
2
3
4
5
6
7
8
9
D7 D6 D5 D4 D3 D2 D1 D0 ACK
SCL held low until
data is processed
9
ACK
Data from MSB or
LSB of register
P
FIGURE 1-7:
Read signal (Internal) for GP0
1
SDA
Address
MCP23016
READ FROM INPUT PORTS (CASE 1)
© 2007 Microchip Technology Inc.
0
© 2007 Microchip Technology Inc.
2
3
0
4
0
5
A2
6
7
A0
8
1
2
3
4
5
4
5
6
7
8
9
3
1
2
D7 D6 D5 D4 D3 D2 D1 D0
6
8
1
2
3
4
5
1
2
3
4
5
6
7
8
9
6
P
7
8
D7 D6 D5 D4 D3 D2 D1 D0
Data from GP1
9
ACK
Data from GP1
D7 D6 D5 D4 D3 D2 D1 D0 ACK
7
D7 D6 D5 D4 D3 D2 D1 D0
Data from GP0
9
ACK
Data from GP0
ACK
A1
It is assumed that command byte is already set to 00.
SCL S
1
R/W=0
9
ACK
FIGURE 1-8:
Note:
1
SDA
Address
MCP23016
READ FROM INPUT PORTS
(CASE 2)
DS20090C-page 17
MCP23016
NOTES:
DS20090C-page 18
© 2007 Microchip Technology Inc.
MCP23016
2.0
ELECTRICAL CHARACTERISTICS
Absolute Maximum Ratings †
Ambient temperature under bias................................................................................................................ -55 to +125°C
Storage temperature .............................................................................................................................. -65°C to +150°C
Voltage on any pin with respect to VSS ......................................................................................... -0.3V to (VDD + 0.3V)
Voltage on VDD with respect to VSS ......................................................................................................... -0.3V to +6.5V
Total power dissipation (Note 1) ............................................................................................................................ 1.0 W
Maximum current out of VSS pin .......................................................................................................................... 300 mA
Maximum current into VDD pin ............................................................................................................................. 250 mA
Input clamp current, IIK (VI & lt; 0, or VI & gt; VDD) ....................................................................................................... ± 20 mA
Output clamp current, IOK (VO & lt; 0, or VO & gt; VDD) ................................................................................................ ± 20 mA
Maximum output current sunk by any I/O pin......................................................................................................... 25 mA
Maximum output current sourced by any I/O pin ................................................................................................... 25 mA
Maximum current sunk by combined PORTS ...................................................................................................... 200 mA
Maximum current sourced by combined PORTS ................................................................................................ 200 mA
Note 1: Power dissipation is calculated as follows:
Pdis = VDD x {IDD - ∑ IOH} + ∑ {(VDD-VOH) x IOH} + ∑(VOl x IOL)
† NOTICE: Stresses above those listed under “Absolute Maximum Ratings” may cause permanent damage to the
device. This is a stress rating only and functional operation of the device at those or any other conditions above those
indicated in the operation listings of this specification is not implied. Exposure to maximum rating conditions for
extended periods may affect device reliability.
© 2007 Microchip Technology Inc.
DS20090C-page 19
MCP23016
2.1
DC Characteristics
TABLE 2-1:
DC CHARACTERISTICS
Standard Operating Conditions (unless otherwise stated)
Operating temperature: -40°C ≤ TA ≤ +85°C for industrial
DC CHARACTERISTICS
Param
No.
Sym
Min
Typ†
Max
Units
Supply Voltage
VDD
2.0
—
5.5
V
D002
Standby Current
IDD
—
0.4
mA
IARES = 1
D003
Standby Current
IPD
—
25
µA
IARES = 0
Vss
—
0.15 VDD
V
For entire VDD range
Vss
—
0.8V
Vss
—
0.2 VDD
V
D001
Characteristic
Conditions
Input Low Voltage
I/O ports
D004
VIL
TTL buffer
D004A
D005
Schmitt Trigger buffer
4.5V ≤ VDD ≤ 5.5V
Input High Voltage
I/O ports
—
VIH
—
VDD
V
4.5V ≤ VDD ≤ 5.5V
VDD
0.25
+ 0.8V
D006
—
VDD
V
For entire VDD range
0.8 VDD
—
VDD
V
For entire VDD range
—
—
±1.0
µA
Vss ≤ VPIN ≤ VDD,
Pin at hi-impedance
—
—
±5.0
µA
Vss ≤ VPIN ≤ VDD
VOL
—
—
0.6
V
IOL = 8.5 mA, VDD = 4.5V
IOH = 3.0 mA, VDD = 4.5V
TTL buffer
2.0
D006A
D007
Schmitt Trigger buffer
Input Leakage Current
D008
I/O ports
D009
IIL
CLK
Output Low Voltage
D010
I/O Ports
Output High Voltage
D010
I/O Ports
VOH
VDD-0.7
—
—
V
D011
VDD start voltage to ensure
internal POR signal
VPOR
—
Vss
—
V
D012
VDD rise rate to ensure
internal POR signal
SVDD
0.05
-
—
DC Trip Point
VTPOR
1.5
1.7
1.9
VDD rise rate to ensure
internal POR signal with
PWRT enabled
SVDD
0.05
—
—
DC Current Draw
IPOR
—
5.0
—
D012
Note 1:
2:
3:
4:
5:
V/ms Note 1
V
DC Slow Ramp
V/ms Note 1
µA
At 5.0V (1 µ/Volt typical)
These parameters are characterized but not tested.
Data in " Typ " column is at 5V, 25°C unless otherwise stated. These parameters are for design guidance
only and are not tested.
Standby current is measured with all I/O in hi-impedance state and tied to VDD and VSS.
For RC CLK, current through REXT is not included. The current through the resistor can be estimated by
the formula
Ir = VDD/2 REXT (mA) with REXT in kohm.
Negative current is defined as coming out of the pin.
DS20090C-page 20
© 2007 Microchip Technology Inc.
MCP23016
FIGURE 2-1:
RESPONSE TIME
VDD
1
TABLE 2-2:
Parameter
No.
RESPONSE TIME
Symbol
1
Characteristic
Response Time
FIGURE 2-2:
Min
Typ†
Max
Units
100
—
—
ns
Conditions
Minimum time where a VDD
transition from 5.0V to 0.0V to
5.0V will cause a RESET. All
times less than 100 ns will be
filtered.
TEST POINT CLOCK TIMING
2
TTP
TABLE 2-3:
Parameter
No.
TEST POINT CLOCK TIMING
Symbol
Characteristic
Min
Typ†
Max
Units
Conditions
FTP
—
1.0
—
MHz
Measured at TP pin,
IARES = ‘1’.
TTP
2
TP pin Frequency
TP pin CLK Period
—
1.0
—
µs
Measured at TP pin,
IARES = ‘1’.
† Data in " Typ " column is at 5V, +25°C unless otherwise stated. These parameters are for design guidance
only and are not tested.
TABLE 2-4:
POWER-UP TIMER REQUIREMENTS
Parameter
No.
Symbol
3
TPWRT
Characteristic
Power-up Timer Period
Min
Typ†
Max
Units
—
72
—
ms
Conditions
† Data in " Typ " column is at 5V, +25°C unless otherwise stated. These parameters are for design guidance
only and are not tested.
© 2007 Microchip Technology Inc.
DS20090C-page 21
MCP23016
I2C BUS START/STOP BITS TIMING
FIGURE 2-3:
SCL
91
93
90
92
SDA
STOP
Condition
START
Condition
I2C BUS START/STOP BITS REQUIREMENTS
TABLE 2-5:
Param
No.
Symbol
90
TSU:STA
START condition
Setup time
400 kHz mode
600
—
—
91
THD:STA
START condition
100 kHz mode
4000
—
—
Hold time
400 kHz mode
600
—
—
100 kHz mode
4700
—
—
Min
Ty
Max Units
p
4700
—
Characteristic
100 kHz mode
—
92
TSU:STO
STOP condition
Setup time
400 kHz mode
600
—
THD:STO
STOP condition
100 kHz mode
4000
—
—
Hold time
400 kHz mode
600
—
ns
Only relevant for Repeated
START condition (Note 1)
ns
After this period, the first
clock pulse is generated
(Note 1)
—
93
Conditions
—
Note 1:
ns
ns
These parameters are characterized but not tested.
DS20090C-page 22
© 2007 Microchip Technology Inc.
MCP23016
FIGURE 2-4:
I2C BUS DATA TIMING
103
102
100
101
SCL
90
106
111
91
107
92
SDA
In
110
109
109
SDA
Out
© 2007 Microchip Technology Inc.
DS20090C-page 23
MCP23016
I2C BUS DATA REQUIREMENTS
TABLE 2-5:
Param
No.
Symbol
100
THIGH
Clock High Time
101
TLOW
Clock Low Time
102
TR
Characteristic
Min
Max
Units
100 kHz mode
4.0
—
µs
400 kHz mode
0.6
—
µs
100 kHz mode
4.7
—
µs
Conditions
(Note 1)
(Note 1)
400 kHz mode
TF
TSU:STA
90
91
THD:STA
106
107
THD:DAT
TSU:DAT
TSU:STO
92
109
110
TAA
TBUF
CB
111
Note 1:
2:
3:
TWAIT
—
µs
—
1000
ns
(Note 1)
20 + 0.1 CB
300
ns
CB is specified to be from
10 - 400 pF
SDA and SCL Fall
Time
100 kHz mode
—
300
ns
(Note 1)
400 kHz mode
20 + 0.1 CB
300
ns
CB is specified to be from
10 - 400 pF
START Condition
Setup Time
100 kHz mode
4.7
—
µs
400 kHz mode
0.6
—
µs
Only relevant for repeated
START condition (Note 1)
START Condition
Hold Time
100 kHz mode
4.0
—
µs
400 kHz mode
0.6
—
µs
After this period, the first
clock pulse is generated
(Note 1)
Data Input Hold
Time
100 kHz mode
0
—
ns
(Note 1)
400 kHz mode
0
0.9
µs
Data Input Setup
Time
100 kHz mode
250
—
ns
400 kHz mode
100
—
ns
STOP Condition
Setup Time
100 kHz mode
4.7
—
µs
400 kHz mode
0.6
—
µs
Output Valid from
Clock
100 kHz mode
—
3500
ns
400 kHz mode
—
—
ns
100 kHz mode
4.7
—
µs
400 kHz mode
103
1.3
SDA and SCL Rise 100 kHz mode
Time
400 kHz mode
1.3
—
µs
Bus Free Time
Bus Capacitive Loading
Clock wait time
after ninth pulse
—
400
12 µs
—
µs
400 kHz mode
12 µs
—
µs
(Note 1)
(Note 1) (Note 2)
Time the bus must be free
before a new transmission can start (Note 1)
pF
100 kHz mode
(Note 1) (Note 3)
Time the bus must remain
free after the ninth clock
pulse before a new
transmission can start.
These parameters are characterized but not tested.
As a transmitter, the device must provide this internal minimum delay time to bridge the undefined region
(min. 300 ns) of the falling edge of SCL to avoid unintended generation of START or STOP conditions.
A Fast mode (400 kHz) I2C bus device can be used in a Standard mode (100 kHz) I2C bus system, but the
requirement TSU:DAT ≥ 250 ns must then be met. This will automatically be the case if the device does not
stretch the LOW period of the SCL signal. If such a device does stretch the LOW period of the SCL signal,
it must output the next data bit to the SDA line TR max.+TSU:DAT = 1000 + 250 = 1250 ns (according to the
Standard mode I2C bus specification), before the SCL line is released.
DS20090C-page 24
© 2007 Microchip Technology Inc.
MCP23016
TABLE 2-7:
Param
No.
GP0 AND GP1 TIMING REQUIREMENTS
Symbol
Characteristic
Min
Typ.
Max
Units
Conditions
tGPV0
GP0 output data
valid time
—
40
—
µs
tGPV1
GP1 output data
valid time
—
50
—
µs
tRDd0
GP0 data read
delay time
—
40
—
µs
tRDd1
GP1 data read
delay time
—
50
—
µs
tISD0
GP0 Interrupt set
delay time
—
—
200
µs
IARES = 1, TP = 1 MHz
—
—
32
ms
IARES = 0, TP = 1 MHz
GP1 Interrupt set
delay time
—
—
200
µs
IARES = 1, TP = 1 MHz
—
—
32
ms
IARES = 0, TP = 1 MHz
tLCD0
GP0 Interrupt clear
delay time (for
read)
—
100
—
µs
TP = 1 MHz
tLCD1
GP1 Interrupt clear
delay time (for
read)
—
100
—
µs
tISD1
Note 1:
TP = 1 MHz
These parameters are characterized but not tested.
© 2007 Microchip Technology Inc.
DS20090C-page 25
DS20090C-page 26
SCL S
SDA
3
0
4
0
Data in GP0
2
1
5
Note:
tIsd
7
A0
8
9
ACK
2
tIcd0
tRDd0
1
3
4
5
6
7
8
9
D7 D6 D5 D4 D3 D2 D1 D0 ACK
Data from LSB or
MSB of register
It is assumed that command byte is already set to ‘00’.
INT
Read signal(Internal) for GP1
Data in GP1
6
A2 A1
R/W=0
2
3
tIcd1
tRDd1
SCL held low until
data is processed
1
4
5
6
7
8
9
D7 D6 D5 D4 D3 D2 D1 D0 ACK
Data from MSB or
LSB of register
P
FIGURE 2-5:
Read signal(Internal) for GP0
1
0
Address
MCP23016
GP0 AND GP1 PORT TIMINGS
© 2007 Microchip Technology Inc.
MCP23016
3.0
PACKAGE INFORMATION
3.1
Package Marking Information
28-Lead PDIP (Skinny DIP)
Example:
MCP23016-I/SP e3
XXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXX
YYWWNNN
28-Lead SOIC
Example:
XXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXX
YYWWNNN
28-Lead SSOP
MCP23016-I/SO e3
0710017
Example:
XXXXXXXXXXXX
XXXXXXXXXXXX
YYWWNNN
28-Lead QFN
MCP23016
-I/SS e3
0720017
Example:
XXXXXXXX
XXXXXXXX
YYWWNNN
MCP23016
-I/ML e3
0710017
Legend: XX...X
Y
YY
WW
NNN
*
e3
Note:
0717017
Customer-specific information
Year code (last digit of calendar year)
Year code (last 2 digits of calendar year)
Week code (week of January 1 is week ‘01’)
Alphanumeric traceability code
Pb-free JEDEC designator for Matte Tin (Sn)
This package is Pb-free. The Pb-free JEDEC designator (
can be found on the outer packaging for this package.
)
e3
In the event the full Microchip part number cannot be marked on one line, it will
be carried over to the next line, thus limiting the number of available
characters for customer-specific information.
© 2007 Microchip Technology Inc.
DS20090C-page 27
MCP23016
28-Lead Skinny Plastic Dual In-Line (SP) – 300 mil Body [SPDIP]
Note:
For the most current package drawings, please see the Microchip Packaging Specification located at
http://www.microchip.com/packaging
N
NOTE 1
E1
1 2 3
D
E
A2
A
L
c
b1
A1
b
e
eB
Units
Dimension Limits
Number of Pins
INCHES
MIN
N
Pitch
A
MAX
28
e
Top to Seating Plane
NOM
.100 BSC
–
–
.200
Molded Package Thickness
A2
.120
.135
.150
Base to Seating Plane
A1
.015
–
–
Shoulder to Shoulder Width
E
.290
.310
.335
Molded Package Width
E1
.240
.285
.295
Overall Length
D
1.345
1.365
1.400
Tip to Seating Plane
L
.110
.130
.150
Lead Thickness
c
.008
.010
.015
Upper Lead Width
b1
.040
.050
.070
Lower Lead Width
b
.014
.018
.022
Overall Row Spacing §
eB
–
–
.430
Notes:
1. Pin 1 visual index feature may vary, but must be located within the hatched area.
2. § Significant Characteristic.
3. Dimensions D and E1 do not include mold flash or protrusions. Mold flash or protrusions shall not exceed .010 " per side.
4. Dimensioning and tolerancing per ASME Y14.5M.
DS20090C-page 28
© 2007 Microchip Technology Inc.
MCP23016
28-Lead Plastic Small Outline (SO) – Wide, 7.50 mm Body [SOIC]
Note:
For the most current package drawings, please see the Microchip Packaging Specification located at
http://www.microchip.com/packaging
D
N
E
E1
NOTE 1
1 2 3
b
e
h
α
A2
A
h
c
φ
L
A1
Units
Dimension Limits
Number of Pins
β
L1
MILLMETERS
MIN
N
NOM
MAX
28
Pitch
e
Overall Height
A
–
1.27 BSC
–
Molded Package Thickness
A2
2.05
–
–
Standoff §
A1
0.10
–
0.30
Overall Width
E
Molded Package Width
E1
7.50 BSC
Overall Length
D
2.65
10.30 BSC
17.90 BSC
Chamfer (optional)
h
0.25
–
0.75
Foot Length
L
0.40
–
1.27
Footprint
L1
Foot Angle Top
φ
0°
–
8°
Lead Thickness
c
0.18
–
0.33
Lead Width
b
0.31
–
0.51
Mold Draft Angle Top
α
5°
–
15°
Mold Draft Angle Bottom
β
5°
–
1.40 REF
15°
Notes:
1. Pin 1 visual index feature may vary, but must be located within the hatched area.
2. § Significant Characteristic.
3. Dimensions D and E1 do not include mold flash or protrusions. Mold flash or protrusions shall not exceed 0.15 mm per side.
4. Dimensioning and tolerancing per ASME Y14.5M.
BSC: Basic Dimension. Theoretically exact value shown without tolerances.
REF: Reference Dimension, usually without tolerance, for information purposes only.
Microchip Technology Drawing C04-052B
© 2007 Microchip Technology Inc.
DS20090C-page 29
MCP23016
28-Lead Plastic Shrink Small Outline (SS) – 5.30 mm Body [SSOP]
Note:
For the most current package drawings, please see the Microchip Packaging Specification located at
http://www.microchip.com/packaging
D
N
E
E1
1 2
NOTE 1
b
e
c
A2
A
φ
A1
L
L1
Units
Dimension Limits
Number of Pins
MILLIMETERS
MIN
N
Pitch
A
MAX
28
e
Overall Height
NOM
0.65 BSC
–
–
2.00
1.85
Molded Package Thickness
A2
1.65
1.75
Standoff
A1
0.05
–
–
Overall Width
E
7.40
7.80
8.20
Molded Package Width
E1
5.00
5.30
5.60
Overall Length
D
9.90
10.20
10.50
Foot Length
L
0.55
0.75
0.95
Footprint
L1
1.25 REF
Lead Thickness
c
0.09
–
Foot Angle
φ
0°
4°
0.25
8°
Lead Width
b
0.22
–
0.38
Notes:
1. Pin 1 visual index feature may vary, but must be located within the hatched area.
2. Dimensions D and E1 do not include mold flash or protrusions. Mold flash or protrusions shall not exceed 0.20 mm per side.
3. Dimensioning and tolerancing per ASME Y14.5M.
BSC: Basic Dimension. Theoretically exact value shown without tolerances.
REF: Reference Dimension, usually without tolerance, for information purposes only.
Microchip Technology Drawing C04-073B
DS20090C-page 30
© 2007 Microchip Technology Inc.
MCP23016
28-Lead Plastic Quad Flat, No Lead Package (ML) – 6x6 mm Body [QFN]
with 0.55 mm Contact Length
Note:
For the most current package drawings, please see the Microchip Packaging Specification located at
http://www.microchip.com/packaging
D
D2
EXPOSED
PAD
e
E
b
E2
2
2
1
1
N
K
N
NOTE 1
L
BOTTOM VIEW
TOP VIEW
A
A3
A1
Units
Dimension Limits
Number of Pins
MILLIMETERS
MIN
N
NOM
MAX
28
Pitch
e
Overall Height
A
0.80
0.65 BSC
0.90
1.00
Standoff
A1
0.00
0.02
0.05
Contact Thickness
A3
0.20 REF
Overall Width
E
6.00 BSC
Exposed Pad Width
E2
Overall Length
D
Exposed Pad Length
3.65
3.70
4.20
6.00 BSC
D2
3.65
3.70
4.20
Contact Width
b
0.23
0.30
0.35
Contact Length
L
0.50
0.55
0.70
Contact-to-Exposed Pad
K
0.20
–
Notes:
1. Pin 1 visual index feature may vary, but must be located within the hatched area.
2. Package is saw singulated.
3. Dimensioning and tolerancing per ASME Y14.5M.
BSC: Basic Dimension. Theoretically exact value shown without tolerances.
REF: Reference Dimension, usually without tolerance, for information purposes only.
–
Microchip Technology Drawing C04-105B
© 2007 Microchip Technology Inc.
DS20090C-page 31
MCP23016
NOTES:
DS20090C-page 32
© 2007 Microchip Technology Inc.
MCP23016
APPENDIX A:
REVISION HISTORY
Revision A (December 2002)
Original data sheet for MCP23016 device.
Revision B (September 2003)
1.
2.
Addition of Output Low Voltage section to
Table 2-1 in Electrical Characteristics.
Addition of Output High Voltage section to
Table 2-1 in Electrical Characteristics.
Revision C (January 2007)
This revision includes updates to the packaging
diagrams.
© 2007 Microchip Technology Inc.
DS20090C-page 33
MCP23016
NOTES:
DS20090C-page 34
© 2007 Microchip Technology Inc.
MCP23016
PRODUCT IDENTIFICATION SYSTEM
To order or obtain information (e.g., on pricing or delivery) refer to the factory or the listed sales office.
PART NO.
X
/XX
Device
Temperature
Range
Package
Examples:
DSTEMP: 16-Bit I2C I/O Expander
Temperature
Range:
I = -40°C to +85°C
Package:
SP
SO
SS
ML
=
=
=
=
DSTEMP-I/P:
a)
DSTEMP-I/SO:
a)
DSTEMP-I/SS:
a)
Device:
a)
DSTEMP-I/ML:
Industrial Temperature,
PDIP package.
Industrial Temperature,
SOIC package.
Industrial Temperature,
SOIC package.
Industrial Temperature,
QFN package.
Plastic DIP (300 mil Body), 28-lead
Plastic SOIC, Wide (300 mil Body), 28-lead
Plastic SOIC, (209 mil, 5.30mm), 28-lead
Plastic Quad, Flat No Leads (QFN), 28-lead
© 2007 Microchip Technology Inc.
DS20090C-page 35
MCP23016
NOTES:
DS20090C-page 36
© 2007 Microchip Technology Inc.
Note the following details of the code protection feature on Microchip devices:
•
Microchip products meet the specification contained in their particular Microchip Data Sheet.
•
Microchip believes that its family of products is one of the most secure families of its kind on the market today, when used in the
intended manner and under normal conditions.
•
There are dishonest and possibly illegal methods used to breach the code protection feature. All of these methods, to our
knowledge, require using the Microchip products in a manner outside the operating specifications contained in Microchip’s Data
Sheets. Most likely, the person doing so is engaged in theft of intellectual property.
•
Microchip is willing to work with the customer who is concerned about the integrity of their code.
•
Neither Microchip nor any other semiconductor manufacturer can guarantee the security of their code. Code protection does not
mean that we are guaranteeing the product as “unbreakable.”
Code protection is constantly evolving. We at Microchip are committed to continuously improving the code protection features of our
products. Attempts to break Microchip’s code protection feature may be a violation of the Digital Millennium Copyright Act. If such acts
allow unauthorized access to your software or other copyrighted work, you may have a right to sue for relief under that Act.
Information contained in this publication regarding device
applications and the like is provided only for your convenience
and may be superseded by updates. It is your responsibility to
ensure that your application meets with your specifications.
MICROCHIP MAKES NO REPRESENTATIONS OR
WARRANTIES OF ANY KIND WHETHER EXPRESS OR
IMPLIED, WRITTEN OR ORAL, STATUTORY OR
OTHERWISE, RELATED TO THE INFORMATION,
INCLUDING BUT NOT LIMITED TO ITS CONDITION,
QUALITY, PERFORMANCE, MERCHANTABILITY OR
FITNESS FOR PURPOSE. Microchip disclaims all liability
arising from this information and its use. Use of Microchip
devices in life support and/or safety applications is entirely at
the buyer’s risk, and the buyer agrees to defend, indemnify and
hold harmless Microchip from any and all damages, claims,
suits, or expenses resulting from such use. No licenses are
conveyed, implicitly or otherwise, under any Microchip
intellectual property rights.
Trademarks
The Microchip name and logo, the Microchip logo, Accuron,
dsPIC, KEELOQ, microID, MPLAB, PIC, PICmicro, PICSTART,
PRO MATE, PowerSmart, rfPIC, and SmartShunt are
registered trademarks of Microchip Technology Incorporated
in the U.S.A. and other countries.
AmpLab, FilterLab, Migratable Memory, MXDEV, MXLAB,
SEEVAL, SmartSensor and The Embedded Control Solutions
Company are registered trademarks of Microchip Technology
Incorporated in the U.S.A.
Analog-for-the-Digital Age, Application Maestro, CodeGuard,
dsPICDEM, dsPICDEM.net, dsPICworks, ECAN,
ECONOMONITOR, FanSense, FlexROM, fuzzyLAB,
In-Circuit Serial Programming, ICSP, ICEPIC, Linear Active
Thermistor, Mindi, MiWi, MPASM, MPLIB, MPLINK, PICkit,
PICDEM, PICDEM.net, PICLAB, PICtail, PowerCal,
PowerInfo, PowerMate, PowerTool, REAL ICE, rfLAB,
rfPICDEM, Select Mode, Smart Serial, SmartTel, Total
Endurance, UNI/O, WiperLock and ZENA are trademarks of
Microchip Technology Incorporated in the U.S.A. and other
countries.
SQTP is a service mark of Microchip Technology Incorporated
in the U.S.A.
All other trademarks mentioned herein are property of their
respective companies.
© 2007, Microchip Technology Incorporated, Printed in the
U.S.A., All Rights Reserved.
Printed on recycled paper.
Microchip received ISO/TS-16949:2002 certification for its worldwide
headquarters, design and wafer fabrication facilities in Chandler and
Tempe, Arizona, Gresham, Oregon and Mountain View, California. The
Company’s quality system processes and procedures are for its PIC®
MCUs and dsPIC DSCs, KEELOQ® code hopping devices, Serial
EEPROMs, microperipherals, nonvolatile memory and analog
products. In addition, Microchip’s quality system for the design and
manufacture of development systems is ISO 9001:2000 certified.
© 2007 Microchip Technology Inc.
DS20090C-page 37
WORLDWIDE SALES AND SERVICE
AMERICAS
ASIA/PACIFIC
ASIA/PACIFIC
EUROPE
Corporate Office
2355 West Chandler Blvd.
Chandler, AZ 85224-6199
Tel: 480-792-7200
Fax: 480-792-7277
Technical Support:
http://support.microchip.com
Web Address:
www.microchip.com
Asia Pacific Office
Suites 3707-14, 37th Floor
Tower 6, The Gateway
Habour City, Kowloon
Hong Kong
Tel: 852-2401-1200
Fax: 852-2401-3431
India - Bangalore
Tel: 91-80-4182-8400
Fax: 91-80-4182-8422
India - New Delhi
Tel: 91-11-4160-8631
Fax: 91-11-4160-8632
Austria - Wels
Tel: 43-7242-2244-39
Fax: 43-7242-2244-393
Denmark - Copenhagen
Tel: 45-4450-2828
Fax: 45-4485-2829
India - Pune
Tel: 91-20-2566-1512
Fax: 91-20-2566-1513
France - Paris
Tel: 33-1-69-53-63-20
Fax: 33-1-69-30-90-79
Japan - Yokohama
Tel: 81-45-471- 6166
Fax: 81-45-471-6122
Germany - Munich
Tel: 49-89-627-144-0
Fax: 49-89-627-144-44
Atlanta
Duluth, GA
Tel: 678-957-9614
Fax: 678-957-1455
Boston
Westborough, MA
Tel: 774-760-0087
Fax: 774-760-0088
Chicago
Itasca, IL
Tel: 630-285-0071
Fax: 630-285-0075
Dallas
Addison, TX
Tel: 972-818-7423
Fax: 972-818-2924
Detroit
Farmington Hills, MI
Tel: 248-538-2250
Fax: 248-538-2260
Kokomo
Kokomo, IN
Tel: 765-864-8360
Fax: 765-864-8387
Los Angeles
Mission Viejo, CA
Tel: 949-462-9523
Fax: 949-462-9608
Santa Clara
Santa Clara, CA
Tel: 408-961-6444
Fax: 408-961-6445
Toronto
Mississauga, Ontario,
Canada
Tel: 905-673-0699
Fax: 905-673-6509
Australia - Sydney
Tel: 61-2-9868-6733
Fax: 61-2-9868-6755
China - Beijing
Tel: 86-10-8528-2100
Fax: 86-10-8528-2104
China - Chengdu
Tel: 86-28-8665-5511
Fax: 86-28-8665-7889
Korea - Gumi
Tel: 82-54-473-4301
Fax: 82-54-473-4302
China - Fuzhou
Tel: 86-591-8750-3506
Fax: 86-591-8750-3521
Korea - Seoul
Tel: 82-2-554-7200
Fax: 82-2-558-5932 or
82-2-558-5934
China - Hong Kong SAR
Tel: 852-2401-1200
Fax: 852-2401-3431
Malaysia - Penang
Tel: 60-4-646-8870
Fax: 60-4-646-5086
China - Qingdao
Tel: 86-532-8502-7355
Fax: 86-532-8502-7205
Philippines - Manila
Tel: 63-2-634-9065
Fax: 63-2-634-9069
China - Shanghai
Tel: 86-21-5407-5533
Fax: 86-21-5407-5066
Taiwan - Hsin Chu
Tel: 886-3-572-9526
Fax: 886-3-572-6459
China - Shenzhen
Tel: 86-755-8203-2660
Fax: 86-755-8203-1760
Taiwan - Kaohsiung
Tel: 886-7-536-4818
Fax: 886-7-536-4803
China - Shunde
Tel: 86-757-2839-5507
Fax: 86-757-2839-5571
Taiwan - Taipei
Tel: 886-2-2500-6610
Fax: 886-2-2508-0102
China - Wuhan
Tel: 86-27-5980-5300
Fax: 86-27-5980-5118
Netherlands - Drunen
Tel: 31-416-690399
Fax: 31-416-690340
Singapore
Tel: 65-6334-8870
Fax: 65-6334-8850
China - Shenyang
Tel: 86-24-2334-2829
Fax: 86-24-2334-2393
Italy - Milan
Tel: 39-0331-742611
Fax: 39-0331-466781
Thailand - Bangkok
Tel: 66-2-694-1351
Fax: 66-2-694-1350
Spain - Madrid
Tel: 34-91-708-08-90
Fax: 34-91-708-08-91
UK - Wokingham
Tel: 44-118-921-5869
Fax: 44-118-921-5820
China - Xian
Tel: 86-29-8833-7250
Fax: 86-29-8833-7256
12/08/06
DS20090C-page 38
© 2007 Microchip Technology Inc.