資料介紹
PCB圖如下:
?
成分
MCP23017T-E/SO 微芯片技術 |
× 1 |
CC0805KRX7R9BB104 國巨 |
× 1 |
CC0805ZRY5V6BB105 國巨 |
× 1 |
CL21A475KAQNNNE 三星電機 |
× 1 |
AECR0805F1K00K9 電阻 0805 1k 今日電阻 |
× 2 |
描述
面包板友好型 MCP23017 分線器
2C 端口擴展器或擴展器是非常有用的設備,我在我的項目中使用了很多。我的首選設備絕對是 PCF8574,主要是因為它有點“面包板友好”。MCP23017 沒有本地可用的現有分接頭。因此,我決定設計我自己的面包板友好型 MCP23017 分線板版本。
分線模塊 PCB 及其特性
面包板友好型 MCP23017 分線板 - 正面
面包板友好型 MCP23017 分線板 – 返回
雖然這絕對是我比較容易的項目之一,但仍然需要一些時間才能讓它恰到好處并將一些基本組件和功能直接添加到 PCB 上。
本次突破的主要特點:
– DIP12 布局 – 所有引腳都斷開,地址引腳到跳線頭……
– 適當的去耦電容,盡可能靠近 MCP23017 芯片。
我不得不利用 PCB 的背面層來做到這一點,這并不完全理想,但有適當的電源和接地層,以及漂亮的厚走線,我相信它們會很好。
– 地址選擇器跳線 – 本地可用的分線器沒有這些。
– 面包板友好布局 – 33.020 毫米 x 20.320 毫米 [電路板尺寸],各排引腳之間的垂直間距為 15.240 毫米,確保您可以輕松地將其安裝到面包板上,同時仍有空間將跳線添加到引腳。水平引腳間距為標準 2.54mm。
原理圖
原理圖簡單明了。不過有幾點需要注意:
– 原理圖上未顯示地址選擇頭以及 io 引腳頭。
– I2C 上拉電阻設置為 1k,但可以根據電路的需要替換為更合適的值
使用突破
讓我們看看這款芯片的一些特點
16 位遠程雙向 I/O 端口:
I/O 引腳默認為輸入
? 高速 I2C 接口 (MCP23017):
100kHz
400kHz
1.7兆赫
? 高速 SPI 接口 (MCP23S17):
10 兆赫(最大)
? 三個硬件地址引腳最多允許
總線上有八個設備
? 可配置中斷輸出引腳:
可配置為高電平有效、低電平有效或
開漏
? INTA 和 INTB 可配置為運行
獨立或一起
? 可配置中斷源:
來自配置寄存器的變化中斷
默認值或引腳更改
? 極性反轉寄存器配置
輸入端口數據的極性
? 外部復位輸入
? 低待機電流:1 μA(最大值)
? 工作電壓:
1.8V 至 5.5V @ -40°C 至 +85°C
2.7V 至 5.5V @ -40°C 至 +85°C
4.5V 至 5.5V @ -40°C 至 +125°C
16 個 I/O 端口分為兩個“端口”——A(右側)和 B(左側)。引腳 9 連接到 5V,10 到 GND,11 未使用,12 是 I2C 總線時鐘線(Arduino Uno/Duemailnove 模擬引腳 5,Mega 引腳 21)和 13 是 I2C 總線數據線(Arduino Uno/Duemailnove 模擬引腳 4,Mega 引腳 20)。
應在 I2C 總線上使用外部上拉電阻——在我們的示例中,我們使用 1k 歐姆值。引腳 14 未使用,我們不會查看中斷,因此請忽略引腳 19 和 20。引腳 18 是復位引腳,通常為高電平 - 因此您將其接地以復位 IC。所以把它連接到5V!
最后我們得到了三個硬件地址引腳 15~17。這些用于確定芯片的 I2C 總線地址。如果將它們全部連接到 GND,則地址為 0x20。如果您有其他具有該地址的器件或需要使用多個 MCP23017,請參見數據表中的圖 1-2。
您可以通過將引腳 15~17 的組合連接到 5V (1) 或 GND (0) 來更改地址。例如,如果將 15~17 全部連接到 5V,則控制字節變為二進制的 0100111,或十六進制的 0x27。
使用標準 Wire.h 庫
尋址
23017 具有三個輸入引腳,允許您為每個連接的 MCP23017 設置不同的地址。
以上對應于對應于 IC 輸入引腳值的三行 A0、A1、A2 的硬件地址。您必須將這些硬件輸入的值設置為 0V 或(高)伏特,不要讓它們懸空,否則它們會從電噪聲中獲得隨機值,芯片將無能為力!
最左邊的四位固定為 0100(由向制造商分配地址范圍的聯盟指定)。
因此 MCP23017 I2C 地址范圍是十進制 32 到十進制 37 或 MCP23017 的 0x20 到 0x27。
請注意:地址與 PCF8475 相同。因此,如果您在同一 i2c 總線上使用這兩個設備,則必須小心!
MCP23017 非中斷寄存器
IODIR I/O 方向寄存器
為了控制每個引腳的 I/O 方向,寄存器 IODIR (A/B) 允許您在寫入零時將引腳設置為輸出,在向寄存器位寫入“1”時將引腳設置為輸入。這與大多數微控制器的方案相同——關鍵是要記住零(“0”)等于輸出中的“O”。
GPPU上拉寄存器
設置一個高位設置相應 I/O 引腳的上拉有效。
OLAT 輸出鎖存器
這與 18F 系列 PIC 芯片中的 I/O 端口完全相同,無論是否達到該引腳的實際狀態,您都可以讀回端口引腳的“所需”輸出。即考慮連接到引腳的強電流 LED - 很容易將引腳上的輸出電壓拉低到邏輯閾值以下,即如果從引腳本身讀取,您會讀回零,而實際上它應該是一. 從軟件工程的角度來看,讀取 OLAT 寄存器位會返回“一”。
IPOL 引腳反轉寄存器
IPOL(A/B) 寄存器允許您選擇性地反轉任何輸入引腳。這減少了將其他設備連接到 MCP23017 所需的膠合邏輯,因為您無需添加反相邏輯芯片即可將正確的信號極性輸入 MCP23017。
以正確的方式獲取信號也非常方便,例如通常使用上拉電阻進行輸入,因此當用戶按下輸入鍵時,電壓輸入為零,因此在軟件中您必須記住測試零。
使用 MCP23017,您可以反轉該輸入并測試 1(在我看來,按鍵更等同于開啟狀態,即“1”)但是我一直使用上拉(并且 uC 通常在啟用時使用內部上拉) 所以必須忍受零作為“按下”。使用此設備可以輕松糾正此問題。注意:到處使用低電平有效信號的原因是歷史原因:TTL(晶體管晶體管邏輯)設備由于內部電路而在低電平有效狀態下消耗更多功率,并且它對于減少不必要的功耗非常重要——因此,大多數時間處于非活動狀態的信號(例如芯片選擇信號)被定義為高電平。對于 CMOS 設備,任何一種狀態都會導致相同的功耗,因此現在無關緊要 - 但是使用低電平有效,因為每個人現在都使用它并且過去使用它。
SEQOP 輪詢模式:寄存器位:(在 IOCON 寄存器內)
如果您的設計具有關鍵中斷代碼,例如用于執行時序關鍵測量,您可能不希望非關鍵輸入產生中斷,即您為最重要的輸入數據保留中斷。
在這種情況下,允許輪詢某些設備輸入可能更有意義。為了便于實現這一點,提供了“字節模式”。在此模式下,您可以使用時鐘讀取同一組 GPIO,而無需提供其他控制信息。即它保持在同一組 GPIO 位上,您可以連續讀取它而無需更新寄存器地址。在非字節模式下,您要么必須將從(A 或 B 組)讀取的地址設置為控制輸入數據。
現在來檢查如何在我們的草圖中使用 IC。
正如您現在應該知道的,大多數 I2C 設備都有幾個可以尋址的寄存器。每個地址包含一個字節的數據,用于確定各種選項。所以在使用之前我們需要設置每個端口是輸入還是輸出。首先,我們將檢查將它們設置為輸出。
因此,要將端口 A 設置為輸出,我們使用:
Wire.beginTransmission(0x20);
Wire.write(0x00); // IODIRA 寄存器
Wire.write(0x00); // 將所有端口 A 設置為輸出
Wire.endTransmission();
然后將端口 B 設置為輸出,我們使用:
Wire.beginTransmission(0x20);
Wire.write(0x01); // IODIRB 寄存器
Wire.write(0x00); // 將所有端口 B 設置為輸出
Wire.endTransmission();
所以現在我們處于 void loop() 或您自己創建的函數中,并且想要控制一些輸出引腳。要控制端口 A,我們使用:
Wire.beginTransmission(0x20);
Wire.write(0x12); //地址端口A
Wire.write(??); //要發送的值
Wire.endTransmission();
要控制端口 B,我們使用:
Wire.beginTransmission(0x20);
Wire.write(0x13); //地址端口B
Wire.write(??); //要發送的值
Wire.endTransmission();
……更換??將二進制或等效的十六進制或十進制值發送到寄存器。
要計算所需的數字,請考慮從 7 到 0 的每個 I/O 引腳匹配二進制數的一位 - 1 表示開啟,0 表示關閉。因此,您可以插入一個表示每個輸出引腳狀態的二進制數。或者,如果您使用二進制,請將其轉換為十六進制。或十進制數。
例如,您希望引腳 7 和 1 打開。二進制表示 10000010,十六進制表示 0x82,或 130 十進制。(如果要顯示遞增值或函數結果中的值,使用小數會很方便)。
例如,我們希望端口 A 為 11001100,端口 B 為 10001000 - 所以我們發送以下內容(注意我們將二進制值轉換為十進制):
Wire.beginTransmission(0x20);
Wire.write(0x12); //地址端口A
Wire.write(204); //要發送的值
Wire.endTransmission();
Wire.beginTransmission(0x20);
Wire.write(0x13); //地址端口B
Wire.write(136); //要發送的值
Wire.endTransmission();
一個完整的例子
// 引腳 15~17 到 GND,I2C 總線地址為 0x20
#include "Wire.h"
無效設置()
{
Wire.begin(); // 喚醒 I2C 總線
// 將 I/O 引腳設置為輸出
Wire.beginTransmission(0x20);
Wire.write(0x00); // IODIRA 寄存器
Wire.write(0x00); // 將所有端口 A 設置為輸出
Wire.endTransmission();
Wire.beginTransmission(0x20);
Wire.write(0x01); // IODIRB 寄存器
Wire.write(0x00); // 將所有端口 B 設置為輸出
Wire.endTransmission();
}
無效二進制計數()
{
對于(字節 a=0;a<256;a++)
{
Wire.beginTransmission(0x20);
Wire.write(0x12); // GPIOA
Wire.write(a); // 端口 A
Wire.endTransmission();
Wire.beginTransmission(0x20);
Wire.write(0x13); // 通用輸入輸出接口
Wire.write(a); // 端口 B
Wire.endTransmission();
}
}
無效循環()
{
二進制計數();
延遲(500);
}
使用引腳作為輸入
盡管這可能看起來像是一個簡單的演示,但它的創建展示了如何使用輸出。所以現在您知道如何控制設置為輸出的 I/O 引腳了。請注意,您不能從每個引腳提供超過 25 mA 的電流,因此如果切換更高的電流負載,請使用晶體管和外部電源等。
現在讓我們扭轉局面,繼續使用 I/O 引腳作為數字輸入。MCP23017 I/O 引腳默認為輸入模式,因此我們只需啟動 I2C 總線。然后在 void loop() 或其他函數中,我們所做的就是設置寄存器的地址來讀取和接收一個字節的數據。
// 引腳 15~17 到 GND,I2C 總線地址為 0x20
#include "Wire.h"
字節輸入=0;
無效設置()
{
序列號.開始(9600);
Wire.begin(); // 喚醒 I2C 總線
}
無效循環()
{
Wire.beginTransmission(0x20);
Wire.write(0x13); // 將 MCP23017 內存指針設置為 GPIOB 地址
Wire.endTransmission();
Wire.requestFrom(0x20, 1); // 從 MCP20317 請求一個字節的數據
輸入=Wire.read(); // 將傳入的字節存儲到“輸入”中
if (inputs>0) // 如果按鈕被按下
{
Serial.println(輸入,BIN);// 以二進制顯示GPIOB寄存器的內容
延遲(200);// 去抖動
}
}
使用 Adafruit 庫
您可以從此處下載 Adafruit MCP23017 庫。
一些例子,直接來自庫,所有代碼都屬于Adafruit,不是我寫的。
1. 按鈕示例
#include
#include “Adafruit_MCP23017.h”
// MCP23017 I/O 擴展器的基本引腳讀取和上拉測試
// 公共區域!
// 將擴展器的引腳 #12 連接到模擬 5(i2c 時鐘)
// 將擴展器的引腳 #13 連接到模擬 4(i2c 數據)
// 將擴展器的引腳#15、16 和 17 接地(地址選擇)
// 將擴展器的引腳 #9 連接到 5V(電源)
// 將擴展器的引腳 #10 接地(公共接地)
//通過?10kohm電阻將引腳#18連接到5V(復位引腳,低電平有效)
// 輸入#0 在引腳 21 上,因此連接一個按鈕或從那里切換到地
Adafruit_MCP23017 mcp;
無效設置(){
mcp.begin(); // 使用默認地址 0
mcp.pinMode(0,輸入);
mcp.pullUp(0, HIGH); // 在內部開啟 100K 上拉
pinMode(13,輸出);// 使用 p13 LED 作為調試
}
無效循環(){
// LED 將“回顯”按鈕
數字寫入(13,mcp.digitalRead(0));
}
2. 中斷示例
// 安裝 LowPower 庫以獲得可選的睡眠支持。
// 有關用法的詳細信息,請參閱 loop() 函數注釋。
//#include
#include
#include
Adafruit_MCP23017 mcp;
字節 LEDPin=13;
// 來自 MCP 的中斷將由該 PIN 處理
字節arduinoIntPin=3;
// ... 還有這個中斷向量
字節 arduinoInterrupt=1;
volatile boolean wakeByInterrupt = false;
// MCP 上的兩個引腳(端口 A/B,其中一些按鈕已設置。)
// 按鈕將引腳連接到地,引腳被拉起。
字節 mcpPinA=7;
字節 mcpPinB=15;
無效設置(){
序列號.開始(9600);
Serial.println("MCP23007 中斷測試");
pinMode(arduinoIntPin,輸入);
mcp.begin(); // 使用默認地址 0
// 我們鏡像 INTA 和 INTB,因此在 MCP 和 Arduino 之間只需要一條線用于 int 報告
// INTA/B 不會浮動
// INT 將發出 LOW 信號
mcp.setupInterrupts(true,false,LOW);
// 端口 A 上的按鈕配置
// 當引腳被按鈕接地時將觸發中斷
mcp.pinMode(mcpPinA,輸入);
mcp.pullUp(mcpPinA,高);// 在內部開啟 100K 上拉
mcp.setupInterruptPin(mcpPinA,FALLING);
// 類似,但在端口 B。
mcp.pinMode(mcpPinB,輸入);
mcp.pullUp(mcpPinB, HIGH); // 在內部打開 100K 上拉電阻
mcp.setupInterruptPin(mcpPinB,FALLING);
// 我們將從 int 例程中設置一個用于閃爍的引腳
pinMode(ledPin,輸出);// 使用 p13 LED 作為調試
}
// int 處理程序只會發出 int 已經發生的信號
// 我們將從主循環中完成工作。
無效intCallBack(){
喚醒中斷=真;
}
無效句柄中斷(){
// 從 INT 獲取 MCP 的更多信息
uint8_t pin=mcp.getLastInterruptPin();
uint8_t val=mcp.getLastInterruptPinValue();
// 我們將根據觸發中斷的 PIN 使 LED 閃爍 1 或 2 次
// 3 和 4 個 flases 應該是不可能的條件......只是為了調試。
uint8_t 閃爍=4;
如果(pin==mcpPinA)閃爍=1;
如果(pin==mcpPinB)閃爍=2;
if(val!=LOW) 閃爍=3;
// 模擬一些與此相關的輸出
for(int i=0;i<閃爍;i++){
延遲(100);
數字寫入(ledPin,HIGH);
延遲(100);
數字寫入(ledPin,低);
}
// 我們必須等待中斷條件完成
// 否則我們可能會在持續狀態下進入睡眠狀態,并且再也不會醒來。
// 因為,需要一個動作來清除 INT 標志,并允許它再次觸發。
// 請參閱數據表了解數據。
而(!(mcp.digitalRead(mcpPinB)&& mcp.digitalRead(mcpPinA)));
// 并清除排隊的 INT 信號
清潔中斷();
}
// 方便按鈕觸發的中斷
// 由于彈跳問題,通常會發出一些信號
無效的清潔中斷(){
EIFR=0x01;
喚醒中斷=假;
}
/**
*主要程序:讓arduino睡覺,并在中斷時醒來。
* 睡眠需要 LowPower 庫或類似庫,但此處模擬睡眠。
* 如數據表所述,實際上可以讓 MCP 在待機時僅消耗 1uA,
* 但是沒有待機模式。這一切都歸結為以電流不流動的方式設置每個引腳。
* 并且您可以在等待時等待中斷。
*/
無效循環(){
// 在進入睡眠/等待之前啟用中斷
// 我們為 arduino INT 處理程序設置了一個回調。
attachInterrupt(arduinoInterrupt,intCallBack,FALLING);
//模擬深度睡眠
while(!awakenByInterrupt);
// 或者讓 arduino 睡覺,這個庫很棒,如果你有的話。
//LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF);
// 在處理中斷時禁用中斷。
分離中斷(arduinoInterrupt);
如果(喚醒ByInterrupt)句柄中斷();
}
代碼
https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library
- 面包板電源軌橋開源分享
- 重新設計的MCP23017分線
- MCP23017分線板IOBOB開源
- MCP23017無延遲閃爍開源項目
- 使用Galileo II和ANSI C驅動MCP23017 IO擴展器16個通用輸出
- 面包板空氣吉他開源分享
- 使用ICL7660、3 個帽和運算放大器的面包板友好型溢出導軌PSU
- CAN BUS分線器開源項目
- arduino和其他開發板的面包板開源項目
- ATX分線板開源項目
- MCP23017 16位GPIO擴展器演示板
- 基于MCP23017的32通道具有I2C控制的繼電器和電磁閥驅動器
- MCP23017-E_SS 16路IO擴展模塊 IIC擴展板
- MCP23017和MCP23S17帶有串行接口的16位IO擴展器數據手冊免費下載 73次下載
- MCP23017/MCP23S17帶有串行接口的16位 I/O擴展器相關資料.pdf 118次下載
- 關于差分線的問題解答 1196次閱讀
- 優秀的IC/FPGA開源項目:偽紅外圖像處理 1949次閱讀
- MCP存儲器以及MCP存儲器的應用介紹 4590次閱讀
- 淺談差分處理和信號分析 1967次閱讀
- 微雪電子MCP23017 IO擴展模塊16IO口 I2C接口簡介 1.3w次閱讀
- dfrobot面包板電源板簡介 2621次閱讀
- dfrobot面包板U型實驗跳線介紹 2829次閱讀
- dfrobot優質迷你面包板簡介 1706次閱讀
- digilent繞接板面包板介紹 1817次閱讀
- dfrobot中型面包板簡介 1118次閱讀
- digilent無焊面包板套件(大)介紹 1150次閱讀
- digilent無焊面包板套件(小)介紹 1096次閱讀
- dfrobot高品質面包線簡介 1519次閱讀
- 分線盒的作用是什么?分線器和路由器的區別 3w次閱讀
- 威爾金森型功分器仿真實驗 1w次閱讀
下載排行
本周
- 1山景DSP芯片AP8248A2數據手冊
- 1.06 MB | 532次下載 | 免費
- 2RK3399完整板原理圖(支持平板,盒子VR)
- 3.28 MB | 339次下載 | 免費
- 3TC358743XBG評估板參考手冊
- 1.36 MB | 330次下載 | 免費
- 4DFM軟件使用教程
- 0.84 MB | 295次下載 | 免費
- 5元宇宙深度解析—未來的未來-風口還是泡沫
- 6.40 MB | 227次下載 | 免費
- 6迪文DGUS開發指南
- 31.67 MB | 194次下載 | 免費
- 7元宇宙底層硬件系列報告
- 13.42 MB | 182次下載 | 免費
- 8FP5207XR-G1中文應用手冊
- 1.09 MB | 178次下載 | 免費
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 2555集成電路應用800例(新編版)
- 0.00 MB | 33566次下載 | 免費
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費
- 4開關電源設計實例指南
- 未知 | 21549次下載 | 免費
- 5電氣工程師手冊免費下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費
- 6數字電路基礎pdf(下載)
- 未知 | 13750次下載 | 免費
- 7電子制作實例集錦 下載
- 未知 | 8113次下載 | 免費
- 8《LED驅動電路設計》 溫德爾著
- 0.00 MB | 6656次下載 | 免費
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費
- 2protel99se軟件下載(可英文版轉中文版)
- 78.1 MB | 537798次下載 | 免費
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420027次下載 | 免費
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費
- 6電路仿真軟件multisim 10.0免費下載
- 340992 | 191187次下載 | 免費
- 7十天學會AVR單片機與C語言視頻教程 下載
- 158M | 183279次下載 | 免費
- 8proe5.0野火版下載(中文版免費下載)
- 未知 | 138040次下載 | 免費
評論
查看更多